mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-04-24 20:43:51 +00:00
fix: use expansion-aware item size in LootResponseParser for Classic/TBC
The previous per-iteration heuristic (remaining >= 22 → 22 bytes, >= 14 → 14 bytes)
incorrectly parsed Classic/TBC multi-item loots: 2+ items × 14 bytes would
trigger the 22-byte WotLK path for the first item, corrupting subsequent items.
Classic 1.12 and TBC 2.4.3 use 14 bytes/item (slot+itemId+count+displayInfo+slotType).
WotLK 3.3.5a uses 22 bytes/item (adds randomSuffix+randomPropertyId).
Add isWotlkFormat bool parameter to LootResponseParser::parse and pass
isActiveExpansion('wotlk') from handleLootResponse.
This commit is contained in:
parent
dd7d74cb93
commit
750b270502
3 changed files with 22 additions and 28 deletions
|
|
@ -2015,7 +2015,9 @@ public:
|
||||||
/** SMSG_LOOT_RESPONSE parser */
|
/** SMSG_LOOT_RESPONSE parser */
|
||||||
class LootResponseParser {
|
class LootResponseParser {
|
||||||
public:
|
public:
|
||||||
static bool parse(network::Packet& packet, LootResponseData& data);
|
// isWotlkFormat: true for WotLK 3.3.5a (22 bytes/item with randomSuffix+randomProp),
|
||||||
|
// false for Classic 1.12 and TBC 2.4.3 (14 bytes/item).
|
||||||
|
static bool parse(network::Packet& packet, LootResponseData& data, bool isWotlkFormat = true);
|
||||||
};
|
};
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
|
|
|
||||||
|
|
@ -16164,7 +16164,10 @@ void GameHandler::unstuckHearth() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameHandler::handleLootResponse(network::Packet& packet) {
|
void GameHandler::handleLootResponse(network::Packet& packet) {
|
||||||
if (!LootResponseParser::parse(packet, currentLoot)) return;
|
// Classic 1.12 and TBC 2.4.3 use 14 bytes/item (no randomSuffix/randomProp fields);
|
||||||
|
// WotLK 3.3.5a uses 22 bytes/item.
|
||||||
|
const bool wotlkLoot = isActiveExpansion("wotlk");
|
||||||
|
if (!LootResponseParser::parse(packet, currentLoot, wotlkLoot)) return;
|
||||||
lootWindowOpen = true;
|
lootWindowOpen = true;
|
||||||
localLootState_[currentLoot.lootGuid] = LocalLootState{currentLoot, false};
|
localLootState_[currentLoot.lootGuid] = LocalLootState{currentLoot, false};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3320,7 +3320,7 @@ network::Packet LootReleasePacket::build(uint64_t lootGuid) {
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LootResponseParser::parse(network::Packet& packet, LootResponseData& data) {
|
bool LootResponseParser::parse(network::Packet& packet, LootResponseData& data, bool isWotlkFormat) {
|
||||||
data = LootResponseData{};
|
data = LootResponseData{};
|
||||||
if (packet.getSize() - packet.getReadPos() < 14) {
|
if (packet.getSize() - packet.getReadPos() < 14) {
|
||||||
LOG_WARNING("LootResponseParser: packet too short");
|
LOG_WARNING("LootResponseParser: packet too short");
|
||||||
|
|
@ -3332,36 +3332,25 @@ bool LootResponseParser::parse(network::Packet& packet, LootResponseData& data)
|
||||||
data.gold = packet.readUInt32();
|
data.gold = packet.readUInt32();
|
||||||
uint8_t itemCount = packet.readUInt8();
|
uint8_t itemCount = packet.readUInt8();
|
||||||
|
|
||||||
|
// Item wire size:
|
||||||
|
// WotLK 3.3.5a: slot(1)+itemId(4)+count(4)+displayInfo(4)+randSuffix(4)+randProp(4)+slotType(1) = 22
|
||||||
|
// Classic/TBC: slot(1)+itemId(4)+count(4)+displayInfo(4)+slotType(1) = 14
|
||||||
|
const size_t kItemSize = isWotlkFormat ? 22u : 14u;
|
||||||
|
|
||||||
auto parseLootItemList = [&](uint8_t listCount, bool markQuestItems) -> bool {
|
auto parseLootItemList = [&](uint8_t listCount, bool markQuestItems) -> bool {
|
||||||
for (uint8_t i = 0; i < listCount; ++i) {
|
for (uint8_t i = 0; i < listCount; ++i) {
|
||||||
size_t remaining = packet.getSize() - packet.getReadPos();
|
size_t remaining = packet.getSize() - packet.getReadPos();
|
||||||
if (remaining < 10) {
|
if (remaining < kItemSize) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prefer the richest format when possible:
|
|
||||||
// 22-byte (WotLK/full): slot+id+count+display+randSuffix+randProp+slotType
|
|
||||||
// 14-byte (compact): slot+id+count+display+slotType
|
|
||||||
// 10-byte (minimal): slot+id+count+slotType
|
|
||||||
uint8_t bytesPerItem = 10;
|
|
||||||
if (remaining >= 22) {
|
|
||||||
bytesPerItem = 22;
|
|
||||||
} else if (remaining >= 14) {
|
|
||||||
bytesPerItem = 14;
|
|
||||||
}
|
|
||||||
|
|
||||||
LootItem item;
|
LootItem item;
|
||||||
item.slotIndex = packet.readUInt8();
|
item.slotIndex = packet.readUInt8();
|
||||||
item.itemId = packet.readUInt32();
|
item.itemId = packet.readUInt32();
|
||||||
item.count = packet.readUInt32();
|
item.count = packet.readUInt32();
|
||||||
|
|
||||||
if (bytesPerItem >= 14) {
|
|
||||||
item.displayInfoId = packet.readUInt32();
|
item.displayInfoId = packet.readUInt32();
|
||||||
} else {
|
|
||||||
item.displayInfoId = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bytesPerItem == 22) {
|
if (isWotlkFormat) {
|
||||||
item.randomSuffix = packet.readUInt32();
|
item.randomSuffix = packet.readUInt32();
|
||||||
item.randomPropertyId = packet.readUInt32();
|
item.randomPropertyId = packet.readUInt32();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue