mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-22 23:30:14 +00:00
game: add Classic 1.12 overrides for parseSpellStart and parseSpellGo
Vanilla 1.12 SMSG_SPELL_START and SMSG_SPELL_GO use: - PackedGuid (variable-length) for caster and target GUIDs, not full uint64 - uint16 castFlags, not uint32 as in TBC/WotLK - uint16 targetFlags in SpellCastTargets, not uint32 Without these overrides Classic inherited TBC's implementations which read 8 bytes for each GUID (over-reading the PackedGuid) and then 4 bytes for castFlags instead of 2, misaligning all subsequent fields and producing garbage spell IDs, cast times, and target GUIDs. Hit and miss target GUIDs in SMSG_SPELL_GO are also PackedGuid in Vanilla (vs full uint64 in TBC), handled by the new parseSpellGo.
This commit is contained in:
parent
c011d724c6
commit
5f06c18a54
2 changed files with 95 additions and 0 deletions
|
|
@ -405,6 +405,9 @@ public:
|
|||
bool parseMonsterMove(network::Packet& packet, MonsterMoveData& data) override {
|
||||
return MonsterMoveParser::parseVanilla(packet, data);
|
||||
}
|
||||
// Classic 1.12 uses PackedGuid (not full uint64) and uint16 castFlags (not uint32)
|
||||
bool parseSpellStart(network::Packet& packet, SpellStartData& data) override;
|
||||
bool parseSpellGo(network::Packet& packet, SpellGoData& data) override;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -314,6 +314,98 @@ network::Packet ClassicPacketParsers::buildUseItem(uint8_t bagIndex, uint8_t slo
|
|||
return packet;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Classic parseSpellStart — Vanilla 1.12 SMSG_SPELL_START
|
||||
//
|
||||
// Key differences from TBC:
|
||||
// - GUIDs are PackedGuid (variable-length byte mask + non-zero bytes),
|
||||
// NOT full uint64 as in TBC/WotLK.
|
||||
// - castFlags is uint16 (NOT uint32 as in TBC/WotLK).
|
||||
// - SpellCastTargets uses uint16 targetFlags (NOT uint32 as in TBC).
|
||||
//
|
||||
// Format: PackedGuid(casterObj) + PackedGuid(casterUnit) + uint8(castCount)
|
||||
// + uint32(spellId) + uint16(castFlags) + uint32(castTime)
|
||||
// + uint16(targetFlags) [+ PackedGuid(unitTarget) if TARGET_FLAG_UNIT]
|
||||
// ============================================================================
|
||||
bool ClassicPacketParsers::parseSpellStart(network::Packet& packet, SpellStartData& data) {
|
||||
auto rem = [&]() { return packet.getSize() - packet.getReadPos(); };
|
||||
if (rem() < 2) return false;
|
||||
|
||||
data.casterGuid = UpdateObjectParser::readPackedGuid(packet);
|
||||
if (rem() < 1) return false;
|
||||
data.casterUnit = UpdateObjectParser::readPackedGuid(packet);
|
||||
|
||||
// uint8 castCount + uint32 spellId + uint16 castFlags + uint32 castTime = 11 bytes
|
||||
if (rem() < 11) return false;
|
||||
data.castCount = packet.readUInt8();
|
||||
data.spellId = packet.readUInt32();
|
||||
data.castFlags = packet.readUInt16(); // uint16 in Vanilla (uint32 in TBC/WotLK)
|
||||
data.castTime = packet.readUInt32();
|
||||
|
||||
// SpellCastTargets: uint16 targetFlags in Vanilla (uint32 in TBC/WotLK)
|
||||
if (rem() < 2) return true;
|
||||
uint16_t targetFlags = packet.readUInt16();
|
||||
// TARGET_FLAG_UNIT (0x02) or TARGET_FLAG_OBJECT (0x800) carry a packed GUID
|
||||
if (((targetFlags & 0x02) || (targetFlags & 0x800)) && rem() >= 1) {
|
||||
data.targetGuid = UpdateObjectParser::readPackedGuid(packet);
|
||||
}
|
||||
|
||||
LOG_DEBUG("[Classic] Spell start: spell=", data.spellId, " castTime=", data.castTime, "ms");
|
||||
return true;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Classic parseSpellGo — Vanilla 1.12 SMSG_SPELL_GO
|
||||
//
|
||||
// Same GUID and castFlags format differences as parseSpellStart:
|
||||
// - GUIDs are PackedGuid (not full uint64)
|
||||
// - castFlags is uint16 (not uint32)
|
||||
// - Hit/miss target GUIDs are also PackedGuid in Vanilla
|
||||
//
|
||||
// Format: PackedGuid(casterObj) + PackedGuid(casterUnit) + uint8(castCount)
|
||||
// + uint32(spellId) + uint16(castFlags)
|
||||
// + uint8(hitCount) + [PackedGuid(hitTarget) × hitCount]
|
||||
// + uint8(missCount) + [PackedGuid(missTarget) + uint8(missType)] × missCount
|
||||
// ============================================================================
|
||||
bool ClassicPacketParsers::parseSpellGo(network::Packet& packet, SpellGoData& data) {
|
||||
auto rem = [&]() { return packet.getSize() - packet.getReadPos(); };
|
||||
if (rem() < 2) return false;
|
||||
|
||||
data.casterGuid = UpdateObjectParser::readPackedGuid(packet);
|
||||
if (rem() < 1) return false;
|
||||
data.casterUnit = UpdateObjectParser::readPackedGuid(packet);
|
||||
|
||||
// uint8 castCount + uint32 spellId + uint16 castFlags = 7 bytes
|
||||
if (rem() < 7) return false;
|
||||
data.castCount = packet.readUInt8();
|
||||
data.spellId = packet.readUInt32();
|
||||
data.castFlags = packet.readUInt16(); // uint16 in Vanilla (uint32 in TBC/WotLK)
|
||||
|
||||
// Hit targets
|
||||
if (rem() < 1) return true;
|
||||
data.hitCount = packet.readUInt8();
|
||||
data.hitTargets.reserve(data.hitCount);
|
||||
for (uint8_t i = 0; i < data.hitCount && rem() >= 1; ++i) {
|
||||
data.hitTargets.push_back(UpdateObjectParser::readPackedGuid(packet));
|
||||
}
|
||||
|
||||
// Miss targets
|
||||
if (rem() < 1) return true;
|
||||
data.missCount = packet.readUInt8();
|
||||
data.missTargets.reserve(data.missCount);
|
||||
for (uint8_t i = 0; i < data.missCount && rem() >= 2; ++i) {
|
||||
SpellGoMissEntry m;
|
||||
m.targetGuid = UpdateObjectParser::readPackedGuid(packet);
|
||||
if (rem() < 1) break;
|
||||
m.missType = packet.readUInt8();
|
||||
data.missTargets.push_back(m);
|
||||
}
|
||||
|
||||
LOG_DEBUG("[Classic] Spell go: spell=", data.spellId, " hits=", (int)data.hitCount,
|
||||
" misses=", (int)data.missCount);
|
||||
return true;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Classic SMSG_CAST_FAILED: no castCount byte (added in TBC/WotLK)
|
||||
// Format: spellId(u32) + result(u8)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue