Add multi-expansion support with data-driven protocol layer

Replace hardcoded WotLK protocol constants with a data-driven architecture
supporting Classic 1.12.1, TBC 2.4.3, and WotLK 3.3.5a. Each expansion
has JSON profiles for opcodes, update fields, and DBC layouts, plus C++
polymorphic packet parsers for binary format differences (movement flags,
speed fields, transport data, spline format, char enum layout).

Key components:
- ExpansionRegistry: scans Data/expansions/*/expansion.json at startup
- OpcodeTable: logical enum <-> wire values loaded from JSON
- UpdateFieldTable: field indices loaded from JSON per expansion
- DBCLayout: schema-driven DBC field lookups replacing magic numbers
- PacketParsers: WotLK/TBC/Classic parsers with correct flag positions
- Multi-manifest AssetManager: layered manifests with priority ordering
- HDPackManager: overlay texture packs with expansion compatibility
- Auth screen expansion picker replacing hardcoded version dropdown
This commit is contained in:
Kelsi 2026-02-12 22:56:36 -08:00
parent aa16a687c2
commit 7092844b5e
51 changed files with 5258 additions and 887 deletions

View file

@ -13,6 +13,8 @@ static void printUsage(const char* prog) {
<< " --output <path> Output directory for extracted assets\n"
<< "\n"
<< "Options:\n"
<< " --expansion <id> Expansion ID (classic/tbc/wotlk/cata).\n"
<< " Output goes to <output>/expansions/<id>/\n"
<< " --verify CRC32 verify all extracted files\n"
<< " --threads <N> Number of extraction threads (default: auto)\n"
<< " --verbose Verbose output\n"
@ -21,12 +23,15 @@ static void printUsage(const char* prog) {
int main(int argc, char** argv) {
wowee::tools::Extractor::Options opts;
std::string expansion;
for (int i = 1; i < argc; ++i) {
if (std::strcmp(argv[i], "--mpq-dir") == 0 && i + 1 < argc) {
opts.mpqDir = argv[++i];
} else if (std::strcmp(argv[i], "--output") == 0 && i + 1 < argc) {
opts.outputDir = argv[++i];
} else if (std::strcmp(argv[i], "--expansion") == 0 && i + 1 < argc) {
expansion = argv[++i];
} else if (std::strcmp(argv[i], "--threads") == 0 && i + 1 < argc) {
opts.threads = std::atoi(argv[++i]);
} else if (std::strcmp(argv[i], "--verify") == 0) {
@ -49,9 +54,17 @@ int main(int argc, char** argv) {
return 1;
}
// If --expansion given, redirect output into expansions/<id>/ subdirectory
if (!expansion.empty()) {
opts.outputDir += "/expansions/" + expansion;
}
std::cout << "=== Wowee Asset Extractor ===\n";
std::cout << "MPQ directory: " << opts.mpqDir << "\n";
std::cout << "Output: " << opts.outputDir << "\n";
if (!expansion.empty()) {
std::cout << "Expansion: " << expansion << "\n";
}
if (!wowee::tools::Extractor::run(opts)) {
std::cerr << "Extraction failed!\n";