diff --git a/include/game/packet_parsers.hpp b/include/game/packet_parsers.hpp index 4c7edb11..6fb9b8ae 100644 --- a/include/game/packet_parsers.hpp +++ b/include/game/packet_parsers.hpp @@ -298,6 +298,10 @@ public: // TBC 2.4.3 SMSG_MAIL_LIST_RESULT: uint8 count (not uint32+uint8), no body field, // attachment uses uint64 itemGuid (not uint32), enchants are 7×u32 id-only (not 7×{id+dur+charges}) bool parseMailList(network::Packet& packet, std::vector& inbox) override; + // TBC 2.4.3 SMSG_ATTACKERSTATEUPDATE uses full uint64 GUIDs (WotLK uses packed GUIDs) + 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; }; /** diff --git a/src/game/packet_parsers_tbc.cpp b/src/game/packet_parsers_tbc.cpp index 55ad50fa..bef4b411 100644 --- a/src/game/packet_parsers_tbc.cpp +++ b/src/game/packet_parsers_tbc.cpp @@ -977,5 +977,75 @@ bool TbcPacketParsers::parseMailList(network::Packet& packet, std::vector(packet.readUInt32()); + data.subDamageCount = packet.readUInt8(); + + for (uint8_t i = 0; i < data.subDamageCount; ++i) { + SubDamage sub; + sub.schoolMask = packet.readUInt32(); + sub.damage = packet.readFloat(); + sub.intDamage = packet.readUInt32(); + sub.absorbed = packet.readUInt32(); + sub.resisted = packet.readUInt32(); + data.subDamages.push_back(sub); + } + + data.victimState = packet.readUInt32(); + data.overkill = static_cast(packet.readUInt32()); + + if (packet.getReadPos() < packet.getSize()) { + data.blocked = packet.readUInt32(); + } + + LOG_INFO("[TBC] Melee hit: ", data.totalDamage, " damage", + data.isCrit() ? " (CRIT)" : "", + data.isMiss() ? " (MISS)" : ""); + return true; +} + +// ============================================================================ +// TbcPacketParsers::parseSpellDamageLog — TBC 2.4.3 SMSG_SPELLNONMELEEDAMAGELOG +// +// TBC uses full uint64 GUIDs; WotLK uses packed GUIDs. +// ============================================================================ +bool TbcPacketParsers::parseSpellDamageLog(network::Packet& packet, SpellDamageLogData& data) { + if (packet.getSize() - packet.getReadPos() < 29) return false; + + data.targetGuid = packet.readUInt64(); // full GUID in TBC + data.attackerGuid = packet.readUInt64(); // full GUID in TBC + data.spellId = packet.readUInt32(); + data.damage = packet.readUInt32(); + data.schoolMask = packet.readUInt8(); + data.absorbed = packet.readUInt32(); + data.resisted = packet.readUInt32(); + + uint8_t periodicLog = packet.readUInt8(); + (void)periodicLog; + packet.readUInt8(); // unused + packet.readUInt32(); // blocked + uint32_t flags = packet.readUInt32(); + data.isCrit = (flags & 0x02) != 0; + + // TBC does not have an overkill field here + data.overkill = 0; + + LOG_INFO("[TBC] Spell damage: spellId=", data.spellId, " dmg=", data.damage, + data.isCrit ? " CRIT" : ""); + return true; +} + } // namespace game } // namespace wowee