Corrected CharGeosets group assignments verified via vertex bounding boxes:
- Group 4 (401+) = gloves/forearms, Group 5 (501+) = boots/shins,
Group 8 (801+) = sleeves (chest-controlled), Group 9 = kneepads,
Group 13 (1301+) = pants/trousers, Group 20 (2002) = bare feet
- Changed bare shin default from 501 to 502 for better width match
with thigh mesh (0.39 vs 0.32, thighs are 0.42)
- Added clearCompositeCache() to prevent stale composite textures
from being reused across equipment changes
- Fixed character preview geoset defaults to match corrected mapping
Implement full mail send/receive: SMSG_SHOW_MAILBOX, CMSG_GET_MAIL_LIST,
SMSG_MAIL_LIST_RESULT, CMSG_SEND_MAIL, SMSG_SEND_MAIL_RESULT, mail take
money/item/delete/mark-as-read, and inbox/compose UI windows.
Fix periodic stuttering in Stormwind caused by synchronous per-line disk
flushes in the logger — remove fileStream.flush() and std::endl, downgrade
high-volume per-packet/per-model/per-texture LOG_INFO to LOG_DEBUG.
SpellCastTargets target mask is uint16 in vanilla 1.12.x, not uint32
like WotLK. The 2 extra bytes corrupted every spell packet. Also add
classic CMSG_USE_ITEM builder (bag+slot+spellIndex+targets only, no
spellId/itemGuid/glyphIndex/castFlags fields that WotLK added).
When the taxi node ID from the server isn't in TaxiNodes.dbc (custom
server nodes, missing data), fall back to hardcoded gryphon/wyvern
display IDs so the player still appears mounted during flight.
- Per-family mount sounds (kodo, tallstrider, mechanostrider, etc.) detected from M2 model path
- Skip WMO groups with SHOW_SKYBOX flag or all-untextured batches (grey mesh in Orgrimmar)
- Freeze physics during taxi landing until terrain loads to prevent falling through void
- Disable bone animations on tropical vegetation (palm, bamboo, banana, etc.) to fix wiggling
- Snap player to final taxi waypoint on flight completion
- Extract mount aura spell ID from classic UNIT_FIELD_AURAS for CMSG_CANCEL_AURA dismount
- Increase /unstuck forward nudge to 5 units
- Parse MCLQ sub-chunks in vanilla ADTs for water rendering (WotLK uses MH2O)
- Load TaxiPathNode.dbc for MO_TRANSPORT world-coordinate paths (vanilla boats)
- Parse data[] from SMSG_GAMEOBJECT_QUERY_RESPONSE (taxiPathId for transports)
- Support vanilla M2 particle emitters (504-byte struct, different from WotLK 476)
- Add character preview texture diagnostic logging
- Fix disconnect handling on character screen (show error only when no chars)
Classic gossip packets lack the menuId field and quest items don't have
questFlags/isRepeatable, causing the WotLK parser to read garbage counts
(541M quests) and hang. Added ClassicPacketParsers::parseGossipMessage
override with the correct vanilla format.
Add resetDbcCaches() to GameHandler to clear stale spell name, skill,
taxi, and talent caches when switching expansions. Called from
reloadExpansionData() so switching servers (e.g. WotLK to Turtle)
reloads DBC data instead of using stale entries from the previous
expansion.
Fix critical skip/copy parsing bug where source pointer advanced for
both skip and copy sections (skip has no source data). Implement real
relocations using delta-encoded offsets. Strip RSA signature before
zlib decompression. Load module when download completes and cache to
disk. Add empirical hash testing against CR entries and compute
SHA1(moduleImage) response with SHA1Randx key derivation for any seed.
GameHandler::update() now detects when the socket closes mid-session
(e.g. Warden rejection) and transitions to DISCONNECTED state.
Character screen shows a disconnect message instead of hanging on
"Loading characters..." forever. Reverted SHA1(seed+module) fallback
to SHA1(seed) since neither is correct without module execution.
CharSections fields were mapped incorrectly (Variation/Color at 4-5,
textures at 6-8) — corrected to textures at 4-6, Flags at 7,
Variation at 8, Color at 9. Fixed in both dbc_layout.cpp and all
expansion JSON configs. Also fix Warden HASH_REQUEST to SHA1 over
seed+moduleImage instead of just seed.
Fix WotLK chat parser not stripping null terminators from messages,
fix channel message local echo missing channelName, expand default
channels to General/Trade/LocalDefense/LookingForGroup with
configurable auto-join, add Classic packet format for join/leave
channel, display channel index prefix in chat, and add Chat settings
tab with timestamps, font size, and auto-join toggles.
Three Classic packet format fixes:
1. CMSG_CAST_SPELL: target flags are uint32 (not uint16). The wrong
size caused the server to misparse the packet as an item enchant
operation, returning "item already enchanted".
2. SMSG_CAST_FAILED: Classic has no castCount byte prefix (added in
TBC). Added parseCastFailed override to ClassicPacketParsers.
Without this, the parser read the wrong bytes and produced
"Spell cast failed (error 0)" for every failure.
3. SMSG_MESSAGECHAT: Removed spurious receiverGuid read for SAY/YELL
types. Classic chat format has no second GUID before the message
body — the extra 8-byte read consumed messageLen + message data,
producing empty chat messages.
Chat: renderTextWithLinks now properly handles |cAARRGGBB color codes
that aren't item links (e.g. colored player names), rendering the text
in the specified color instead of discarding it.
Dismount: Classic/Vanilla lacks CMSG_CANCEL_MOUNT_AURA (TBC+ opcode).
Track mount aura spell ID when mountDisplayId changes, then use
CMSG_CANCEL_AURA as fallback on expansions without the dedicated opcode.
Binary ItemDisplayInfo.dbc has 23 fields with texture components at
14-21, not 15-22. The previous "fix" shifted all fields by +1 which
read wrong columns and broke both player and NPC equipment rendering.
Also fix local player texture cycling: rebuildOnlineInventory() was
called on every item query response (including for other players),
unconditionally setting onlineEquipDirty_ which triggered redundant
texture recompositing. Now tracks previous equipment displayInfoIds
and only sets dirty when they actually change.
Unified all 3 equipment texture code paths (local player, other
players, NPCs) to use the DBC layout system with correct field 14
base index.
Cache composite textures by input key so identical NPC equipment
combos share one GPU texture. Use DBC layout system for
ItemDisplayInfo texture component fields instead of hardcoded
indices (cross-expansion support). Selective player equipment
re-emission on item query response instead of broadcasting to
all players.
Default PLAYER_VISIBLE_ITEM layout to known WotLK 3.3.5a values
(base=284, stride=2) so equipment reads work immediately without
waiting for heuristic detection. Add equipment texture compositing
for humanoid NPCs over baked body textures using ItemDisplayInfo.dbc
region lookups (texture-only, no geoset changes to avoid invisibility).
Two bugs fixed:
1. SMSG_INSPECT_RESULTS (0x115) was falling through to the inspect
handler, but this opcode is not the real inspect response. Removed
the case so only SMSG_INSPECT_TALENT (0x3F4) triggers the handler.
2. EmotesText DBC layout was missing "ID" field in all 4 expansion
JSON files, causing operator[] to return 0xFFFFFFFF instead of 0.
This broke the dbcId reverse lookup, so other players' emotes
always fell back to generic "performs an emote" text. Added ID
and OthersTargetTextID/OthersNoTargetTextID to all layouts.
Opcode 0x3F4 is SMSG_TALENTS_INFO, sent both for the player's own
talents (type=0, on login/respec) and inspect results (type=1). The
handler was missing the type byte read, treating all packets as
inspect results and spamming "Inspecting target" messages.
Load third-person emote text templates (othersTarget/othersNoTarget)
from EmotesText.dbc fields 3 and 7 alongside existing sender text.
Build reverse lookup map from dbcId to EmoteInfo for incoming
SMSG_TEXT_EMOTE resolution. Other players now show proper emote
descriptions like "Player dances with Target" instead of generic
"Player performs an emote" text.
Guild O tab: fallback to character guildId when guildName_ not yet
queried, re-query guild info on roster open. /who: add missing
stringCount field and fix maxLevel default (0→100). /inspect: add
SMSG_INSPECT_TALENT opcode (0x3F4) and rewrite parser for WotLK
PackedGUID+talent format. Character preview: reset all tracking
variables in setAssetManager() to force model reload on login.
Chat tabs filter messages into General/Combat/Whispers/Trade tabs. Text
emotes now send CMSG_TEXT_EMOTE to server and display incoming emotes
from other players. Channel system auto-joins General/Trade on login with
/join, /leave, and /1-/9 shortcuts. Chat bubbles render as ImGui overlays
above entities for SAY/YELL messages with fade-out animation.
Parse PE sections from WoW.exe into a flat virtual memory image so
MEM_CHECK returns real binary contents instead of zeros. Also mocks
KUSER_SHARED_DATA (0x7FFE026C) with Windows 7 version info.
PAGE_A uses 24 bytes in vanilla (no addr+len), but PAGE_B always uses
29 bytes (with addr+len) regardless of expansion. Splitting the cases
fixes remaining unknown check type errors on Turtle WoW.
Vanilla PAGE_A/B checks are 24 bytes (no addr+len), PROC checks are
25 bytes (no second strIdx+offset), unlike WotLK's 29/30. Wrong sizes
caused incomplete responses with bad checksums, silently blocking
character creation on Turtle WoW.
Filter races/classes in character creation screen by expansion profile
constraints, add 10s server response timeout, and reset Warden crypto
state on disconnect so reconnections use the correct session key.
Expansion overlays allow each expansion to supplement the base asset data
via an assetManifest field in expansion.json, loaded at priority 50 (below
HD packs). The asset extractor gains --reference-manifest for delta-only
extraction. Also fixes CharSections field indices (VariationIndex=4,
ColorIndex=5, Texture1=6) across all DBC layout references.
Bags are now individual draggable ImGui windows (backpack + each equipped
bag) with per-bag toggle from the bag bar. B key opens/closes all. A
settings toggle under Gameplay lets users switch back to the original
aggregate single-window mode. Window width adapts to bag item name length.
Fix dismount by clearing local mount state immediately (optimistic) instead
of waiting for server confirmation, and allow buff bar right-click dismount
regardless of the aura's buff flag.
Fix other players appearing naked by queuing them for auto-inspect when
the visible item field layout hasn't been detected yet.
Vanilla CMSG_CAST_SPELL target mask is uint16 (not uint32 like WotLK),
the extra 2 bytes were corrupting packets. Also implement full bag
content tracking: extract container slot GUIDs from CONTAINER update
objects, set proper bag sizes, and populate bag items in inventory
rebuild.
- Parse vanilla M2 animation tracks (flat arrays with M2Range indices)
instead of skipping them, fixing T-pose on all vanilla models
- Use C4Quaternion (float[4]) for vanilla bone rotations instead of
CompressedQuat (int16[4]) which produced garbage transforms
- Fix vanilla M2 attachment struct size (48 bytes, not 40) so weapons
attach to correct bones instead of model origin
- Route movement packets through expansion-specific packet parsers
instead of hardcoded WotLK format, fixing server-side position sync
- Fix Spell.dbc field indices for classic/turtle (Name=120, Rank=129,
IconID=117) - were pointing to Portuguese locale column (+7 offset)
- Change guild roster keybind from J to O (WoW default)
- Add guild opcodes for all expansions
- Route SMSG_UPDATE_OBJECT through polymorphic parsers for correct
vanilla format (uint8 updateFlags, 6 speeds vs WotLK uint16/9)
- Fix SMSG_DESTROY_OBJECT for vanilla (8 bytes, no isDeath field)
- Add MSG_MOVE_* handlers for other player movement relay
- Add ClassicPacketParsers::parseMessageChat with targetGuid read
and monster-type name handling
- Resolve chat sender names from player name cache before display
- Fix CSV DBC field 0 always treated as numeric ID (fixes 16+ garbled
Turtle CSVs including Map, AreaTable, Spell, CreatureDisplayInfo)
- Add CSV DBC validation: reject garbled CSVs (>80% zero IDs) and
fall back to binary DBC files
- Fix ItemDisplayInfo texture component field index (14+ not 15+)
for binary DBC with gender-aware suffix resolution
- Spawn other players as visible M2 models via creature callback
- Map name cache dedup prevents overwrites from duplicate CSV records
- Vanilla M2 bone struct (108 bytes) with 28-byte animation tracks
- Version-aware bone parsing (vanilla vs WotLK format detection)
- Fix CharSections.dbc field layout for vanilla (variation/color at 4-5)
- Remove broken CharSections.csv files (all fields marked as strings)
- Expansion data reload on profile switch (DBC cache clear, layout reload)
- Vanilla packet encryption (VanillaCrypt XOR-based header crypt)
- Extended character preview geoset range (0-99) for vanilla models
- DBC cache clear support in AssetManager
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
Added MD5 hashing and extensive testing documentation for future attempts
at supporting strict Warden servers like Warmane.
Enhancements:
- Added MD5 hash support to Crypto class (OpenSSL-based)
- Tested 6 different module ACK response formats against Warmane
- Analyzed module packet structure (37 bytes: opcode + seed + trailing)
- Enhanced debug logging for plaintext and encrypted Warden data
Documentation:
- WARDEN_IMPLEMENTATION.md: Complete implementation guide with all attempts
- WARDEN_QUICK_REFERENCE.md: Quick troubleshooting and testing guide
Test Results (Warmane):
- Empty ACK (0 bytes): Server silent
- XOR/MD5 checksum (18 bytes): Server silent
- Single byte (1 byte): Server disconnects (rejected)
- Echo trailing (20 bytes): Server silent
- Result + SHA1 (21 bytes): Server silent
Conclusion:
- Current implementation works with permissive/disabled Warden servers
- Warmane requires module execution or undocumented response format
- Full documentation provided for future reverse engineering attempts
Next steps documented:
1. Capture packets from real WoW client (protocol analysis)
2. Implement module execution engine (months of work)
3. Test with local AzerothCore server
Add complete RC4 encryption/decryption for Warden packets with proper
module initialization, seed extraction, and encrypted check responses.
New components:
- WardenCrypto class: Handles RC4 cipher state for incoming/outgoing packets
- Module initialization: Extracts 16-byte seed from first SMSG_WARDEN_DATA
- Separate input/output RC4 ciphers with proper key derivation
- Enhanced module ACK: Sends encrypted acknowledgment with checksum
Updated GameHandler:
- First packet: Initialize crypto and send encrypted module ACK
- Subsequent packets: Decrypt checks, generate responses, encrypt replies
- Support for module info, hash checks, Lua checks, and memory scans
- Detailed logging of plaintext and encrypted data for debugging
Works with servers that:
- Use standard WoW 3.3.5a Warden protocol
- Accept crypto-based responses without module execution
- Have permissive or disabled Warden settings
Tested against Warmane (strict enforcement) and ready for less restrictive servers.