Kelsidavis-WoWee/include/game/expansion_profile.hpp
Kelsi 7092844b5e 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
2026-02-12 22:56:36 -08:00

67 lines
2 KiB
C++

#pragma once
#include <cstdint>
#include <string>
#include <vector>
#include <unordered_map>
#include <optional>
namespace wowee {
namespace game {
/**
* Identifies a WoW expansion for protocol/asset selection.
*/
struct ExpansionProfile {
std::string id; // "classic", "tbc", "wotlk", "cata"
std::string name; // "Wrath of the Lich King"
std::string shortName; // "WotLK"
uint8_t majorVersion = 0;
uint8_t minorVersion = 0;
uint8_t patchVersion = 0;
uint16_t build = 0;
uint8_t protocolVersion = 0; // SRP auth protocol version byte
std::string dataPath; // Absolute path to expansion data dir
uint32_t maxLevel = 60;
std::vector<uint32_t> races;
std::vector<uint32_t> classes;
std::string versionString() const; // e.g. "3.3.5a"
};
/**
* Scans Data/expansions/ for available expansion profiles and manages the active selection.
*/
class ExpansionRegistry {
public:
/**
* Scan dataRoot/expansions/ for expansion.json files.
* @param dataRoot Path to Data/ directory (e.g. "./Data")
* @return Number of profiles discovered
*/
size_t initialize(const std::string& dataRoot);
/** All discovered profiles. */
const std::vector<ExpansionProfile>& getAllProfiles() const { return profiles_; }
/** Lookup by id (e.g. "wotlk"). Returns nullptr if not found. */
const ExpansionProfile* getProfile(const std::string& id) const;
/** Set the active expansion. Returns false if id not found. */
bool setActive(const std::string& id);
/** Get the active expansion profile. Never null after successful initialize(). */
const ExpansionProfile* getActive() const;
/** Convenience: active expansion id. Empty if none. */
const std::string& getActiveId() const { return activeId_; }
private:
std::vector<ExpansionProfile> profiles_;
std::string activeId_;
bool loadProfile(const std::string& jsonPath, const std::string& dirPath);
};
} // namespace game
} // namespace wowee