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

@ -6,6 +6,7 @@
#include "pipeline/loose_file_reader.hpp"
#include <memory>
#include <string>
#include <vector>
#include <map>
#include <mutex>
@ -16,6 +17,8 @@ namespace pipeline {
* AssetManager - Unified interface for loading WoW assets
*
* Reads pre-extracted loose files indexed by manifest.json.
* Supports layered manifests: overlay manifests (HD packs, mods)
* are checked before the base manifest, with higher priority first.
* Use the asset_extract tool to extract MPQ archives first.
* All reads are fully parallel (no serialization mutex needed).
*/
@ -41,6 +44,26 @@ public:
*/
bool isInitialized() const { return initialized; }
/**
* Add an overlay manifest (HD packs, mods) checked before the base manifest.
* Higher priority overlays are checked first.
* @param manifestPath Full path to the overlay's manifest.json
* @param priority Priority level (higher = checked first)
* @param id Unique identifier for this overlay (e.g. "hd_character")
* @return true if overlay loaded successfully
*/
bool addOverlayManifest(const std::string& manifestPath, int priority, const std::string& id);
/**
* Remove a previously added overlay manifest by id.
*/
void removeOverlay(const std::string& id);
/**
* Get list of active overlay IDs.
*/
std::vector<std::string> getOverlayIds() const;
/**
* Load a BLP texture
* @param path Virtual path to BLP file (e.g., "Textures\\Minimap\\Background.blp")
@ -105,10 +128,24 @@ private:
bool initialized = false;
std::string dataPath;
// Loose file backend
// Base manifest (loaded from dataPath/manifest.json)
AssetManifest manifest_;
LooseFileReader looseReader_;
// Overlay manifests (HD packs, mods) - sorted by priority descending
struct ManifestLayer {
AssetManifest manifest;
int priority;
std::string id;
};
std::vector<ManifestLayer> overlayLayers_; // Sorted by priority desc
/**
* Resolve filesystem path checking overlays first, then base manifest.
* Returns empty string if not found in any layer.
*/
std::string resolveLayeredPath(const std::string& normalizedPath) const;
mutable std::mutex cacheMutex;
std::map<std::string, std::shared_ptr<DBCFile>> dbcCache;