From d72912714b9771b15fcd88df4e25eae561d1515b Mon Sep 17 00:00:00 2001 From: Kelsi Date: Mon, 9 Mar 2026 23:20:15 -0700 Subject: [PATCH] game: fix SMSG_SPELL_FAILURE GUID format for TBC/Classic vs WotLK WotLK uses packed GUIDs in SMSG_SPELL_FAILURE / SMSG_SPELL_FAILED_OTHER. TBC 2.4.3 and Classic 1.12 use full uint64 GUIDs. The previous fix used UpdateObjectParser::readPackedGuid for all expansions, which would mis-parse the caster GUID on TBC/Classic servers, leaving stale cast bars and potentially corrupting subsequent packet reads. Now checks isClassicLikeExpansion() || isActiveExpansion("tbc") and reads a raw uint64 for those expansions, matching the TBC/Classic wire format used in parseSpellStart/parseSpellGo overrides. --- src/game/game_handler.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/game/game_handler.cpp b/src/game/game_handler.cpp index 543236ea..c7a7eefa 100644 --- a/src/game/game_handler.cpp +++ b/src/game/game_handler.cpp @@ -1780,8 +1780,12 @@ void GameHandler::handlePacket(network::Packet& packet) { // ---- Spell failed on another unit ---- case Opcode::SMSG_SPELL_FAILED_OTHER: { - // packed_guid + uint8 castCount + uint32 spellId + uint8 reason - uint64_t failOtherGuid = UpdateObjectParser::readPackedGuid(packet); + // WotLK: packed_guid + uint8 castCount + uint32 spellId + uint8 reason + // TBC/Classic: full uint64 + uint8 castCount + uint32 spellId + uint8 reason + const bool tbcLike2 = isClassicLikeExpansion() || isActiveExpansion("tbc"); + uint64_t failOtherGuid = tbcLike2 + ? (packet.getSize() - packet.getReadPos() >= 8 ? packet.readUInt64() : 0) + : UpdateObjectParser::readPackedGuid(packet); if (failOtherGuid != 0 && failOtherGuid != playerGuid) { unitCastStates_.erase(failOtherGuid); } @@ -2532,8 +2536,12 @@ void GameHandler::handlePacket(network::Packet& packet) { handleSpellGo(packet); break; case Opcode::SMSG_SPELL_FAILURE: { - // packed_guid caster + uint8 castCount + uint32 spellId + uint8 failReason - uint64_t failGuid = UpdateObjectParser::readPackedGuid(packet); + // WotLK: packed_guid + uint8 castCount + uint32 spellId + uint8 failReason + // TBC/Classic: full uint64 + uint8 castCount + uint32 spellId + uint8 failReason + const bool tbcOrClassic = isClassicLikeExpansion() || isActiveExpansion("tbc"); + uint64_t failGuid = tbcOrClassic + ? (packet.getSize() - packet.getReadPos() >= 8 ? packet.readUInt64() : 0) + : UpdateObjectParser::readPackedGuid(packet); if (failGuid == playerGuid || failGuid == 0) { // Player's own cast failed casting = false;