mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-25 16:30:15 +00:00
tbc: fix combat damage parsing for TBC 2.4.3
TBC 2.4.3 SMSG_ATTACKERSTATEUPDATE and SMSG_SPELLNONMELEEDAMAGELOG send full uint64 GUIDs for attacker/target, while WotLK 3.3.5a uses packed (variable-length) GUIDs. Using the WotLK reader on TBC packets consumes 1-8 bytes where a fixed 8 are expected, shifting all subsequent reads and producing completely wrong damage/absorbed/resisted values. Add TbcPacketParsers overrides that read plain uint64 GUIDs. Also note that TBC SMSG_SPELLNONMELEEDAMAGELOG lacks the WotLK overkill field.
This commit is contained in:
parent
1c967e9628
commit
b4f744d000
2 changed files with 74 additions and 0 deletions
|
|
@ -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<MailMessage>& 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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -977,5 +977,75 @@ bool TbcPacketParsers::parseMailList(network::Packet& packet, std::vector<MailMe
|
|||
return !inbox.empty();
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// TbcPacketParsers::parseAttackerStateUpdate — TBC 2.4.3 SMSG_ATTACKERSTATEUPDATE
|
||||
//
|
||||
// TBC uses full uint64 GUIDs for attacker and target.
|
||||
// WotLK uses packed (variable-length) GUIDs — using the WotLK reader here
|
||||
// would mis-parse TBC's GUIDs and corrupt all subsequent damage fields.
|
||||
// ============================================================================
|
||||
bool TbcPacketParsers::parseAttackerStateUpdate(network::Packet& packet, AttackerStateUpdateData& data) {
|
||||
if (packet.getSize() - packet.getReadPos() < 21) return false;
|
||||
|
||||
data.hitInfo = packet.readUInt32();
|
||||
data.attackerGuid = packet.readUInt64(); // full GUID in TBC
|
||||
data.targetGuid = packet.readUInt64(); // full GUID in TBC
|
||||
data.totalDamage = static_cast<int32_t>(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<int32_t>(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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue