diff --git a/bin/pack/Index b/bin/pack/Index index c96e66f1..90de63a7 100644 --- a/bin/pack/Index +++ b/bin/pack/Index @@ -1,249 +1,102 @@ -PACK -* -patch1 -* -season3_eu -* -patch2 -* -metin2_patch_snow -pack/ -metin2_patch_snow_dungeon -pack/ -metin2_patch_etc_costume1 -pack/ -metin2_patch_pet1 -pack/ -metin2_patch_pet2 -pack/ -metin2_patch_ramadan_costume -pack/ -metin2_patch_flame -pack/ -metin2_patch_flame_dungeon -pack/ -metin2_patch_w21_etc -pack/ -metin2_patch_w21_mobs -pack/ -metin2_patch_w21_mobs_m -pack/ -metin2_patch_dss_box -pack/ -metin2_patch_costume_soccer -pack/ -metin2_patch_easter1 -pack/ -metin2_patch_mineral -pack/ -metin2_patch_w20_sound -pack/ -metin2_patch_ds -pack/ -metin2_patch_5th_armor -pack/ -metin2_patch_w20_etc -pack/ -metin2_patch_dragon_rock -pack/ -metin2_patch_dragon_rock_mobs -pack/ -metin2_patch_etc -pack/ -metin2_patch_xmas -pack/ -metin2_patch_eu3 -pack/ -metin2_patch_eu4 -pack/ -metin2_patch_mundi -pack/ -metin2_patch_sd -pack/ -metin2_patch_halloween -pack/ -metin2_patch_party -pack/ -metin2_patch_dance -d:/ymir work/pc/ -pc -d:/ymir work/pc2/ -pc2 -d:/ymir work/monster/ -monster -d:/ymir work/monster2/ -monster2 -d:/ymir work/effect/ -effect -d:/ymir work/zone/ -zone -d:/ymir work/terrainmaps/ -terrain -d:/ymir work/npc/ -npc -d:/ymir work/npc2/ -npc2 -d:/ymir work/tree/ -tree -d:/ymir work/guild/ -guild -d:/ymir work/item/ -item -textureset/ -textureset -property/ -property -icon/ -icon -season1/ -season1 -season2/ -season2 -metin2_map_a1/ -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 +patch1 ZIP +season3_eu ZIP +patch2 ZIP +metin2_patch_snow ZIP +metin2_patch_snow_dungeon ZIP +metin2_patch_etc_costume1 ZIP +metin2_patch_pet1 ZIP +metin2_patch_pet2 ZIP +metin2_patch_ramadan_costume ZIP +metin2_patch_flame ZIP +metin2_patch_flame_dungeon ZIP +metin2_patch_w21_etc ZIP +metin2_patch_w21_mobs ZIP +metin2_patch_w21_mobs_m ZIP +metin2_patch_dss_box ZIP +metin2_patch_costume_soccer ZIP +metin2_patch_easter1 ZIP +metin2_patch_mineral ZIP +metin2_patch_w20_sound ZIP +metin2_patch_ds ZIP +metin2_patch_5th_armor ZIP +metin2_patch_w20_etc ZIP +metin2_patch_dragon_rock ZIP +metin2_patch_dragon_rock_mobs ZIP +metin2_patch_etc ZIP +metin2_patch_xmas ZIP +metin2_patch_eu3 ZIP +metin2_patch_eu4 ZIP +metin2_patch_mundi ZIP +metin2_patch_sd ZIP +metin2_patch_halloween ZIP +metin2_patch_party ZIP +metin2_patch_dance ZIP +pc ZIP +pc2 ZIP +monster ZIP +monster2 ZIP +effect ZIP +zone ZIP +terrain ZIP +npc ZIP +npc2 ZIP +tree ZIP +guild ZIP +item ZIP +textureset ZIP +property ZIP +icon ZIP +season1 ZIP +season2 ZIP +outdoora1 ZIP +outdoora2 ZIP +outdoora3 ZIP +outdoorb1 ZIP +outdoorb3 ZIP +outdoorc1 ZIP +outdoorc3 ZIP +outdoorsnow1 ZIP +outdoordesert1 ZIP +outdoorflame1 ZIP +outdoorfielddungeon1 ZIP +outdoort1 ZIP +outdoort2 ZIP +outdoort3 ZIP +outdoort4 ZIP +outdoorwedding ZIP +outdoormilgyo1 ZIP +indoorspiderdungeon1 ZIP +indoordeviltower1 ZIP +indoormonkeydungeon1 ZIP +indoormonkeydungeon2 ZIP +indoormonkeydungeon3 ZIP +outdoortrent02 ZIP +outdoorguild1 ZIP +outdoorguild2 ZIP +outdoorguild3 ZIP +outdoortrent ZIP +outdoorduel ZIP +outdoorgmguildbuild ZIP +sound ZIP +sound_m ZIP +sound2 ZIP +bgm ZIP +ETC ZIP +locale_de ZIP +locale_es ZIP +locale_fr ZIP +locale_gr ZIP +locale_it ZIP +locale_nl ZIP +locale_pl ZIP +locale_pt ZIP +locale_tr ZIP +locale_en ZIP +locale_ro ZIP +locale_ru ZIP +locale_dk ZIP +locale_cz ZIP +locale_hu ZIP +uiscript ZIP +uiloading ZIP +root ZIP diff --git a/bin/pack/Index.dev b/bin/pack/Index.dev new file mode 100644 index 00000000..03c7170f --- /dev/null +++ b/bin/pack/Index.dev @@ -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 diff --git a/bin/pack/pack.bat b/bin/pack/pack.bat index 3d311340..856181ab 100644 --- a/bin/pack/pack.bat +++ b/bin/pack/pack.bat @@ -5,8 +5,8 @@ FOR /d %%i IN ("*") DO ( echo Packing %%i rem "C:\Program Files\7-Zip\7z.exe" a "%%i.zip" ".\%%i\*" -m0=BZip2 rem "C:\Program Files\7-Zip-Zstandard\7za.exe" a "%%i.zip" ".\%%i\*" -m0=Zstd - "C:\Program Files\7-Zip\7z.exe" a "%%i.zip" ".\%%i\*" -m0=Copy - rem "C:\Program Files\7-Zip\7z.exe" a "%%i.zip" ".\%%i\*" + rem "C:\Program Files\7-Zip\7z.exe" a "%%i.zip" ".\%%i\*" -m0=Copy + "C:\Program Files\7-Zip\7z.exe" a "%%i.zip" ".\%%i\*" if !errorlevel! neq 0 exit /b !errorlevel! cls diff --git a/src/EterPack/EterPackManager.cpp b/src/EterPack/EterPackManager.cpp index bdc98726..3d8c0737 100644 --- a/src/EterPack/EterPackManager.cpp +++ b/src/EterPack/EterPackManager.cpp @@ -183,10 +183,22 @@ bool CEterPackManager::isExist(const char * c_szFileName) return isExistInPack(c_szFileName); } - -bool CEterPackManager::RegisterPack(const char * c_szName, const char * c_szDirectory, const BYTE* c_pbIV) +bool CEterPackManager::PackExists(const std::string& name, const std::string& container) { - auto it = m_PackMap.find(c_szName); + if (container == "FOLDER") { + return _access(name.c_str(), 0) == 0; + } + else if (container == "ZIP") { + std::string zipName = name + ".zip"; + return _access(zipName.c_str(), 0) == 0; + } + + throw std::runtime_error("Unexpected container type: " + container + "!"); +} + +bool CEterPackManager::RegisterPack(const std::string& name, const std::string& container) +{ + auto it = m_PackMap.find(name); if (it != m_PackMap.end()) return true; @@ -196,24 +208,28 @@ bool CEterPackManager::RegisterPack(const char * c_szName, const char * c_szDire std::shared_ptr pack; - // TODO: allow configurable containers - - //pack = std::make_shared(c_szName); - pack = std::make_shared(std::string(c_szName) + ".zip"); + // Determine requested container type + if (container == "FOLDER") + pack = std::make_shared(name); + else if (container == "ZIP") + pack = std::make_shared(name + ".zip"); + else + throw std::runtime_error("Unexpected container type: " + container + "!"); + // Load container data auto packFiles = pack->listFiles(); for (auto const& fileName : packFiles) m_FileMap.insert({ fileName, pack }); - m_PackMap.insert({ c_szName, pack }); + m_PackMap.insert({ name, pack }); return true; } catch (std::exception& e) { #ifdef _DEBUG - Tracef("Unable to load file provider '%s': %s\n", c_szName, e.what()); + Tracef("Unable to load file provider '%s': %s\n", name.c_str(), e.what()); #endif return false; diff --git a/src/EterPack/EterPackManager.h b/src/EterPack/EterPackManager.h index 80c71c1b..286b2daa 100644 --- a/src/EterPack/EterPackManager.h +++ b/src/EterPack/EterPackManager.h @@ -17,8 +17,8 @@ class CEterPackManager : public CSingleton }; typedef std::list> TEterPackList; - typedef std::unordered_map, stringhash> TEterPackMap; - typedef std::unordered_map, stringhash> TFileMap; + typedef std::unordered_map> TEterPackMap; + typedef std::unordered_map> TFileMap; typedef std::shared_ptr> TPackDataPtr; public: @@ -34,7 +34,8 @@ class CEterPackManager : public CSingleton bool isExist(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); + bool RegisterPack(const std::string& name, const std::string& container); std::string ConvertFileName(std::string fileName); const TFileMap& GetFileMap(); diff --git a/src/UserInterface/UserInterface.cpp b/src/UserInterface/UserInterface.cpp index a37cc789..2225661d 100644 --- a/src/UserInterface/UserInterface.cpp +++ b/src/UserInterface/UserInterface.cpp @@ -203,18 +203,31 @@ const char* ApplicationStringTable_GetStringz(DWORD dwID) int Setup(LPSTR lpCmdLine); // Internal function forward -bool PackInitialize(const char * c_pszFolder) +bool PackInitialize(const std::string& packFolder) { NANOBEGIN - if (_access(c_pszFolder, 0) != 0) + if (_access(packFolder.c_str(), 0) != 0) return true; - std::string stFolder(c_pszFolder); - stFolder += "/"; + // Initialize variables + bool bPackFirst = true; + std::string stFolder = packFolder + "/"; + std::string stFileName; - std::string stFileName(stFolder); - stFileName += "Index"; +#ifdef _DISTRIBUTE + 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; LPCVOID pvData; @@ -228,52 +241,43 @@ bool PackInitialize(const char * c_pszFolder) CMemoryTextFileLoader TextLoader; TextLoader.Bind(file.Size(), pvData); - bool bPackFirst = TRUE; - - 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("¾Ë¸²: ÆÑ ¸ðµåÀÔ´Ï´Ù.\n"); - - //if (0 == strPackType.compare("FILE")) - //{ - // bPackFirst = FALSE; - // Tracef("¾Ë¸²: ÆÄÀÏ ¸ðµåÀÔ´Ï´Ù.\n"); - //} - //else - //{ - // Tracef("¾Ë¸²: ÆÑ ¸ðµåÀÔ´Ï´Ù.\n"); - //} -#else - bPackFirst = FALSE; - Tracef("¾Ë¸²: ÆÄÀÏ ¸ðµåÀÔ´Ï´Ù.\n"); -#endif - + // Set up archive manager CTextFileLoader::SetCacheMode(); CEterPackManager::Instance().SetSearchMode(bPackFirst); CSoundData::SetPackMode(); // Miles ÆÄÀÏ ÄݹéÀ» ¼ÂÆà + // Read lines and parse tokens 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); - const std::string & c_rstName = TextLoader.GetLineString(i + 1); + // Split line into tokens + 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; - strTexCachePackName = strPackName + "_texcache"; + CEterPackManager::Instance().RegisterPack(strPackName, c_rstContainer); - CEterPackManager::Instance().RegisterPack(strPackName.c_str(), c_rstFolder.c_str()); - CEterPackManager::Instance().RegisterPack(strTexCachePackName.c_str(), c_rstFolder.c_str()); + // Try to load texture cache pack if it exists + strTexCachePackName = strPackName + "_texcache"; + if (CEterPackManager::Instance().PackExists(strTexCachePackName, c_rstContainer)) { + CEterPackManager::Instance().RegisterPack(strTexCachePackName, c_rstContainer); + } } - CEterPackManager::Instance().RegisterPack((stFolder + "root").c_str(), (stFolder + "root").c_str()); NANOEND return true; }