From 63d82003030c435d56ad6239c310cc5fc29aec2e Mon Sep 17 00:00:00 2001 From: Kelsi Date: Mon, 9 Mar 2026 21:36:12 -0700 Subject: [PATCH] tbc: fix heal log GUID parsing and route combat through virtual dispatch Add TbcPacketParsers::parseSpellHealLog override using full uint64 GUIDs (TBC) instead of packed GUIDs (WotLK). Route handleAttackerStateUpdate, handleSpellDamageLog, and handleSpellHealLog through the virtual packetParsers_ interface so expansion-specific overrides are actually called. Previously the game handler bypassed virtual dispatch with direct static parser calls, making all three TBC overrides dead code. --- include/game/packet_parsers.hpp | 7 +++++++ src/game/game_handler.cpp | 6 +++--- src/game/packet_parsers_tbc.cpp | 24 ++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/include/game/packet_parsers.hpp b/include/game/packet_parsers.hpp index 6fb9b8ae..4dd25170 100644 --- a/include/game/packet_parsers.hpp +++ b/include/game/packet_parsers.hpp @@ -93,6 +93,11 @@ public: return SpellDamageLogParser::parse(packet, data); } + /** Parse SMSG_SPELLHEALLOG */ + virtual bool parseSpellHealLog(network::Packet& packet, SpellHealLogData& data) { + return SpellHealLogParser::parse(packet, data); + } + // --- Spells --- /** Parse SMSG_INITIAL_SPELLS */ @@ -302,6 +307,8 @@ public: bool parseAttackerStateUpdate(network::Packet& packet, AttackerStateUpdateData& data) override; // TBC 2.4.3 SMSG_SPELLNONMELEEDAMAGELOG uses full uint64 GUIDs (WotLK uses packed GUIDs) bool parseSpellDamageLog(network::Packet& packet, SpellDamageLogData& data) override; + // TBC 2.4.3 SMSG_SPELLHEALLOG uses full uint64 GUIDs (WotLK uses packed GUIDs) + bool parseSpellHealLog(network::Packet& packet, SpellHealLogData& data) override; }; /** diff --git a/src/game/game_handler.cpp b/src/game/game_handler.cpp index 7d63d4db..28e78cbf 100644 --- a/src/game/game_handler.cpp +++ b/src/game/game_handler.cpp @@ -12079,7 +12079,7 @@ void GameHandler::handleMonsterMoveTransport(network::Packet& packet) { void GameHandler::handleAttackerStateUpdate(network::Packet& packet) { AttackerStateUpdateData data; - if (!AttackerStateUpdateParser::parse(packet, data)) return; + if (!packetParsers_->parseAttackerStateUpdate(packet, data)) return; bool isPlayerAttacker = (data.attackerGuid == playerGuid); bool isPlayerTarget = (data.targetGuid == playerGuid); @@ -12141,7 +12141,7 @@ void GameHandler::handleAttackerStateUpdate(network::Packet& packet) { void GameHandler::handleSpellDamageLog(network::Packet& packet) { SpellDamageLogData data; - if (!SpellDamageLogParser::parse(packet, data)) return; + if (!packetParsers_->parseSpellDamageLog(packet, data)) return; bool isPlayerSource = (data.attackerGuid == playerGuid); bool isPlayerTarget = (data.targetGuid == playerGuid); @@ -12158,7 +12158,7 @@ void GameHandler::handleSpellDamageLog(network::Packet& packet) { void GameHandler::handleSpellHealLog(network::Packet& packet) { SpellHealLogData data; - if (!SpellHealLogParser::parse(packet, data)) return; + if (!packetParsers_->parseSpellHealLog(packet, data)) return; bool isPlayerSource = (data.casterGuid == playerGuid); bool isPlayerTarget = (data.targetGuid == playerGuid); diff --git a/src/game/packet_parsers_tbc.cpp b/src/game/packet_parsers_tbc.cpp index bef4b411..b4d803a9 100644 --- a/src/game/packet_parsers_tbc.cpp +++ b/src/game/packet_parsers_tbc.cpp @@ -1047,5 +1047,29 @@ bool TbcPacketParsers::parseSpellDamageLog(network::Packet& packet, SpellDamageL return true; } +// ============================================================================ +// TbcPacketParsers::parseSpellHealLog — TBC 2.4.3 SMSG_SPELLHEALLOG +// +// TBC uses full uint64 GUIDs; WotLK uses packed GUIDs. +// ============================================================================ +bool TbcPacketParsers::parseSpellHealLog(network::Packet& packet, SpellHealLogData& data) { + if (packet.getSize() - packet.getReadPos() < 25) return false; + + data.targetGuid = packet.readUInt64(); // full GUID in TBC + data.casterGuid = packet.readUInt64(); // full GUID in TBC + data.spellId = packet.readUInt32(); + data.heal = packet.readUInt32(); + data.overheal = packet.readUInt32(); + // TBC has no absorbed field in SMSG_SPELLHEALLOG; skip crit flag + if (packet.getReadPos() < packet.getSize()) { + uint8_t critFlag = packet.readUInt8(); + data.isCrit = (critFlag != 0); + } + + LOG_INFO("[TBC] Spell heal: spellId=", data.spellId, " heal=", data.heal, + data.isCrit ? " CRIT" : ""); + return true; +} + } // namespace game } // namespace wowee