// eterpack_pack — build a 40250 pack (.eix/.epk) from a directory with the ported CEterPack, the way // the original locale packs are made: every file COMPRESS (LZO), index LZO + TEA encrypted. // // eterpack_pack // // Pack names are , lowercased with '/' (inlineConvertPackFilename). // An existing .eix/.epk is replaced. The result is reopened read-only and every file read back // through CEterPack::Get and compared with its source. #include "EterPack/StdAfx.h" #include "EterPack/EterPack.h" #include "EterPack/EterPackManager.h" #include "EterBase/MappedFile.h" #include "../src/platform/UserInterface/UserInterface.h" #include #include #include #include #include #include #include namespace fs = std::filesystem; static std::vector read_file(const fs::path& path) { std::ifstream in(path, std::ios::binary); return {std::istreambuf_iterator(in), std::istreambuf_iterator()}; } int main(int argc, char** argv) { if (argc != 4) { std::fprintf(stderr, "usage: %s \n", argv[0]); return 2; } const std::string db = argv[1]; const fs::path source = argv[2]; std::string prefix = argv[3]; if (!prefix.empty() && prefix.back() != '/') prefix += '/'; std::vector> files; for (const auto& e : fs::recursive_directory_iterator(source)) if (e.is_regular_file()) files.emplace_back(prefix + e.path().lexically_relative(source).generic_string(), e.path()); std::sort(files.begin(), files.end()); if (files.empty()) { std::fprintf(stderr, "no files under %s\n", source.c_str()); return 1; } PackSingletons(); std::error_code ec; fs::remove(db + ".eix", ec); fs::remove(db + ".epk", ec); { CEterFileDict dict; CEterPack pack; if (!pack.Create(dict, db.c_str(), "", false)) { std::fprintf(stderr, "cannot create %s.eix/.epk\n", db.c_str()); return 1; } for (const auto& [name, path] : files) { const std::vector data = read_file(path); if (name.size() > FILENAME_MAX_LEN || !pack.Put(name.c_str(), data.data(), long(data.size()), COMPRESSED_TYPE_COMPRESS)) { std::fprintf(stderr, "cannot put %s\n", name.c_str()); return 1; } } if (!pack.EncryptIndexFile()) return 1; } // Read back as the client does. CEterFileDict dict; CEterPack pack; if (!pack.Create(dict, db.c_str(), prefix.c_str(), true)) { std::fprintf(stderr, "cannot reopen %s\n", db.c_str()); return 1; } int failures = 0; for (const auto& [name, path] : files) { const std::vector want = read_file(path); CMappedFile mapped; LPCVOID data = nullptr; if (!pack.Get(mapped, name.c_str(), &data) || mapped.Size() != want.size() || (!want.empty() && std::memcmp(data, want.data(), want.size()) != 0)) { std::fprintf(stderr, "read-back mismatch: %s\n", name.c_str()); ++failures; } } if (failures) return 1; std::printf("%s: %zu files, COMPRESS, encrypted index\n", db.c_str(), files.size()); return 0; }