Commit graph

583 commits

Author SHA1 Message Date
Kelsi
35034ca544 Throttle player equipment compositing and spawning to fix walking stutter
Defer equipment texture compositing to a queue processed max 1 per frame
instead of compositing immediately on callback (each compositeWithRegions
call does file I/O + CPU blit + GPU upload on the main thread). Reduce
MAX_SPAWNS_PER_FRAME from 96 to 8 and increase inspect rate limit from
0.75s to 2s. Demote noisy per-frame logs to DEBUG level.
2026-02-16 00:51:59 -08:00
Kelsi
d87a86e35c Remove debug logging and add negative texture cache to fix lag spikes
Remove PPM composite dumps, MODEL1_BOUNDS vertex analysis, TEX_REGION
logging, FOUNTAIN_PARTICLES debug output, and verbose chat/warden gate
logging. Add negative cache for failed texture loads to prevent repeated
file I/O for missing textures like deathknighteyeglow.blp.
2026-02-16 00:45:47 -08:00
Kelsi
4190cb796f Fix composite cache clearing to not delete NPC textures
clearCompositeCache() now only clears the lookup map without deleting
GPU textures, preventing NPC and other instance textures from being
accidentally destroyed during player equipment changes.
2026-02-16 00:19:07 -08:00
Kelsi
dcd6c488fa Clean up bare shin geoset comments 2026-02-15 20:59:29 -08:00
Kelsi
ed6b305158 Fix character geoset mapping and texture corruption on equipment change
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
2026-02-15 20:53:01 -08:00
Kelsi
8a468e9533 Add mailbox system and fix logging performance stutter
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.
2026-02-15 14:00:41 -08:00
Kelsi
9bc8c5c85a Fix character texture compositing and add YouTube video to README
Use authoritative WoW Model Viewer atlas coordinates (256x256 reference)
for face, underwear, and body region placement. Previously all coordinates
were hardcoded at 512x512 scale causing overlays to be clipped on the
256x256 base skin. Also include face upper+lower textures from
CharSections.dbc in compositing for both player and other-player characters.
2026-02-15 12:53:15 -08:00
Kelsi
7f0eceaacc Fix PopStyleVar mismatches and character geoset IDs
Fix 9 PopStyleVar(2) calls that should be PopStyleVar(1) across
player frame, target frame, cast bar, party frames, buff bar, escape
menu, death dialog, and resurrect dialog. Fix action bar from
PopStyleVar(2) to PopStyleVar(4) to match 4 pushes.

