Commit graph

693 commits

Author SHA1 Message Date
Kelsi
d817e4144c feat: debuff dispel-type border coloring in buff bar
Read DispelType from Spell.dbc (new field in all expansion DBC layouts)
and use it to color debuff icon borders: magic=blue, curse=purple,
disease=brown, poison=green, other=red. Buffs remain green-bordered.
Adds getSpellDispelType() to GameHandler for lazy cache lookup.
2026-03-12 06:55:16 -07:00
Kelsi
3e8f03c7b7 feat: add PROC_TRIGGER floating combat text for spell procs
Handles SMSG_SPELL_CHANCE_PROC_LOG (previously silently ignored) to
display gold "PROC!" floating text when the player triggers a spell
proc. Reads caster/target packed GUIDs and spell ID from the packet
header; skips variable-length effect payload.

Adds CombatTextEntry::PROC_TRIGGER type with gold color rendering,
visible alongside existing damage/heal/energize floating numbers.
2026-03-12 06:06:41 -07:00
Kelsi
b6a43d6ce7 feat: track and visualize global cooldown (GCD) on action bar
- GameHandler tracks GCD in gcdTotal_/gcdStartedAt_ (time-based)
- SMSG_SPELL_COOLDOWN: spellId=0 entries (<=2s) are treated as GCD
- castSpell(): optimistically starts 1.5s GCD client-side on cast
- Action bar: non-cooldown slots show subtle dark sweep + dim tint
  during the GCD window, matching WoW standard behavior
2026-03-12 05:38:13 -07:00
Kelsi
5827a8fcdd feat: add Shaman totem bar in player frame
Store active totem state (slot, spellId, duration, placedAt) from
SMSG_TOTEM_CREATED. Render 4 element slots (Earth/Fire/Water/Air) as
color-coded duration bars in the player frame for Shamans (class 7).
Shows countdown seconds, element letter when inactive, and tooltip
with spell name + remaining time on hover.
2026-03-12 05:16:43 -07:00
Kelsi
c35bf8d953 feat: add duel countdown overlay (3-2-1-Fight!)
Parse SMSG_DUEL_COUNTDOWN to get the countdown duration, track the
start time, and render a large centered countdown overlay. Numbers
display in pulsing gold; transitions to pulsing red 'Fight!' for the
last 0.5 seconds. Countdown clears on SMSG_DUEL_COMPLETE.
2026-03-12 05:06:14 -07:00
Kelsi
29a989e1f4 feat: add reputation bar above XP bar
Show a color-coded reputation progress bar for the most recently gained
faction above the XP bar. The bar is auto-shown when any faction rep
changes (watchedFactionId_ tracks the last changed faction). Colors
follow WoW conventions: red=Hated/Hostile, orange=Unfriendly,
yellow=Neutral, green=Friendly, blue=Honored, purple=Revered,
gold=Exalted. Tooltip shows exact standing values on hover.
2026-03-12 05:03:03 -07:00
Kelsi
b682e8c686 feat: add countdown timer to loot roll popup
Show a color-coded progress bar (green→yellow→pulsing red) in the loot
roll window indicating time remaining to make a roll decision. The
countdown duration is read from SMSG_LOOT_START_ROLL (or defaults to
60s for the SMSG_LOOT_ROLL path). Remaining seconds are displayed on
the bar itself.
2026-03-12 04:57:36 -07:00
Kelsi
b34bf39746 feat: add quest completion toast notification
When a quest is turned in (SMSG_QUESTGIVER_QUEST_COMPLETE), a gold-bordered
toast slides in from the right showing "Quest Complete" header with the quest
title, consistent with the rep change and achievement toast systems.
2026-03-12 04:53:03 -07:00
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