Commit graph

195 commits

Author SHA1 Message Date
Kelsi
83a368aa85 fix(combatlog): reject spell start packets missing target flags 2026-03-14 21:52:03 -07:00
Kelsi
71e34e41b7 fix(combatlog): clamp attacker-state subdamage count to payload 2026-03-14 21:52:03 -07:00
Kelsi
80d59a80aa fix(combatlog): relax packed GUID minimum-size gates 2026-03-14 21:52:03 -07:00
Kelsi
6ccfdc9d11 fix(combatlog): validate packed GUID bounds in spell damage/heal logs 2026-03-14 21:52:03 -07:00
Kelsi
24a63beb3c fix(combatlog): reject truncated spell start target GUIDs 2026-03-14 21:52:03 -07:00
Kelsi
bcfdcce062 fix(combatlog): reject truncated spell go packets missing counts 2026-03-14 21:52:03 -07:00
Kelsi
f0ba85fa80 fix(combatlog): reset spell go parser output before decode 2026-03-14 21:52:03 -07:00
Kelsi
e0ac81450d fix(combatlog): enforce full spell start fixed-field bounds 2026-03-14 21:52:03 -07:00
Kelsi
918762501f fix(combatlog): fail spell go parse on truncated target lists 2026-03-14 21:52:03 -07:00
Kelsi
ffa6dda4d9 fix(combatlog): validate packed GUID bounds in attacker state parsers 2026-03-14 21:52:03 -07:00
Kelsi
5a9be91fac fix(combatlog): validate packed guid bounds in spell go parser 2026-03-14 21:52:03 -07:00
Kelsi
4561eb8696 fix(combatlog): validate packed GUID bounds in spell start parser 2026-03-14 21:52:03 -07:00
Kelsi
69ff91e9a2 fix(combatlog): validate packed GUID bounds in spell cast parsers 2026-03-14 21:52:03 -07:00
Kelsi
5ecc46623a fix(combatlog): consume full spell go target lists when capped 2026-03-14 21:52:03 -07:00
Kelsi
013f6be162 fix(mail): correct WotLK mail list attachment parsing 2026-03-14 07:14:15 -07:00
Kelsi
5fa5020af5 fix(mail): use attachment item guid for WotLK take item 2026-03-14 07:11:18 -07:00
Kelsi
aa9dc128d8 fix(chat): make /r resolve last whisper sender reliably 2026-03-14 06:56:16 -07:00
Kelsi
5b195781ad fix(death): restore corpse reclaim and enforce ghost grayscale 2026-03-14 06:43:49 -07:00
Kelsi
3f1083e9b5 fix(combatlog): consume reflect payload in spell-go miss entries 2026-03-13 23:15:56 -07:00
Kelsi
cf68c156f1 fix(combatlog): accept short packed spell-go packets 2026-03-13 21:16:24 -07:00
Kelsi
16c8a2fd33 fix(combatlog): parse packed spell-go hit target GUIDs 2026-03-13 21:08:00 -07:00
Kelsi
ef7494700e feat: parse and display Heroic/Unique/Unique-Equipped item flags in tooltips 2026-03-13 11:32:32 -07:00
Kelsi
03f8642fad feat: parse and display elemental resistances and race restrictions in item tooltips
- Store holyRes/fireRes/natureRes/frostRes/shadowRes/arcaneRes in ItemQueryResponseData
- Parse resistance fields in WotLK, TBC, and Classic parsers (previously discarded)
- Display non-zero resistances (e.g. "+40 Fire Resistance") in both tooltip paths
- Add getPlayerRace() accessor to GameHandler
- Show race restriction line (e.g. "Races: Blood Elf, Draenei") in both tooltip paths,
  highlighted red when player's race is not allowed
- Useful for fire/nature/frost resist gear (Onyxia, AQ40, Naxx encounters)
2026-03-13 11:23:55 -07:00
Kelsi
b0b47c354a feat: parse and display item skill/reputation requirements in tooltips
- Store requiredSkill, requiredSkillRank, allowableClass, allowableRace,
  requiredReputationFaction, and requiredReputationRank from
  SMSG_ITEM_QUERY_SINGLE_RESPONSE in ItemQueryResponseData (was discarded)
- Show "Requires <Skill> (<rank>)" in item tooltip, highlighted red when
  the player doesn't have sufficient skill level
- Show "Requires <Rank> with <Faction>" for reputation-gated items
- Skill names resolved from SkillLine.dbc; faction names from Faction.dbc
- Also fix loot window tooltip suppressing items with names starting with 'I'
2026-03-13 11:11:33 -07:00
Kelsi
4272491d56 feat: send CMSG_SET_ACTION_BUTTON to server when action bar slot changes
Action bar changes (dragging spells/items) were only saved locally.
Now notifies the server via CMSG_SET_ACTION_BUTTON so the layout
persists across relogs. Supports Classic (5-byte) and TBC/WotLK
(packed uint32) wire formats.
2026-03-13 04:25:05 -07:00
Kelsi
27213c1d40 fix: robust SMSG_ATTACKERSTATEUPDATE parsing for WotLK format
Two issues in the WotLK SMSG_ATTACKERSTATEUPDATE parser:

1. subDamageCount could read a school-mask byte when a packed GUID is
   off by one byte, producing values like 32/40/44/48 (shadow/frost/etc
   school masks) as the count. The parser then tried to read 32-48
   sub-damages before hitting EOF. Fix: silently clamp subDamageCount to
   floor(remaining/20) so we only attempt entries that actually fit.

2. After sub-damages, AzerothCore sends victimState(4)+unk1(4)+unk2(4)+
   overkill(4) (16 bytes), not the 8-byte victimState+overkill the
   parser was reading. Fix: consume unk1 and unk2 before reading overkill.
   Also handle the hitInfo-conditional HITINFO_BLOCK/RAGE_GAIN/FAKE_DAMAGE
   fields at the end of the packet.
2026-03-13 02:47:40 -07:00
Kelsi
1cd8e53b2f fix: handle SPLINEFLAG_ANIMATION in UPDATE_OBJECT legacy spline layout
When SPLINEFLAG_ANIMATION (0x00400000) is set, AzerothCore inserts 5 bytes
(uint8 animationType + int32 animTime) between durationModNext and
verticalAccel in the SMSG_UPDATE_OBJECT MoveSpline block. The parser was
not accounting for these bytes, causing verticalAccel, effectStartTime,
and pointCount to be read from the wrong offset.

This produced garbage pointCount values (e.g. 3322451254) triggering the
"Spline pointCount invalid (legacy+compact)" fallback path and breaking
UPDATE_OBJECT parsing for animated-spline entities, causing all subsequent
update blocks in the same packet to be dropped.
2026-03-13 02:38:53 -07:00
Kelsi
367b48af6b fix: handle short loot-failure response in LootResponseParser
Servers send a 9-byte packet (guid+lootType) with lootType=LOOT_NONE when
loot is unavailable (locked chest, another player looting, needs a key).
The previous parser required ≥14 bytes (guid+lootType+gold+itemCount) and
logged a spurious WARNING for every such failure response.

Now:
- Accept the 9-byte form; return false so the caller skips opening the
  loot window (correct behaviour for a failure/empty response).
- Log at DEBUG level instead of WARNING for the short form.
- Keep the original WARNING for genuinely malformed packets < 9 bytes.
2026-03-13 01:29:21 -07:00
Kelsi
1d9dc6dcae feat: parse SMSG_RESPOND_INSPECT_ACHIEVEMENTS and request on inspect
When the player inspects another player on WotLK 3.3.5a, also send
CMSG_QUERY_INSPECT_ACHIEVEMENTS so the server responds with
SMSG_RESPOND_INSPECT_ACHIEVEMENTS.  The new handler parses the
achievement-id/date sentinel-terminated block (same layout as
SMSG_ALL_ACHIEVEMENT_DATA but prefixed with a packed guid) and stores
the earned achievement IDs keyed by GUID in
inspectedPlayerAchievements_.  The new public getter
getInspectedPlayerAchievements(guid) exposes this data for the inspect
UI.  The cache is cleared on world entry to prevent stale data.
QueryInspectAchievementsPacket::build() handles the CMSG wire format
(uint64 guid + uint8 unk=0).
2026-03-12 23:23:02 -07:00
Kelsi
1bf4c2442a feat: add title selection window with CMSG_SET_TITLE support
Track player titles from SMSG_TITLE_EARNED into knownTitleBits_ set,
read active title from PLAYER_CHOSEN_TITLE update field (WotLK index
1349), expose via getFormattedTitle()/sendSetTitle() on GameHandler.

Add SetTitlePacket builder (CMSG_SET_TITLE: int32 titleBit, -1=clear).

Titles window (H key) lists all earned titles from CharTitles.dbc,
highlights the active one in gold, and lets the player click to equip
or unequip a title with a single server round-trip.
2026-03-12 20:23:36 -07:00
Kelsi
bba2f20588 feat: implement CMSG_PET_RENAME with rename dialog in pet frame
- Add PetRenamePacket::build(petGuid, name, isDeclined) builder
- Add GameHandler::renamePet(newName) — sends packet via petGuid_
- Add 'Rename Pet' to pet frame context menu (right-click pet name)
- Modal input dialog with 12-char limit matches server validation
2026-03-12 19:42:31 -07:00
Kelsi
284b98d93a feat: implement pet stable system (MSG_LIST_STABLED_PETS, CMSG_STABLE_PET, CMSG_UNSTABLE_PET)
- Parse MSG_LIST_STABLED_PETS (SMSG): populate StabledPet list with
  petNumber, entry, level, name, displayId, and active status
- Detect stable master via gossip option text/keyword matching and
  auto-send MSG_LIST_STABLED_PETS request to open the stable UI
- Refresh list automatically after SMSG_STABLE_RESULT to reflect state
- New packet builders: ListStabledPetsPacket, StablePetPacket, UnstablePetPacket
- New public API: requestStabledPetList(), stablePet(slot), unstablePet(petNumber)
- Stable window UI: shows active/stabled pets with store/retrieve buttons,
  slot count, refresh, and close; opens when server sends pet list
- Clear stable state on world logout/disconnect
2026-03-12 19:15:52 -07:00
Kelsi
48f12d9ca8 feat: parse item set ID and display set name in item tooltip via ItemSet.dbc 2026-03-12 12:35:56 -07:00
Kelsi
0a2cd213dc feat: display gem socket slots and socket bonus in item tooltips 2026-03-12 12:15:08 -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
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