mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-05-03 08:03:50 +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 ----
|
// ---- Spell log miss ----
|
||||||
case Opcode::SMSG_SPELLLOGMISS: {
|
case Opcode::SMSG_SPELLLOGMISS: {
|
||||||
// WotLK: packed_guid caster + packed_guid target + uint8 isCrit + uint32 count
|
// All expansions: uint32 spellId first.
|
||||||
// TBC/Classic: full uint64 caster + full uint64 target + uint8 isCrit + uint32 count
|
// WotLK: spellId(4) + packed_guid caster + uint8 unk + uint32 count
|
||||||
// + count × (uint64 victimGuid + uint8 missInfo)
|
// + 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");
|
const bool spellMissTbcLike = isClassicLikeExpansion() || isActiveExpansion("tbc");
|
||||||
auto readSpellMissGuid = [&]() -> uint64_t {
|
auto readSpellMissGuid = [&]() -> uint64_t {
|
||||||
if (spellMissTbcLike)
|
if (spellMissTbcLike)
|
||||||
return (packet.getSize() - packet.getReadPos() >= 8) ? packet.readUInt64() : 0;
|
return (packet.getSize() - packet.getReadPos() >= 8) ? packet.readUInt64() : 0;
|
||||||
return UpdateObjectParser::readPackedGuid(packet);
|
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;
|
if (packet.getSize() - packet.getReadPos() < (spellMissTbcLike ? 8 : 1)) break;
|
||||||
uint64_t casterGuid = readSpellMissGuid();
|
uint64_t casterGuid = readSpellMissGuid();
|
||||||
if (packet.getSize() - packet.getReadPos() < (spellMissTbcLike ? 8 : 1)) break;
|
|
||||||
/*uint64_t targetGuidLog =*/ readSpellMissGuid();
|
|
||||||
if (packet.getSize() - packet.getReadPos() < 5) break;
|
if (packet.getSize() - packet.getReadPos() < 5) break;
|
||||||
/*uint8_t isCrit =*/ packet.readUInt8();
|
/*uint8_t unk =*/ packet.readUInt8();
|
||||||
uint32_t count = packet.readUInt32();
|
uint32_t count = packet.readUInt32();
|
||||||
count = std::min(count, 32u);
|
count = std::min(count, 32u);
|
||||||
for (uint32_t i = 0; i < count && packet.getSize() - packet.getReadPos() >= 9; ++i) {
|
for (uint32_t i = 0; i < count; ++i) {
|
||||||
/*uint64_t victimGuid =*/ packet.readUInt64();
|
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();
|
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
|
// Show combat text only for local player's spell misses
|
||||||
if (casterGuid == playerGuid) {
|
if (casterGuid == playerGuid) {
|
||||||
static const CombatTextEntry::Type missTypes[] = {
|
static const CombatTextEntry::Type missTypes[] = {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue