mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-22 23:30:14 +00:00
game: fix Classic 1.12 SMSG_AUCTION_LIST_RESULT enchant slot count
Classic 1.12 auction entries contain only 1 enchant slot (3 uint32s), while TBC and WotLK expanded this to 3 enchant slots (9 uint32s). Parsing Classic auction results with the WotLK parser consumed 24 extra bytes per entry (two extra enchant slots), corrupting randomPropertyId, stackCount, ownerGuid, pricing and expiry data for every auction item. - AuctionListResultParser::parse() gains a numEnchantSlots parameter (default 3) - Classic path reads 1 enchant slot; TBC/WotLK read 3 - handleAuctionListResult/OwnerList/BidderList pass isClassicLikeExpansion()?1:3
This commit is contained in:
parent
8dd4bc80ec
commit
528b796dff
3 changed files with 40 additions and 26 deletions
|
|
@ -2632,7 +2632,8 @@ public:
|
||||||
/** SMSG_AUCTION_LIST_RESULT parser (shared for browse/owner/bidder) */
|
/** SMSG_AUCTION_LIST_RESULT parser (shared for browse/owner/bidder) */
|
||||||
class AuctionListResultParser {
|
class AuctionListResultParser {
|
||||||
public:
|
public:
|
||||||
static bool parse(network::Packet& packet, AuctionListResult& data);
|
// numEnchantSlots: Classic 1.12 = 1, TBC/WotLK = 3 (extra enchant slots per entry)
|
||||||
|
static bool parse(network::Packet& packet, AuctionListResult& data, int numEnchantSlots = 3);
|
||||||
};
|
};
|
||||||
|
|
||||||
/** SMSG_AUCTION_COMMAND_RESULT parser */
|
/** SMSG_AUCTION_COMMAND_RESULT parser */
|
||||||
|
|
|
||||||
|
|
@ -17576,8 +17576,10 @@ void GameHandler::handleAuctionHello(network::Packet& packet) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameHandler::handleAuctionListResult(network::Packet& packet) {
|
void GameHandler::handleAuctionListResult(network::Packet& packet) {
|
||||||
|
// Classic 1.12 has 1 enchant slot per auction entry; TBC/WotLK have 3.
|
||||||
|
const int enchSlots = isClassicLikeExpansion() ? 1 : 3;
|
||||||
AuctionListResult result;
|
AuctionListResult result;
|
||||||
if (!AuctionListResultParser::parse(packet, result)) {
|
if (!AuctionListResultParser::parse(packet, result, enchSlots)) {
|
||||||
LOG_WARNING("Failed to parse SMSG_AUCTION_LIST_RESULT");
|
LOG_WARNING("Failed to parse SMSG_AUCTION_LIST_RESULT");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -17594,8 +17596,9 @@ void GameHandler::handleAuctionListResult(network::Packet& packet) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameHandler::handleAuctionOwnerListResult(network::Packet& packet) {
|
void GameHandler::handleAuctionOwnerListResult(network::Packet& packet) {
|
||||||
|
const int enchSlots = isClassicLikeExpansion() ? 1 : 3;
|
||||||
AuctionListResult result;
|
AuctionListResult result;
|
||||||
if (!AuctionListResultParser::parse(packet, result)) {
|
if (!AuctionListResultParser::parse(packet, result, enchSlots)) {
|
||||||
LOG_WARNING("Failed to parse SMSG_AUCTION_OWNER_LIST_RESULT");
|
LOG_WARNING("Failed to parse SMSG_AUCTION_OWNER_LIST_RESULT");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -17607,8 +17610,9 @@ void GameHandler::handleAuctionOwnerListResult(network::Packet& packet) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameHandler::handleAuctionBidderListResult(network::Packet& packet) {
|
void GameHandler::handleAuctionBidderListResult(network::Packet& packet) {
|
||||||
|
const int enchSlots = isClassicLikeExpansion() ? 1 : 3;
|
||||||
AuctionListResult result;
|
AuctionListResult result;
|
||||||
if (!AuctionListResultParser::parse(packet, result)) {
|
if (!AuctionListResultParser::parse(packet, result, enchSlots)) {
|
||||||
LOG_WARNING("Failed to parse SMSG_AUCTION_BIDDER_LIST_RESULT");
|
LOG_WARNING("Failed to parse SMSG_AUCTION_BIDDER_LIST_RESULT");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4514,45 +4514,54 @@ network::Packet AuctionListBidderItemsPacket::build(
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AuctionListResultParser::parse(network::Packet& packet, AuctionListResult& data) {
|
bool AuctionListResultParser::parse(network::Packet& packet, AuctionListResult& data, int numEnchantSlots) {
|
||||||
|
// Per-entry fixed size: auctionId(4) + itemEntry(4) + enchantSlots×3×4 +
|
||||||
|
// randProp(4) + suffix(4) + stack(4) + charges(4) + flags(4) +
|
||||||
|
// ownerGuid(8) + startBid(4) + outbid(4) + buyout(4) + expire(4) +
|
||||||
|
// bidderGuid(8) + curBid(4)
|
||||||
|
// Classic: numEnchantSlots=1 → 80 bytes/entry
|
||||||
|
// TBC/WotLK: numEnchantSlots=3 → 104 bytes/entry
|
||||||
if (packet.getSize() - packet.getReadPos() < 4) return false;
|
if (packet.getSize() - packet.getReadPos() < 4) return false;
|
||||||
|
|
||||||
uint32_t count = packet.readUInt32();
|
uint32_t count = packet.readUInt32();
|
||||||
data.auctions.clear();
|
data.auctions.clear();
|
||||||
data.auctions.reserve(count);
|
data.auctions.reserve(count);
|
||||||
|
|
||||||
|
const size_t minPerEntry = static_cast<size_t>(8 + numEnchantSlots * 12 + 28 + 8 + 8);
|
||||||
for (uint32_t i = 0; i < count; ++i) {
|
for (uint32_t i = 0; i < count; ++i) {
|
||||||
if (packet.getReadPos() + 64 > packet.getSize()) break;
|
if (packet.getReadPos() + minPerEntry > packet.getSize()) break;
|
||||||
AuctionEntry e;
|
AuctionEntry e;
|
||||||
e.auctionId = packet.readUInt32();
|
e.auctionId = packet.readUInt32();
|
||||||
e.itemEntry = packet.readUInt32();
|
e.itemEntry = packet.readUInt32();
|
||||||
// 3 enchant slots: enchantId, duration, charges
|
// First enchant slot always present
|
||||||
e.enchantId = packet.readUInt32();
|
e.enchantId = packet.readUInt32();
|
||||||
packet.readUInt32(); // enchant duration
|
packet.readUInt32(); // enchant1 duration
|
||||||
packet.readUInt32(); // enchant charges
|
packet.readUInt32(); // enchant1 charges
|
||||||
packet.readUInt32(); // enchant2 id
|
// Extra enchant slots for TBC/WotLK
|
||||||
packet.readUInt32(); // enchant2 duration
|
for (int s = 1; s < numEnchantSlots; ++s) {
|
||||||
packet.readUInt32(); // enchant2 charges
|
packet.readUInt32(); // enchant N id
|
||||||
packet.readUInt32(); // enchant3 id
|
packet.readUInt32(); // enchant N duration
|
||||||
packet.readUInt32(); // enchant3 duration
|
packet.readUInt32(); // enchant N charges
|
||||||
packet.readUInt32(); // enchant3 charges
|
}
|
||||||
e.randomPropertyId = packet.readUInt32();
|
e.randomPropertyId = packet.readUInt32();
|
||||||
e.suffixFactor = packet.readUInt32();
|
e.suffixFactor = packet.readUInt32();
|
||||||
e.stackCount = packet.readUInt32();
|
e.stackCount = packet.readUInt32();
|
||||||
packet.readUInt32(); // item charges
|
packet.readUInt32(); // item charges
|
||||||
packet.readUInt32(); // item flags (unused)
|
packet.readUInt32(); // item flags (unused)
|
||||||
e.ownerGuid = packet.readUInt64();
|
e.ownerGuid = packet.readUInt64();
|
||||||
e.startBid = packet.readUInt32();
|
e.startBid = packet.readUInt32();
|
||||||
e.minBidIncrement = packet.readUInt32();
|
e.minBidIncrement = packet.readUInt32();
|
||||||
e.buyoutPrice = packet.readUInt32();
|
e.buyoutPrice = packet.readUInt32();
|
||||||
e.timeLeftMs = packet.readUInt32();
|
e.timeLeftMs = packet.readUInt32();
|
||||||
e.bidderGuid = packet.readUInt64();
|
e.bidderGuid = packet.readUInt64();
|
||||||
e.currentBid = packet.readUInt32();
|
e.currentBid = packet.readUInt32();
|
||||||
data.auctions.push_back(e);
|
data.auctions.push_back(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
data.totalCount = packet.readUInt32();
|
if (packet.getSize() - packet.getReadPos() >= 8) {
|
||||||
data.searchDelay = packet.readUInt32();
|
data.totalCount = packet.readUInt32();
|
||||||
|
data.searchDelay = packet.readUInt32();
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue