Merge pull request 'Add new archive manager, removed Panama & HybridCrypt, config utility improvements' (#20) from nightly into master

Reviewed-on: #20
This commit is contained in:
Exynox 2025-04-12 10:36:11 +03:00
commit 6c1e703ee2
71 changed files with 1026 additions and 4693 deletions

3
bin/.gitignore vendored
View File

@ -16,8 +16,7 @@ log.txt
syserr.txt syserr.txt
# Game files # Game files
pack/*.eix pack/*.zip
pack/*.epk
# Guild images # Guild images
mark/ mark/

View File

@ -1,249 +1,102 @@
PACK patch1 ZIP
* season3_eu ZIP
patch1 patch2 ZIP
* metin2_patch_snow ZIP
season3_eu metin2_patch_snow_dungeon ZIP
* metin2_patch_etc_costume1 ZIP
patch2 metin2_patch_pet1 ZIP
* metin2_patch_pet2 ZIP
metin2_patch_snow metin2_patch_ramadan_costume ZIP
pack/ metin2_patch_flame ZIP
metin2_patch_snow_dungeon metin2_patch_flame_dungeon ZIP
pack/ metin2_patch_w21_etc ZIP
metin2_patch_etc_costume1 metin2_patch_w21_mobs ZIP
pack/ metin2_patch_w21_mobs_m ZIP
metin2_patch_pet1 metin2_patch_dss_box ZIP
pack/ metin2_patch_costume_soccer ZIP
metin2_patch_pet2 metin2_patch_easter1 ZIP
pack/ metin2_patch_mineral ZIP
metin2_patch_ramadan_costume metin2_patch_w20_sound ZIP
pack/ metin2_patch_ds ZIP
metin2_patch_flame metin2_patch_5th_armor ZIP
pack/ metin2_patch_w20_etc ZIP
metin2_patch_flame_dungeon metin2_patch_dragon_rock ZIP
pack/ metin2_patch_dragon_rock_mobs ZIP
metin2_patch_w21_etc metin2_patch_etc ZIP
pack/ metin2_patch_xmas ZIP
metin2_patch_w21_mobs metin2_patch_eu3 ZIP
pack/ metin2_patch_eu4 ZIP
metin2_patch_w21_mobs_m metin2_patch_mundi ZIP
pack/ metin2_patch_sd ZIP
metin2_patch_dss_box metin2_patch_halloween ZIP
pack/ metin2_patch_party ZIP
metin2_patch_costume_soccer metin2_patch_dance ZIP
pack/ pc ZIP
metin2_patch_easter1 pc2 ZIP
pack/ monster ZIP
metin2_patch_mineral monster2 ZIP
pack/ effect ZIP
metin2_patch_w20_sound zone ZIP
pack/ terrain ZIP
metin2_patch_ds npc ZIP
pack/ npc2 ZIP
metin2_patch_5th_armor tree ZIP
pack/ guild ZIP
metin2_patch_w20_etc item ZIP
pack/ textureset ZIP
metin2_patch_dragon_rock property ZIP
pack/ icon ZIP
metin2_patch_dragon_rock_mobs season1 ZIP
pack/ season2 ZIP
metin2_patch_etc outdoora1 ZIP
pack/ outdoora2 ZIP
metin2_patch_xmas outdoora3 ZIP
pack/ outdoorb1 ZIP
metin2_patch_eu3 outdoorb3 ZIP
pack/ outdoorc1 ZIP
metin2_patch_eu4 outdoorc3 ZIP
pack/ outdoorsnow1 ZIP
metin2_patch_mundi outdoordesert1 ZIP
pack/ outdoorflame1 ZIP
metin2_patch_sd outdoorfielddungeon1 ZIP
pack/ outdoort1 ZIP
metin2_patch_halloween outdoort2 ZIP
pack/ outdoort3 ZIP
metin2_patch_party outdoort4 ZIP
pack/ outdoorwedding ZIP
metin2_patch_dance outdoormilgyo1 ZIP
d:/ymir work/pc/ indoorspiderdungeon1 ZIP
pc indoordeviltower1 ZIP
d:/ymir work/pc2/ indoormonkeydungeon1 ZIP
pc2 indoormonkeydungeon2 ZIP
d:/ymir work/monster/ indoormonkeydungeon3 ZIP
monster outdoortrent02 ZIP
d:/ymir work/monster2/ outdoorguild1 ZIP
monster2 outdoorguild2 ZIP
d:/ymir work/effect/ outdoorguild3 ZIP
effect outdoortrent ZIP
d:/ymir work/zone/ outdoorduel ZIP
zone outdoorgmguildbuild ZIP
d:/ymir work/terrainmaps/ sound ZIP
terrain sound_m ZIP
d:/ymir work/npc/ sound2 ZIP
npc bgm ZIP
d:/ymir work/npc2/ ETC ZIP
npc2 locale_de ZIP
d:/ymir work/tree/ locale_es ZIP
tree locale_fr ZIP
d:/ymir work/guild/ locale_gr ZIP
guild locale_it ZIP
d:/ymir work/item/ locale_nl ZIP
item locale_pl ZIP
textureset/ locale_pt ZIP
textureset locale_tr ZIP
property/ locale_en ZIP
property locale_ro ZIP
icon/ locale_ru ZIP
icon locale_dk ZIP
season1/ locale_cz ZIP
season1 locale_hu ZIP
season2/ uiscript ZIP
season2 uiloading ZIP
metin2_map_a1/ root ZIP
outdoora1
map_a2/
outdoora2
metin2_map_a3/
outdoora3
metin2_map_b1/
outdoorb1
metin2_map_b3/
outdoorb3
metin2_map_c1/
outdoorc1
metin2_map_c3/
outdoorc3
map_n_snowm_01/
outdoorsnow1
metin2_map_n_desert_01/
outdoordesert1
metin2_map_n_flame_01/
outdoorflame1
map_b_fielddungeon/
outdoorfielddungeon1
metin2_map_t1/
outdoort1
metin2_map_t2/
outdoort2
metin2_map_t3/
outdoort3
metin2_map_t4/
outdoort4
metin2_map_wedding_01/
outdoorwedding
metin2_map_milgyo/
outdoormilgyo1
metin2_map_spiderdungeon/
indoorspiderdungeon1
metin2_map_deviltower1/
indoordeviltower1
metin2_map_monkeydungeon/
indoormonkeydungeon1
metin2_map_monkeydungeon_02/
indoormonkeydungeon2
metin2_map_monkeydungeon_03/
indoormonkeydungeon3
metin2_map_trent02/
outdoortrent02
metin2_map_guild_01/
outdoorguild1
metin2_map_guild_02/
outdoorguild2
metin2_map_guild_03/
outdoorguild3
metin2_map_trent/
outdoortrent
metin2_map_trent02/
outdoortrent02
metin2_map_duel/
outdoorduel
gm_guild_build/
outdoorgmguildbuild
sound/ambience/
sound
sound/common/
sound
sound/effect/
sound
sound/monster/
sound
sound/npc/
sound
sound/pc/
sound
sound/ui/
sound
sound/ambience/
sound_m
sound/common/
sound_m
sound/effect/
sound_m
sound/monster/
sound_m
sound/npc/
sound_m
sound/pc/
sound_m
sound/ui/
sound_m
sound/monster2/
sound2
sound/pc2/
sound2
bgm/
bgm
d:/ymir work/special/
ETC
d:/ymir work/environment/
ETC
locale/ca/
locale_ca
locale/ae/
locale_ae
locale/de/
locale_de
locale/es/
locale_es
locale/fr/
locale_fr
locale/gr/
locale_gr
locale/it/
locale_it
locale/nl/
locale_nl
locale/pl/
locale_pl
locale/pt/
locale_pt
locale/tr/
locale_tr
locale/uk/
locale_uk
locale/bg/
locale_bg
locale/en/
locale_en
locale/mx/
locale_mx
locale/ro/
locale_ro
locale/ru/
locale_ru
locale/dk/
locale_dk
locale/cz/
locale_cz
locale/hu/
locale_hu
locale/us/
locale_us
locale/pa/
locale_pa
uiscript/
uiscript
d:/ymir work/ui/
ETC
d:/ymir work/uiloading/
uiloading

102
bin/pack/Index.dev Normal file
View File

@ -0,0 +1,102 @@
patch1 FOLDER
season3_eu FOLDER
patch2 FOLDER
metin2_patch_snow FOLDER
metin2_patch_snow_dungeon FOLDER
metin2_patch_etc_costume1 FOLDER
metin2_patch_pet1 FOLDER
metin2_patch_pet2 FOLDER
metin2_patch_ramadan_costume FOLDER
metin2_patch_flame FOLDER
metin2_patch_flame_dungeon FOLDER
metin2_patch_w21_etc FOLDER
metin2_patch_w21_mobs FOLDER
metin2_patch_w21_mobs_m FOLDER
metin2_patch_dss_box FOLDER
metin2_patch_costume_soccer FOLDER
metin2_patch_easter1 FOLDER
metin2_patch_mineral FOLDER
metin2_patch_w20_sound FOLDER
metin2_patch_ds FOLDER
metin2_patch_5th_armor FOLDER
metin2_patch_w20_etc FOLDER
metin2_patch_dragon_rock FOLDER
metin2_patch_dragon_rock_mobs FOLDER
metin2_patch_etc FOLDER
metin2_patch_xmas FOLDER
metin2_patch_eu3 FOLDER
metin2_patch_eu4 FOLDER
metin2_patch_mundi FOLDER
metin2_patch_sd FOLDER
metin2_patch_halloween FOLDER
metin2_patch_party FOLDER
metin2_patch_dance FOLDER
pc FOLDER
pc2 FOLDER
monster FOLDER
monster2 FOLDER
effect FOLDER
zone FOLDER
terrain FOLDER
npc FOLDER
npc2 FOLDER
tree FOLDER
guild FOLDER
item FOLDER
textureset FOLDER
property FOLDER
icon FOLDER
season1 FOLDER
season2 FOLDER
outdoora1 FOLDER
outdoora2 FOLDER
outdoora3 FOLDER
outdoorb1 FOLDER
outdoorb3 FOLDER
outdoorc1 FOLDER
outdoorc3 FOLDER
outdoorsnow1 FOLDER
outdoordesert1 FOLDER
outdoorflame1 FOLDER
outdoorfielddungeon1 FOLDER
outdoort1 FOLDER
outdoort2 FOLDER
outdoort3 FOLDER
outdoort4 FOLDER
outdoorwedding FOLDER
outdoormilgyo1 FOLDER
indoorspiderdungeon1 FOLDER
indoordeviltower1 FOLDER
indoormonkeydungeon1 FOLDER
indoormonkeydungeon2 FOLDER
indoormonkeydungeon3 FOLDER
outdoortrent02 FOLDER
outdoorguild1 FOLDER
outdoorguild2 FOLDER
outdoorguild3 FOLDER
outdoortrent FOLDER
outdoorduel FOLDER
outdoorgmguildbuild FOLDER
sound FOLDER
sound_m FOLDER
sound2 FOLDER
bgm FOLDER
ETC FOLDER
locale_de FOLDER
locale_es FOLDER
locale_fr FOLDER
locale_gr FOLDER
locale_it FOLDER
locale_nl FOLDER
locale_pl FOLDER
locale_pt FOLDER
locale_tr FOLDER
locale_en FOLDER
locale_ro FOLDER
locale_ru FOLDER
locale_dk FOLDER
locale_cz FOLDER
locale_hu FOLDER
uiscript FOLDER
uiloading FOLDER
root FOLDER

View File

@ -6,7 +6,7 @@ ECHO Only use on a clean project directory.
ECHO ====================================================== ECHO ======================================================
rem SET M2_MSVC_DIR=C:\Program Files\Microsoft Visual Studio\2022\Community\ rem SET M2_MSVC_DIR=C:\Program Files\Microsoft Visual Studio\2022\Community\
rem SET M2_PML_PATH=C:\Users\User\Path\To\PackMakerLite\PackMakerLite.exe rem SET M2_7ZIP_PATH=C:\Program Files\7-Zip\7z.exe
rem Check the environment variables rem Check the environment variables
VERIFY OTHER 2>nul VERIFY OTHER 2>nul
@ -16,17 +16,21 @@ IF NOT DEFINED M2_MSVC_DIR (
ECHO M2_MSVC_DIR is NOT defined! Please define M2_MSVC_DIR with the path of your local MSVC install. ECHO M2_MSVC_DIR is NOT defined! Please define M2_MSVC_DIR with the path of your local MSVC install.
EXIT /B -1 EXIT /B -1
) )
IF NOT DEFINED M2_PML_PATH ( IF NOT DEFINED M2_7ZIP_PATH (
ECHO M2_PML_PATH is NOT defined! Please define M2_PML_PATH with the path of your local PackMakerLite executable. ECHO M2_7ZIP_PATH is NOT defined! Please define M2_7ZIP_PATH with the path of your local 7-Zip "7z.exe" executable.
EXIT /B -1 EXIT /B -1
) )
ENDLOCAL ENDLOCAL
rem Cause variables to be expanded at execution time (in order for !errorlevel! to work)
SETLOCAL EnableDelayedExpansion
rem Initialize the MSVC environment rem Initialize the MSVC environment
CALL "%M2_MSVC_DIR%\VC\Auxiliary\Build\vcvars32.bat" CALL "%M2_MSVC_DIR%\VC\Auxiliary\Build\vcvars32.bat"
rem Build rem Build
msbuild Metin2Client.sln /p:Configuration=Distribute /p:Platform="Win32" msbuild Metin2Client.sln /p:Configuration=Distribute /p:Platform="Win32"
if !errorlevel! neq 0 exit /b !errorlevel!
rem Start assembling the client package rem Start assembling the client package
RMDIR /S /Q dist RMDIR /S /Q dist
@ -48,12 +52,11 @@ MKDIR dist\screenshot\
xcopy bin\upload\ dist\upload\ /E /Y /Q xcopy bin\upload\ dist\upload\ /E /Y /Q
rem Build and copy the archives rem Build and copy the archives
DEL /F /Q "bin\pack\*.eix" DEL /F /Q "bin\pack\*.zip"
DEL /F /Q "bin\pack\*.epk"
FOR /d %%i IN ("bin\pack\*") DO ( FOR /d %%i IN ("bin\pack\*") DO (
echo Packing %%i echo Packing %%i
%M2_PML_PATH% --nolog --parallel -p "%%i" "%M2_7ZIP_PATH%" a "%%i.zip" ".\%%i\*"
if !errorlevel! neq 0 exit /b !errorlevel!
) )
MOVE /Y bin\pack\*.eix dist\pack\ MOVE /Y bin\pack\*.zip dist\pack\
MOVE /Y bin\pack\*.epk dist\pack\

View File

@ -3,7 +3,7 @@
#include <d3d9.h> #include <d3d9.h>
#include <algorithm> #include <algorithm>
#include <math.h> #include <vector>
#define APP_NAME _T("Metin2 Config") #define APP_NAME _T("Metin2 Config")
#define FILENAME_CONFIG "metin2.cfg" #define FILENAME_CONFIG "metin2.cfg"
@ -164,12 +164,24 @@ BOOL CMainDialog::OnInitDialog(CWindow wndFocus, LPARAM lInitParam)
m_comboShadow.SetCurSel(m_stConfig.iShadowLevel); m_comboShadow.SetCurSel(m_stConfig.iShadowLevel);
// Language // Language
ATL::CString language;
// Load the languages into an array
std::vector<ATL::CString> languages;
for (int i = 0; i < kLanguageMax; ++i) { for (int i = 0; i < kLanguageMax; ++i) {
ATL::CString language;
language.LoadString(kLanguageConfig[i].stringId); language.LoadString(kLanguageConfig[i].stringId);
m_comboLanguage.InsertString(i, language); languages.push_back(language);
} }
// Sort the array
std::sort(languages.begin(), languages.end(), [](const ATL::CString& a, const ATL::CString& b) {
return a.CompareNoCase(b) < 0;
});
// Add the languages to the combo
for (auto& language : languages)
m_comboLanguage.AddString(language);
m_stConfig.language = std::clamp((int) m_stConfig.language, 0, kLanguageMax - 1); m_stConfig.language = std::clamp((int) m_stConfig.language, 0, kLanguageMax - 1);
m_comboLanguage.SetCurSel(m_stConfig.language); m_comboLanguage.SetCurSel(m_stConfig.language);
@ -229,10 +241,66 @@ void CMainDialog::InitDefaultConfig()
auto lang = PRIMARYLANGID(LANGIDFROMLCID(GetUserDefaultLCID())); auto lang = PRIMARYLANGID(LANGIDFROMLCID(GetUserDefaultLCID()));
switch (lang) { switch (lang) {
case LANG_CZECH:
m_stConfig.language = kLanguageCzech;
break;
case LANG_DANISH:
m_stConfig.language = kLanguageDanish;
break;
case LANG_DUTCH:
m_stConfig.language = kLanguageDutch;
break;
case LANG_ENGLISH:
m_stConfig.language = kLanguageEnglish;
break;
case LANG_FRENCH:
m_stConfig.language = kLanguageFrench;
break;
case LANG_GERMAN: case LANG_GERMAN:
m_stConfig.language = kLanguageGerman; m_stConfig.language = kLanguageGerman;
break; break;
case LANG_GREEK:
m_stConfig.language = kLanguageGreek;
break;
case LANG_HUNGARIAN:
m_stConfig.language = kLanguageHungarian;
break;
case LANG_ITALIAN:
m_stConfig.language = kLanguageItalian;
break;
case LANG_POLISH:
m_stConfig.language = kLanguagePolish;
break;
case LANG_PORTUGUESE:
m_stConfig.language = kLanguagePortuguese;
break;
case LANG_ROMANIAN:
m_stConfig.language = kLanguageRomanian;
break;
case LANG_RUSSIAN:
m_stConfig.language = kLanguageRussian;
break;
case LANG_SPANISH:
m_stConfig.language = kLanguageSpanish;
break;
case LANG_TURKISH:
m_stConfig.language = kLanguageTurkish;
break;
default: default:
m_stConfig.language = kLanguageEnglish; m_stConfig.language = kLanguageEnglish;
break; break;

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
</assembly>

View File

@ -17,3 +17,6 @@ IDR_MAINFRAME ICON "metin2.ico"
#define METIN2_COMPONENT_TYPE VFT_APP #define METIN2_COMPONENT_TYPE VFT_APP
#include <version_info.rc> #include <version_info.rc>
// Visual Styles manifest
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "Metin2Config.exe.manifest"

View File

@ -31,18 +31,18 @@
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v143</PlatformToolset> <PlatformToolset>v143</PlatformToolset>
<UseOfMfc>false</UseOfMfc> <UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Distribute|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Distribute|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v143</PlatformToolset> <PlatformToolset>v143</PlatformToolset>
<UseOfMfc>false</UseOfMfc> <UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseOfMfc>false</UseOfMfc> <UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v143</PlatformToolset> <PlatformToolset>v143</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

Binary file not shown.

View File

@ -15,8 +15,8 @@
#endif #endif
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 0, 3, 1, 0 FILEVERSION 0,4,0,0
PRODUCTVERSION 0, 3, 1, 0 PRODUCTVERSION 0,4,0,0
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
FILEFLAGS METIN2_DEBUG FILEFLAGS METIN2_DEBUG
FILEOS VOS__WINDOWS32 FILEOS VOS__WINDOWS32
@ -29,12 +29,12 @@ BEGIN
BEGIN BEGIN
VALUE "CompanyName", "The Old Metin2 Project" VALUE "CompanyName", "The Old Metin2 Project"
VALUE "FileDescription", METIN2_COMPONENT_DESCRIPTION VALUE "FileDescription", METIN2_COMPONENT_DESCRIPTION
VALUE "FileVersion", "0.3.1.0" VALUE "FileVersion", "0.4.0.0"
VALUE "InternalName", METIN2_COMPONENT_INTERNALNAME VALUE "InternalName", METIN2_COMPONENT_INTERNALNAME
VALUE "LegalCopyright", "Copyright (C) 2024" VALUE "LegalCopyright", "Copyright (C) 2022-2025"
VALUE "OriginalFilename", METIN2_COMPONENT_FILENAME VALUE "OriginalFilename", METIN2_COMPONENT_FILENAME
VALUE "ProductName", "Metin2Config" VALUE "ProductName", "Metin2Config"
VALUE "ProductVersion", "0.3.1.0" VALUE "ProductVersion", "0.4.0.0"
END END
END END

View File

@ -192,15 +192,14 @@ BOOL CEffectMesh::__LoadData_Ver002(int iSize, const BYTE * c_pbBuf)
if (0 == strExtension.compare("ifl")) if (0 == strExtension.compare("ifl"))
{ {
LPCVOID pMotionData; CEterPackManager::TPackDataPtr motionData;
CMappedFile File; CMemoryTextFileLoader textFileLoader;
if (CEterPackManager::Instance().Get(File, pMeshData->szDiffuseMapFileName, &pMotionData)) if (CEterPackManager::Instance().Get(pMeshData->szDiffuseMapFileName, motionData))
{ {
CMemoryTextFileLoader textFileLoader;
std::vector<std::string> stTokenVector; std::vector<std::string> stTokenVector;
textFileLoader.Bind(File.Size(), pMotionData); textFileLoader.Bind(motionData->size(), motionData->data());
std::string strPathName; std::string strPathName;
GetOnlyPathName(pMeshData->szDiffuseMapFileName, strPathName); GetOnlyPathName(pMeshData->szDiffuseMapFileName, strPathName);
@ -337,15 +336,14 @@ BOOL CEffectMesh::__LoadData_Ver001(int iSize, const BYTE * c_pbBuf)
if (0 == strExtension.compare("ifl")) if (0 == strExtension.compare("ifl"))
{ {
LPCVOID pMotionData; CEterPackManager::TPackDataPtr motionData;
CMappedFile File; CMemoryTextFileLoader textFileLoader;
if (CEterPackManager::Instance().Get(File, pMeshData->szDiffuseMapFileName, &pMotionData)) if (CEterPackManager::Instance().Get(pMeshData->szDiffuseMapFileName, motionData))
{ {
CMemoryTextFileLoader textFileLoader;
std::vector<std::string> stTokenVector; std::vector<std::string> stTokenVector;
textFileLoader.Bind(File.Size(), pMotionData); textFileLoader.Bind(motionData->size(), motionData->data());
std::string strPathName; std::string strPathName;
GetOnlyPathName(pMeshData->szDiffuseMapFileName, strPathName); GetOnlyPathName(pMeshData->szDiffuseMapFileName, strPathName);

View File

@ -234,18 +234,6 @@ bool CTGAImage::LoadFromMemory(int iSize, const BYTE * c_pbMem)
return true; return true;
} }
bool CTGAImage::LoadFromDiskFile(const char * c_szFileName)
{
CMappedFile file;
const BYTE * c_pbMap;
if (!file.Create(c_szFileName, (const void **) &c_pbMap, 0, 0))
return false;
return LoadFromMemory(file.Size(), c_pbMap);
}
int CTGAImage::GetRLEPixelCount(const DWORD * data) int CTGAImage::GetRLEPixelCount(const DWORD * data)
{ {
int r = 0; int r = 0;

View File

@ -17,7 +17,6 @@ class CTGAImage : public CImage
virtual void Create(int width, int height); virtual void Create(int width, int height);
virtual bool LoadFromMemory(int iSize, const BYTE * c_pbMem); virtual bool LoadFromMemory(int iSize, const BYTE * c_pbMem);
virtual bool LoadFromDiskFile(const char * c_szFileName);
virtual bool SaveToDiskFile(const char* c_szFileName); virtual bool SaveToDiskFile(const char* c_szFileName);
void SetCompressed(bool isCompress = true); void SetCompressed(bool isCompress = true);

View File

@ -47,9 +47,6 @@ void CFileLoaderThread::Destroy()
CloseHandle(m_hSemaphore); CloseHandle(m_hSemaphore);
m_hSemaphore = NULL; m_hSemaphore = NULL;
} }
stl_wipe(m_pRequestDeque);
stl_wipe(m_pCompleteDeque);
} }
UINT CFileLoaderThread::Setup() UINT CFileLoaderThread::Setup()
@ -111,13 +108,11 @@ UINT CFileLoaderThread::Execute(void * /*pvArg*/)
return 1; return 1;
} }
void CFileLoaderThread::Request(std::string & c_rstFileName) // called in main thread void CFileLoaderThread::Request(const std::string& c_rstFileName) // called in main thread
{ {
TData * pData = new TData; TData pData;
pData.fileName = c_rstFileName;
pData->dwSize = 0; pData.data = nullptr;
pData->pvBuf = NULL;
pData->stFileName = c_rstFileName;
m_RequestMutex.Lock(); m_RequestMutex.Lock();
m_pRequestDeque.push_back(pData); m_pRequestDeque.push_back(pData);
@ -131,7 +126,7 @@ void CFileLoaderThread::Request(std::string & c_rstFileName) // called in main t
--m_iRestSemCount; --m_iRestSemCount;
} }
bool CFileLoaderThread::Fetch(TData ** ppData) // called in main thread bool CFileLoaderThread::Fetch(TData& data) // called in main thread
{ {
m_CompleteMutex.Lock(); m_CompleteMutex.Lock();
@ -141,7 +136,7 @@ bool CFileLoaderThread::Fetch(TData ** ppData) // called in main thread
return false; return false;
} }
*ppData = m_pCompleteDeque.front(); data = m_pCompleteDeque.front();
m_pCompleteDeque.pop_front(); m_pCompleteDeque.pop_front();
m_CompleteMutex.Unlock(); m_CompleteMutex.Unlock();
@ -158,22 +153,16 @@ void CFileLoaderThread::Process() // called in loader thread
return; return;
} }
TData * pData = m_pRequestDeque.front(); auto request = m_pRequestDeque.front();
m_pRequestDeque.pop_front(); m_pRequestDeque.pop_front();
m_RequestMutex.Unlock(); m_RequestMutex.Unlock();
LPCVOID pvBuf; if (!CEterPackManager::Instance().Get(request.fileName, request.data))
request.data = nullptr;
if (CEterPackManager::Instance().Get(pData->File, pData->stFileName.c_str(), &pvBuf))
{
pData->dwSize = pData->File.Size();
pData->pvBuf = new char [pData->dwSize];
memcpy(pData->pvBuf, pvBuf, pData->dwSize);
}
m_CompleteMutex.Lock(); m_CompleteMutex.Lock();
m_pCompleteDeque.push_back(pData); m_pCompleteDeque.push_back(request);
m_CompleteMutex.Unlock(); m_CompleteMutex.Unlock();
Sleep(g_iLoadingDelayTime); Sleep(g_iLoadingDelayTime);

View File

@ -2,20 +2,18 @@
#define __INC_YMIR_ETERLIB_FILELOADERTHREAD_H__ #define __INC_YMIR_ETERLIB_FILELOADERTHREAD_H__
#include <deque> #include <deque>
#include <memory>
#include <vector>
#include "Thread.h" #include "Thread.h"
#include "Mutex.h" #include "Mutex.h"
#include "../eterBase/MappedFile.h"
class CFileLoaderThread class CFileLoaderThread
{ {
public: public:
typedef struct SData typedef struct SData
{ {
std::string stFileName; std::string fileName;
std::shared_ptr<std::vector<char>> data;
CMappedFile File;
LPVOID pvBuf;
DWORD dwSize;
} TData; } TData;
public: public:
@ -25,8 +23,8 @@ class CFileLoaderThread
int Create(void * arg); int Create(void * arg);
public: public:
void Request(std::string & c_rstFileName); void Request(const std::string& c_rstFileName);
bool Fetch(TData ** ppData); bool Fetch(TData& data);
void Shutdown(); void Shutdown();
protected: protected:
@ -49,10 +47,10 @@ class CFileLoaderThread
void Process(); void Process();
private: private:
std::deque<TData *> m_pRequestDeque; std::deque<TData> m_pRequestDeque;
Mutex m_RequestMutex; Mutex m_RequestMutex;
std::deque<TData *> m_pCompleteDeque; std::deque<TData> m_pCompleteDeque;
Mutex m_CompleteMutex; Mutex m_CompleteMutex;
HANDLE m_hSemaphore; HANDLE m_hSemaphore;

View File

@ -50,13 +50,11 @@ bool CGraphicImageTexture::CreateDeviceObjects()
} }
else else
{ {
CMappedFile mappedFile; CEterPackManager::TPackDataPtr data;
LPCVOID c_pvMap; if (!CEterPackManager::Instance().Get(m_stFileName, data))
if (!CEterPackManager::Instance().Get(mappedFile, m_stFileName.c_str(), &c_pvMap))
return false; return false;
return CreateFromMemoryFile(mappedFile.Size(), c_pvMap, m_d3dFmt, m_dwFilter); return CreateFromMemoryFile(data->size(), data->data(), m_d3dFmt, m_dwFilter);
} }
m_bEmpty = false; m_bEmpty = false;

View File

@ -42,18 +42,17 @@ void CResource::Load()
const char * c_szFileName = GetFileName(); const char * c_szFileName = GetFileName();
DWORD dwStart = ELTimer_GetMSec(); DWORD dwStart = ELTimer_GetMSec();
CMappedFile file; CEterPackManager::TPackDataPtr fileData;
LPCVOID fileData;
//Tracenf("Load %s", c_szFileName); //Tracenf("Load %s", c_szFileName);
if (CEterPackManager::Instance().Get(file, c_szFileName, &fileData)) if (CEterPackManager::Instance().Get(c_szFileName, fileData))
{ {
m_dwLoadCostMiliiSecond = ELTimer_GetMSec() - dwStart; m_dwLoadCostMiliiSecond = ELTimer_GetMSec() - dwStart;
//Tracef("CResource::Load %s (%d bytes) in %d ms\n", c_szFileName, file.Size(), m_dwLoadCostMiliiSecond); //Tracef("CResource::Load %s (%d bytes) in %d ms\n", c_szFileName, file.Size(), m_dwLoadCostMiliiSecond);
if (OnLoad(file.Size(), fileData)) if (OnLoad(fileData->size(), fileData->data()))
{ {
me_state = STATE_EXIST; me_state = STATE_EXIST;
} }
@ -81,12 +80,11 @@ void CResource::Reload()
Clear(); Clear();
Tracef("CResource::Reload %s\n", GetFileName()); Tracef("CResource::Reload %s\n", GetFileName());
CMappedFile file; CEterPackManager::TPackDataPtr fileData;
LPCVOID fileData;
if (CEterPackManager::Instance().Get(file, GetFileName(), &fileData)) if (CEterPackManager::Instance().Get(GetFileName(), fileData))
{ {
if (OnLoad(file.Size(), fileData)) if (OnLoad(fileData->size(), fileData->data()))
{ {
me_state = STATE_EXIST; me_state = STATE_EXIST;
} }

View File

@ -61,17 +61,17 @@ void CResourceManager::ProcessBackgroundLoading()
DWORD dwCurrentTime = ELTimer_GetMSec(); DWORD dwCurrentTime = ELTimer_GetMSec();
CFileLoaderThread::TData * pData; CFileLoaderThread::TData pData;
while (ms_loadingThread.Fetch(&pData)) while (ms_loadingThread.Fetch(pData))
{ {
//printf("LOD %s\n", pData->stFileName.c_str()); //printf("LOD %s\n", pData->stFileName.c_str());
CResource * pResource = GetResourcePointer(pData->stFileName.c_str()); CResource * pResource = GetResourcePointer(pData.fileName.c_str());
if (pResource) if (pResource)
{ {
if (pResource->IsEmpty()) if (pResource->IsEmpty())
{ {
pResource->OnLoad(pData->dwSize, pData->pvBuf); pResource->OnLoad(pData.data->size(), pData.data->data());
pResource->AddReferenceOnly(); pResource->AddReferenceOnly();
// 여기서 올라간 레퍼런스 카운트를 일정 시간이 지난 뒤에 풀어주기 위하여 // 여기서 올라간 레퍼런스 카운트를 일정 시간이 지난 뒤에 풀어주기 위하여
@ -79,10 +79,7 @@ void CResourceManager::ProcessBackgroundLoading()
} }
} }
m_WaitingMap.erase(GetCRC32(pData->stFileName.c_str(), pData->stFileName.size())); m_WaitingMap.erase(GetCRC32(pData.fileName.c_str(), pData.fileName.size()));
delete [] ((char *) pData->pvBuf);
delete pData;
} }
// DO : 일정 시간이 지나고 난뒤 미리 로딩해 두었던 리소스의 레퍼런스 카운트를 감소 시킨다 - [levites] // DO : 일정 시간이 지나고 난뒤 미리 로딩해 두었던 리소스의 레퍼런스 카운트를 감소 시킨다 - [levites]

View File

@ -2,6 +2,7 @@
#include "Resource.h" #include "Resource.h"
#include "FileLoaderThread.h" #include "FileLoaderThread.h"
#include "../EterBase/Singleton.h"
#include <set> #include <set>
#include <map> #include <map>

View File

@ -179,14 +179,13 @@ bool CTextFileLoader::Load(const char * c_szFileName)
{ {
m_strFileName = ""; m_strFileName = "";
const VOID* pvData; CEterPackManager::TPackDataPtr data;
CMappedFile kFile; if (!CEterPackManager::Instance().Get(c_szFileName, data))
if (!CEterPackManager::Instance().Get(kFile, c_szFileName, &pvData))
return false; return false;
if (m_dwBufCapacity<kFile.Size()) if (m_dwBufCapacity < data->size())
{ {
m_dwBufCapacity=kFile.Size(); m_dwBufCapacity = data->size();
if (m_acBufData) if (m_acBufData)
delete [] m_acBufData; delete [] m_acBufData;
@ -194,8 +193,8 @@ bool CTextFileLoader::Load(const char * c_szFileName)
m_acBufData=new char[m_dwBufCapacity]; m_acBufData=new char[m_dwBufCapacity];
} }
m_dwBufSize=kFile.Size(); m_dwBufSize = data->size();
memcpy(m_acBufData, pvData, m_dwBufSize); memcpy_s(m_acBufData, m_dwBufCapacity, data->data(), data->size());
m_strFileName = c_szFileName; m_strFileName = c_szFileName;
m_dwcurLineIndex = 0; m_dwcurLineIndex = 0;

View File

@ -20,16 +20,14 @@ void PrintfTabs(FILE * File, int iTabCount, const char * c_szString, ...)
bool LoadTextData(const char * c_szFileName, CTokenMap & rstTokenMap) bool LoadTextData(const char * c_szFileName, CTokenMap & rstTokenMap)
{ {
LPCVOID pMotionData; CEterPackManager::TPackDataPtr motionData;
CMappedFile File; CMemoryTextFileLoader textFileLoader;
if (!CEterPackManager::Instance().Get(File, c_szFileName, &pMotionData)) if (!CEterPackManager::Instance().Get(c_szFileName, motionData))
return false; return false;
CMemoryTextFileLoader textFileLoader;
CTokenVector stTokenVector; CTokenVector stTokenVector;
textFileLoader.Bind(motionData->size(), motionData->data());
textFileLoader.Bind(File.Size(), pMotionData);
for (DWORD i = 0; i < textFileLoader.GetLineCount(); ++i) for (DWORD i = 0; i < textFileLoader.GetLineCount(); ++i)
{ {
@ -50,18 +48,16 @@ bool LoadTextData(const char * c_szFileName, CTokenMap & rstTokenMap)
bool LoadMultipleTextData(const char * c_szFileName, CTokenVectorMap & rstTokenVectorMap) bool LoadMultipleTextData(const char * c_szFileName, CTokenVectorMap & rstTokenVectorMap)
{ {
LPCVOID pModelData; CEterPackManager::TPackDataPtr modelData;
CMappedFile File; CMemoryTextFileLoader textFileLoader;
if (!CEterPackManager::Instance().Get(File, c_szFileName, &pModelData)) if (!CEterPackManager::Instance().Get(c_szFileName, modelData))
return false; return false;
DWORD i; DWORD i;
CMemoryTextFileLoader textFileLoader;
CTokenVector stTokenVector; CTokenVector stTokenVector;
textFileLoader.Bind(File.Size(), pModelData); textFileLoader.Bind(modelData->size(), modelData->data());
for (i = 0; i < textFileLoader.GetLineCount(); ++i) for (i = 0; i < textFileLoader.GetLineCount(); ++i)
{ {

File diff suppressed because it is too large Load Diff

View File

@ -1,243 +0,0 @@
#ifndef __INC_ETERPACKLIB_ETERPACK_H__
#define __INC_ETERPACKLIB_ETERPACK_H__
#include <list>
#include <unordered_map>
#include "../EterBase/MappedFile.h"
#ifndef MAKEFOURCC
#define MAKEFOURCC(ch0, ch1, ch2, ch3) \
((DWORD)(BYTE) (ch0 ) | ((DWORD)(BYTE) (ch1) << 8) | \
((DWORD)(BYTE) (ch2) << 16) | ((DWORD)(BYTE) (ch3) << 24))
#endif
//#define CHECKSUM_CHECK_MD5
#include "md5.h"
namespace eterpack
{
const DWORD c_PackCC = MAKEFOURCC('E', 'P', 'K', 'D');
const DWORD c_IndexCC = MAKEFOURCC('E', 'P', 'K', 'D');
const DWORD c_Version = 2;
// FourCC + Version + m_indexCount
const DWORD c_HeaderSize = sizeof(DWORD) + sizeof(DWORD) + sizeof(long);
};
enum EEterPackTypes
{
DBNAME_MAX_LEN = 255,
FILENAME_MAX_LEN = 160,
FREE_INDEX_BLOCK_SIZE = 32768,
FREE_INDEX_MAX_SIZE = 512,
DATA_BLOCK_SIZE = 256,
COMPRESSED_TYPE_NONE = 0,
COMPRESSED_TYPE_COMPRESS = 1,
COMPRESSED_TYPE_SECURITY = 2,
COMPRESSED_TYPE_PANAMA = 3,
COMPRESSED_TYPE_HYBRIDCRYPT = 4,
COMPRESSED_TYPE_HYBRIDCRYPT_WITHSDB = 5,
COMPRESSED_TYPE_COUNT = 6,
};
#pragma pack(push, 4)
typedef struct SEterPackIndex
{
long id;
char filename[FILENAME_MAX_LEN + 1];
DWORD filename_crc;
long real_data_size;
long data_size;
#ifdef CHECKSUM_CHECK_MD5
BYTE MD5Digest[16];
#else
DWORD data_crc;
#endif
long data_position;
char compressed_type;
} TEterPackIndex;
#pragma pack(pop)
typedef std::unordered_map<DWORD, TEterPackIndex *> TDataPositionMap;
typedef std::list<TEterPackIndex *> TFreeIndexList;
class CEterPack;
class CEterFileDict
{
public:
struct Item
{
Item() : pkPack(NULL), pkInfo(NULL) {}
CEterPack* pkPack;
TEterPackIndex* pkInfo;
};
enum
{
BUCKET_SIZE = 16,
};
typedef std::unordered_multimap<DWORD, Item> TDict;
public:
void InsertItem(CEterPack* pkPack, TEterPackIndex* pkInfo);
void UpdateItem(CEterPack* pkPack, TEterPackIndex* pkInfo);
Item* GetItem(DWORD dwFileNameHash, const char* c_pszFileName);
const TDict& GetDict() const
{
return m_dict;
}
private:
TDict m_dict;
};
class EterPackPolicy_CSHybridCrypt;
class CEterPack
{
public:
CEterPack();
virtual ~CEterPack();
void Destroy();
bool Create(CEterFileDict& rkFileDict, const char * dbname, const char * pathName, bool bReadOnly = true, const BYTE* iv = NULL);
bool DecryptIV(DWORD dwPanamaKey);
const std::string& GetPathName();
const char * GetDBName();
bool Get(CMappedFile & mappedFile, const char * filename, LPCVOID * data);
bool Get2(CMappedFile & mappedFile, const char * filename, TEterPackIndex* index, LPCVOID * data);
bool Put(const char * filename, const char * sourceFilename, BYTE packType, const std::string& strRelateMapName);
bool Put(const char * filename, LPCVOID data, long len, BYTE packType);
bool Delete(const char * filename);
bool Extract();
long GetFragmentSize();
bool IsExist(const char * filename);
TDataPositionMap & GetIndexMap();
bool EncryptIndexFile();
bool DecryptIndexFile();
DWORD DeleteUnreferencedData(); // 몇개가 삭제 되었는지 리턴 한다.
bool GetNames(std::vector<std::string>* retNames);
EterPackPolicy_CSHybridCrypt* GetPackPolicy_HybridCrypt() const;
private:
bool __BuildIndex(CEterFileDict& rkFileDict, bool bOverwirte=false);
bool CreateIndexFile();
TEterPackIndex * FindIndex(const char * filename);
long GetNewIndexPosition(CFileBase& file);
TEterPackIndex * NewIndex(CFileBase& file, const char * filename, long size);
void WriteIndex(CFileBase& file, TEterPackIndex * index);
int GetFreeBlockIndex(long size);
void PushFreeIndex(TEterPackIndex * index);
bool CreateDataFile();
long GetNewDataPosition(CFileBase& file);
bool ReadData(CFileBase& file, TEterPackIndex * index, LPVOID data, long maxsize);
bool WriteData(CFileBase& file, TEterPackIndex * index, LPCVOID data);
bool WriteNewData(CFileBase& file, TEterPackIndex * index, LPCVOID data);
bool Delete(TEterPackIndex * pIndex);
protected:
CMappedFile m_file;
char* m_file_data;
unsigned m_file_size;
long m_indexCount;
bool m_bEncrypted;
char m_dbName[DBNAME_MAX_LEN+1];
char m_indexFileName[MAX_PATH+1];
TEterPackIndex * m_indexData;
long m_FragmentSize;
bool m_bReadOnly;
bool m_bDecrypedIV;
std::unordered_map<DWORD, DWORD> m_map_indexRefCount;
TDataPositionMap m_DataPositionMap;
TFreeIndexList m_FreeIndexList[FREE_INDEX_MAX_SIZE + 1]; // MAX 도 억세스 하므로 + 1 크기만큼 만든다.
std::string m_stDataFileName;
std::string m_stPathName;
EterPackPolicy_CSHybridCrypt* m_pCSHybridCryptPolicy;
private:
void __CreateFileNameKey_Panama(const char * filename, BYTE * key, unsigned int keySize);
bool __Decrypt_Panama(const char* filename, const BYTE* data, SIZE_T dataSize, CLZObject& zObj);
bool __Encrypt_Panama(const char* filename, const BYTE* data, SIZE_T dataSize, CLZObject& zObj);
std::string m_stIV_Panama;
//private:
// bool m_bIsDataLoaded;
// // 그냥 time_t를 쓰면, 32bit time_t를 사용하는 소스에서는,
// // CEterPack의 size를 실제 size - 4로 인식하기 때문에 문제가 발생할 수 있다.
// __time64_t m_tLastAccessTime;
//public:
// __time64_t GetLastAccessTime() { return m_tLastAccessTime; }
// void UpdateLastAccessTime();
// void ClearDataMemoryMap();
#ifdef CHECKSUM_CHECK_MD5
void GenerateMD5Hash( BYTE* pData, int nLength, IN OUT MD5_CTX& context );
#endif
};
class CMakePackLog
{
public:
static CMakePackLog& GetSingleton();
public:
CMakePackLog();
~CMakePackLog();
void SetFileName(const char* c_szFileName);
void Writef(const char* c_szFormat, ...);
void Writenf(const char* c_szFormat, ...);
void Write(const char* c_szBuf);
void WriteErrorf(const char* c_szFormat, ...);
void WriteErrornf(const char* c_szFormat, ...);
void WriteError(const char* c_szBuf);
void FlushError();
private:
void __Write(const char* c_szBuf, int nBufLen);
void __WriteError(const char* c_szBuf, int nBufLen);
bool __IsLogMode();
private:
FILE* m_fp;
FILE* m_fp_err;
std::string m_stFileName;
std::string m_stErrorFileName;
};
#endif

View File

@ -170,20 +170,6 @@
</Lib> </Lib>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="EterPack.cpp">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Distribute|Win32'">MaxSpeed</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
</ClCompile>
<ClCompile Include="EterPackCursor.cpp">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Distribute|Win32'">MaxSpeed</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
</ClCompile>
<ClCompile Include="EterPackManager.cpp"> <ClCompile Include="EterPackManager.cpp">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization> <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks> <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
@ -191,25 +177,16 @@
<Optimization Condition="'$(Configuration)|$(Platform)'=='Distribute|Win32'">MaxSpeed</Optimization> <Optimization Condition="'$(Configuration)|$(Platform)'=='Distribute|Win32'">MaxSpeed</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization> <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
</ClCompile> </ClCompile>
<ClCompile Include="EterPackPolicy_CSHybridCrypt.cpp" /> <ClCompile Include="Folder.cpp" />
<ClCompile Include="md5.c" /> <ClCompile Include="ZIP.cpp" />
<ClCompile Include="StdAfx.cpp">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Distribute|Win32'">MaxSpeed</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="EterPack.h" />
<ClInclude Include="EterPackCursor.h" />
<ClInclude Include="EterPackManager.h" /> <ClInclude Include="EterPackManager.h" />
<ClInclude Include="EterPackPolicy_CSHybridCrypt.h" /> <ClInclude Include="FileProvider.h" />
<ClInclude Include="Folder.h" />
<ClInclude Include="Inline.h" /> <ClInclude Include="Inline.h" />
<ClInclude Include="md5.h" />
<ClInclude Include="StdAfx.h" /> <ClInclude Include="StdAfx.h" />
<ClInclude Include="ZIP.h" />
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">

View File

@ -9,48 +9,39 @@
<UniqueIdentifier>{c156ef19-8b61-496c-a499-8bf66e9ca80d}</UniqueIdentifier> <UniqueIdentifier>{c156ef19-8b61-496c-a499-8bf66e9ca80d}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl</Extensions> <Extensions>h;hpp;hxx;hm;inl</Extensions>
</Filter> </Filter>
<Filter Include="File Providers">
<UniqueIdentifier>{6348898e-222d-4516-8d4e-e37f9e17d872}</UniqueIdentifier>
</Filter>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="EterPack.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="EterPackCursor.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="EterPackManager.cpp"> <ClCompile Include="EterPackManager.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="EterPackPolicy_CSHybridCrypt.cpp"> <ClCompile Include="Folder.cpp">
<Filter>Source Files</Filter> <Filter>File Providers</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="md5.c"> <ClCompile Include="ZIP.cpp">
<Filter>Source Files</Filter> <Filter>File Providers</Filter>
</ClCompile>
<ClCompile Include="StdAfx.cpp">
<Filter>Source Files</Filter>
</ClCompile> </ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="EterPack.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="EterPackCursor.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="EterPackManager.h"> <ClInclude Include="EterPackManager.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="EterPackPolicy_CSHybridCrypt.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Inline.h"> <ClInclude Include="Inline.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="md5.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="StdAfx.h"> <ClInclude Include="StdAfx.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Folder.h">
<Filter>File Providers</Filter>
</ClInclude>
<ClInclude Include="ZIP.h">
<Filter>File Providers</Filter>
</ClInclude>
<ClInclude Include="FileProvider.h">
<Filter>File Providers</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -1,59 +0,0 @@
#include "StdAfx.h"
#include "EterPackCursor.h"
#include "Inline.h"
CEterPackCursor::CEterPackCursor(CEterPack* pack) : m_pPack(pack), m_pData(NULL), m_ReadPoint(0)
{
}
CEterPackCursor::~CEterPackCursor()
{
Close();
}
bool CEterPackCursor::Open(const char* filename)
{
assert(m_pPack != NULL);
char tmpFilename[MAX_PATH + 1];
strncpy(tmpFilename, filename, MAX_PATH);
inlineConvertPackFilename(tmpFilename);
if (!m_pPack->Get(m_file, tmpFilename, &m_pData))
return false;
return true;
}
void CEterPackCursor::Close()
{
m_file.Destroy();
m_pData = NULL;
m_ReadPoint = 0;
}
void CEterPackCursor::Seek(long offset)
{
m_ReadPoint = max(0, min(Size(), offset));
}
bool CEterPackCursor::Read(LPVOID data, long size)
{
if (m_file.IsNull())
return false;
if (m_ReadPoint + size > Size())
return false;
memcpy(data, (char*) m_pData + m_ReadPoint, size);
m_ReadPoint += size;
return true;
}
long CEterPackCursor::Size()
{
if (m_file.IsNull())
return 0;
return m_file.Size();
}

View File

@ -1,25 +0,0 @@
#ifndef __INC_ETERPACKCURSOR_H__
#define __INC_ETERPACKCURSOR_H__
#include "EterPack.h"
class CEterPackCursor
{
public:
CEterPackCursor(CEterPack * pack);
~CEterPackCursor();
bool Open(const char* filename);
void Close();
void Seek(long offset);
bool Read(LPVOID data, long size);
long Size();
private:
CEterPack * m_pPack;
CMappedFile m_file;
LPCVOID m_pData;
long m_ReadPoint;
};
#endif

View File

@ -1,73 +1,34 @@
#include "StdAfx.h" #include "StdAfx.h"
#include <fstream>
#include <io.h> #include <io.h>
#include <assert.h> #include <assert.h>
#include "EterPackManager.h" #include "EterPackManager.h"
#include "EterPackPolicy_CSHybridCrypt.h"
#include "../eterBase/Debug.h" #include "../eterBase/Debug.h"
#include "../eterBase/CRC32.h" #include "../eterBase/CRC32.h"
#include "Folder.h"
#include "ZIP.h"
#define PATH_ABSOLUTE_YMIRWORK1 "d:/ymir work/" #define PATH_ABSOLUTE_YMIRWORK1 "d:/ymir work/"
#define PATH_ABSOLUTE_YMIRWORK2 "d:\\ymir work\\" #define PATH_ABSOLUTE_YMIRWORK2 "d:\\ymir work\\"
CEterPack* CEterPackManager::FindPack(const char* c_szPathName)
{
std::string strFileName;
if (0 == ConvertFileName(c_szPathName, strFileName))
{
return &m_RootPack;
}
else
{
for (TEterPackMap::iterator itor = m_DirPackMap.begin(); itor != m_DirPackMap.end(); ++itor)
{
const std::string & c_rstrName = itor->first;
CEterPack * pEterPack = itor->second;
if (CompareName(c_rstrName.c_str(), c_rstrName.length(), strFileName.c_str()))
{
return pEterPack;
}
}
}
return NULL;
}
void CEterPackManager::SetCacheMode()
{
m_isCacheMode=true;
}
void CEterPackManager::SetRelativePathMode()
{
m_bTryRelativePath = true;
}
// StringPath std::string 버전 // StringPath std::string 버전
int CEterPackManager::ConvertFileName(const char * c_szFileName, std::string & rstrFileName) std::string CEterPackManager::ConvertFileName(std::string fileName)
{ {
rstrFileName = c_szFileName; std::string convertedFileName = fileName;
stl_lowers(rstrFileName); stl_lowers(convertedFileName);
int iCount = 0; for (DWORD i = 0; i < convertedFileName.length(); i++)
for (DWORD i = 0; i < rstrFileName.length(); ++i)
{ {
if (rstrFileName[i] == '/') if (convertedFileName[i] == '\\')
++iCount; convertedFileName[i] = '/';
else if (rstrFileName[i] == '\\')
{
rstrFileName[i] = '/';
++iCount;
}
} }
return iCount; return convertedFileName;
} }
bool CEterPackManager::CompareName(const char * c_szDirectoryName, DWORD /*dwLength*/, const char * c_szFileName) bool CEterPackManager::CompareName(const char * c_szDirectoryName, DWORD /*dwLength*/, const char * c_szFileName)
@ -87,54 +48,6 @@ bool CEterPackManager::CompareName(const char * c_szDirectoryName, DWORD /*dwLen
return true; return true;
} }
void CEterPackManager::LoadStaticCache(const char* c_szFileName)
{
if (!m_isCacheMode)
return;
std::string strFileName;
if (0 == ConvertFileName(c_szFileName, strFileName))
{
return;
}
DWORD dwFileNameHash = GetCRC32(strFileName.c_str(), strFileName.length());
std::unordered_map<DWORD, SCache>::iterator f = m_kMap_dwNameKey_kCache.find(dwFileNameHash);
if (m_kMap_dwNameKey_kCache.end() != f)
return;
CMappedFile kMapFile;
const void* c_pvData;
if (!Get(kMapFile, c_szFileName, &c_pvData))
return;
SCache kNewCache;
kNewCache.m_dwBufSize = kMapFile.Size();
kNewCache.m_abBufData = new BYTE[kNewCache.m_dwBufSize];
memcpy(kNewCache.m_abBufData, c_pvData, kNewCache.m_dwBufSize);
m_kMap_dwNameKey_kCache.insert(std::unordered_map<DWORD, SCache>::value_type(dwFileNameHash, kNewCache));
}
CEterPackManager::SCache* CEterPackManager::__FindCache(DWORD dwFileNameHash)
{
std::unordered_map<DWORD, SCache>::iterator f=m_kMap_dwNameKey_kCache.find(dwFileNameHash);
if (m_kMap_dwNameKey_kCache.end()==f)
return NULL;
return &f->second;
}
void CEterPackManager::__ClearCacheMap()
{
std::unordered_map<DWORD, SCache>::iterator i;
for (i = m_kMap_dwNameKey_kCache.begin(); i != m_kMap_dwNameKey_kCache.end(); ++i)
delete [] i->second.m_abBufData;
m_kMap_dwNameKey_kCache.clear();
}
struct TimeChecker struct TimeChecker
{ {
TimeChecker(const char* name) : name(name) TimeChecker(const char* name) : name(name)
@ -150,27 +63,37 @@ struct TimeChecker
DWORD baseTime; DWORD baseTime;
}; };
bool CEterPackManager::Get(CMappedFile & rMappedFile, const char * c_szFileName, LPCVOID * pData) bool CEterPackManager::Get(const std::string& fileName, TPackDataPtr& dataPtr)
{ {
//TimeChecker timeChecker(c_szFileName); //TimeChecker timeChecker(c_szFileName);
//Logf(1, "Load %s\n", c_szFileName); //Logf(1, "Load %s\n", c_szFileName);
if (m_iSearchMode == SEARCH_FILE_FIRST) if (m_iSearchMode == SEARCH_FILE_FIRST)
{ {
if (GetFromFile(rMappedFile, c_szFileName, pData)) if (GetFromFile(fileName, dataPtr))
{
return true; return true;
}
return GetFromPack(rMappedFile, c_szFileName, pData); return GetFromPack(fileName, dataPtr);
} }
if (GetFromPack(rMappedFile, c_szFileName, pData)) if (GetFromPack(fileName, dataPtr))
{
return true; return true;
}
return GetFromFile(rMappedFile, c_szFileName, pData); return GetFromFile(fileName, dataPtr);
}
bool CEterPackManager::Get(const std::string& fileName, std::stringstream& dataStream)
{
CEterPackManager::TPackDataPtr data;
if (!Get(fileName, data))
return false;
// Copy the data from the pack into the file sstream
dataStream.str("");
std::copy(data->begin(), data->end(), std::ostream_iterator<char>(dataStream));
return true;
} }
struct FinderLock struct FinderLock
@ -188,109 +111,60 @@ struct FinderLock
CRITICAL_SECTION* p_cs; CRITICAL_SECTION* p_cs;
}; };
bool CEterPackManager::GetFromPack(CMappedFile & rMappedFile, const char * c_szFileName, LPCVOID * pData) bool CEterPackManager::GetFromPack(const std::string& fileName, TPackDataPtr& dataPtr)
{ {
FinderLock lock(m_csFinder); FinderLock lock(m_csFinder);
static std::string strFileName; std::string strFileName = ConvertFileName(fileName);
if (0 == ConvertFileName(c_szFileName, strFileName)) auto pkFileItem = m_FileMap.find(strFileName);
{
return m_RootPack.Get(rMappedFile, strFileName.c_str(), pData);
}
else
{
DWORD dwFileNameHash = GetCRC32(strFileName.c_str(), strFileName.length());
SCache* pkCache = __FindCache(dwFileNameHash);
if (pkCache) if (pkFileItem == m_FileMap.end()) {
{
rMappedFile.Link(pkCache->m_dwBufSize, pkCache->m_abBufData);
return true;
}
CEterFileDict::Item* pkFileItem = m_FileDict.GetItem(dwFileNameHash, strFileName.c_str());
if (pkFileItem)
if (pkFileItem->pkPack)
{
bool r = pkFileItem->pkPack->Get2(rMappedFile, strFileName.c_str(), pkFileItem->pkInfo, pData);
//pkFileItem->pkPack->ClearDataMemoryMap();
return r;
}
}
#ifdef _DEBUG #ifdef _DEBUG
TraceError("CANNOT_FIND_PACK_FILE [%s]", strFileName.c_str()); TraceError("CANNOT_FIND_PACK_FILE [%s]", strFileName.c_str());
#endif #endif
return false; return false;
}
auto data = std::make_shared<std::vector<char>>();
if (!pkFileItem->second->getFile(strFileName, data))
return false;
// Set dataPtr to the retreived data pointer
dataPtr = data;
return true;
} }
const time_t g_tCachingInterval = 10; // 10초 bool CEterPackManager::GetFromFile(const std::string& fileName, TPackDataPtr& dataPtr)
void CEterPackManager::ArrangeMemoryMappedPack()
{ {
//time_t curTime = time(NULL); // Try to open the file
//CEterFileDict::TDict dict = m_FileDict.GetDict(); std::ifstream file(fileName, std::ios::binary);
//for (CEterFileDict::TDict::iterator it = dict.begin(); it != dict.end(); ++it) if (!file.is_open())
//{ return false;
// CEterFileDict::Item &rFileItem = it->second;
// CEterPack* pkPack = rFileItem.pkPack;
// if (pkPack)
// {
// if (curTime - pkPack->GetLastAccessTime() > g_tCachingInterval)
// {
// pkPack->ClearDataMemoryMap();
// }
// }
//}
}
bool CEterPackManager::GetFromFile(CMappedFile & rMappedFile, const char * c_szFileName, LPCVOID * pData) // Read the file's contents
{ dataPtr = std::make_shared<std::vector<char>>(
#ifndef _DEBUG std::istreambuf_iterator<char>(file),
//const char *pcExt = strchr(c_szFileName, '.'); std::istreambuf_iterator<char>()
//if (pcExt && );
// _strnicmp(pcExt, ".py", 3) == 0 && // python 스크립트 중 return true;
// stricmp(c_szFileName, "logininfo.py") != 0 && // 로그인 정보 파일이 아니고
// strnicmp(c_szFileName, "locale", 6) != 0
// )
//{
// return false;
//}
#endif
//if(m_bTryRelativePath) {
// if (strnicmp(c_szFileName, PATH_ABSOLUTE_YMIRWORK1, strlen(PATH_ABSOLUTE_YMIRWORK1)) == 0 || strnicmp(c_szFileName, PATH_ABSOLUTE_YMIRWORK2, strlen(PATH_ABSOLUTE_YMIRWORK2)) == 0) {
// if(rMappedFile.Create(c_szFileName+strlen(PATH_ABSOLUTE_YMIRWORK1), pData, 0, 0))
// {
// return true;
// }
// }
//}
return rMappedFile.Create(c_szFileName, pData, 0, 0) ? true : false;
} }
bool CEterPackManager::isExistInPack(const char * c_szFileName) bool CEterPackManager::isExistInPack(const char * c_szFileName)
{ {
std::string strFileName; std::string strFileName = ConvertFileName(c_szFileName);
if (0 == ConvertFileName(c_szFileName, strFileName)) auto pkFileItem = m_FileMap.find(strFileName);
{
return m_RootPack.IsExist(strFileName.c_str());
}
else
{
DWORD dwFileNameHash = GetCRC32(strFileName.c_str(), strFileName.length());
CEterFileDict::Item* pkFileItem = m_FileDict.GetItem(dwFileNameHash, strFileName.c_str());
if (pkFileItem) if (pkFileItem == m_FileMap.end())
if (pkFileItem->pkPack) return false;
return pkFileItem->pkPack->IsExist(strFileName.c_str());
}
// NOTE : 매치 되는 팩이 없다면 false - [levites] if (!pkFileItem->second)
return false; return false;
return pkFileItem->second->fileExists(strFileName.c_str());
} }
bool CEterPackManager::isExist(const char * c_szFileName) bool CEterPackManager::isExist(const char * c_szFileName)
@ -300,99 +174,66 @@ bool CEterPackManager::isExist(const char * c_szFileName)
if (isExistInPack(c_szFileName)) if (isExistInPack(c_szFileName))
return true; return true;
return _access(c_szFileName, 0) == 0 ? true : false; return _access(c_szFileName, 0) == 0;
} }
//if(m_bTryRelativePath) {
// if (strnicmp(c_szFileName, PATH_ABSOLUTE_YMIRWORK1, strlen(PATH_ABSOLUTE_YMIRWORK1)) == 0 || strnicmp(c_szFileName, PATH_ABSOLUTE_YMIRWORK2, strlen(PATH_ABSOLUTE_YMIRWORK2)) == 0) {
// if(access(c_szFileName+strlen(PATH_ABSOLUTE_YMIRWORK1), 0) == 0)
// return true;
// }
//}
if (_access(c_szFileName, 0) == 0) if (_access(c_szFileName, 0) == 0)
return true; return true;
return isExistInPack(c_szFileName); return isExistInPack(c_szFileName);
} }
bool CEterPackManager::PackExists(const std::string& name, const std::string& container)
void CEterPackManager::RegisterRootPack(const char * c_szName)
{ {
if (!m_RootPack.Create(m_FileDict, c_szName, "")) if (container == "FOLDER") {
{ return _access(name.c_str(), 0) == 0;
TraceError("%s: Pack file does not exist", c_szName);
} }
} else if (container == "ZIP") {
std::string zipName = name + ".zip";
const char * CEterPackManager::GetRootPackFileName() return _access(zipName.c_str(), 0) == 0;
{
return m_RootPack.GetDBName();
}
bool CEterPackManager::DecryptPackIV(DWORD dwPanamaKey)
{
TEterPackMap::iterator itor = m_PackMap.begin();
while (itor != m_PackMap.end())
{
itor->second->DecryptIV(dwPanamaKey);
itor++;
} }
return true;
throw std::runtime_error("Unexpected container type: " + container + "!");
} }
bool CEterPackManager::RegisterPackWhenPackMaking(const char * c_szName, const char * c_szDirectory, CEterPack* pPack) bool CEterPackManager::RegisterPack(const std::string& name, const std::string& container)
{ {
m_PackMap.insert(TEterPackMap::value_type(c_szName, pPack)); auto it = m_PackMap.find(name);
m_PackList.push_front(pPack);
m_DirPackMap.insert(TEterPackMap::value_type(c_szDirectory, pPack)); if (it != m_PackMap.end())
return true; return true;
}
try {
bool bReadOnly = true;
bool CEterPackManager::RegisterPack(const char * c_szName, const char * c_szDirectory, const BYTE* c_pbIV) std::shared_ptr<FileProvider> pack;
{
CEterPack * pEterPack = NULL;
{
TEterPackMap::iterator itor = m_PackMap.find(c_szName);
if (m_PackMap.end() == itor) // Determine requested container type
{ if (container == "FOLDER")
bool bReadOnly = true; pack = std::make_shared<Folder>(name);
else if (container == "ZIP")
pEterPack = new CEterPack; pack = std::make_shared<ZIP>(name + ".zip");
if (pEterPack->Create(m_FileDict, c_szName, c_szDirectory, bReadOnly, c_pbIV))
{
m_PackMap.insert(TEterPackMap::value_type(c_szName, pEterPack));
}
else
{
#ifdef _DEBUG
Tracef("The eterpack doesn't exist [%s]\n", c_szName);
#endif
delete pEterPack;
pEterPack = NULL;
return false;
}
}
else else
{ throw std::runtime_error("Unexpected container type: " + container + "!");
pEterPack = itor->second;
}
}
if (c_szDirectory && c_szDirectory[0] != '*') // Load container data
auto packFiles = pack->listFiles();
for (auto const& fileName : packFiles)
m_FileMap.insert({ fileName, pack });
m_PackMap.insert({ name, pack });
return true;
}
catch (std::exception& e)
{ {
TEterPackMap::iterator itor = m_DirPackMap.find(c_szDirectory); #ifdef _DEBUG
if (m_DirPackMap.end() == itor) Tracef("Unable to load file provider '%s': %s\n", name.c_str(), e.what());
{ #endif
m_PackList.push_front(pEterPack);
m_DirPackMap.insert(TEterPackMap::value_type(c_szDirectory, pEterPack));
}
}
return true; return false;
}
} }
void CEterPackManager::SetSearchMode(bool bPackFirst) void CEterPackManager::SetSearchMode(bool bPackFirst)
@ -405,209 +246,16 @@ int CEterPackManager::GetSearchMode()
return m_iSearchMode; return m_iSearchMode;
} }
CEterPackManager::CEterPackManager() : m_bTryRelativePath(false), m_iSearchMode(SEARCH_FILE_FIRST), m_isCacheMode(false) CEterPackManager::CEterPackManager() : m_iSearchMode(SEARCH_FILE_FIRST)
{ {
InitializeCriticalSection(&m_csFinder); InitializeCriticalSection(&m_csFinder);
} }
CEterPackManager::~CEterPackManager() CEterPackManager::~CEterPackManager()
{ {
__ClearCacheMap();
TEterPackMap::iterator i = m_PackMap.begin();
TEterPackMap::iterator e = m_PackMap.end();
while (i != e)
{
delete i->second;
i++;
}
DeleteCriticalSection(&m_csFinder); DeleteCriticalSection(&m_csFinder);
} }
void CEterPackManager::RetrieveHybridCryptPackKeys(const BYTE *pStream) const CEterPackManager::TFileMap& CEterPackManager::GetFileMap() {
{ return this->m_FileMap;
////dump file format
//total packagecnt (4byte)
// for packagecntpackage
// db name hash ( stl.h stringhash )
// extension cnt( 4byte)
// for extension cnt
// ext hash ( stl.h stringhash )
// key-16byte
// iv-16byte
int iMemOffset = 0;
int iPackageCnt;
DWORD dwPackageNameHash;
memcpy( &iPackageCnt, pStream + iMemOffset, sizeof(int) );
iMemOffset += sizeof(iPackageCnt);
for( int i = 0; i < iPackageCnt; ++i )
{
int iRecvedCryptKeySize = 0;
memcpy( &iRecvedCryptKeySize, pStream + iMemOffset, sizeof(iRecvedCryptKeySize) );
iRecvedCryptKeySize -= sizeof(dwPackageNameHash); // 서버에서 받은 key stream에는 filename hash가 포함되어 있으므로, hash 사이즈 만큼 배줌.
iMemOffset += sizeof(iRecvedCryptKeySize);
memcpy( &dwPackageNameHash, pStream + iMemOffset, sizeof(dwPackageNameHash) );
iMemOffset += sizeof(dwPackageNameHash);
TEterPackMap::const_iterator cit;
for( cit = m_PackMap.begin(); cit != m_PackMap.end(); ++cit )
{
std::string noPathName = CFileNameHelper::NoPath(std::string(cit->first));
if( dwPackageNameHash == stringhash().GetHash(noPathName) )
{
EterPackPolicy_CSHybridCrypt* pCryptPolicy = cit->second->GetPackPolicy_HybridCrypt();
int iHavedCryptKeySize = pCryptPolicy->ReadCryptKeyInfoFromStream( pStream + iMemOffset );
if (iRecvedCryptKeySize != iHavedCryptKeySize)
{
TraceError("CEterPackManager::RetrieveHybridCryptPackKeys cryptokey length of file(%s) is not matched. received(%d) != haved(%d)", noPathName.c_str(), iRecvedCryptKeySize, iHavedCryptKeySize);
}
break;
}
}
iMemOffset += iRecvedCryptKeySize;
}
}
void CEterPackManager::RetrieveHybridCryptPackSDB( const BYTE* pStream )
{
//cnt
//for cnt
//DWORD dwPackageIdentifier;
//DWORD dwFileIdentifier;
//std::vector<BYTE> vecSDBStream;
int iReadOffset = 0;
int iSDBInfoCount = 0;
memcpy( &iSDBInfoCount, pStream+iReadOffset, sizeof(int) );
iReadOffset += sizeof(int);
for( int i = 0; i < iSDBInfoCount; ++i )
{
DWORD dwPackgeIdentifier;
memcpy( &dwPackgeIdentifier, pStream+iReadOffset, sizeof(DWORD) );
iReadOffset += sizeof(DWORD);
TEterPackMap::const_iterator cit;
for( cit = m_PackMap.begin(); cit != m_PackMap.end(); ++cit )
{
std::string noPathName = CFileNameHelper::NoPath(std::string(cit->first));
if( dwPackgeIdentifier == stringhash().GetHash(noPathName) )
{
EterPackPolicy_CSHybridCrypt* pCryptPolicy = cit->second->GetPackPolicy_HybridCrypt();
iReadOffset += pCryptPolicy->ReadSupplementatyDataBlockFromStream( pStream+iReadOffset );
break;
}
}
}
}
void CEterPackManager::WriteHybridCryptPackInfo(const char* pFileName)
{
//NOTE : this file format contains a little bit of redundant data.
//however it`s better for seperating cryptkey & supplementary data block.
//dump file format
//SDB data offset(4)
// about cryptkey
//total packagecnt (4byte)
// for packagecnt
// db name hash 4byte( stl.h stringhash )
// extension cnt( 4byte)
// for extension cnt
// ext hash ( stl.h stringhash )
// key-16byte
// iv-16byte
//about SDB data
//total packagecnt (4byte)
// for packagecnt
// db name hash 4byte( stl.h stringhash ) +child node size(4byte)
// sdb file cnt( 4byte )
// for sdb file cnt
// filename hash ( stl.h stringhash )
// related map name size(4), relate map name
// sdb block size( 1byte )
// sdb blocks
CFileBase keyFile;
if( !keyFile.Create( pFileName, CFileBase::FILEMODE_WRITE) )
{
//TODO : write log
return;
}
int iKeyPackageCount = 0;
//write later ( SDB Offset & PackageCnt for Key )
keyFile.SeekCur(2*sizeof(int));
TEterPackMap::const_iterator cit;
for( cit = m_PackMap.begin(); cit != m_PackMap.end(); ++cit )
{
EterPackPolicy_CSHybridCrypt* pPolicy = cit->second->GetPackPolicy_HybridCrypt();
if( !pPolicy || !pPolicy->IsContainingCryptKey() )
continue;
iKeyPackageCount++;
std::string noPathName = CFileNameHelper::NoPath(std::string(cit->first));
DWORD dwPackNamehash = stringhash().GetHash(noPathName);
CMakePackLog::GetSingleton().Writef("CEterPackManager::WriteHybridCryptPackInfo PackName : %s, Hash : %x", noPathName.c_str(), dwPackNamehash);
keyFile.Write( &dwPackNamehash, sizeof(DWORD) );
pPolicy->WriteCryptKeyToFile( keyFile );
}
//Write SDB Data
int iSDBDataOffset = keyFile.GetPosition();
int iSDBPackageCnt = 0;
//Write SDB PackageCnt Later
keyFile.SeekCur(sizeof(int));
for( cit = m_PackMap.begin(); cit != m_PackMap.end(); ++cit )
{
EterPackPolicy_CSHybridCrypt* pPolicy = cit->second->GetPackPolicy_HybridCrypt();
if( !pPolicy || !pPolicy->IsContainingSDBFile() )
continue;
iSDBPackageCnt++;
std::string noPathName = CFileNameHelper::NoPath(std::string(cit->first));
DWORD dwPackNamehash = stringhash().GetHash(noPathName);
keyFile.Write( &dwPackNamehash, sizeof(DWORD) );
int iSDBSizeWriteOffset = keyFile.GetPosition();
keyFile.SeekCur(sizeof(int));
pPolicy->WriteSupplementaryDataBlockToFile( keyFile );
int iSDBSizeAfterWrite = keyFile.GetPosition();
keyFile.Seek(iSDBSizeWriteOffset);
int iSDBSize = iSDBSizeAfterWrite-(iSDBSizeWriteOffset+4);
keyFile.Write( &iSDBSize, sizeof(int) );
keyFile.Seek(iSDBSizeAfterWrite);
}
//write sdb data start offset & package cnt
keyFile.Seek(0);
keyFile.Write( &iSDBDataOffset, sizeof(int));
keyFile.Write( &iKeyPackageCount, sizeof(int));
keyFile.Seek(iSDBDataOffset);
keyFile.Write( &iSDBPackageCnt, sizeof(int));
keyFile.Close();
} }

View File

@ -5,16 +5,10 @@
#include "../eterBase/Singleton.h" #include "../eterBase/Singleton.h"
#include "../eterBase/Stl.h" #include "../eterBase/Stl.h"
#include "EterPack.h" #include "FileProvider.h"
class CEterPackManager : public CSingleton<CEterPackManager> class CEterPackManager : public CSingleton<CEterPackManager>
{ {
public:
struct SCache
{
BYTE* m_abBufData;
DWORD m_dwBufSize;
};
public: public:
enum ESearchModes enum ESearchModes
{ {
@ -22,69 +16,40 @@ class CEterPackManager : public CSingleton<CEterPackManager>
SEARCH_PACK_FIRST SEARCH_PACK_FIRST
}; };
typedef std::list<CEterPack*> TEterPackList; typedef std::list<std::shared_ptr<FileProvider>> TEterPackList;
typedef std::unordered_map<std::string, CEterPack*, stringhash> TEterPackMap; typedef std::unordered_map<std::string, std::shared_ptr<FileProvider>> TEterPackMap;
typedef std::unordered_map<std::string, std::shared_ptr<FileProvider>> TFileMap;
typedef std::shared_ptr<std::vector<char>> TPackDataPtr;
public: public:
CEterPackManager(); CEterPackManager();
virtual ~CEterPackManager(); virtual ~CEterPackManager();
void SetCacheMode();
void SetRelativePathMode();
void LoadStaticCache(const char* c_szFileName);
void SetSearchMode(bool bPackFirst); void SetSearchMode(bool bPackFirst);
int GetSearchMode(); int GetSearchMode();
bool Get(CMappedFile & rMappedFile, const char * c_szFileName, LPCVOID * pData); bool Get(const std::string& fileName, TPackDataPtr& dataPtr);
bool Get(const std::string& fileName, std::stringstream& dataStream);
bool GetFromPack(CMappedFile & rMappedFile, const char * c_szFileName, LPCVOID * pData);
bool GetFromFile(CMappedFile & rMappedFile, const char * c_szFileName, LPCVOID * pData);
bool isExist(const char * c_szFileName); bool isExist(const char * c_szFileName);
bool isExistInPack(const char * c_szFileName); bool isExistInPack(const char * c_szFileName);
bool RegisterPack(const char * c_szName, const char * c_szDirectory, const BYTE* c_pbIV = NULL); bool PackExists(const std::string& name, const std::string& container);
void RegisterRootPack(const char * c_szName); bool RegisterPack(const std::string& name, const std::string& container);
bool RegisterPackWhenPackMaking(const char * c_szName, const char * c_szDirectory, CEterPack* pPack); std::string ConvertFileName(std::string fileName);
const TFileMap& GetFileMap();
bool DecryptPackIV(DWORD key);
const char * GetRootPackFileName();
//for hybridcrypt
void WriteHybridCryptPackInfo(const char* pFileName);
void RetrieveHybridCryptPackKeys( const BYTE* pStream );
void RetrieveHybridCryptPackSDB( const BYTE* pStream );
// 메모리에 매핑된 팩들 가운데, 정리해야할 것들 정리.
public:
void ArrangeMemoryMappedPack();
protected: protected:
int ConvertFileName(const char * c_szFileName, std::string & rstrFileName); // StringPath std::string 버전
bool CompareName(const char * c_szDirectoryName, DWORD iLength, const char * c_szFileName); bool CompareName(const char * c_szDirectoryName, DWORD iLength, const char * c_szFileName);
bool GetFromPack(const std::string& fileName, TPackDataPtr& dataPtr);
CEterPack* FindPack(const char* c_szPathName); bool GetFromFile(const std::string& fileName, TPackDataPtr& dataPtr);
SCache* __FindCache(DWORD dwFileNameHash);
void __ClearCacheMap();
protected: protected:
bool m_bTryRelativePath;
bool m_isCacheMode;
int m_iSearchMode; int m_iSearchMode;
CEterFileDict m_FileDict; TFileMap m_FileMap;
CEterPack m_RootPack;
TEterPackList m_PackList;
TEterPackMap m_PackMap; TEterPackMap m_PackMap;
TEterPackMap m_DirPackMap;
std::unordered_map<DWORD, SCache> m_kMap_dwNameKey_kCache;
CRITICAL_SECTION m_csFinder; CRITICAL_SECTION m_csFinder;
}; };

View File

@ -0,0 +1,14 @@
#pragma once
#include <vector>
#include <string>
#include <sstream>
#include <memory>
class FileProvider
{
public:
virtual std::vector<std::string> listFiles() = 0;
virtual bool fileExists(const std::string& fileName) = 0;
virtual bool getFile(const std::string& fileName, std::shared_ptr<std::vector<char>>& fileData) = 0;
};

98
src/EterPack/Folder.cpp Normal file
View File

@ -0,0 +1,98 @@
#include "Folder.h"
#include "EterPackManager.h"
#include <iostream>
#include <fstream>
#include <Windows.h>
#include "../eterBase/Stl.h"
void Folder::ListFiles(const std::string& directory, const std::string& relativePath = "") {
WIN32_FIND_DATA findData;
HANDLE hFind;
std::string searchPath = directory + "\\*";
// Start searching for files and directories
hFind = FindFirstFile(searchPath.c_str(), &findData);
if (hFind == INVALID_HANDLE_VALUE)
throw std::runtime_error("Failed to open directory: " + directory);
do {
const std::string fileOrDirName = findData.cFileName;
// Skip the "." and ".." directories
if (fileOrDirName == "." || fileOrDirName == "..") {
continue;
}
// Construct the full and relative paths
std::string fullPath = directory + "\\" + fileOrDirName;
std::string currentRelativePath = relativePath + fileOrDirName;
// Check if the current entry is a directory
if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
// Recurse into the subdirectory
ListFiles(fullPath, currentRelativePath + "\\");
}
else {
if (currentRelativePath.rfind("ymir work\\", 0) == 0) {
currentRelativePath = "d:\\" + currentRelativePath;
}
currentRelativePath = CEterPackManager::Instance().ConvertFileName(currentRelativePath);
// Print the file's relative path
this->fileList.insert(currentRelativePath);
}
} while (FindNextFile(hFind, &findData) != 0);
FindClose(hFind);
}
Folder::Folder(const std::string& folderPath)
{
this->folderPath = folderPath;
ListFiles(folderPath);
}
std::vector<std::string> Folder::listFiles()
{
std::vector<std::string> result;
std::copy(fileList.begin(), fileList.end(), std::back_inserter(result));
return result;
}
bool Folder::fileExists(const std::string& fileName)
{
auto it = fileList.find(fileName);
if (it == fileList.end())
return false;
return true;
}
bool Folder::getFile(const std::string& fileName, std::shared_ptr<std::vector<char>>& fileData)
{
std::string realFileName = fileName;
std::string ymirPrefix = "d:/";
if (fileName.find(ymirPrefix) == 0)
realFileName = realFileName.substr(ymirPrefix.length());
realFileName = this->folderPath + "/" + realFileName;
// Try to open the file
std::ifstream file(realFileName, std::ios::binary);
if (!file.is_open())
return false;
// Read the file's contents
fileData = std::make_shared<std::vector<char>>(
std::istreambuf_iterator<char>(file),
std::istreambuf_iterator<char>()
);
return true;
}

23
src/EterPack/Folder.h Normal file
View File

@ -0,0 +1,23 @@
#pragma once
#include <string>
#include <set>
#include "FileProvider.h"
class Folder : public FileProvider
{
protected:
std::string folderPath;
std::set<std::string> fileList = {};
public:
Folder(const std::string& folderPath);
std::vector<std::string> listFiles();
bool fileExists(const std::string& fileName);
bool getFile(const std::string& fileName, std::shared_ptr<std::vector<char>>& fileData);
private:
void ListFiles(const std::string& directory, const std::string& relativePath);
};

View File

@ -1,2 +0,0 @@
#include "stdafx.h"

97
src/EterPack/ZIP.cpp Normal file
View File

@ -0,0 +1,97 @@
#include "ZIP.h"
#include "EterPackManager.h"
#include <iostream>
#include <fstream>
#include <Windows.h>
#include "../eterBase/Stl.h"
ZIP::ZIP(const std::string& archivePath)
{
int err;
if ((zipFile = zip_open(archivePath.c_str(), 0, &err)) == NULL) {
zip_error_t error;
zip_error_init_with_code(&error, err);
std::string errorMessage = zip_error_strerror(&error);
zip_error_fini(&error);
throw std::runtime_error("Cannot open ZIP archive '" + archivePath + "': " + errorMessage);
}
// Read the list of files in the archive
zip_int64_t numEntries = zip_get_num_entries(zipFile, 0);
for (int index = 0; index < numEntries; index++)
{
zip_stat_t fileData;
zip_stat_index(zipFile, index, 0, &fileData);
std::string fileName(fileData.name);
if (fileData.size == 0) {
// This is a folder, skip it
continue;
}
if (fileName.rfind("ymir work/", 0) == 0) {
fileName = "d:/" + fileName;
}
fileName = CEterPackManager::Instance().ConvertFileName(fileName);
fileList.insert({ fileName, fileData.index });
}
}
ZIP::~ZIP()
{
zip_close(zipFile);
zipFile = nullptr;
}
std::vector<std::string> ZIP::listFiles()
{
std::vector<std::string> result;
for (auto const& file : fileList)
result.push_back(file.first);
return result;
}
bool ZIP::fileExists(const std::string& fileName)
{
auto it = fileList.find(fileName);
if (it == fileList.end())
return false;
return true;
}
bool ZIP::getFile(const std::string& fileName, std::shared_ptr<std::vector<char>>& fileData)
{
auto it = fileList.find(fileName);
if (it == fileList.end())
return false;
auto file = zip_fopen_index(zipFile, it->second, 0);
if (file == NULL)
return false;
zip_stat_t fileInfo;
zip_stat_index(zipFile, it->second, 0, &fileInfo);
// Initialize the buffer
fileData = std::make_shared<std::vector<char>>(fileInfo.size);
// Attempt to read the data into the buffer
auto retval = zip_fread(file, fileData->data(), fileData->size());
// Close the file
zip_fclose(file);
if (retval == -1)
return false;
return true;
}

20
src/EterPack/ZIP.h Normal file
View File

@ -0,0 +1,20 @@
#include <string>
#include <map>
#include <zip.h>
#include "FileProvider.h"
class ZIP : public FileProvider
{
protected:
zip_t* zipFile = nullptr;
std::map<std::string, zip_uint64_t> fileList;
public:
ZIP(const std::string& archivePath);
~ZIP();
std::vector<std::string> listFiles();
bool fileExists(const std::string& fileName);
bool getFile(const std::string& fileName, std::shared_ptr<std::vector<char>>& fileData);
};

File diff suppressed because it is too large Load Diff

View File

@ -1,128 +0,0 @@
#ifndef __INC_ETERPACKLIB_MD5_H__
#define __INC_ETERPACKLIB_MD5_H__
/*
***********************************************************************
** md5.h -- header file for implementation of MD5 **
** RSA Data Security, Inc. MD5 Message-Digest Algorithm **
** Created: 2/17/90 RLR **
** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version **
** Revised (for MD5): RLR 4/27/91 **
** -- G modified to have y&~z instead of y&z **
** -- FF, GG, HH modified to add in last register done **
** -- Access pattern: round 2 works mod 5, round 3 works mod 3 **
** -- distinct additive constant for each step **
** -- round 4 added, working mod 7 **
***********************************************************************
*/
/*
***********************************************************************
** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. **
** **
** License to copy and use this software is granted provided that **
** it is identified as the "RSA Data Security, Inc. MD5 Message- **
** Digest Algorithm" in all material mentioning or referencing this **
** software or this function. **
** **
** License is also granted to make and use derivative works **
** provided that such works are identified as "derived from the RSA **
** Data Security, Inc. MD5 Message-Digest Algorithm" in all **
** material mentioning or referencing the derived work. **
** **
** RSA Data Security, Inc. makes no representations concerning **
** either the merchantability of this software or the suitability **
** of this software for any particular purpose. It is provided "as **
** is" without express or implied warranty of any kind. **
** **
** These notices must be retained in any copies of any part of this **
** documentation and/or software. **
***********************************************************************
*/
/* typedef a 32-bit type */
typedef unsigned long int UINT4;
/* Data structure for MD5 (Message-Digest) computation */
typedef struct {
UINT4 i[2]; /* number of _bits_ handled mod 2^64 */
UINT4 buf[4]; /* scratch buffer */
unsigned char in[64]; /* input buffer */
unsigned char digest[16]; /* actual digest after MD5Final call */
} MD5_CTX;
#if defined (__cplusplus)
extern "C" {
#endif
void MD5Init (MD5_CTX *);
void MD5Update (MD5_CTX *,unsigned char *,unsigned int);
void MD5Final (MD5_CTX *);
void MD5Transform(UINT4 *,UINT4 *);
#if defined (__cplusplus)
};
#endif
/*
***********************************************************************
** End of md5.h **
******************************** (cut) ********************************
*/
#endif

View File

@ -106,10 +106,8 @@ bool CTerrain::LoadShadowMap(const char * c_pszFileName)
DWORD dwStart = ELTimer_GetMSec(); DWORD dwStart = ELTimer_GetMSec();
Tracef("LoadShadowMap %s ", c_pszFileName); Tracef("LoadShadowMap %s ", c_pszFileName);
CMappedFile file; CEterPackManager::TPackDataPtr data;
LPCVOID c_pvData; if (!CEterPackManager::Instance().Get(c_pszFileName, data))
if (!CEterPackManager::Instance().Get(file, c_pszFileName, &c_pvData))
{ {
TraceError(" CTerrain::LoadShadowMap - %s OPEN ERROR", c_pszFileName); TraceError(" CTerrain::LoadShadowMap - %s OPEN ERROR", c_pszFileName);
return false; return false;
@ -117,13 +115,13 @@ bool CTerrain::LoadShadowMap(const char * c_pszFileName)
DWORD dwShadowMapSize = sizeof(WORD) * 256 * 256; DWORD dwShadowMapSize = sizeof(WORD) * 256 * 256;
if (file.Size() != dwShadowMapSize) if (data->size() != dwShadowMapSize)
{ {
TraceError(" CTerrain::LoadShadowMap - %s SIZE ERROR", c_pszFileName); TraceError(" CTerrain::LoadShadowMap - %s SIZE ERROR", c_pszFileName);
return false; return false;
} }
memcpy(m_awShadowMap, c_pvData, dwShadowMapSize); memcpy_s(m_awShadowMap, dwShadowMapSize, data->data(), data->size());
Tracef("%d ms\n", ELTimer_GetMSec() - dwStart); Tracef("%d ms\n", ELTimer_GetMSec() - dwStart);
return true; return true;

View File

@ -95,14 +95,12 @@ CItemData * CItemManager::MakeItemData(DWORD dwIndex)
bool CItemManager::LoadItemList(const char * c_szFileName) bool CItemManager::LoadItemList(const char * c_szFileName)
{ {
CMappedFile File; CEterPackManager::TPackDataPtr data;
LPCVOID pData; CMemoryTextFileLoader textFileLoader;
if (!CEterPackManager::Instance().Get(c_szFileName, data))
if (!CEterPackManager::Instance().Get(File, c_szFileName, &pData))
return false; return false;
CMemoryTextFileLoader textFileLoader; textFileLoader.Bind(data->size(), data->data());
textFileLoader.Bind(File.Size(), pData);
CTokenVector TokenVector; CTokenVector TokenVector;
for (DWORD i = 0; i < textFileLoader.GetLineCount(); ++i) for (DWORD i = 0; i < textFileLoader.GetLineCount(); ++i)
@ -196,16 +194,15 @@ const std::string& __SnapString(const std::string& c_rstSrc, std::string& rstTem
bool CItemManager::LoadItemDesc(const char* c_szFileName) bool CItemManager::LoadItemDesc(const char* c_szFileName)
{ {
const VOID* pvData; CEterPackManager::TPackDataPtr data;
CMappedFile kFile; CMemoryTextFileLoader kTextFileLoader;
if (!CEterPackManager::Instance().Get(kFile, c_szFileName, &pvData)) if (!CEterPackManager::Instance().Get(c_szFileName, data))
{ {
Tracenf("CItemManager::LoadItemDesc(c_szFileName=%s) - Load Error", c_szFileName); Tracenf("CItemManager::LoadItemDesc(c_szFileName=%s) - Load Error", c_szFileName);
return false; return false;
} }
CMemoryTextFileLoader kTextFileLoader; kTextFileLoader.Bind(data->size(), data->data());
kTextFileLoader.Bind(kFile.Size(), pvData);
std::string stTemp; std::string stTemp;
@ -254,22 +251,27 @@ DWORD GetHashCode( const char* pString )
bool CItemManager::LoadItemTable(const char* c_szFileName) bool CItemManager::LoadItemTable(const char* c_szFileName)
{ {
CMappedFile file; std::stringstream data;
LPCVOID pvData; if (!CEterPackManager::Instance().Get(c_szFileName, data))
if (!CEterPackManager::Instance().Get(file, c_szFileName, &pvData))
return false; return false;
DWORD dwFourCC, dwElements, dwDataSize; DWORD dwFourCC, dwElements, dwDataSize;
DWORD dwVersion=0; DWORD dwVersion=0;
DWORD dwStride=0; DWORD dwStride=0;
file.Read(&dwFourCC, sizeof(DWORD)); data.read((char*)&dwFourCC, sizeof(DWORD));
if (!data)
return false;
if (dwFourCC == MAKEFOURCC('M', 'I', 'P', 'X')) if (dwFourCC == MAKEFOURCC('M', 'I', 'P', 'X'))
{ {
file.Read(&dwVersion, sizeof(DWORD)); data.read((char*)&dwVersion, sizeof(DWORD));
file.Read(&dwStride, sizeof(DWORD)); if (!data)
return false;
data.read((char*)&dwStride, sizeof(DWORD));
if (!data)
return false;
if (dwVersion != 1) if (dwVersion != 1)
{ {
@ -289,19 +291,25 @@ bool CItemManager::LoadItemTable(const char* c_szFileName)
return false; return false;
} }
file.Read(&dwElements, sizeof(DWORD)); data.read((char*)&dwElements, sizeof(DWORD));
file.Read(&dwDataSize, sizeof(DWORD)); if (!data)
return false;
BYTE * pbData = new BYTE[dwDataSize]; data.read((char*)&dwDataSize, sizeof(DWORD));
file.Read(pbData, dwDataSize); if (!data)
return false;
auto pbData = std::make_shared<std::vector<BYTE>>(dwDataSize);
data.read((char*)pbData->data(), pbData->size());
if (!data)
return false;
///// /////
CLZObject zObj; CLZObject zObj;
if (!CLZO::Instance().Decompress(zObj, pbData, s_adwItemProtoKey)) if (!CLZO::Instance().Decompress(zObj, pbData->data(), s_adwItemProtoKey))
{ {
delete [] pbData;
return false; return false;
} }
@ -382,7 +390,6 @@ bool CItemManager::LoadItemTable(const char* c_szFileName)
// pItemData->SetItemTableData(table); // pItemData->SetItemTableData(table);
// } // }
delete [] pbData;
return true; return true;
} }

View File

@ -597,14 +597,14 @@ void CMapManager::GetBaseXY(DWORD * pdwBaseX, DWORD * pdwBaseY)
void CMapManager::__LoadMapInfoVector() void CMapManager::__LoadMapInfoVector()
{ {
CMappedFile kFile; CEterPackManager::TPackDataPtr data;
LPCVOID pData; CMemoryTextFileLoader textFileLoader;
if (!CEterPackManager::Instance().Get(kFile, m_stAtlasInfoFileName.c_str(), &pData))
if (!CEterPackManager::Instance().Get(kFile, "AtlasInfo.txt", &pData)) if (!CEterPackManager::Instance().Get(m_stAtlasInfoFileName, data))
if (!CEterPackManager::Instance().Get("AtlasInfo.txt", data))
return; return;
CMemoryTextFileLoader textFileLoader; textFileLoader.Bind(data->size(), data->data());
textFileLoader.Bind(kFile.Size(), pData);
char szMapName[256]; char szMapName[256];
int x, y; int x, y;

View File

@ -452,19 +452,18 @@ bool CMapOutdoor::LoadMonsterAreaInfo()
char c_szFileName[256]; char c_szFileName[256];
sprintf(c_szFileName, "%s\\regen.txt", GetMapDataDirectory().c_str()); sprintf(c_szFileName, "%s\\regen.txt", GetMapDataDirectory().c_str());
LPCVOID pModelData; CEterPackManager::TPackDataPtr modelData;
CMappedFile File; CMemoryTextFileLoader textFileLoader;
if (!CEterPackManager::Instance().Get(File, c_szFileName, &pModelData)) if (!CEterPackManager::Instance().Get(c_szFileName, modelData))
{ {
//TraceError(" CMapOutdoorAccessor::LoadMonsterAreaInfo Load File %s ERROR", c_szFileName); //TraceError(" CMapOutdoorAccessor::LoadMonsterAreaInfo Load File %s ERROR", c_szFileName);
return false; return false;
} }
CMemoryTextFileLoader textFileLoader;
CTokenVector stTokenVector; CTokenVector stTokenVector;
textFileLoader.Bind(File.Size(), pModelData); textFileLoader.Bind(modelData->size(), modelData->data());
for (DWORD i = 0; i < textFileLoader.GetLineCount(); ++i) for (DWORD i = 0; i < textFileLoader.GetLineCount(); ++i)
{ {

View File

@ -136,54 +136,6 @@ void GetTimeString(char * str, time_t ct)
tm.tm_sec); tm.tm_sec);
} }
bool CProperty::Save(const char * c_pszFileName)
{
CTempFile file;
DWORD fourcc = MAKEFOURCC('Y', 'P', 'R', 'T');
file.Write(&fourcc, sizeof(DWORD));
file.Write("\r\n", 2);
if (0 == m_stCRC.length())
{
char szCRC[MAX_PATH + 16 + 1];
GetTimeString(szCRC, time(0));
strcpy(szCRC + strlen(szCRC), c_pszFileName);
m_dwCRC = CPropertyManager::Instance().GetUniqueCRC(szCRC);
_snprintf(szCRC, sizeof(szCRC), "%u", m_dwCRC);
m_stCRC.assign(szCRC);
}
file.Write(m_stCRC.c_str(), m_stCRC.length());
file.Write("\r\n", 2);
CTokenVectorMap::iterator itor = m_stTokenMap.begin();
char buf[4096 + 1];
while (itor != m_stTokenMap.end())
{
CTokenVector & tokenVector = itor->second;
int len = _snprintf(buf, sizeof(buf), "%s\t", itor->first.c_str());
file.Write(buf, len);
for (DWORD i = 0; i < tokenVector.size(); ++i)
{
len = _snprintf(buf, sizeof(buf), "\t\"%s\"", tokenVector[i].c_str());
file.Write(buf, len);
}
file.Write("\r\n", 2);
++itor;
}
file.Close();
return CPropertyManager::Instance().Put(c_pszFileName, file.GetFileName());
}
bool CProperty::ReadFromMemory(const void * c_pvData, int iLen, const char * c_pszFileName) bool CProperty::ReadFromMemory(const void * c_pvData, int iLen, const char * c_pszFileName)
{ {
const char * pcData = (const char *) c_pvData; const char * pcData = (const char *) c_pvData;

View File

@ -19,8 +19,6 @@ class CProperty
void PutVector(const char * c_pszKey, const CTokenVector & c_rTokenVector); void PutVector(const char * c_pszKey, const CTokenVector & c_rTokenVector);
void PutString(const char * c_pszKey, const char * c_pszString); void PutString(const char * c_pszKey, const char * c_pszString);
bool Save(const char * c_pszFileName);
DWORD GetSize(); DWORD GetSize();
DWORD GetCRC(); DWORD GetCRC();

View File

@ -4,7 +4,7 @@
#include "PropertyManager.h" #include "PropertyManager.h"
#include "Property.h" #include "Property.h"
CPropertyManager::CPropertyManager() : m_isFileMode(true) CPropertyManager::CPropertyManager()
{ {
} }
@ -13,90 +13,34 @@ CPropertyManager::~CPropertyManager()
Clear(); Clear();
} }
bool CPropertyManager::Initialize(const char * c_pszPackFileName) void CPropertyManager::Initialize()
{ {
if (c_pszPackFileName) auto fileMap = CEterPackManager::Instance().GetFileMap();
for (auto& itor : fileMap)
{ {
if (!m_pack.Create(m_fileDict, c_pszPackFileName, "", true)) if (itor.first.rfind("property/reserve", 0) == 0)
{ {
LogBoxf("Cannot open property pack file (filename %s)", c_pszPackFileName); LoadReservedCRC(itor.first.c_str());
return false;
}
m_isFileMode = false;
TDataPositionMap & indexMap = m_pack.GetIndexMap();
TDataPositionMap::iterator itor = indexMap.begin();
typedef std::map<DWORD, TEterPackIndex *> TDataPositionMap;
int i = 0;
while (indexMap.end() != itor)
{
TEterPackIndex * pIndex = itor->second;
++itor;
if (!stricmp("property/reserve", pIndex->filename))
{
LoadReservedCRC(pIndex->filename);
continue;
}
if (!Register(pIndex->filename))
continue;
++i;
}
}
else
{
m_isFileMode = true;
// NOTE : 여기서 Property를 등록시키면 WorldEditor에서 이상이 생김 ;
// 또한, Property Tree List에도 등록을 시켜야 되기 때문에 바깥쪽에서.. - [levites]
}
return true;
}
bool CPropertyManager::BuildPack()
{
if (!m_pack.Create(m_fileDict, "property", ""))
return false;
WIN32_FIND_DATA fdata;
HANDLE hFind = FindFirstFile("property\\*", &fdata);
if (hFind == INVALID_HANDLE_VALUE)
return false;
do
{
if (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
continue; continue;
}
char szSourceFileName[256 + 1]; if (itor.first.rfind("property/", 0) == 0) {
_snprintf(szSourceFileName, sizeof(szSourceFileName), "property\\%s", fdata.cFileName); if (!Register(itor.first.c_str()))
continue;
m_pack.Put(fdata.cFileName, szSourceFileName,COMPRESSED_TYPE_NONE,""); }
} }
while (FindNextFile(hFind, &fdata));
FindClose(hFind);
return true;
} }
bool CPropertyManager::LoadReservedCRC(const char * c_pszFileName) bool CPropertyManager::LoadReservedCRC(const char * c_pszFileName)
{ {
CMappedFile file; CEterPackManager::TPackDataPtr data;
LPCVOID c_pvData; CMemoryTextFileLoader textFileLoader;
if (!CEterPackManager::Instance().Get(file, c_pszFileName, &c_pvData)) if (!CEterPackManager::Instance().Get(c_pszFileName, data))
return false; return false;
CMemoryTextFileLoader textFileLoader; textFileLoader.Bind(data->size(), data->data());
textFileLoader.Bind(file.Size(), c_pvData);
for (DWORD i = 0; i < textFileLoader.GetLineCount(); ++i) for (DWORD i = 0; i < textFileLoader.GetLineCount(); ++i)
{ {
@ -136,15 +80,13 @@ DWORD CPropertyManager::GetUniqueCRC(const char * c_szSeed)
bool CPropertyManager::Register(const char * c_pszFileName, CProperty ** ppProperty) bool CPropertyManager::Register(const char * c_pszFileName, CProperty ** ppProperty)
{ {
CMappedFile file; CEterPackManager::TPackDataPtr data;
LPCVOID c_pvData; if (!CEterPackManager::Instance().Get(c_pszFileName, data))
if (!CEterPackManager::Instance().Get(file, c_pszFileName, &c_pvData))
return false; return false;
CProperty * pProperty = new CProperty(c_pszFileName); CProperty * pProperty = new CProperty(c_pszFileName);
if (!pProperty->ReadFromMemory(c_pvData, file.Size(), c_pszFileName)) if (!pProperty->ReadFromMemory(data->data(), data->size(), c_pszFileName))
{ {
delete pProperty; delete pProperty;
return false; return false;
@ -188,67 +130,6 @@ bool CPropertyManager::Get(DWORD dwCRC, CProperty ** ppProperty)
return true; return true;
} }
bool CPropertyManager::Put(const char * c_pszFileName, const char * c_pszSourceFileName)
{
if (!CopyFile(c_pszSourceFileName, c_pszFileName, FALSE))
return false;
if (!m_isFileMode) // 팩 파일에도 넣음
{
if (!m_pack.Put(c_pszFileName, NULL, COMPRESSED_TYPE_NONE,""))
{
assert(!"CPropertyManager::Put cannot write to pack file");
return false;
}
}
Register(c_pszFileName);
return true;
}
bool CPropertyManager::Erase(DWORD dwCRC)
{
TPropertyCRCMap::iterator itor = m_PropertyByCRCMap.find(dwCRC);
if (m_PropertyByCRCMap.end() == itor)
return false;
CProperty * pProperty = itor->second;
m_PropertyByCRCMap.erase(itor);
DeleteFile(pProperty->GetFileName());
ReserveCRC(pProperty->GetCRC());
if (!m_isFileMode) // 파일 모드가 아니면 팩에서도 지움
m_pack.Delete(pProperty->GetFileName());
FILE * fp = fopen("property/reserve", "a+");
if (!fp)
LogBox("Unable to Open Scheduled CRC Files.");
else
{
char szCRC[64 + 1];
_snprintf(szCRC, sizeof(szCRC), "%u\r\n", pProperty->GetCRC());
fputs(szCRC, fp);
fclose(fp);
}
delete pProperty;
return true;
}
bool CPropertyManager::Erase(const char * c_pszFileName)
{
CProperty * pProperty = NULL;
if (Get(c_pszFileName, &pProperty))
return Erase(pProperty->GetCRC());
return false;
}
void CPropertyManager::Clear() void CPropertyManager::Clear()
{ {
stl_wipe_second(m_PropertyByCRCMap); stl_wipe_second(m_PropertyByCRCMap);

View File

@ -1,7 +1,5 @@
#pragma once #pragma once
#include "../eterPack/EterPack.h"
class CPropertyManager : public CSingleton<CPropertyManager> class CPropertyManager : public CSingleton<CPropertyManager>
{ {
public: public:
@ -10,34 +8,20 @@ class CPropertyManager : public CSingleton<CPropertyManager>
void Clear(); void Clear();
void SetPack(CEterPack * pPack);
bool BuildPack();
bool LoadReservedCRC(const char * c_pszFileName); bool LoadReservedCRC(const char * c_pszFileName);
void ReserveCRC(DWORD dwCRC); void ReserveCRC(DWORD dwCRC);
DWORD GetUniqueCRC(const char * c_szSeed); DWORD GetUniqueCRC(const char * c_szSeed);
bool Initialize(const char * c_pszPackFileName = NULL); void Initialize();
bool Register(const char * c_pszFileName, CProperty ** ppProperty = NULL); bool Register(const char * c_pszFileName, CProperty ** ppProperty = NULL);
bool Get(DWORD dwCRC, CProperty ** ppProperty); bool Get(DWORD dwCRC, CProperty ** ppProperty);
bool Get(const char * c_pszFileName, CProperty ** ppProperty); bool Get(const char * c_pszFileName, CProperty ** ppProperty);
// bool Add(const char * c_pszFileName);
// bool Remove(DWORD dwCRC);
bool Put(const char * c_pszFileName, const char * c_pszSourceFileName);
bool Erase(DWORD dwCRC);
bool Erase(const char * c_pszFileName);
protected: protected:
typedef std::map<DWORD, CProperty *> TPropertyCRCMap; typedef std::map<DWORD, CProperty *> TPropertyCRCMap;
typedef std::set<DWORD> TCRCSet; typedef std::set<DWORD> TCRCSet;
bool m_isFileMode;
TPropertyCRCMap m_PropertyByCRCMap; TPropertyCRCMap m_PropertyByCRCMap;
TCRCSet m_ReservedCRCSet; TCRCSet m_ReservedCRCSet;
CEterPack m_pack;
CEterFileDict m_fileDict;
}; };

View File

@ -237,14 +237,13 @@ bool CRaceManager::__LoadRaceMotionList(CRaceData& rkRaceData, const char* pathN
s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("SKILL5", CRaceMotionData::NAME_SKILL+125)); s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("SKILL5", CRaceMotionData::NAME_SKILL+125));
} }
const void* pvData; CEterPackManager::TPackDataPtr data;
CMappedFile kMappedFile; CMemoryTextFileLoader kTextFileLoader;
if (!CEterPackManager::Instance().Get(kMappedFile, motionListFileName, &pvData))
if (!CEterPackManager::Instance().Get(motionListFileName, data))
return false; return false;
kTextFileLoader.Bind(data->size(), data->data());
CMemoryTextFileLoader kTextFileLoader;
kTextFileLoader.Bind(kMappedFile.Size(), pvData);
rkRaceData.RegisterMotionMode(CRaceMotionData::MODE_GENERAL); rkRaceData.RegisterMotionMode(CRaceMotionData::MODE_GENERAL);

View File

@ -5,7 +5,7 @@
#include "../eterBase/Timer.h" #include "../eterBase/Timer.h"
bool CSoundData::ms_isSoundFile[SOUND_FILE_MAX_NUM]; bool CSoundData::ms_isSoundFile[SOUND_FILE_MAX_NUM];
CMappedFile CSoundData::ms_SoundFile[SOUND_FILE_MAX_NUM]; std::stringstream CSoundData::ms_SoundFile[SOUND_FILE_MAX_NUM];
const char * CSoundData::GetFileName() const char * CSoundData::GetFileName()
{ {
@ -139,9 +139,7 @@ U32 AILCALLBACK CSoundData::open_callback(char const * filename, U32 *file_handl
if (-1 == iIndex) if (-1 == iIndex)
return 0; return 0;
LPCVOID pMap; if (!CEterPackManager::Instance().Get(filename, ms_SoundFile[iIndex]))
if (!CEterPackManager::Instance().Get(ms_SoundFile[iIndex], filename, &pMap))
return 0; return 0;
ms_isSoundFile[iIndex] = true; ms_isSoundFile[iIndex] = true;
@ -155,7 +153,7 @@ void AILCALLBACK CSoundData::close_callback(U32 file_handle)
if (!isSlotIndex(file_handle)) if (!isSlotIndex(file_handle))
return; return;
ms_SoundFile[file_handle].Destroy(); ms_SoundFile[file_handle].str("");
ms_isSoundFile[file_handle] = false; ms_isSoundFile[file_handle] = false;
} }
@ -164,7 +162,8 @@ S32 AILCALLBACK CSoundData::seek_callback(U32 file_handle, S32 offset, U32 type)
if (!isSlotIndex(file_handle)) if (!isSlotIndex(file_handle))
return 0; return 0;
return ms_SoundFile[file_handle].Seek(offset, type); ms_SoundFile[file_handle].seekg(offset, type);
return ms_SoundFile[file_handle].tellg();
} }
U32 AILCALLBACK CSoundData::read_callback(U32 file_handle, void * buffer, U32 bytes) U32 AILCALLBACK CSoundData::read_callback(U32 file_handle, void * buffer, U32 bytes)
@ -172,9 +171,8 @@ U32 AILCALLBACK CSoundData::read_callback(U32 file_handle, void * buffer, U32 by
if (!isSlotIndex(file_handle)) if (!isSlotIndex(file_handle))
return 0; return 0;
DWORD dwRealSize = min(ms_SoundFile[file_handle].Size(), bytes); ms_SoundFile[file_handle].read((char*) buffer, bytes);
ms_SoundFile[file_handle].Read(buffer, dwRealSize); return ms_SoundFile[file_handle].gcount();
return dwRealSize;
} }
void CSoundData::SetPackMode() void CSoundData::SetPackMode()

View File

@ -1,6 +1,7 @@
#ifndef __MILESLIB_CSOUNDDATA_H__ #ifndef __MILESLIB_CSOUNDDATA_H__
#define __MILESLIB_CSOUNDDATA_H__ #define __MILESLIB_CSOUNDDATA_H__
#include <sstream>
#include <miles/MSS.H> #include <miles/MSS.H>
#include "../eterBase/MappedFile.h" #include "../eterBase/MappedFile.h"
@ -53,7 +54,7 @@ class CSoundData
static int GetEmptySlotIndex(); static int GetEmptySlotIndex();
static bool ms_isSoundFile[SOUND_FILE_MAX_NUM]; static bool ms_isSoundFile[SOUND_FILE_MAX_NUM];
static CMappedFile ms_SoundFile[SOUND_FILE_MAX_NUM]; static std::stringstream ms_SoundFile[SOUND_FILE_MAX_NUM];
}; };
#endif #endif

View File

@ -76,18 +76,23 @@ bool CTerrainImpl::LoadHeightMap(const char*c_szFileName)
{ {
Tracef("LoadRawHeightMapFile %s ", c_szFileName); Tracef("LoadRawHeightMapFile %s ", c_szFileName);
CMappedFile kMappedFile; std::stringstream data;
LPCVOID lpcvFileData; if (!CEterPackManager::Instance().Get(c_szFileName, data))
if (!CEterPackManager::Instance().Get(kMappedFile, c_szFileName, &lpcvFileData))
{ {
Tracen("Error"); Tracen("Error");
TraceError("CTerrainImpl::LoadHeightMap - %s OPEN ERROR", c_szFileName); TraceError("CTerrainImpl::LoadHeightMap - %s OPEN ERROR", c_szFileName);
return false; return false;
} }
memcpy(m_awRawHeightMap, lpcvFileData, sizeof(WORD)*HEIGHTMAP_RAW_XSIZE*HEIGHTMAP_RAW_YSIZE); data.read((char*) m_awRawHeightMap, sizeof(WORD)*HEIGHTMAP_RAW_XSIZE*HEIGHTMAP_RAW_YSIZE);
if (!data)
{
// Could not read data
TraceError("CTerrainImpl::LoadHeightMap - %s READ ERROR", c_szFileName);
return false;
}
// Data read successfully
return true; return true;
} }
@ -96,18 +101,13 @@ bool CTerrainImpl::LoadAttrMap(const char *c_szFileName)
DWORD dwStart = ELTimer_GetMSec(); DWORD dwStart = ELTimer_GetMSec();
Tracef("LoadAttrMapFile %s ", c_szFileName); Tracef("LoadAttrMapFile %s ", c_szFileName);
CMappedFile kMappedFile; std::stringstream data;
LPCVOID lpcvFileData; if (!CEterPackManager::Instance().Get(c_szFileName, data))
if (!CEterPackManager::Instance().Get(kMappedFile, c_szFileName, &lpcvFileData))
{ {
TraceError("CTerrainImpl::LoadAttrMap - %s OPEN ERROR", c_szFileName); TraceError("CTerrainImpl::LoadAttrMap - %s OPEN ERROR", c_szFileName);
return false; return false;
} }
DWORD dwFileSize = kMappedFile.Size();
BYTE * abFileData = (BYTE *) lpcvFileData;
// LoadAttrMap // LoadAttrMap
{ {
#pragma pack(push) #pragma pack(push)
@ -120,15 +120,14 @@ bool CTerrainImpl::LoadAttrMap(const char *c_szFileName)
}; };
#pragma pack(pop) #pragma pack(pop)
if (dwFileSize < sizeof(SAttrMapHeader)) SAttrMapHeader kAttrMapHeader;
data.read((char*) &kAttrMapHeader, sizeof(kAttrMapHeader));
if (!data)
{ {
TraceError(" CTerrainImpl::LoadAttrMap - %s FILE SIZE ERROR", c_szFileName); TraceError(" CTerrainImpl::LoadAttrMap - %s FILE SIZE ERROR", c_szFileName);
return false; return false;
} }
SAttrMapHeader kAttrMapHeader;
memcpy(&kAttrMapHeader, abFileData, sizeof(kAttrMapHeader));
const WORD c_wAttrMapMagic = 2634; const WORD c_wAttrMapMagic = 2634;
if (c_wAttrMapMagic != kAttrMapHeader.m_wMagic) if (c_wAttrMapMagic != kAttrMapHeader.m_wMagic)
{ {
@ -148,40 +147,40 @@ bool CTerrainImpl::LoadAttrMap(const char *c_szFileName)
return false; return false;
} }
DWORD dwFileRestSize=dwFileSize-sizeof(kAttrMapHeader); data.read((char*)m_abyAttrMap, sizeof(m_abyAttrMap));
DWORD dwFileNeedSize=sizeof(m_abyAttrMap); if (!data)
if (dwFileRestSize != dwFileNeedSize)
{ {
TraceError("CTerrainImpl::LoadAttrMap - %s FILE DATA SIZE(rest %d != need %d) ERROR", c_szFileName, dwFileRestSize, dwFileNeedSize); TraceError("CTerrainImpl::LoadAttrMap - %s FILE DATA SIZE ERROR", c_szFileName);
return false; return false;
} }
BYTE* abSrcAttrData= abFileData+sizeof(kAttrMapHeader);
memcpy(m_abyAttrMap, abSrcAttrData, sizeof(m_abyAttrMap));
} }
Tracef("%d\n", ELTimer_GetMSec() - dwStart); Tracef("%d\n", ELTimer_GetMSec() - dwStart);
return true; return true;
} }
bool CTerrainImpl::RAW_LoadTileMap(const char * c_szFileName) bool CTerrainImpl::RAW_LoadTileMap(const char* c_szFileName)
{ {
Tracef("LoadSplatFile %s ", c_szFileName); Tracef("LoadSplatFile %s ", c_szFileName);
CMappedFile kMappedFile; std::stringstream data;
LPCVOID lpcvFileData; if (!CEterPackManager::Instance().Get(c_szFileName, data))
if (!CEterPackManager::Instance().Get(kMappedFile, c_szFileName, &lpcvFileData))
{ {
Tracen("Error"); Tracen("Error");
TraceError("CTerrainImpl::RAW_LoadTileMap - %s OPEN ERROR", c_szFileName); TraceError("CTerrainImpl::RAW_LoadTileMap - %s OPEN ERROR", c_szFileName);
return false; return false;
} }
memcpy(m_abyTileMap, lpcvFileData, sizeof(BYTE)*(TILEMAP_RAW_XSIZE)*(TILEMAP_RAW_YSIZE)); data.read((char*)m_abyTileMap, sizeof(BYTE) * (TILEMAP_RAW_XSIZE) * (TILEMAP_RAW_YSIZE));
if (!data)
{
// Could not read data
TraceError("CTerrainImpl::RAW_LoadTileMap - %s READ ERROR", c_szFileName);
return false;
}
// Data read successfully
return true; return true;
} }
bool CTerrainImpl::LoadWaterMap(const char * c_szFileName) bool CTerrainImpl::LoadWaterMap(const char * c_szFileName)
@ -206,18 +205,16 @@ bool CTerrainImpl::LoadWaterMap(const char * c_szFileName)
bool CTerrainImpl::LoadWaterMapFile(const char * c_szFileName) bool CTerrainImpl::LoadWaterMapFile(const char * c_szFileName)
{ {
CMappedFile kMappedFile; std::stringstream data;
LPCVOID lpcvFileData; size_t fileSize = 0;
if (!CEterPackManager::Instance().Get(c_szFileName, data))
if (!CEterPackManager::Instance().Get(kMappedFile, c_szFileName, &lpcvFileData))
{ {
Tracen("Error"); Tracen("Error");
TraceError("CTerrainImpl::LoadWaterMap - %s OPEN ERROR", c_szFileName); TraceError("CTerrainImpl::LoadWaterMap - %s OPEN ERROR", c_szFileName);
return false; return false;
} }
DWORD dwFileSize = kMappedFile.Size(); fileSize = data.str().length();
BYTE* abFileData = (BYTE*)lpcvFileData;
{ {
#pragma pack(push) #pragma pack(push)
@ -231,15 +228,14 @@ bool CTerrainImpl::LoadWaterMapFile(const char * c_szFileName)
}; };
#pragma pack(pop) #pragma pack(pop)
if (dwFileSize < sizeof(SWaterMapHeader)) SWaterMapHeader kWaterMapHeader;
data.read((char*)&kWaterMapHeader, sizeof(kWaterMapHeader));
if (!data)
{ {
TraceError("CTerrainImpl::LoadWaterMap - %s FILE SIZE ERROR", c_szFileName); TraceError("CTerrainImpl::LoadWaterMap - %s FILE SIZE ERROR", c_szFileName);
return false; return false;
} }
SWaterMapHeader kWaterMapHeader;
memcpy(&kWaterMapHeader, abFileData, sizeof(kWaterMapHeader));
const WORD c_wWaterMapMagic = 5426; const WORD c_wWaterMapMagic = 5426;
if (c_wWaterMapMagic != kWaterMapHeader.m_wMagic) if (c_wWaterMapMagic != kWaterMapHeader.m_wMagic)
@ -262,22 +258,23 @@ bool CTerrainImpl::LoadWaterMapFile(const char * c_szFileName)
m_byNumWater = kWaterMapHeader.m_byLayerCount; m_byNumWater = kWaterMapHeader.m_byLayerCount;
DWORD dwFileRestSize = dwFileSize - sizeof(kWaterMapHeader); DWORD dwFileRestSize = fileSize - sizeof(kWaterMapHeader);
DWORD dwFileNeedSize = sizeof(m_abyWaterMap) + sizeof(long) * m_byNumWater; DWORD dwFileNeedSize = sizeof(m_abyWaterMap) + sizeof(long) * m_byNumWater;
DWORD dwFileNeedSize2 = sizeof(m_abyWaterMap) + sizeof(WORD) * m_byNumWater; DWORD dwFileNeedSize2 = sizeof(m_abyWaterMap) + sizeof(WORD) * m_byNumWater;
if (dwFileRestSize == dwFileNeedSize2) if (dwFileRestSize == dwFileNeedSize2)
{ {
WORD wWaterHeight[MAX_WATER_NUM + 1]; WORD wWaterHeight[MAX_WATER_NUM + 1];
BYTE * abSrcWaterData = abFileData + sizeof(kWaterMapHeader); data.read((char*)m_abyWaterMap, sizeof(m_abyWaterMap));
memcpy(m_abyWaterMap, abSrcWaterData, sizeof(m_abyWaterMap)); if (!data)
return false;
BYTE * abSrcWaterHeight = abSrcWaterData + sizeof(m_abyWaterMap);
m_byNumWater = MIN(MAX_WATER_NUM, m_byNumWater); m_byNumWater = MIN(MAX_WATER_NUM, m_byNumWater);
if (m_byNumWater) if (m_byNumWater)
{ {
memcpy(wWaterHeight, abSrcWaterHeight, sizeof(WORD) * m_byNumWater); data.read((char*)wWaterHeight, sizeof(WORD) * m_byNumWater);
if (!data)
return false;
for (int i = 0; i < m_byNumWater; ++i) for (int i = 0; i < m_byNumWater; ++i)
m_lWaterHeight[i] = wWaterHeight[i]; m_lWaterHeight[i] = wWaterHeight[i];
@ -289,13 +286,15 @@ bool CTerrainImpl::LoadWaterMapFile(const char * c_szFileName)
return false; return false;
} }
BYTE * abSrcWaterData = abFileData + sizeof(kWaterMapHeader); data.read((char*)m_abyWaterMap, sizeof(m_abyWaterMap));
memcpy(m_abyWaterMap, abSrcWaterData, sizeof(m_abyWaterMap)); if (!data)
return false;
BYTE * abSrcWaterHeight = abSrcWaterData + sizeof(m_abyWaterMap); if (m_byNumWater) {
data.read((char*)m_lWaterHeight, sizeof(long)* m_byNumWater);
if (m_byNumWater) if (!data)
memcpy(m_lWaterHeight, abSrcWaterHeight, sizeof(long) * m_byNumWater); return false;
}
} }
return true; return true;

View File

@ -196,21 +196,19 @@ bool CPythonLauncher::RunCompiledFile(const char* c_szFileName)
} }
bool CPythonLauncher::RunMemoryTextFile(const char* c_szFileName, UINT uFileSize, const VOID* c_pvFileData) bool CPythonLauncher::RunMemoryTextFile(const char* c_szFileName, std::shared_ptr<std::vector<char>> fileData)
{ {
NANOBEGIN NANOBEGIN
const CHAR* c_pcFileData=(const CHAR*)c_pvFileData;
std::string stConvFileData; std::string stConvFileData;
stConvFileData.reserve(uFileSize); stConvFileData.reserve(fileData->size());
stConvFileData+="exec(compile('''"; stConvFileData+="exec(compile('''";
// ConvertPythonTextFormat // ConvertPythonTextFormat
{ {
for (UINT i=0; i<uFileSize; ++i) for (UINT i=0; i<fileData->size(); ++i)
{ {
if (c_pcFileData[i]!=13) if ((*fileData)[i] != 13)
stConvFileData+=c_pcFileData[i]; stConvFileData+= (*fileData)[i];
} }
} }
@ -227,29 +225,14 @@ bool CPythonLauncher::RunMemoryTextFile(const char* c_szFileName, UINT uFileSize
bool CPythonLauncher::RunFile(const char* c_szFileName) bool CPythonLauncher::RunFile(const char* c_szFileName)
{ {
char* acBufData=NULL; CEterPackManager::TPackDataPtr data;
DWORD dwBufSize=0; if (!CEterPackManager::Instance().Get(c_szFileName, data))
return false;
{ if (data->size() == 0)
CMappedFile file; return false;
const VOID* pvData;
CEterPackManager::Instance().Get(file, c_szFileName, &pvData);
dwBufSize=file.Size(); return RunMemoryTextFile(c_szFileName, data);
if (dwBufSize==0)
return false;
acBufData=new char[dwBufSize];
memcpy(acBufData, pvData, dwBufSize);
}
bool ret=false;
ret=RunMemoryTextFile(c_szFileName, dwBufSize, acBufData);
delete [] acBufData;
return ret;
} }
bool CPythonLauncher::RunLine(const char* c_szSrc) bool CPythonLauncher::RunLine(const char* c_szSrc)

View File

@ -15,7 +15,7 @@ class CPythonLauncher : public CSingleton<CPythonLauncher>
void SetTraceFunc(int (*pFunc)(PyObject * obj, PyFrameObject * f, int what, PyObject *arg)); void SetTraceFunc(int (*pFunc)(PyObject * obj, PyFrameObject * f, int what, PyObject *arg));
bool RunLine(const char* c_szLine); bool RunLine(const char* c_szLine);
bool RunFile(const char* c_szFileName); bool RunFile(const char* c_szFileName);
bool RunMemoryTextFile(const char* c_szFileName, UINT uFileSize, const VOID* c_pvFileData); bool RunMemoryTextFile(const char* c_szFileName, std::shared_ptr<std::vector<char>> fileData);
bool RunCompiledFile(const char* c_szFileName); bool RunCompiledFile(const char* c_szFileName);
const char* GetError(); const char* GetError();

View File

@ -75,16 +75,15 @@ BOOL CSpeedTreeForest::GetMainTree(DWORD dwCRC, CSpeedTreeWrapper ** ppMainTree,
pTree = itor->second; pTree = itor->second;
else else
{ {
CMappedFile file; CEterPackManager::TPackDataPtr data;
LPCVOID c_pvData;
// NOTE : 파일이 없을때는 return FALSE 아닌가요? - [levites] // NOTE : 파일이 없을때는 return FALSE 아닌가요? - [levites]
if (!CEterPackManager::Instance().Get(file, c_pszFileName, &c_pvData)) if (!CEterPackManager::Instance().Get(c_pszFileName, data))
return FALSE; return FALSE;
pTree = new CSpeedTreeWrapper; pTree = new CSpeedTreeWrapper;
if (!pTree->LoadTree(c_pszFileName, (const BYTE *) c_pvData, file.Size())) if (!pTree->LoadTree(c_pszFileName, (const BYTE *) data->data(), data->size()))
{ {
delete pTree; delete pTree;
pTree = nullptr; pTree = nullptr;
@ -92,8 +91,6 @@ BOOL CSpeedTreeForest::GetMainTree(DWORD dwCRC, CSpeedTreeWrapper ** ppMainTree,
} }
m_pMainTreeMap.insert(std::map<DWORD, CSpeedTreeWrapper *>::value_type(dwCRC, pTree)); m_pMainTreeMap.insert(std::map<DWORD, CSpeedTreeWrapper *>::value_type(dwCRC, pTree));
file.Destroy();
} }
*ppMainTree = pTree; *ppMainTree = pTree;

View File

@ -141,13 +141,6 @@ bool CAccountConnector::__HandshakeState_Process()
if (!__AnalyzePacket(HEADER_GC_PING, sizeof(TPacketGCPing), &CAccountConnector::__AuthState_RecvPing)) if (!__AnalyzePacket(HEADER_GC_PING, sizeof(TPacketGCPing), &CAccountConnector::__AuthState_RecvPing))
return false; return false;
// TODO : 차후 서버와 동일하게 가변길이 data serialize & deserialize 작업해야 한다.
if (!__AnalyzeVarSizePacket(HEADER_GC_HYBRIDCRYPT_KEYS, &CAccountConnector::__AuthState_RecvHybridCryptKeys))
return false;
if (!__AnalyzeVarSizePacket(HEADER_GC_HYBRIDCRYPT_SDB, &CAccountConnector::__AuthState_RecvHybridCryptSDB))
return false;
return true; return true;
} }
@ -185,16 +178,6 @@ bool CAccountConnector::__AuthState_Process()
if (!__AnalyzePacket(HEADER_GC_HANDSHAKE, sizeof(TPacketGCHandshake), &CAccountConnector::__AuthState_RecvHandshake)) if (!__AnalyzePacket(HEADER_GC_HANDSHAKE, sizeof(TPacketGCHandshake), &CAccountConnector::__AuthState_RecvHandshake))
return false; return false;
if (!__AnalyzePacket(HEADER_GC_PANAMA_PACK, sizeof(TPacketGCPanamaPack), &CAccountConnector::__AuthState_RecvPanamaPack))
return false;
// TODO : 차후 서버와 동일하게 가변길이 data serialize & deserialize 작업해야 한다.
if (!__AnalyzeVarSizePacket(HEADER_GC_HYBRIDCRYPT_KEYS, &CAccountConnector::__AuthState_RecvHybridCryptKeys))
return false;
if (!__AnalyzeVarSizePacket(HEADER_GC_HYBRIDCRYPT_SDB, &CAccountConnector::__AuthState_RecvHybridCryptSDB))
return false;
return true; return true;
} }
@ -345,50 +328,6 @@ bool CAccountConnector::__AuthState_RecvHandshake()
return true; return true;
} }
bool CAccountConnector::__AuthState_RecvPanamaPack()
{
TPacketGCPanamaPack kPacket;
if (!Recv(sizeof(TPacketGCPanamaPack), &kPacket))
return false;
CEterPackManager::instance().RegisterPack(kPacket.szPackName, "*", kPacket.abIV);
return true;
}
bool CAccountConnector::__AuthState_RecvHybridCryptKeys(int iTotalSize)
{
int iFixedHeaderSize = TPacketGCHybridCryptKeys::GetFixedHeaderSize();
TPacketGCHybridCryptKeys kPacket(iTotalSize-iFixedHeaderSize);
if (!Recv(iFixedHeaderSize, &kPacket))
return false;
if (!Recv(kPacket.iKeyStreamLen, kPacket.m_pStream))
return false;
CEterPackManager::Instance().RetrieveHybridCryptPackKeys( kPacket.m_pStream );
return true;
}
bool CAccountConnector::__AuthState_RecvHybridCryptSDB(int iTotalSize)
{
int iFixedHeaderSize = TPacketGCHybridSDB::GetFixedHeaderSize();
TPacketGCHybridSDB kPacket(iTotalSize-iFixedHeaderSize);
if (!Recv(iFixedHeaderSize, &kPacket))
return false;
if (!Recv(kPacket.iSDBStreamLen, kPacket.m_pStream))
return false;
CEterPackManager::Instance().RetrieveHybridCryptPackSDB( kPacket.m_pStream );
return true;
}
bool CAccountConnector::__AuthState_RecvPing() bool CAccountConnector::__AuthState_RecvPing()
{ {
TPacketGCPing kPacketPing; TPacketGCPing kPacketPing;
@ -423,9 +362,6 @@ bool CAccountConnector::__AuthState_RecvAuthSuccess()
} }
else else
{ {
DWORD dwPanamaKey = kAuthSuccessPacket.dwLoginKey ^ g_adwEncryptKey[0] ^ g_adwEncryptKey[1] ^ g_adwEncryptKey[2] ^ g_adwEncryptKey[3];
CEterPackManager::instance().DecryptPackIV(dwPanamaKey);
CPythonNetworkStream & rkNet = CPythonNetworkStream::Instance(); CPythonNetworkStream & rkNet = CPythonNetworkStream::Instance();
rkNet.SetLoginKey(kAuthSuccessPacket.dwLoginKey); rkNet.SetLoginKey(kAuthSuccessPacket.dwLoginKey);
rkNet.Connect(m_strAddr.c_str(), m_iPort); rkNet.Connect(m_strAddr.c_str(), m_iPort);
@ -451,9 +387,6 @@ bool CAccountConnector::__AuthState_RecvAuthSuccess_OpenID()
} }
else else
{ {
DWORD dwPanamaKey = kAuthSuccessOpenIDPacket.dwLoginKey ^ g_adwEncryptKey[0] ^ g_adwEncryptKey[1] ^ g_adwEncryptKey[2] ^ g_adwEncryptKey[3];
CEterPackManager::instance().DecryptPackIV(dwPanamaKey);
CPythonNetworkStream & rkNet = CPythonNetworkStream::Instance(); CPythonNetworkStream & rkNet = CPythonNetworkStream::Instance();
rkNet.SetLoginInfo(kAuthSuccessOpenIDPacket.login, "0000"); //OpenID 인증 과정에서 비밀번호는 사용되지 않는다. rkNet.SetLoginInfo(kAuthSuccessOpenIDPacket.login, "0000"); //OpenID 인증 과정에서 비밀번호는 사용되지 않는다.
rkNet.SetLoginKey(kAuthSuccessOpenIDPacket.dwLoginKey); rkNet.SetLoginKey(kAuthSuccessOpenIDPacket.dwLoginKey);

View File

@ -59,9 +59,6 @@ class CAccountConnector : public CNetworkStream, public CSingleton<CAccountConne
bool __AuthState_RecvChinaMatrixCard(); bool __AuthState_RecvChinaMatrixCard();
bool __AuthState_RecvRunupMatrixQuiz(); bool __AuthState_RecvRunupMatrixQuiz();
bool __AuthState_RecvNEWCIBNPasspodRequest(); bool __AuthState_RecvNEWCIBNPasspodRequest();
bool __AuthState_RecvPanamaPack();
bool __AuthState_RecvHybridCryptKeys(int VarSize);
bool __AuthState_RecvHybridCryptSDB(int VarSize);
bool __AnalyzePacket(UINT uHeader, UINT uPacketSize, bool (CAccountConnector::*pfnDispatchPacket)()); bool __AnalyzePacket(UINT uHeader, UINT uPacketSize, bool (CAccountConnector::*pfnDispatchPacket)());
// TODO: 지금 현재는 임시다. header뒤에 size 4byte가 무조건 온다는 가정임. // TODO: 지금 현재는 임시다. header뒤에 size 4byte가 무조건 온다는 가정임.

View File

@ -324,12 +324,6 @@ enum
// END_OF_SUPPORT_BGM // END_OF_SUPPORT_BGM
HEADER_GC_AUTH_SUCCESS = 150, HEADER_GC_AUTH_SUCCESS = 150,
HEADER_GC_PANAMA_PACK = 151,
//HYBRID CRYPT
HEADER_GC_HYBRIDCRYPT_KEYS = 152,
HEADER_GC_HYBRIDCRYPT_SDB = 153, // SDB means Supplmentary Data Blocks
//HYBRID CRYPT
HEADER_GC_AUTH_SUCCESS_OPENID = 154, HEADER_GC_AUTH_SUCCESS_OPENID = 154,
@ -2612,70 +2606,6 @@ typedef struct SPacketGCResetOnTime
BYTE header; BYTE header;
} TPacketGCResetOnTime; } TPacketGCResetOnTime;
typedef struct SPacketGCPanamaPack
{
BYTE bHeader;
char szPackName[256];
BYTE abIV[32];
} TPacketGCPanamaPack;
typedef struct SPacketGCHybridCryptKeys
{
private:
SPacketGCHybridCryptKeys() : m_pStream(NULL) {}
public:
SPacketGCHybridCryptKeys(int iStreamSize) : iKeyStreamLen(iStreamSize)
{
m_pStream = new BYTE[iStreamSize];
}
~SPacketGCHybridCryptKeys()
{
if( m_pStream )
{
delete[] m_pStream;
m_pStream = NULL;
}
}
static int GetFixedHeaderSize()
{
return sizeof(BYTE)+sizeof(WORD)+sizeof(int);
}
BYTE bHeader;
WORD wDynamicPacketSize;
int iKeyStreamLen;
BYTE* m_pStream;
} TPacketGCHybridCryptKeys;
typedef struct SPacketGCHybridSDB
{
private:
SPacketGCHybridSDB() : m_pStream(NULL) {}
public:
SPacketGCHybridSDB(int iStreamSize) : iSDBStreamLen(iStreamSize)
{
m_pStream = new BYTE[iStreamSize];
}
~SPacketGCHybridSDB()
{
delete[] m_pStream;
m_pStream = NULL;
}
static int GetFixedHeaderSize()
{
return sizeof(BYTE)+sizeof(WORD)+sizeof(int);
}
BYTE bHeader;
WORD wDynamicPacketSize;
int iSDBStreamLen;
BYTE* m_pStream;
} TPacketGCHybridSDB;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Client To Client // Client To Client

View File

@ -1042,12 +1042,11 @@ class CTextLineLoader
public: public:
CTextLineLoader(const char * c_szFileName) CTextLineLoader(const char * c_szFileName)
{ {
const VOID* pvData; CEterPackManager::TPackDataPtr data;
CMappedFile kFile; if (!CEterPackManager::Instance().Get(c_szFileName, data))
if (!CEterPackManager::Instance().Get(kFile, c_szFileName, &pvData))
return; return;
m_kTextFileLoader.Bind(kFile.Size(), pvData); m_kTextFileLoader.Bind(data->size(), data->data());
} }
DWORD GetLineCount() DWORD GetLineCount()

View File

@ -241,19 +241,7 @@ void CPythonBackground::Initialize()
void CPythonBackground::__CreateProperty() void CPythonBackground::__CreateProperty()
{ {
if (CEterPackManager::SEARCH_FILE_FIRST == CEterPackManager::Instance().GetSearchMode() && m_PropertyManager.Initialize();
_access("property", 0) == 0)
{
m_PropertyManager.Initialize(NULL);
CPropertyLoader PropertyLoader;
PropertyLoader.SetPropertyManager(&m_PropertyManager);
PropertyLoader.Create("*.*", "Property");
}
else
{
m_PropertyManager.Initialize("pack/property");
}
} }
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////

View File

@ -106,16 +106,11 @@ void CPythonEventManager::__InitEventSet(TEventSet& rEventSet)
int CPythonEventManager::RegisterEventSet(const char * c_szFileName) int CPythonEventManager::RegisterEventSet(const char * c_szFileName)
{ {
CMappedFile File; std::stringstream data;
LPCVOID pMap; if (!CEterPackManager::Instance().Get(c_szFileName, data))
if (!CEterPackManager::Instance().Get(File, c_szFileName, &pMap))
return -1; return -1;
std::string strEventString; std::string strEventString = data.str();
strEventString.resize(File.Size()+1);
File.Read(&strEventString[0], File.Size());
TEventSet * pEventSet = m_EventSetPool.Alloc(); TEventSet * pEventSet = m_EventSetPool.Alloc();
if (!pEventSet) if (!pEventSet)

View File

@ -176,8 +176,6 @@ class CMainPacketHeaderMap : public CNetworkPacketHeaderMap
Set(HEADER_GC_HS_REQUEST, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketHSCheck), STATIC_SIZE_PACKET)); Set(HEADER_GC_HS_REQUEST, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketHSCheck), STATIC_SIZE_PACKET));
Set(HEADER_GC_XTRAP_CS1_REQUEST, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketXTrapCSVerify), STATIC_SIZE_PACKET)); Set(HEADER_GC_XTRAP_CS1_REQUEST, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketXTrapCSVerify), STATIC_SIZE_PACKET));
Set(HEADER_GC_HYBRIDCRYPT_KEYS, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCHybridCryptKeys), DYNAMIC_SIZE_PACKET));
Set(HEADER_GC_HYBRIDCRYPT_SDB, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCHybridSDB), DYNAMIC_SIZE_PACKET));
Set(HEADER_GC_SPECIFIC_EFFECT, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCSpecificEffect), STATIC_SIZE_PACKET)); Set(HEADER_GC_SPECIFIC_EFFECT, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCSpecificEffect), STATIC_SIZE_PACKET));
Set(HEADER_GC_DRAGON_SOUL_REFINE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCDragonSoulRefine), STATIC_SIZE_PACKET)); Set(HEADER_GC_DRAGON_SOUL_REFINE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCDragonSoulRefine), STATIC_SIZE_PACKET));

View File

@ -264,9 +264,6 @@ class CPythonNetworkStream : public CNetworkStream, public CSingleton<CPythonNet
bool RecvHandshakePacket(); bool RecvHandshakePacket();
bool RecvHandshakeOKPacket(); bool RecvHandshakeOKPacket();
bool RecvHybridCryptKeyPacket();
bool RecvHybridCryptSDBPacket();
// ETC // ETC
DWORD GetMainActorVID(); DWORD GetMainActorVID();
DWORD GetMainActorRace(); DWORD GetMainActorRace();

View File

@ -591,16 +591,6 @@ void CPythonNetworkStream::GamePhase()
return; return;
break; break;
case HEADER_GC_HYBRIDCRYPT_KEYS:
RecvHybridCryptKeyPacket();
return;
break;
case HEADER_GC_HYBRIDCRYPT_SDB:
RecvHybridCryptSDBPacket();
return;
break;
case HEADER_GC_HS_REQUEST: case HEADER_GC_HS_REQUEST:
ret = RecvHSCheckRequest(); ret = RecvHSCheckRequest();
break; break;

View File

@ -61,16 +61,6 @@ void CPythonNetworkStream::HandShakePhase()
RecvPingPacket(); RecvPingPacket();
return; return;
break; break;
case HEADER_GC_HYBRIDCRYPT_KEYS:
RecvHybridCryptKeyPacket();
return;
break;
case HEADER_GC_HYBRIDCRYPT_SDB:
RecvHybridCryptSDBPacket();
return;
break;
} }
RecvErrorPacket(header); RecvErrorPacket(header);
@ -145,46 +135,6 @@ bool CPythonNetworkStream::RecvHandshakeOKPacket()
return true; return true;
} }
bool CPythonNetworkStream::RecvHybridCryptKeyPacket()
{
int iFixedHeaderSize = TPacketGCHybridCryptKeys::GetFixedHeaderSize();
TDynamicSizePacketHeader header;
if( !Peek( sizeof(header), &header) )
return false;
TPacketGCHybridCryptKeys kPacket(header.size-iFixedHeaderSize);
if (!Recv(iFixedHeaderSize, &kPacket))
return false;
if (!Recv(kPacket.iKeyStreamLen, kPacket.m_pStream))
return false;
CEterPackManager::Instance().RetrieveHybridCryptPackKeys( kPacket.m_pStream );
return true;
}
bool CPythonNetworkStream::RecvHybridCryptSDBPacket()
{
int iFixedHeaderSize = TPacketGCHybridSDB::GetFixedHeaderSize();
TDynamicSizePacketHeader header;
if( !Peek( sizeof(header), &header) )
return false;
TPacketGCHybridSDB kPacket(header.size-iFixedHeaderSize);
if (!Recv(iFixedHeaderSize, &kPacket))
return false;
if (!Recv(kPacket.iSDBStreamLen, kPacket.m_pStream))
return false;
CEterPackManager::Instance().RetrieveHybridCryptPackSDB( kPacket.m_pStream );
return true;
}
bool CPythonNetworkStream::RecvHSCheckRequest() bool CPythonNetworkStream::RecvHSCheckRequest()
{ {
TPacketHSCheck packet; TPacketHSCheck packet;

View File

@ -33,13 +33,12 @@ bool CPythonNetworkStream::IsInsultIn(const char* c_szMsg)
bool CPythonNetworkStream::LoadInsultList(const char* c_szInsultListFileName) bool CPythonNetworkStream::LoadInsultList(const char* c_szInsultListFileName)
{ {
CMappedFile file; CEterPackManager::TPackDataPtr data;
const VOID* pvData; CMemoryTextFileLoader kMemTextFileLoader;
if (!CEterPackManager::Instance().Get(file, c_szInsultListFileName, &pvData)) if (!CEterPackManager::Instance().Get(c_szInsultListFileName, data))
return false; return false;
CMemoryTextFileLoader kMemTextFileLoader; kMemTextFileLoader.Bind(data->size(), data->data());
kMemTextFileLoader.Bind(file.Size(), pvData);
m_kInsultChecker.Clear(); m_kInsultChecker.Clear();
for (DWORD dwLineIndex=0; dwLineIndex<kMemTextFileLoader.GetLineCount(); ++dwLineIndex) for (DWORD dwLineIndex=0; dwLineIndex<kMemTextFileLoader.GetLineCount(); ++dwLineIndex)
@ -55,9 +54,8 @@ bool CPythonNetworkStream::LoadConvertTable(DWORD dwEmpireID, const char* c_szFi
if (dwEmpireID<1 || dwEmpireID>=4) if (dwEmpireID<1 || dwEmpireID>=4)
return false; return false;
CMappedFile file; std::stringstream data;
const VOID* pvData; if (!CEterPackManager::Instance().Get(c_szFileName, data))
if (!CEterPackManager::Instance().Get(file, c_szFileName, &pvData))
return false; return false;
DWORD dwEngCount=26; DWORD dwEngCount=26;
@ -65,15 +63,16 @@ bool CPythonNetworkStream::LoadConvertTable(DWORD dwEmpireID, const char* c_szFi
DWORD dwHanSize=dwHanCount*2; DWORD dwHanSize=dwHanCount*2;
DWORD dwFileSize=dwEngCount*2+dwHanSize; DWORD dwFileSize=dwEngCount*2+dwHanSize;
if (file.Size()<dwFileSize) if (data.str().length() < dwFileSize)
return false; return false;
char* pcData=(char*)pvData;
STextConvertTable& rkTextConvTable=m_aTextConvTable[dwEmpireID-1]; STextConvertTable& rkTextConvTable=m_aTextConvTable[dwEmpireID-1];
memcpy(rkTextConvTable.acUpper, pcData, dwEngCount);pcData+=dwEngCount; data.read((char*)rkTextConvTable.acUpper, dwEngCount);
memcpy(rkTextConvTable.acLower, pcData, dwEngCount);pcData+=dwEngCount; data.read((char*)rkTextConvTable.acLower, dwEngCount);
memcpy(rkTextConvTable.aacHan, pcData, dwHanSize); data.read((char*)rkTextConvTable.aacHan, dwHanSize);
if (!data)
return false;
return true; return true;
} }
@ -146,17 +145,6 @@ void CPythonNetworkStream::LoadingPhase()
return; return;
break; break;
case HEADER_GC_HYBRIDCRYPT_KEYS:
RecvHybridCryptKeyPacket();
return;
break;
case HEADER_GC_HYBRIDCRYPT_SDB:
RecvHybridCryptSDBPacket();
return;
break;
default: default:
GamePhase(); GamePhase();
return; return;

View File

@ -68,16 +68,6 @@ void CPythonNetworkStream::LoginPhase()
return; return;
break; break;
case HEADER_GC_HYBRIDCRYPT_KEYS:
RecvHybridCryptKeyPacket();
return;
break;
case HEADER_GC_HYBRIDCRYPT_SDB:
RecvHybridCryptSDBPacket();
return;
break;
default: default:
if (RecvDefaultPacket(header)) if (RecvDefaultPacket(header))
return; return;

View File

@ -99,16 +99,6 @@ void CPythonNetworkStream::SelectPhase()
return; return;
break; break;
case HEADER_GC_HYBRIDCRYPT_KEYS:
RecvHybridCryptKeyPacket();
return;
break;
case HEADER_GC_HYBRIDCRYPT_SDB:
RecvHybridCryptSDBPacket();
return;
break;
case HEADER_GC_PLAYER_POINT_CHANGE: case HEADER_GC_PLAYER_POINT_CHANGE:
TPacketGCPointChange PointChange; TPacketGCPointChange PointChange;
Recv(sizeof(TPacketGCPointChange), &PointChange); Recv(sizeof(TPacketGCPointChange), &PointChange);

View File

@ -14,17 +14,17 @@ bool CPythonNonPlayer::LoadNonPlayerData(const char * c_szFileName)
6822045 6822045
}; };
CMappedFile file;
LPCVOID pvData;
Tracef("CPythonNonPlayer::LoadNonPlayerData: %s, sizeof(TMobTable)=%u\n", c_szFileName, sizeof(TMobTable)); Tracef("CPythonNonPlayer::LoadNonPlayerData: %s, sizeof(TMobTable)=%u\n", c_szFileName, sizeof(TMobTable));
if (!CEterPackManager::Instance().Get(file, c_szFileName, &pvData)) std::stringstream data;
if (!CEterPackManager::Instance().Get(c_szFileName, data))
return false; return false;
DWORD dwFourCC, dwElements, dwDataSize; DWORD dwFourCC, dwElements, dwDataSize;
file.Read(&dwFourCC, sizeof(DWORD)); data.read((char*)&dwFourCC, sizeof(DWORD));
if (!data)
return false;
if (dwFourCC != MAKEFOURCC('M', 'M', 'P', 'T')) if (dwFourCC != MAKEFOURCC('M', 'M', 'P', 'T'))
{ {
@ -32,20 +32,26 @@ bool CPythonNonPlayer::LoadNonPlayerData(const char * c_szFileName)
return false; return false;
} }
file.Read(&dwElements, sizeof(DWORD)); data.read((char*)&dwElements, sizeof(DWORD));
file.Read(&dwDataSize, sizeof(DWORD)); if (!data)
return false;
data.read((char*)&dwDataSize, sizeof(DWORD));
if (!data)
return false;
auto pbData = std::make_shared<std::vector<BYTE>>(dwDataSize);
data.read((char*)pbData->data(), pbData->size());
if (!data)
return false;
BYTE * pbData = new BYTE[dwDataSize];
file.Read(pbData, dwDataSize);
///// /////
CLZObject zObj; CLZObject zObj;
if (!CLZO::Instance().Decompress(zObj, pbData, s_adwMobProtoKey)) if (!CLZO::Instance().Decompress(zObj, pbData->data(), s_adwMobProtoKey))
{
delete [] pbData;
return false; return false;
}
if ((zObj.GetSize() % sizeof(TMobTable)) != 0) if ((zObj.GetSize() % sizeof(TMobTable)) != 0)
{ {
@ -64,7 +70,6 @@ bool CPythonNonPlayer::LoadNonPlayerData(const char * c_szFileName)
m_NonPlayerDataMap.insert(TNonPlayerDataMap::value_type(pNonPlayerData->dwVnum, pNonPlayerData)); m_NonPlayerDataMap.insert(TNonPlayerDataMap::value_type(pNonPlayerData->dwVnum, pNonPlayerData));
} }
delete [] pbData;
return true; return true;
} }

View File

@ -63,11 +63,9 @@ PyObject * packGet(PyObject * poSelf, PyObject * poArgs)
(stricmp(pcExt, ".pyc") == 0) || (stricmp(pcExt, ".pyc") == 0) ||
(stricmp(pcExt, ".txt") == 0)) (stricmp(pcExt, ".txt") == 0))
{ {
CMappedFile file; CEterPackManager::TPackDataPtr data;
const void * pData = NULL; if (CEterPackManager::Instance().Get(strFileName, data))
return Py_BuildValue("s#", data->data(), data->size());
if (CEterPackManager::Instance().Get(file,strFileName,&pData))
return Py_BuildValue("s#",pData, file.Size());
} }
} }

View File

@ -89,13 +89,13 @@ void string_replace_word(const char* base, int base_len, const char* src, int sr
bool CPythonSkill::RegisterSkillTable(const char * c_szFileName) bool CPythonSkill::RegisterSkillTable(const char * c_szFileName)
{ {
const VOID* pvData; CEterPackManager::TPackDataPtr data;
CMappedFile kFile; CMemoryTextFileLoader textFileLoader;
if (!CEterPackManager::Instance().Get(kFile, c_szFileName, &pvData))
if (!CEterPackManager::Instance().Get(c_szFileName, data))
return false; return false;
CMemoryTextFileLoader textFileLoader; textFileLoader.Bind(data->size(), data->data());
textFileLoader.Bind(kFile.Size(), pvData);
// OVERWRITE_SKILLPROTO_POLY // OVERWRITE_SKILLPROTO_POLY
std::string src_poly_rand; std::string src_poly_rand;
@ -279,13 +279,13 @@ void CPythonSkill::__RegisterNormalIconImage(TSkillData & rData, const char * c_
extern const DWORD c_iSkillIndex_Riding; extern const DWORD c_iSkillIndex_Riding;
bool CPythonSkill::RegisterSkillDesc(const char * c_szFileName) bool CPythonSkill::RegisterSkillDesc(const char * c_szFileName)
{ {
const VOID* pvData; CEterPackManager::TPackDataPtr data;
CMappedFile kFile; CMemoryTextFileLoader textFileLoader;
if (!CEterPackManager::Instance().Get(kFile, c_szFileName, &pvData))
if (!CEterPackManager::Instance().Get(c_szFileName, data))
return false; return false;
CMemoryTextFileLoader textFileLoader; textFileLoader.Bind(data->size(), data->data());
textFileLoader.Bind(kFile.Size(), pvData);
CTokenVector TokenVector; CTokenVector TokenVector;
for (DWORD i = 0; i < textFileLoader.GetLineCount(); ++i) for (DWORD i = 0; i < textFileLoader.GetLineCount(); ++i)

View File

@ -203,18 +203,31 @@ const char* ApplicationStringTable_GetStringz(DWORD dwID)
int Setup(LPSTR lpCmdLine); // Internal function forward int Setup(LPSTR lpCmdLine); // Internal function forward
bool PackInitialize(const char * c_pszFolder) bool PackInitialize(const std::string& packFolder)
{ {
NANOBEGIN NANOBEGIN
if (_access(c_pszFolder, 0) != 0) if (_access(packFolder.c_str(), 0) != 0)
return true; return true;
std::string stFolder(c_pszFolder); // Initialize variables
stFolder += "/"; bool bPackFirst = true;
std::string stFolder = packFolder + "/";
std::string stFileName;
std::string stFileName(stFolder); #ifdef _DISTRIBUTE
stFileName += "Index"; Tracef("Info: Pack search mode set to archive-first.\n");
// Set Index file name to production value
stFileName = stFolder + "Index";
#else
bPackFirst = false;
Tracef("Info: Pack search mode set to file-first.\n");
// Set Index file name to development value
stFileName = stFolder + "Index.dev";
#endif
// Set up file reader
CMappedFile file; CMappedFile file;
LPCVOID pvData; LPCVOID pvData;
@ -228,56 +241,43 @@ bool PackInitialize(const char * c_pszFolder)
CMemoryTextFileLoader TextLoader; CMemoryTextFileLoader TextLoader;
TextLoader.Bind(file.Size(), pvData); TextLoader.Bind(file.Size(), pvData);
bool bPackFirst = TRUE; // Set up archive manager
const std::string& strPackType = TextLoader.GetLineString(0);
if (strPackType.compare("FILE") && strPackType.compare("PACK"))
{
TraceError("Pack/Index has invalid syntax. First line must be 'PACK' or 'FILE'");
return false;
}
#ifdef _DISTRIBUTE
Tracef("You are in pack mode.\n");
//if (0 == strPackType.compare("FILE"))
//{
// bPackFirst = FALSE;
// Tracef("You are in file mode.\n");
//}
//else
//{
// Tracef("You are in pack mode.\n");
//}
#else
bPackFirst = FALSE;
Tracef("You are in file mode.\n");
#endif
CTextFileLoader::SetCacheMode(); CTextFileLoader::SetCacheMode();
#if defined(USE_RELATIVE_PATH)
CEterPackManager::Instance().SetRelativePathMode();
#endif
CEterPackManager::Instance().SetCacheMode();
CEterPackManager::Instance().SetSearchMode(bPackFirst); CEterPackManager::Instance().SetSearchMode(bPackFirst);
CSoundData::SetPackMode(); // Miles 파일 콜백을 셋팅 CSoundData::SetPackMode(); // Miles 파일 콜백을 셋팅
// Read lines and parse tokens
std::string strPackName, strTexCachePackName; std::string strPackName, strTexCachePackName;
for (DWORD i = 1; i < TextLoader.GetLineCount() - 1; i += 2) CTokenVector tokens = CTokenVector();
for (DWORD i = 0; i < TextLoader.GetLineCount() - 1; i++)
{ {
const std::string & c_rstFolder = TextLoader.GetLineString(i); // Split line into tokens
const std::string & c_rstName = TextLoader.GetLineString(i + 1); TextLoader.SplitLineByTab(i, &tokens);
// Check if the read number of tokens is valid
if (tokens.size() != 2)
{
TraceError("Invalid number of tokens on line %d: expected %d, got %d!", i, 2, tokens.size());
return false;
}
// Assign tokens into variables
const std::string& c_rstName = tokens[0];
const std::string& c_rstContainer = tokens[1];
// Load pack
strPackName = stFolder + c_rstName; strPackName = stFolder + c_rstName;
strTexCachePackName = strPackName + "_texcache"; CEterPackManager::Instance().RegisterPack(strPackName, c_rstContainer);
CEterPackManager::Instance().RegisterPack(strPackName.c_str(), c_rstFolder.c_str()); // Try to load texture cache pack if it exists
CEterPackManager::Instance().RegisterPack(strTexCachePackName.c_str(), c_rstFolder.c_str()); strTexCachePackName = strPackName + "_texcache";
if (CEterPackManager::Instance().PackExists(strTexCachePackName, c_rstContainer)) {
CEterPackManager::Instance().RegisterPack(strTexCachePackName, c_rstContainer);
}
} }
CEterPackManager::Instance().RegisterRootPack((stFolder + std::string("root")).c_str());
NANOEND NANOEND
return true; return true;
} }

View File

@ -126,8 +126,8 @@ IDI_METIN2 ICON "metin2.ico"
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,3,1,0 FILEVERSION 0,4,0,0
PRODUCTVERSION 0,3,1,0 PRODUCTVERSION 0,4,0,0
FILEFLAGSMASK 0x17L FILEFLAGSMASK 0x17L
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -144,12 +144,12 @@ BEGIN
BEGIN BEGIN
VALUE "CompanyName", "The Old Metin2 Project" VALUE "CompanyName", "The Old Metin2 Project"
VALUE "FileDescription", "The Metin2 Client" VALUE "FileDescription", "The Metin2 Client"
VALUE "FileVersion", "0.3.1.0" VALUE "FileVersion", "0.4.0.0"
VALUE "InternalName", "Metin2Client" VALUE "InternalName", "Metin2Client"
VALUE "LegalCopyright", "Copyright (C) 2024" VALUE "LegalCopyright", "Copyright (C) 2022-2025"
VALUE "OriginalFilename", "Metin2.exe" VALUE "OriginalFilename", "Metin2.exe"
VALUE "ProductName", "Metin2Client" VALUE "ProductName", "Metin2Client"
VALUE "ProductVersion", "0.3.1.0" VALUE "ProductVersion", "0.4.0.0"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

View File

@ -15,6 +15,13 @@
"name": "directxsdk", "name": "directxsdk",
"version>=": "jun10" "version>=": "jun10"
}, },
{
"name": "libzip",
"features": [
"zstd"
],
"version>=": "1.10.1"
},
{ {
"name": "lzo", "name": "lzo",
"version>=": "2.10#7" "version>=": "2.10#7"