port 2D step 5b: PackInitialize + pack:// asset_io backend over the ported EterPackManager

Platform UserInterface PackInitialize/PackSingletons (40250 bootstrap, on-disk dbname
resolution), EterBase/FileLoader.cpp mirror, mtpack40250 backend behind asset_io's
pack:// scheme and a Metin2Pack node. port_eterpack_test now registers through
PackInitialize. Nothing reads pack:// at runtime yet; port-map stays TODO.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
shenlei
2026-09-23 01:31:17 +09:00
co-authored by Claude Opus 5
parent 1f1004da79
commit 5a26e93f07
13 changed files with 574 additions and 91 deletions
+15 -17
View File
@@ -1,7 +1,7 @@
// port/EterPack against the real 40250 Client/pack (batch 2D). Registers every pack in pack/Index order the way
// UserInterface.cpp PackInitialize does, then checks the numbers batch 2R measured with tools/epk_scan
// (audit/packs/2R-scan.json): 103 packs + root / 54891 entries / 52609 paths, first-registered pack wins, and exactly
// the 4 short-layout SECURITY files 40250 rejects fail to load.
// port/EterPack against the real 40250 Client/pack (batch 2D). Registers the packs through the platform
// PackInitialize("pack") (40250 UserInterface.cpp), after the singletons Main() creates, then checks the numbers
// batch 2R measured with tools/epk_scan (audit/packs/2R-scan.json): 103 packs + root / 54891 entries / 52609 paths,
// first-registered pack wins, and exactly the 4 short-layout SECURITY files 40250 rejects fail to load.
//
// port_eterpack_test <40250 Client dir>
//
@@ -9,6 +9,7 @@
#include "EterPack/StdAfx.h"
#include "EterPack/EterPackManager.h"
#include "EterBase/CRC32.h"
#include "../src/platform/UserInterface/UserInterface.h"
#include <cstdio>
#include <cstdlib>
@@ -71,27 +72,22 @@ int main(int argc, char** argv)
return is_strict ? 1 : 77;
}
// PackInitialize("pack"): line 0 is PACK, then (folder, name) pairs; every name also gets a _texcache pack.
PackSingletons();
CHECK(PackInitialize("pack"));
CEterPackManager& mgr = CEterPackManager::Instance();
// Expected registration order, from pack/Index independently of PackInitialize: line 0 is PACK, then
// (folder, name) pairs; every name also gets a _texcache pack; a pack is registered where it exists on disk.
const std::vector<std::string> lines = read_lines("pack/Index");
CHECK(!lines.empty() && lines[0] == "PACK");
CEterPackManager manager; // CSingleton: the instance registers itself
CEterPackManager& mgr = CEterPackManager::Instance();
mgr.SetCacheMode();
mgr.SetSearchMode(true);
std::vector<std::string> registered;
for (size_t i = 1; i + 1 < lines.size(); i += 2)
{
const std::string& folder = lines[i];
for (const std::string& name : {lines[i + 1], lines[i + 1] + "_texcache"})
{
const std::string db = "pack/" + on_disk_name("pack", name);
if (mgr.RegisterPack(db.c_str(), folder.c_str()))
if (access((db + ".eix").c_str(), 0) == 0 && access((db + ".epk").c_str(), 0) == 0)
registered.push_back(db);
}
}
mgr.RegisterRootPack("pack/root");
// 124 Index pairs; 119 registrations find a pack (some names are listed twice), 103 distinct packs, + root.
CHECK(registered.size() == 119);
@@ -100,15 +96,17 @@ int main(int argc, char** argv)
// The whole dict (one entry per pack index record, overrides included).
struct Access : CEterPackManager
{
static size_t packs(CEterPackManager& m) { return static_cast<Access&>(m).m_PackMap.size(); }
static const CEterFileDict::TDict& dict(CEterPackManager& m) { return static_cast<Access&>(m).m_FileDict.GetDict(); }
static CEterFileDict::Item* item(CEterPackManager& m, DWORD h, const char* n) { return static_cast<Access&>(m).m_FileDict.GetItem(h, n); }
};
CHECK(Access::packs(mgr) == 103);
const CEterFileDict::TDict& dict = Access::dict(mgr);
CHECK(dict.size() == 54891);
std::map<std::string, int> order;
for (size_t i = 0; i < registered.size(); ++i)
order[registered[i]] = static_cast<int>(i);
order.emplace(registered[i], static_cast<int>(i)); // first registration
// First registration per path, and CRC32 of the name equal to the stored filename_crc.
std::map<std::string, std::string> first;