Fix character geoset defaults: 301→302 (bare hands), 701→702 (ears),
1501→1502 (back/cloak), add 802 (wristbands). No WoW character model
uses geoset 301/701/1501; all use 302/702/1502 as base. This fixes
missing hands/arms on undead and other races with separate hand meshes.
2026-02-15 06:09:38 -08:00
Kelsi
d2b46d410a Add original music to login rotation and zone playlists
11 original tracks in assets/Original Music/ now play on the login
screen and in thematically matched zones across Eastern Kingdoms and
Kalimdor. Added crossfadeToFile to MusicManager for local file
playback during zone transitions. New zones: Tirisfal, Undercity,
Barrens, STV, Duskwood, Burning Steppes, Searing Gorge, Ironforge,
Loch Modan, Orgrimmar, Durotar, Mulgore, Thunder Bluff, Darkshore,
Teldrassil, Darnassus.
2026-02-15 05:53:27 -08:00
Kelsi
9fc41d6f30 Add asset backup script with zstd/pigz/gzip fallback 2026-02-15 04:25:56 -08:00
Kelsi
77f8ebd727 Fix PopStyleVar mismatch in settings window 2026-02-15 04:20:32 -08:00
Kelsi
d7e2b26af7 Unify asset system: one asset set, always high-res
Remove HDPackManager, expansion overlay manifests, and BLP size-comparison
logic. Assets now resolve through a single manifest with a simple override
directory (Data/override/) for future HD upgrades.
2026-02-15 04:18:34 -08:00
Kelsi
1bc7b12b20 Make bag bar draggable and fix slot sizing 2026-02-15 03:17:51 -08:00
Kelsi
630019aea9 Fix particle glow transparency for textures without alpha 2026-02-14 22:32:12 -08:00
Kelsi
a2c049b00b Prefer higher-res variants for all textures 2026-02-14 22:09:28 -08:00
Kelsi
9044cef3af Prefer higher-res character textures across overlays 2026-02-14 22:06:15 -08:00
Kelsi
741e9b8cb0 Close chat input after sending 2026-02-14 22:00:26 -08:00
Kelsi
09de52f310 Fix UI window hotkey toggles and silent mount sound fallback 2026-02-14 21:56:38 -08:00
Kelsi
1a9bdfb64b Fix Classic chat parser missing second GUID for SAY/YELL/PARTY
CMaNGOS-Classic writes senderGuid twice for SAY/PARTY/YELL messages.
Our parser only read one, causing the second GUID bytes to be consumed
as messageLen, resulting in empty/garbage message text and no sender
name. Also fix MONSTER_SAY/MONSTER_YELL which have a leading
senderGuid before the name that we were skipping.
2026-02-14 21:34:09 -08:00
Kelsi
0d4eff65d0 Fix vanilla spell cast and use-item packet formats for Turtle/Classic
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).
2026-02-14 21:29:44 -08:00
Kelsi
eb931ce0fc Fix missing taxi mount when node not found in DBC
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.
2026-02-14 21:18:36 -08:00
Kelsi
ef0b1b45ef Fix grey WMO curtains by skipping window/sky materials, fix /unstuck
- Skip WMO batches with material flags F_SIDN (0x20) or F_WINDOW (0x40)
  which are transparent sky/window panes that render as grey curtains
- Fix /unstuck: always nudge 5 units forward first, then sample floor at
  destination instead of teleporting back to last safe position (which
  could be the stuck location itself)
2026-02-14 21:15:28 -08:00
Kelsi
dd99dd8bad Skip individual untextured WMO batches to fix grey mesh in Orgrimmar
The previous fix only skipped groups where ALL batches were untextured.
Groups with a mix of textured and untextured batches still rendered the
untextured ones as solid grey geometry. Now skip each untextured batch
individually during rendering.
2026-02-14 21:05:51 -08:00
Kelsi
d27387d744 Fix mount sounds, grey WMO meshes, taxi landing, tree animations, and classic dismount
- 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
2026-02-14 21:04:20 -08:00
Kelsi
bf31da8c13 Add MCLQ water, TaxiPathNode transports, and vanilla M2 particles
- 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)
2026-02-14 20:20:43 -08:00
Kelsi
cbb3035313 Fix gossip message parsing for Vanilla/Turtle (flight master hang)
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.
2026-02-14 19:38:11 -08:00
Kelsi
a96dc4ebcc Clear game handler DBC caches on expansion switch
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.
2026-02-14 19:27:35 -08:00
Kelsi
7f9439d774 Reset realm and character lists when switching servers
Add reset() to RealmScreen and CharacterScreen to clear stale selection
state. Clear auth handler realm list on reconnect. Reset both screens
when going back to login or back to realm selection, so switching
servers shows fresh data instead of stale lists from the previous
connection.
2026-02-14 19:24:31 -08:00
Kelsi
388db59463 Fix Warden module loading pipeline and HASH_REQUEST response
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.
2026-02-14 19:20:32 -08:00
Kelsi
f4f23eab7a Detect server disconnect during character loading and show error
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.
2026-02-14 18:46:54 -08:00
Kelsi
0ef4af9c99 Fix CharSections DBC layout and Warden SHA1 hash computation
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.
2026-02-14 18:35:08 -08:00
Kelsi
c2467cf2fc Add chat channels, chat settings, and fix missing chat text
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.
2026-02-14 18:27:59 -08:00
Kelsi
bdedab7c1b docs: update README and guides for multi-expansion direction 2026-02-14 18:05:37 -08:00
Kelsi
139a2f39fe Fix Classic/Turtle spell casting, cast fail parsing, and empty chat
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.
2026-02-14 16:54:43 -08:00
Kelsi
d22d32838f Fix flight master hang on Classic/Turtle
SMSG_SHOWTAXINODES parser was hardcoded to expect 12 mask uint32s
(WotLK, 365 nodes) but Classic/Turtle only sends 4 (120 nodes). The
size check rejected the packet, leaving the gossip window stuck.
Now reads however many mask slots are available in the packet.
2026-02-14 16:47:21 -08:00
Kelsi
f6a0be6a08 Fix empty chat messages and /dismount on Classic/Turtle
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.
2026-02-14 16:42:47 -08:00
Kelsi
8282583b9a Fix equipment textures: correct DBC field indices and stop texture cycling
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.
2026-02-14 16:33:24 -08:00
Kelsi
e0e927cac1 Add clickable item links in chat with stat tooltips
Parse WoW item link format (|cXXXXXXXX|Hitem:ENTRY:...|h[Name]|h|r)
in chat messages. Item names render in quality color, hover shows
tooltip with slot type, armor, and stats. Shift-click inserts the
item link into the chat input. Automatically queries server for
item info on first encounter.
2026-02-14 15:58:54 -08:00
Kelsi
148f63cffe Fix off-by-one in ItemDisplayInfo texture component fields
Texture regions are at DBC fields 15-22, not 14-21. Field 14 is
HelmetGeosetVis[1] (uint32), and getString() on it returned random
strings from the DBC string block, causing garbled textures on
players and missing leg textures on other characters.
2026-02-14 15:54:23 -08:00
Kelsi
3675721016 Improve equipment texture performance and accuracy
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.
2026-02-14 15:48:58 -08:00
Kelsi
d4bea91e37 Fix naked players and NPC gear textures
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).
2026-02-14 15:43:09 -08:00
Kelsi
58d8b88721 Fix inspect spam and emote text lookup for other players
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.
2026-02-14 15:23:32 -08:00
Kelsi
9c61d7ecad Fix SMSG_TALENTS_INFO spam by checking talentType field
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.
2026-02-14 15:16:26 -08:00
Kelsi
314c2cabf5 Fix double 'You' prefix on local emote text 2026-02-14 15:13:54 -08:00
Kelsi
3acb42b363 Resolve emote text from DBC for other players' text emotes
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.
2026-02-14 15:11:43 -08:00
Kelsi
a90c130d6e Fix guild roster, /who, /inspect, and character preview bugs
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.
2026-02-14 15:05:18 -08:00
Kelsi
be425c94dc Fix SMSG_MESSAGECHAT parser missing receiverGuid for most chat types
The parser was not reading the uint64 receiverGuid that WoW 3.3.5
sends for SAY/GUILD/PARTY/YELL/WHISPER/RAID/etc types, causing all
incoming chat from other players to misparse (blank messages, wrong
type displayed). Also fix TEXT_EMOTE display to not prepend "You " for
incoming emotes from other players, and fix CHANNEL/ACHIEVEMENT types
to read the correct receiverGuid field.
2026-02-14 14:37:53 -08:00
Kelsi
9bcead6a0f Add chat tabs, networked text emotes, channel system, and chat bubbles
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.
2026-02-14 14:30:09 -08:00
Kelsi
ca3150e43d Fix mesh artifacts on vanilla/TBC M2 models when using expansion overlays
Vanilla (v256) and TBC (v263) M2 files embed skin data directly, parsed
during M2Loader::load(). The code unconditionally loaded external .skin
files afterwards, which resolved to WotLK-format .skin files (48-byte
submeshes) from the base manifest — overwriting the correctly parsed
embedded skin (32-byte submeshes) and causing mesh corruption on all
character models. Guard all 13 loadSkin() call sites with version >= 264
so external .skin files are only loaded for WotLK M2s that need them.
2026-02-14 13:57:54 -08:00
Kelsi
a67dca5787 Add overlay extraction for multi-expansion asset deduplication
Extracts each expansion's assets as a CRC-compared overlay against a
base manifest, storing only files that differ. Auto-detects overlay mode
when a base manifest already exists. Adds --as-overlay, --full-base
flags and manifest merge for partial extractions.
2026-02-14 03:09:17 -08:00