game: fix TBC 2.4.3 SMSG_CAST_FAILED missing parseCastFailed override

TBC 2.4.3 SMSG_CAST_FAILED format is spellId(u32) + result(u8), same as
Classic. WotLK added a castCount(u8) prefix before spellId. TbcPacketParsers
lacked a parseCastFailed override, so it fell through to the WotLK base
which read one extra byte as castCount, shifting the spellId read by one
byte and corrupting the spell ID and result for every failed cast on TBC.

- Add TbcPacketParsers::parseCastFailed override: reads spellId(4)+result(1)
- ClassicPacketParsers already overrides this (enum shift +1), so Classic unaffected
This commit is contained in:
Kelsi 2026-03-10 01:30:06 -07:00
parent 528b796dff
commit 7270a4e690
2 changed files with 20 additions and 0 deletions

View file

@ -332,6 +332,8 @@ public:
bool parseGossipMessage(network::Packet& packet, GossipMessageData& data) override;
// TBC 2.4.3 SMSG_CAST_RESULT: spellId(u32) + result(u8) — WotLK added castCount(u8) prefix
bool parseCastResult(network::Packet& packet, uint32_t& spellId, uint8_t& result) override;
// TBC 2.4.3 SMSG_CAST_FAILED: spellId(u32) + result(u8) — WotLK added castCount(u8) prefix
bool parseCastFailed(network::Packet& packet, CastFailedData& data) override;
// TBC 2.4.3 SMSG_SPELL_START: full uint64 GUIDs (WotLK uses packed GUIDs)
bool parseSpellStart(network::Packet& packet, SpellStartData& data) override;
// TBC 2.4.3 SMSG_SPELL_GO: full uint64 GUIDs, no timestamp field (WotLK added one)

View file

@ -1080,6 +1080,24 @@ bool TbcPacketParsers::parseCastResult(network::Packet& packet, uint32_t& spellI
return true;
}
// ============================================================================
// TbcPacketParsers::parseCastFailed — TBC 2.4.3 SMSG_CAST_FAILED
//
// TBC format: spellId(u32) + result(u8)
// WotLK added castCount(u8) before spellId; reading it on TBC would shift
// the spellId by one byte and corrupt all subsequent fields.
// Classic has the same layout, but the result enum starts differently (offset +1);
// TBC uses the same result values as WotLK so no offset is needed.
// ============================================================================
bool TbcPacketParsers::parseCastFailed(network::Packet& packet, CastFailedData& data) {
if (packet.getSize() - packet.getReadPos() < 5) return false;
data.castCount = 0; // not present in TBC
data.spellId = packet.readUInt32();
data.result = packet.readUInt8(); // same enum as WotLK
LOG_DEBUG("[TBC] Cast failed: spell=", data.spellId, " result=", (int)data.result);
return true;
}
// ============================================================================
// TbcPacketParsers::parseAttackerStateUpdate — TBC 2.4.3 SMSG_ATTACKERSTATEUPDATE
//