mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-25 16:30:15 +00:00
tbc: fix SMSG_SPELL_START and SMSG_SPELL_GO for TBC 2.4.3
TBC 2.4.3 SMSG_SPELL_START and SMSG_SPELL_GO send full uint64 GUIDs for casterGuid/casterUnit and hit targets. WotLK uses packed (variable-length) GUIDs. Using readPackedGuid() on a full uint64 reads the first byte as the bitmask, consuming 1-8 wrong bytes, which shifts all subsequent fields (spellId, castFlags, castTime) and causes: - Cast bar to never show for the player's own spells - Sound effects to use the wrong spell ID - Hit/miss target tracking to be completely wrong Additionally, TBC SMSG_SPELL_GO lacks the WotLK timestamp field after castFlags. Add TbcPacketParsers::parseSpellStart and ::parseSpellGo using full GUIDs, add virtual base methods, and route both handlers through virtual dispatch.
This commit is contained in:
parent
921c83df2e
commit
0a6f88e8ad
3 changed files with 83 additions and 2 deletions
|
|
@ -105,6 +105,16 @@ public:
|
|||
return InitialSpellsParser::parse(packet, data);
|
||||
}
|
||||
|
||||
/** Parse SMSG_SPELL_START */
|
||||
virtual bool parseSpellStart(network::Packet& packet, SpellStartData& data) {
|
||||
return SpellStartParser::parse(packet, data);
|
||||
}
|
||||
|
||||
/** Parse SMSG_SPELL_GO */
|
||||
virtual bool parseSpellGo(network::Packet& packet, SpellGoData& data) {
|
||||
return SpellGoParser::parse(packet, data);
|
||||
}
|
||||
|
||||
/** Parse SMSG_CAST_FAILED */
|
||||
virtual bool parseCastFailed(network::Packet& packet, CastFailedData& data) {
|
||||
return CastFailedParser::parse(packet, data);
|
||||
|
|
@ -322,6 +332,10 @@ public:
|
|||
bool parseGossipMessage(network::Packet& packet, GossipMessageData& data) override;
|
||||
// TBC 2.4.3 SMSG_CAST_RESULT: spellId(u32) + result(u8) — WotLK added castCount(u8) prefix
|
||||
bool parseCastResult(network::Packet& packet, uint32_t& spellId, uint8_t& result) override;
|
||||
// TBC 2.4.3 SMSG_SPELL_START: full uint64 GUIDs (WotLK uses packed GUIDs)
|
||||
bool parseSpellStart(network::Packet& packet, SpellStartData& data) override;
|
||||
// TBC 2.4.3 SMSG_SPELL_GO: full uint64 GUIDs, no timestamp field (WotLK added one)
|
||||
bool parseSpellGo(network::Packet& packet, SpellGoData& data) override;
|
||||
// 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;
|
||||
|
|
|
|||
|
|
@ -12410,7 +12410,7 @@ static audio::SpellSoundManager::MagicSchool schoolMaskToMagicSchool(uint32_t ma
|
|||
|
||||
void GameHandler::handleSpellStart(network::Packet& packet) {
|
||||
SpellStartData data;
|
||||
if (!SpellStartParser::parse(packet, data)) return;
|
||||
if (!packetParsers_->parseSpellStart(packet, data)) return;
|
||||
|
||||
// If this is the player's own cast, start cast bar
|
||||
if (data.casterUnit == playerGuid && data.castTime > 0) {
|
||||
|
|
@ -12435,7 +12435,7 @@ void GameHandler::handleSpellStart(network::Packet& packet) {
|
|||
|
||||
void GameHandler::handleSpellGo(network::Packet& packet) {
|
||||
SpellGoData data;
|
||||
if (!SpellGoParser::parse(packet, data)) return;
|
||||
if (!packetParsers_->parseSpellGo(packet, data)) return;
|
||||
|
||||
// Cast completed
|
||||
if (data.casterUnit == playerGuid) {
|
||||
|
|
|
|||
|
|
@ -977,6 +977,73 @@ bool TbcPacketParsers::parseMailList(network::Packet& packet, std::vector<MailMe
|
|||
return !inbox.empty();
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// TbcPacketParsers::parseSpellStart — TBC 2.4.3 SMSG_SPELL_START
|
||||
//
|
||||
// TBC uses full uint64 GUIDs for casterGuid and casterUnit.
|
||||
// WotLK uses packed (variable-length) GUIDs.
|
||||
// TBC also lacks the castCount byte — format:
|
||||
// casterGuid(u64) + casterUnit(u64) + castCount(u8) + spellId(u32) + castFlags(u32) + castTime(u32)
|
||||
// Wait: TBC DOES have castCount. But WotLK removed spellId in some paths.
|
||||
// Correct TBC format (cmangos-tbc): objectGuid(u64) + casterGuid(u64) + castCount(u8) + spellId(u32) + castFlags(u32) + castTime(u32)
|
||||
// ============================================================================
|
||||
bool TbcPacketParsers::parseSpellStart(network::Packet& packet, SpellStartData& data) {
|
||||
if (packet.getSize() - packet.getReadPos() < 22) return false;
|
||||
|
||||
data.casterGuid = packet.readUInt64(); // full GUID (object)
|
||||
data.casterUnit = packet.readUInt64(); // full GUID (caster unit)
|
||||
data.castCount = packet.readUInt8();
|
||||
data.spellId = packet.readUInt32();
|
||||
data.castFlags = packet.readUInt32();
|
||||
data.castTime = packet.readUInt32();
|
||||
|
||||
if (packet.getReadPos() + 4 <= packet.getSize()) {
|
||||
uint32_t targetFlags = packet.readUInt32();
|
||||
if ((targetFlags & 0x02) && packet.getReadPos() + 8 <= packet.getSize()) {
|
||||
data.targetGuid = packet.readUInt64(); // full GUID in TBC
|
||||
}
|
||||
}
|
||||
|
||||
LOG_DEBUG("[TBC] Spell start: spell=", data.spellId, " castTime=", data.castTime, "ms");
|
||||
return true;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// TbcPacketParsers::parseSpellGo — TBC 2.4.3 SMSG_SPELL_GO
|
||||
//
|
||||
// TBC uses full uint64 GUIDs, no timestamp field after castFlags.
|
||||
// WotLK uses packed GUIDs and adds a timestamp (u32) after castFlags.
|
||||
// ============================================================================
|
||||
bool TbcPacketParsers::parseSpellGo(network::Packet& packet, SpellGoData& data) {
|
||||
if (packet.getSize() - packet.getReadPos() < 19) return false;
|
||||
|
||||
data.casterGuid = packet.readUInt64(); // full GUID in TBC
|
||||
data.casterUnit = packet.readUInt64(); // full GUID in TBC
|
||||
data.castCount = packet.readUInt8();
|
||||
data.spellId = packet.readUInt32();
|
||||
data.castFlags = packet.readUInt32();
|
||||
// NOTE: NO timestamp field here in TBC (WotLK added packet.readUInt32())
|
||||
|
||||
if (packet.getReadPos() >= packet.getSize()) {
|
||||
LOG_DEBUG("[TBC] Spell go: spell=", data.spellId, " (no hit data)");
|
||||
return true;
|
||||
}
|
||||
|
||||
data.hitCount = packet.readUInt8();
|
||||
data.hitTargets.reserve(data.hitCount);
|
||||
for (uint8_t i = 0; i < data.hitCount && packet.getReadPos() + 8 <= packet.getSize(); ++i) {
|
||||
data.hitTargets.push_back(packet.readUInt64()); // full GUID in TBC
|
||||
}
|
||||
|
||||
if (packet.getReadPos() < packet.getSize()) {
|
||||
data.missCount = packet.readUInt8();
|
||||
}
|
||||
|
||||
LOG_DEBUG("[TBC] Spell go: spell=", data.spellId, " hits=", (int)data.hitCount,
|
||||
" misses=", (int)data.missCount);
|
||||
return true;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// TbcPacketParsers::parseCastResult — TBC 2.4.3 SMSG_CAST_RESULT
|
||||
//
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue