Commit graph

685 commits

Author SHA1 Message Date
Kelsi
40a98f2436 Fix talent tab crash and missing talent points at level 10
Unique child window and button IDs per tab prevent ImGui state corruption
when switching talent tabs. Parse SMSG_INSPECT_TALENT type=0 properly to
populate unspentTalentPoints_ and learnedTalents_ from the server response.
2026-03-12 03:15:56 -07:00
Kelsi
6ab9ba65f9 Store and display played time on character Stats tab
Save totalTimePlayed/levelTimePlayed from SMSG_PLAYED_TIME. Request a
fresh update whenever the character screen is opened. Show total and
level-played time in a two-column layout below the stats panel.
2026-03-12 03:09:52 -07:00
Kelsi
46eb66b77f Store and display achievement criteria progress from SMSG_CRITERIA_UPDATE
Track criteria progress (criteriaId → counter) from SMSG_CRITERIA_UPDATE
and SMSG_ALL_ACHIEVEMENT_DATA. Add a Criteria tab to the achievement window
showing live progress values alongside the existing Earned achievements tab.
2026-03-12 03:03:02 -07:00
Kelsi
920950dfbd Add threat list window showing live aggro data for current target
Store SMSG_THREAT_UPDATE/SMSG_HIGHEST_THREAT_UPDATE in a per-unit map
(sorted descending by threat) and clear on SMSG_THREAT_REMOVE/CLEAR.
Show a threat window (/threat or via target frame button) with a progress
bar per player and gold highlight for the tank, red if local player has aggro.
2026-03-12 02:59:09 -07:00
Kelsi
43de2be1f2 Add inspect window showing talent summary and gear for inspected players
Store inspect results (talent points, dual-spec state, gear entries) in a
new InspectResult struct instead of discarding them as chat messages.
Open the inspect window automatically from all Inspect menu items and /inspect.
2026-03-12 02:52:40 -07:00
Kelsi
92db25038c Parse SMSG_ARENA_TEAM_STATS and display in character screen PvP tab 2026-03-12 02:35:29 -07:00
Kelsi
2bdd024f19 Add GM Ticket window (/ticket, /gm commands and Esc menu button) 2026-03-12 02:31:12 -07:00
Kelsi
adf8e6414e Show boot vote progress in LFG UI; fix unused screenH warning 2026-03-12 02:17:49 -07:00
Kelsi
7a1f330655 Add minimap coordinate tooltip and play time warning display
Hovering over the minimap now shows a tooltip with the player's
WoW canonical coordinates (X=North, Y=West) and a hint about
Ctrl+click pinging.

SMSG_PLAY_TIME_WARNING is now parsed (type + minutes) and shown
as both a chat message and a UIError overlay rather than silently
dropped.
2026-03-12 01:57:03 -07:00
Kelsi
1bc3e6b677 Add Channels tab to social frame and reputation change toast
Social frame now has three tabs: Friends, Ignore, and Channels. The
Channels tab lists joined channels with right-click Leave and an input
to join new channels.

Also adds a slide-in reputation change toast in the lower-right corner:
shows faction name, delta (+/-), and current standing tier (Honored,
Revered, etc.) whenever SMSG_SET_FACTION_STANDING fires a rep change.
2026-03-12 01:51:18 -07:00
Kelsi
06456faa63 Extend UIErrorsFrame to spell failures, interrupts, server shutdown warnings 2026-03-12 01:22:42 -07:00
Kelsi
25e2c60603 Add UIErrorsFrame: center-bottom spell error overlay with fade-out 2026-03-12 01:15:11 -07:00
Kelsi
955b22841e Wire SMSG_FORCE_ANIM animId to emoteAnimCallback 2026-03-12 01:04:16 -07:00
Kelsi
eb9ca8e227 Fix item cooldowns not showing on action bar item-type slots
SMSG_ITEM_COOLDOWN now resolves itemId via onlineItems_ and applies cooldown
to both SPELL-type and ITEM-type action bar slots. Classic SMSG_SPELL_COOLDOWN
also uses the embedded itemId field to update ITEM-type slots.
2026-03-12 00:59:25 -07:00
Kelsi
c89dc50b6c Distinguish channeled spells in cast bar with blue color and draining animation
Adds castIsChannel flag set on MSG_CHANNEL_START, cleared on all cast resets.
Cast bar now drains right-to-left in blue for channels vs gold fill for casts.
2026-03-12 00:43:29 -07:00
Kelsi
c13e18cb55 Add Set Raid Mark submenu to target, party, and raid frame context menus
Implements setRaidMark() using the existing RaidTargetUpdatePacket and exposes
it via right-click on target frame, party member frames, and raid cell frames.
2026-03-12 00:39:56 -07:00
Kelsi
ae8f900410 Add Ctrl+click minimap ping sending
Ctrl+clicking on the minimap converts screen position to world coordinates
and sends MSG_MINIMAP_PING to the server. A local ping is also added
immediately so the sender sees their own ping.
2026-03-11 23:00:03 -07:00
Kelsi
c9c20ce433 Display quest rewards (money and items) in quest log details pane
Parses reward money, guaranteed items, and choice items from SMSG_QUEST_QUERY_RESPONSE fixed header for both Classic/TBC (40-field) and WotLK (55-field) layouts. Rewards are shown in the quest details pane below objective progress with icons, names, and counts.
2026-03-11 22:30:16 -07:00
Kelsi
2e92ec903c Fix SMSG_ITEM_COOLDOWN missing cooldownTotal for sweep animation
SMSG_ITEM_COOLDOWN (on-use trinket/item cooldowns) was only setting
cooldownRemaining, leaving cooldownTotal=0. The action bar clock-sweep
overlay requires both fields; without cooldownTotal the fan shrinks
instantly rather than showing the correct elapsed arc.
2026-03-11 20:21:37 -07:00
Kelsi
6dd7213083 Fix zombie renderer instances on same-map SMSG_NEW_WORLD teleports
Some checks are pending
Build / Build (arm64) (push) Waiting to run
Build / Build (x86-64) (push) Waiting to run
Build / Build (macOS arm64) (push) Waiting to run
Build / Build (windows-arm64) (push) Waiting to run
Build / Build (windows-x86-64) (push) Waiting to run
Security / CodeQL (C/C++) (push) Waiting to run
Security / Semgrep (push) Waiting to run
Security / Sanitizer Build (ASan/UBSan) (push) Waiting to run
When SMSG_NEW_WORLD fires with the same map ID (dungeon wing teleporters,
GM teleports, etc.), entityManager.clear() was called but renderer
instances in creatureInstances_/playerInstances_/gameObjectInstances_
were never despawned.  Fresh CREATE_OBJECTs from the server hit the
early-return guard (guid already in creatureInstances_) and were skipped,
leaving entities in the entity manager without matching renderer state.

Fix: pass isSameMap as isInitialEntry to the world-entry callback.  This
routes same-map SMSG_NEW_WORLD through the reconnect path which properly
despawns all renderer instances before the server resends CREATE_OBJECTs.
2026-03-11 19:59:42 -07:00
Kelsi
711cb966ef Fix chest interaction and measure server RTT for latency meter
Chests (and lockboxes, coffers, etc.) failed to open because CMSG_LOOT
was only sent on Classic/Turtle expansions, and only when GO type was
already cached as type 3.  Fix: always send CMSG_LOOT after
CMSG_GAMEOBJ_USE (server silently ignores it for non-lootable objects).
Also broaden CMSG_GAMEOBJ_REPORT_USE to all non-mailbox WotLK GOs.

Latency meter: record pingTimestamp_ in sendPing() and compute RTT in
handlePong(); add toggleable "Show Latency Meter" checkbox in Interface
settings (saved to settings.cfg).
2026-03-11 19:45:03 -07:00
Kelsi
b5291d1883 Revert quest reward window delay that caused dialog to hang
The delayed-opening logic conflicted with quest details' use of the same
questDetailsOpenTime variable, causing the reward dialog to never appear.
Reverted to immediately opening the window. Item info queries are still
triggered, but will populate asynchronously with placeholders shown initially.
2026-03-11 19:11:02 -07:00
Kelsi
510370dc7b Delay quest reward window opening to load item icons/names
Add 100ms delay before opening the quest offer reward dialog, giving item
info queries time to complete. Prevents "Item X" placeholders where players
can't see item names or icons needed to choose rewards. Reuses the existing
questDetailsOpenTime mechanism with delayed flag check in isQuestOfferRewardOpen().
2026-03-11 18:55:13 -07:00
Kelsi
182b6686ac Pre-query action bar item information to avoid placeholder display
When items are placed on the action bar, pre-fetch their ItemDef information
so the action bar displays the item name instead of a generic "Item" placeholder.
This ensures item names are available when the action bar is rendered, consistent
with the fix applied to quest reward items display.

Calls queryItemInfo() when an item is assigned to an action bar slot.
2026-03-11 18:36:32 -07:00
Kelsi
eef269ffb8 Fix quest reward items showing as 'Item {number}' on first frame
Quest reward items (both in details and offer-reward windows) were showing as "Item {itemId}"
placeholders because the window opened immediately after receiving SMSG_QUESTGIVER_QUEST_DETAILS,
before the item query responses from pre-fetched queries had time to arrive.

Solution: Delay opening the quest details window by 100ms to allow item queries to complete
and be cached before the window first renders. Uses std::chrono::steady_clock for timing.

- Add questDetailsOpenTime field to track delayed opening timestamp
- Modify isQuestDetailsOpen() to check timer and open window when time expires
- Reset timer whenever quest details window closes
- Updated comment to clarify pre-fetch benefits both details and offer-reward windows
2026-03-11 17:27:23 -07:00
Kelsi
b5a48729b8 Add diagnostic logging for player appearance extraction failures
Log a warning when player model spawn fails due to appearance data extraction failure.
This helps diagnose why players appear invisible (missing field indices or malformed
update packets). Logs at both CREATE_OBJECT and VALUES update points.
2026-03-11 17:12:05 -07:00
Kelsi
eb3cdbcc5f Fix stacked item count display in bags after looting
Move onlineItems_ lookup outside field iteration to ensure consistent item
reference when updating stack count/durability. This fixes an issue where
stacked item counts in open bags wouldn't update immediately when looting
additional items until the item was moved to another slot.
2026-03-11 16:58:36 -07:00
Kelsi
4d0eef1f6f Skip tab-targeting empty looted corpses
Dead creatures with no remaining loot items are now excluded from tab-targeting
cycle. Prevents cycling through empty corpses when looking for targetable enemies.
Corpses with available loot remain targetable.
2026-03-11 16:52:53 -07:00
Kelsi
6a8939d420 Harden final 8 parsers against truncated packets (100% coverage)
Remaining parsers now have upfront bounds checking:
- CharCreateResponseParser: validate 1 byte minimum
- QueryTimeResponseParser: validate 8 bytes (serverTime + offset)
- PlayedTimeParser: validate 9 bytes (totalTime + levelTime + flag)
- FriendStatusParser: validate 9 bytes + conditional string/flag
- LogoutResponseParser: validate 5 bytes (result + instant)
- RandomRollParser: validate 28 bytes (two GUIDs + three UInt32s)
- XpGainParser: validate 13 bytes base + conditional kill XP fields
- GroupInviteResponseParser: validate 1 byte + string (safe)

Packet parser hardening now at 100% coverage (all 106 parsers)
2026-03-11 15:08:48 -07:00
Kelsi
80c4e77c12 Harden GuildQueryResponseParser against truncated packets
Add bounds validation before reading guild name and 10 rank names.
Gracefully handle missing emblem data with safe defaults.
2026-03-11 14:46:44 -07:00
Kelsi
1979aa926b Harden TrainerListParser against truncated packets
Add upfront validation for header fields and per-spell bounds checking
before reading trainer spell data. Gracefully handle truncated greeting.
2026-03-11 14:44:52 -07:00
Kelsi
26f1a2d606 Harden GuildBankListParser against truncated packets
Cap tabCount to 8, add bounds validation before each tab and item read.
Gracefully handle truncated tab names, icons, and enchant data.
2026-03-11 14:43:03 -07:00
Kelsi
3849ad75ce Harden GuildRosterParser against unbounded memory allocation
Cap numMembers to 1000 and rankCount to 20 to prevent OOM attacks.
Add per-field bounds checking for member data with graceful truncation.
2026-03-11 14:42:09 -07:00
Kelsi
2c67331bc3 Harden MotdParser and UpdateObjectParser against truncated packets
- MotdParser: cap lineCount to 64 to prevent unbounded memory allocation,
  add bounds check before each string read
- UpdateObjectParser: add bounds validation before each update mask block
  and field value read to prevent reading past packet boundary
2026-03-11 14:41:25 -07:00
Kelsi
6fa1e49cb2 Harden CharEnumParser against truncated packets
Add upfront validation and per-field bounds checking to prevent
undefined behavior when parsing truncated SMSG_CHAR_ENUM packets.
Gracefully handle missing character data with safe defaults.
2026-03-11 14:40:07 -07:00
Kelsi
9892d82c52 Add upfront validation to group-related parsers
SMSG_PARTY_COMMAND_RESULT improvements:
- Validate 8-byte minimum for command + result + name string
- Graceful handling of truncated result field

SMSG_GROUP_DECLINE improvements:
- Validate 1-byte minimum for playerName CString
- Prevent reading from empty packets

Ensures consistent error handling for group system packets.
2026-03-11 14:38:11 -07:00
Kelsi
b699557597 Cap auction count in AuctionListResultParser
SMSG_AUCTION_LIST_RESULT (Classic/TBC/WotLK) improvements:
- Cap auction count to 256 (prevents unbounded memory allocation)
- Each entry is 80-104 bytes depending on expansion
- Prevents DoS from servers sending huge auction lists
- Log warning when cap is reached

Prevents memory exhaustion from malformed auction house packets.
2026-03-11 14:37:27 -07:00
Kelsi
6e94a3345f Add upfront validation to CastFailedParser
SMSG_CAST_FAILED (3.3.5a) improvements:
- Validate 6-byte minimum for castCount + spellId + result
- Prevent reading from truncated packets

Ensures consistent error handling for spell failure feedback.
2026-03-11 14:35:29 -07:00
Kelsi
4f3e817913 Harden GossipMessageParser against malformed packets
SMSG_GOSSIP_MESSAGE (3.3.5a) improvements:
- Validate 20-byte minimum for npcGuid + menuId + titleTextId + optionCount
- Cap optionCount to 64 (prevents unbounded memory allocation)
- Validate 12-byte minimum before each option read (fixed fields + 2 strings)
- Cap questCount to 64 (prevents unbounded memory allocation)
- Validate 18-byte minimum before each quest read (fixed fields + title string)
- Graceful truncation with partial list support

Prevents DoS from servers sending malformed gossip menus with huge option/quest lists.
2026-03-11 14:34:20 -07:00
Kelsi
efc394ce9e Cap spell cooldown entries in SpellCooldownParser
SMSG_SPELL_COOLDOWN (3.3.5a) improvements:
- Validate 9-byte minimum for guid + flags
- Cap cooldown entries to 512 (each entry is 8 bytes: spellId + ms)
- Prevent unbounded memory allocation from malformed packets
- Log warning when cap is reached with remaining data ignored

Prevents DoS from servers sending malformed cooldown lists.
2026-03-11 14:33:02 -07:00
Kelsi
1d4f69add3 Harden combat log parsers against malformed packets
SMSG_ATTACKERSTATEUPDATE (3.3.5a) improvements:
- Validate 13-byte minimum for hitInfo + GUIDs + totalDamage + count
- Cap subDamageCount to 64 (each entry is 20 bytes)
- Validate 20-byte minimum before each sub-damage entry read
- Validate 8-byte minimum before victimState/overkill read
- Validate 4-byte minimum before blocked amount read (optional field)

SMSG_SPELLDAMAGELOG (3.3.5a) improvements:
- Validate 30-byte minimum for all required fields
- Validate core fields before reading (21-byte check)
- Validate trailing fields (10-byte check) before reading flags/crit

SMSG_SPELLHEALLOG (3.3.5a) improvements:
- Validate 21-byte minimum for all required fields
- Validate remaining fields (17-byte check) before reading heal data
- Graceful truncation with field initialization

Prevents DoS and undefined behavior from high-frequency combat log packets.
2026-03-11 14:32:03 -07:00
Kelsi
68b3cef0fe Harden AuraUpdateParser against malformed packets
WotLK SMSG_AURA_UPDATE (3.3.5a) improvements:
- Cap entry count to 512 (isAll) or 1 (single) to prevent unbounded loop DoS
- Validate 5-byte minimum before each slot+spellId read
- Validate 3-byte minimum before flags/level/charges read
- Validate space before casterGuid packed GUID read
- Validate 8-byte minimum before duration field reads
- Validate 4-byte minimum before each effect amount read
- Graceful truncation with field initialization and partial read support
- Log all truncation events with entry index information

Prevents DoS and undefined behavior from high-frequency aura update packets.
2026-03-11 14:30:57 -07:00
Kelsi
7034bc5f63 Cap hit/miss counts in Classic and TBC spell parsers
Add DoS protection to Classic and TBC parseSpellGo implementations:
- Cap hitCount and missCount to 128 each (prevents OOM from huge arrays)
- Track actual reads vs expected counts
- Log truncation warnings with index information
- Graceful truncation with count updates

Ensures consistent hardening across all expansion variants (Vanilla/TBC/WotLK).
2026-03-11 14:29:37 -07:00
Kelsi
164124783b Harden SpellStart and SpellGo parsers against malformed packets
WotLK SMSG_SPELL_START (3.3.5a) improvements:
- Validate 22-byte minimum for packed GUIDs + fixed fields
- Validate targetFlags read (4 bytes)
- Validate targetGuid packed read with size check

WotLK SMSG_SPELL_GO (3.3.5a) improvements:
- Validate 24-byte minimum for core fields
- Cap hitCount to 128 to prevent OOM from huge target lists
- Cap missCount to 128 with same protection
- In-loop validation: check 8 bytes before each hit GUID read
- In-loop validation: check 2 bytes minimum before each miss entry (packed GUID + type)
- Graceful truncation with partial read support and count updates

Prevents DoS and undefined behavior from servers sending malformed combat packets.
2026-03-11 14:28:41 -07:00
Kelsi
98739c1610 Harden NameQueryResponseParser against malformed packets
Add upfront and in-loop validation for the WotLK variant of name query responses:
- Validate packed GUID and found flag reads (minimum 2 bytes)
- Validate strings can be read before attempting parse
- Validate 3 final uint8 fields (race/gender/class) exist before reading
- Graceful truncation handling with field initialization

Prevents undefined behavior from servers sending truncated/malformed packets.
2026-03-11 14:27:39 -07:00
Kelsi
2f1b142e14 Add packet size validation to SMSG_CREATURE_QUERY_RESPONSE parsing
Improve robustness of creature query response parsing by adding defensive
size checks to both WotLK/TBC and Classic variants:

- WotLK/TBC (world_packets.cpp): Add upfront validation for entry field,
  validate minimum size (16 bytes) before reading fixed fields
  (typeFlags, creatureType, family, rank), graceful truncation handling
- Classic (packet_parsers_classic.cpp): Add upfront entry validation,
  enhance existing truncation check with default field initialization,
  improve logging consistency
- Both variants now initialize fields to 0 on truncation and log warnings
  with entry context

Part of ongoing Tier 2 work to improve multi-expansion packet parsing robustness
against malformed or truncated server packets.
2026-03-11 14:19:58 -07:00
Kelsi
e464300346 Add pointCount cap to SMSG_MONSTER_MOVE spline parsing
Improve robustness of monster move spline parsing by capping the pointCount
field to prevent excessive iteration from malformed or malicious packets.

- WotLK: Cap pointCount to 1000 waypoints (realistic maximum for movement)
- Vanilla (Turtle): Reduce existing cap from 16384 to 1000 and add warning
  logging when cap is applied
- Both variants now log warnings when cap is exceeded, including guid context

A malicious or corrupted server sending an unrealistic pointCount value (e.g.
uint32_max) could previously cause the client to allocate excessive memory or
iterate excessively. The 1000-waypoint cap aligns with realistic movement
paths while protecting against DoS vectors.

Part of ongoing Tier 2 work to improve multi-expansion packet parsing robustness.
2026-03-11 14:13:09 -07:00
Kelsi
73abbc2a08 Add packet size validation to SMSG_GAMEOBJECT_QUERY_RESPONSE parsing
Improve robustness of game object query response parsing by adding defensive
size checks to both WotLK/TBC and Classic variants:

- WotLK/TBC (world_packets.cpp): Add upfront validation for entry, type,
  displayId fields, and improved in-loop handling for variable-length data
  array with partial data graceful degradation
- Classic (packet_parsers_classic.cpp): Add upfront validation for entry,
  type, displayId fields, and enhanced in-loop data array read with
  truncation detection
- Both variants now log warnings when data fields are truncated

Part of ongoing Tier 2 work to improve multi-expansion packet parsing robustness
against malformed or truncated server packets.
2026-03-11 14:11:45 -07:00
Kelsi
d1414b6a46 Add packet size validation to SMSG_INITIAL_SPELLS parsing
Improve robustness of initial spells parsing by adding defensive size checks:

- Validate minimum packet size for header (talentSpec + spellCount)
- Cap spellCount to max 256 spells to prevent excessive iteration
- Add in-loop size checks for each spell entry before reading (4 bytes
  vanilla, 6 bytes TBC/WotLK)
- Validate minimum size for cooldownCount field (optional, gracefully
  handles truncation before it)
- Cap cooldownCount to max 256 cooldowns to prevent excessive iteration
- Add in-loop size checks for each cooldown entry before reading (14 bytes
  vanilla, 16 bytes TBC/WotLK)
- Log warnings on packet truncation with clear context

Applies to both vanilla format (Classic) and TBC/WotLK format variants.
Part of ongoing Tier 2 work to improve multi-expansion packet parsing
robustness against malformed or truncated server packets.
2026-03-11 14:10:20 -07:00
Kelsi
f472ee3be8 Add packet size validation to SMSG_ITEM_QUERY_SINGLE_RESPONSE parsing
Improve robustness of item query response parsing across all three expansions
by adding defensive size checks and bounds validation:

- WotLK (world_packets.cpp): Add upfront validation for fixed-size fields,
  bounds cap on statsCount (max 10), in-loop size checks for stat pairs,
  and improved logging for truncation detection
- Classic (packet_parsers_classic.cpp): Add upfront validation for fixed fields,
  in-loop checks for 10 fixed stat pairs and 5 damage entries, and graceful
  truncation handling
- TBC (packet_parsers_tbc.cpp): Add upfront validation, statsCount bounds cap,
  and in-loop size checks for variable-length stats and fixed damage entries

All changes are backward compatible and log warnings on packet truncation.
This is part of ongoing Tier 2 work to improve multi-expansion packet parsing
robustness against malformed or truncated server packets.
2026-03-11 14:08:59 -07:00