diff --git a/include/game/packet_parsers.hpp b/include/game/packet_parsers.hpp index 9fb0f166..40655045 100644 --- a/include/game/packet_parsers.hpp +++ b/include/game/packet_parsers.hpp @@ -419,6 +419,10 @@ public: bool parseMonsterMove(network::Packet& packet, MonsterMoveData& data) override { return MonsterMoveParser::parseVanilla(packet, data); } + // Classic 1.12 SMSG_INITIAL_SPELLS: uint16 spellId + uint16 slot per entry (not uint32 + uint16) + bool parseInitialSpells(network::Packet& packet, InitialSpellsData& data) override { + return InitialSpellsParser::parse(packet, data, /*vanillaFormat=*/true); + } // 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; diff --git a/include/game/world_packets.hpp b/include/game/world_packets.hpp index 539d3b8a..6e5721fd 100644 --- a/include/game/world_packets.hpp +++ b/include/game/world_packets.hpp @@ -1758,7 +1758,10 @@ struct InitialSpellsData { class InitialSpellsParser { public: - static bool parse(network::Packet& packet, InitialSpellsData& data); + // vanillaFormat=true: Classic 1.12 uint16 spellId + uint16 slot (4 bytes/spell) + // vanillaFormat=false: TBC/WotLK uint32 spellId + uint16 unk (6 bytes/spell) + static bool parse(network::Packet& packet, InitialSpellsData& data, + bool vanillaFormat = false); }; /** CMSG_CAST_SPELL packet builder */ diff --git a/src/game/world_packets.cpp b/src/game/world_packets.cpp index 8c7c5ec9..b7d8075b 100644 --- a/src/game/world_packets.cpp +++ b/src/game/world_packets.cpp @@ -2901,18 +2901,13 @@ bool XpGainParser::parse(network::Packet& packet, XpGainData& data) { // Phase 3: Spells, Action Bar, Auras // ============================================================ -bool InitialSpellsParser::parse(network::Packet& packet, InitialSpellsData& data) { - size_t packetSize = packet.getSize(); +bool InitialSpellsParser::parse(network::Packet& packet, InitialSpellsData& data, + bool vanillaFormat) { data.talentSpec = packet.readUInt8(); uint16_t spellCount = packet.readUInt16(); - // Detect vanilla (uint16 spellId) vs WotLK (uint32 spellId) format - // Vanilla: 4 bytes/spell (uint16 id + uint16 slot), WotLK: 6 bytes/spell (uint32 id + uint16 unk) - size_t remainingAfterHeader = packetSize - 3; // subtract talentSpec(1) + spellCount(2) - bool vanillaFormat = remainingAfterHeader < static_cast(spellCount) * 6 + 2; - - LOG_DEBUG("SMSG_INITIAL_SPELLS: packetSize=", packetSize, " bytes, spellCount=", spellCount, - vanillaFormat ? " (vanilla uint16 format)" : " (WotLK uint32 format)"); + LOG_DEBUG("SMSG_INITIAL_SPELLS: spellCount=", spellCount, + vanillaFormat ? " (vanilla uint16 format)" : " (TBC/WotLK uint32 format)"); data.spellIds.reserve(spellCount); for (uint16_t i = 0; i < spellCount; ++i) {