diff --git a/include/game/packet_parsers.hpp b/include/game/packet_parsers.hpp index 4dd25170..03da989d 100644 --- a/include/game/packet_parsers.hpp +++ b/include/game/packet_parsers.hpp @@ -127,6 +127,13 @@ public: return NameQueryResponseParser::parse(packet, data); } + // --- Creature Query --- + + /** Parse SMSG_CREATURE_QUERY_RESPONSE */ + virtual bool parseCreatureQueryResponse(network::Packet& packet, CreatureQueryResponseData& data) { + return CreatureQueryResponseParser::parse(packet, data); + } + // --- Item Query --- /** Build CMSG_ITEM_QUERY_SINGLE */ @@ -339,6 +346,8 @@ public: bool parseCastFailed(network::Packet& packet, CastFailedData& data) override; bool parseMessageChat(network::Packet& packet, MessageChatData& data) override; bool parseGameObjectQueryResponse(network::Packet& packet, GameObjectQueryResponseData& data) override; + // Classic 1.12 SMSG_CREATURE_QUERY_RESPONSE lacks the iconName string that TBC/WotLK include + bool parseCreatureQueryResponse(network::Packet& packet, CreatureQueryResponseData& data) override; bool parseGossipMessage(network::Packet& packet, GossipMessageData& data) override; bool parseGuildRoster(network::Packet& packet, GuildRosterData& data) override; bool parseGuildQueryResponse(network::Packet& packet, GuildQueryResponseData& data) override; diff --git a/src/game/game_handler.cpp b/src/game/game_handler.cpp index 0e167f97..0dfe66b7 100644 --- a/src/game/game_handler.cpp +++ b/src/game/game_handler.cpp @@ -9578,7 +9578,7 @@ void GameHandler::handleNameQueryResponse(network::Packet& packet) { void GameHandler::handleCreatureQueryResponse(network::Packet& packet) { CreatureQueryResponseData data; - if (!CreatureQueryResponseParser::parse(packet, data)) return; + if (!packetParsers_->parseCreatureQueryResponse(packet, data)) return; pendingCreatureQueries.erase(data.entry); diff --git a/src/game/packet_parsers_classic.cpp b/src/game/packet_parsers_classic.cpp index 2e335af1..60a282dc 100644 --- a/src/game/packet_parsers_classic.cpp +++ b/src/game/packet_parsers_classic.cpp @@ -1309,5 +1309,42 @@ bool ClassicPacketParsers::parseQuestDetails(network::Packet& packet, QuestDetai return true; } +// ============================================================================ +// ClassicPacketParsers::parseCreatureQueryResponse +// +// Classic 1.12 SMSG_CREATURE_QUERY_RESPONSE lacks the iconName CString field +// that TBC 2.4.3 and WotLK 3.3.5a include between subName and typeFlags. +// Without this override, the TBC/WotLK parser reads typeFlags bytes as the +// iconName string, shifting typeFlags/creatureType/family/rank by 1-4 bytes. +// ============================================================================ +bool ClassicPacketParsers::parseCreatureQueryResponse(network::Packet& packet, + CreatureQueryResponseData& data) { + data.entry = packet.readUInt32(); + if (data.entry & 0x80000000) { + data.entry &= ~0x80000000; + data.name = ""; + return true; + } + + data.name = packet.readString(); + packet.readString(); // name2 + packet.readString(); // name3 + packet.readString(); // name4 + data.subName = packet.readString(); + // NOTE: NO iconName field in Classic 1.12 — goes straight to typeFlags + if (packet.getReadPos() + 16 > packet.getSize()) { + LOG_WARNING("[Classic] Creature query: truncated at typeFlags (entry=", data.entry, ")"); + return true; + } + data.typeFlags = packet.readUInt32(); + data.creatureType = packet.readUInt32(); + data.family = packet.readUInt32(); + data.rank = packet.readUInt32(); + + LOG_DEBUG("[Classic] Creature query: ", data.name, " type=", data.creatureType, + " rank=", data.rank); + return true; +} + } // namespace game } // namespace wowee