From 5004929f0792578d01fb899638e066b5e87b7952 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Tue, 10 Mar 2026 16:50:14 -0700 Subject: [PATCH] fix: complete classic/vanilla item query parsing for itemLevel, spells, binding, description MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The classic packet parser was stopping after armor/resistances/delay without reading the remaining tail fields present in vanilla 1.12.1 item packets: - Store itemLevel and requiredLevel (were read but discarded) - Read AmmoType and RangedModRange after delay - Read 5 spell slots (SpellId, SpellTrigger, Charges, Cooldown, Category, CatCooldown) - Read Bonding type (bindType) after spells - Read Description (flavor/lore text) cstring after bonding All new fields now flow into ItemDef via rebuildOnlineInventory and display in the item tooltip (same as WotLK/TBC — binding text, spell effects, description). --- src/game/packet_parsers_classic.cpp | 30 +++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/src/game/packet_parsers_classic.cpp b/src/game/packet_parsers_classic.cpp index 33d39b77..5863c377 100644 --- a/src/game/packet_parsers_classic.cpp +++ b/src/game/packet_parsers_classic.cpp @@ -1242,8 +1242,8 @@ bool ClassicPacketParsers::parseItemQueryResponse(network::Packet& packet, ItemQ packet.readUInt32(); // AllowableClass packet.readUInt32(); // AllowableRace - packet.readUInt32(); // ItemLevel - packet.readUInt32(); // RequiredLevel + data.itemLevel = packet.readUInt32(); + data.requiredLevel = packet.readUInt32(); packet.readUInt32(); // RequiredSkill packet.readUInt32(); // RequiredSkillRank packet.readUInt32(); // RequiredSpell @@ -1302,6 +1302,32 @@ bool ClassicPacketParsers::parseItemQueryResponse(network::Packet& packet, ItemQ data.delayMs = packet.readUInt32(); } + // AmmoType + RangedModRange (2 fields, 8 bytes) + if (packet.getSize() - packet.getReadPos() >= 8) { + packet.readUInt32(); // AmmoType + packet.readFloat(); // RangedModRange + } + + // 2 item spells in Vanilla (3 fields each: SpellId, Trigger, Charges) + // Actually vanilla has 5 spells: SpellId, Trigger, Charges, Cooldown, Category, CatCooldown = 24 bytes each + for (int i = 0; i < 5; i++) { + if (packet.getReadPos() + 24 > packet.getSize()) break; + data.spells[i].spellId = packet.readUInt32(); + data.spells[i].spellTrigger = packet.readUInt32(); + packet.readUInt32(); // SpellCharges + packet.readUInt32(); // SpellCooldown + packet.readUInt32(); // SpellCategory + packet.readUInt32(); // SpellCategoryCooldown + } + + // Bonding type + if (packet.getReadPos() + 4 <= packet.getSize()) + data.bindType = packet.readUInt32(); + + // Description (flavor/lore text) + if (packet.getReadPos() < packet.getSize()) + data.description = packet.readString(); + data.valid = !data.name.empty(); LOG_DEBUG("[Classic] Item query response: ", data.name, " (quality=", data.quality, " invType=", data.inventoryType, " stack=", data.maxStack, ")");