mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-22 23:30:14 +00:00
fix: correct SMSG_SPELLLOGMISS packet format for all expansions
All expansions send spellId(4) before the caster guid — the previous handler was missing this field entirely, causing the caster guid read to consume spellId bytes and corrupt all subsequent parsing. Additionally, in WotLK mode, victim guids inside the per-miss loop are packed guids (not full uint64), matching the caster guid format. Also handle the REFLECT (missInfo=11) extra payload in WotLK: the server appends reflectSpellId(4) + reflectResult(1) for reflected spells, which previously caused the following loop entries to be mis-parsed.
This commit is contained in:
parent
d696da9227
commit
1f4880985b
1 changed files with 24 additions and 8 deletions
|
|
@ -2378,26 +2378,42 @@ void GameHandler::handlePacket(network::Packet& packet) {
|
|||
|
||||
// ---- Spell log miss ----
|
||||
case Opcode::SMSG_SPELLLOGMISS: {
|
||||
// WotLK: packed_guid caster + packed_guid target + uint8 isCrit + uint32 count
|
||||
// TBC/Classic: full uint64 caster + full uint64 target + uint8 isCrit + uint32 count
|
||||
// + count × (uint64 victimGuid + uint8 missInfo)
|
||||
// All expansions: uint32 spellId first.
|
||||
// WotLK: spellId(4) + packed_guid caster + uint8 unk + uint32 count
|
||||
// + count × (packed_guid victim + uint8 missInfo)
|
||||
// [missInfo==11(REFLECT): + uint32 reflectSpellId + uint8 reflectResult]
|
||||
// TBC/Classic: spellId(4) + uint64 caster + uint8 unk + uint32 count
|
||||
// + count × (uint64 victim + uint8 missInfo)
|
||||
const bool spellMissTbcLike = isClassicLikeExpansion() || isActiveExpansion("tbc");
|
||||
auto readSpellMissGuid = [&]() -> uint64_t {
|
||||
if (spellMissTbcLike)
|
||||
return (packet.getSize() - packet.getReadPos() >= 8) ? packet.readUInt64() : 0;
|
||||
return UpdateObjectParser::readPackedGuid(packet);
|
||||
};
|
||||
// spellId prefix present in all expansions
|
||||
if (packet.getSize() - packet.getReadPos() < 4) break;
|
||||
/*uint32_t spellId =*/ packet.readUInt32();
|
||||
if (packet.getSize() - packet.getReadPos() < (spellMissTbcLike ? 8 : 1)) break;
|
||||
uint64_t casterGuid = readSpellMissGuid();
|
||||
if (packet.getSize() - packet.getReadPos() < (spellMissTbcLike ? 8 : 1)) break;
|
||||
/*uint64_t targetGuidLog =*/ readSpellMissGuid();
|
||||
if (packet.getSize() - packet.getReadPos() < 5) break;
|
||||
/*uint8_t isCrit =*/ packet.readUInt8();
|
||||
/*uint8_t unk =*/ packet.readUInt8();
|
||||
uint32_t count = packet.readUInt32();
|
||||
count = std::min(count, 32u);
|
||||
for (uint32_t i = 0; i < count && packet.getSize() - packet.getReadPos() >= 9; ++i) {
|
||||
/*uint64_t victimGuid =*/ packet.readUInt64();
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
if (packet.getSize() - packet.getReadPos() < (spellMissTbcLike ? 9u : 2u)) break;
|
||||
/*uint64_t victimGuid =*/ readSpellMissGuid();
|
||||
if (packet.getSize() - packet.getReadPos() < 1) break;
|
||||
uint8_t missInfo = packet.readUInt8();
|
||||
// REFLECT (11): extra uint32 reflectSpellId + uint8 reflectResult
|
||||
if (missInfo == 11 && !spellMissTbcLike) {
|
||||
if (packet.getSize() - packet.getReadPos() >= 5) {
|
||||
/*uint32_t reflectSpellId =*/ packet.readUInt32();
|
||||
/*uint8_t reflectResult =*/ packet.readUInt8();
|
||||
} else {
|
||||
packet.setReadPos(packet.getSize());
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Show combat text only for local player's spell misses
|
||||
if (casterGuid == playerGuid) {
|
||||
static const CombatTextEntry::Type missTypes[] = {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue