mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-04-14 08:23:52 +00:00
fix: migrate 197 unsafe packet bounds checks to hasRemaining/getRemainingSize
All domain handler files used 'packet.getSize() - packet.getReadPos()'
which underflows to ~2^64 when readPos exceeds size (documented in
commit ed63b029). The game_handler.cpp and packet_parsers were migrated
to hasRemaining(N) in an earlier cleanup, but the domain handlers were
created after that migration by the PR #23 split, copying the old
unsafe patterns back in. Now uses hasRemaining(N) for comparisons and
getRemainingSize() for assignments across all 7 handler files.
This commit is contained in:
parent
849542d01d
commit
294c91d84a
7 changed files with 197 additions and 197 deletions
|
|
@ -27,7 +27,7 @@ void ChatHandler::registerOpcodes(DispatchTable& table) {
|
|||
};
|
||||
table[Opcode::SMSG_EMOTE] = [this](network::Packet& packet) {
|
||||
if (owner_.getState() != WorldState::IN_WORLD) return;
|
||||
if (packet.getSize() - packet.getReadPos() < 12) return;
|
||||
if (!packet.hasRemaining(12)) return;
|
||||
uint32_t emoteAnim = packet.readUInt32();
|
||||
uint64_t sourceGuid = packet.readUInt64();
|
||||
if (owner_.emoteAnimCallback_ && sourceGuid != 0)
|
||||
|
|
|
|||
|
|
@ -33,9 +33,9 @@ void CombatHandler::registerOpcodes(DispatchTable& table) {
|
|||
if (owner_.addonEventCallback_) owner_.addonEventCallback_("UNIT_THREAT_LIST_UPDATE", {});
|
||||
};
|
||||
table[Opcode::SMSG_THREAT_REMOVE] = [this](network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() < 1) return;
|
||||
if (!packet.hasRemaining(1)) return;
|
||||
uint64_t unitGuid = packet.readPackedGuid();
|
||||
if (packet.getSize() - packet.getReadPos() < 1) return;
|
||||
if (!packet.hasRemaining(1)) return;
|
||||
uint64_t victimGuid = packet.readPackedGuid();
|
||||
auto it = threatLists_.find(unitGuid);
|
||||
if (it != threatLists_.end()) {
|
||||
|
|
@ -92,7 +92,7 @@ void CombatHandler::registerOpcodes(DispatchTable& table) {
|
|||
};
|
||||
table[Opcode::SMSG_ATTACKERSTATEUPDATE] = [this](network::Packet& packet) { handleAttackerStateUpdate(packet); };
|
||||
table[Opcode::SMSG_AI_REACTION] = [this](network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() < 12) return;
|
||||
if (!packet.hasRemaining(12)) return;
|
||||
uint64_t guid = packet.readUInt64();
|
||||
uint32_t reaction = packet.readUInt32();
|
||||
if (reaction == 2 && owner_.npcAggroCallback_) {
|
||||
|
|
@ -108,7 +108,7 @@ void CombatHandler::registerOpcodes(DispatchTable& table) {
|
|||
table[Opcode::SMSG_ENVIRONMENTAL_DAMAGE_LOG] = [this](network::Packet& packet) {
|
||||
// uint64 victimGuid + uint8 envDmgType + uint32 damage + uint32 absorbed + uint32 resisted
|
||||
// envDmgType: 0=Exhausted(fatigue), 1=Drowning, 2=Fall, 3=Lava, 4=Slime, 5=Fire
|
||||
if (packet.getSize() - packet.getReadPos() < 21) { packet.setReadPos(packet.getSize()); return; }
|
||||
if (!packet.hasRemaining(21)) { packet.setReadPos(packet.getSize()); return; }
|
||||
uint64_t victimGuid = packet.readUInt64();
|
||||
uint8_t envType = packet.readUInt8();
|
||||
uint32_t dmg = packet.readUInt32();
|
||||
|
|
@ -133,20 +133,20 @@ void CombatHandler::registerOpcodes(DispatchTable& table) {
|
|||
// Both packets share the same format:
|
||||
// packed_guid (unit) + packed_guid (highest-threat target or target, unused here)
|
||||
// + uint32 count + count × (packed_guid victim + uint32 threat)
|
||||
if (packet.getSize() - packet.getReadPos() < 1) return;
|
||||
if (!packet.hasRemaining(1)) return;
|
||||
uint64_t unitGuid = packet.readPackedGuid();
|
||||
if (packet.getSize() - packet.getReadPos() < 1) return;
|
||||
if (!packet.hasRemaining(1)) return;
|
||||
(void)packet.readPackedGuid(); // highest-threat / current target
|
||||
if (packet.getSize() - packet.getReadPos() < 4) return;
|
||||
if (!packet.hasRemaining(4)) return;
|
||||
uint32_t cnt = packet.readUInt32();
|
||||
if (cnt > 100) { packet.setReadPos(packet.getSize()); return; } // sanity
|
||||
std::vector<ThreatEntry> list;
|
||||
list.reserve(cnt);
|
||||
for (uint32_t i = 0; i < cnt; ++i) {
|
||||
if (packet.getSize() - packet.getReadPos() < 1) return;
|
||||
if (!packet.hasRemaining(1)) return;
|
||||
ThreatEntry entry;
|
||||
entry.victimGuid = packet.readPackedGuid();
|
||||
if (packet.getSize() - packet.getReadPos() < 4) return;
|
||||
if (!packet.hasRemaining(4)) return;
|
||||
entry.threat = packet.readUInt32();
|
||||
list.push_back(entry);
|
||||
}
|
||||
|
|
@ -558,7 +558,7 @@ void CombatHandler::handleSpellHealLog(network::Packet& packet) {
|
|||
}
|
||||
|
||||
void CombatHandler::handleSetForcedReactions(network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() < 4) return;
|
||||
if (!packet.hasRemaining(4)) return;
|
||||
uint32_t count = packet.readUInt32();
|
||||
if (count > 64) {
|
||||
LOG_WARNING("SMSG_SET_FORCED_REACTIONS: suspicious count ", count, ", ignoring");
|
||||
|
|
@ -567,7 +567,7 @@ void CombatHandler::handleSetForcedReactions(network::Packet& packet) {
|
|||
}
|
||||
forcedReactions_.clear();
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
if (packet.getSize() - packet.getReadPos() < 8) break;
|
||||
if (!packet.hasRemaining(8)) break;
|
||||
uint32_t factionId = packet.readUInt32();
|
||||
uint32_t reaction = packet.readUInt32();
|
||||
forcedReactions_[factionId] = static_cast<uint8_t>(reaction);
|
||||
|
|
|
|||
|
|
@ -40,20 +40,20 @@ void InventoryHandler::registerOpcodes(DispatchTable& table) {
|
|||
table[Opcode::SMSG_LOOT_ROLL_WON] = [this](network::Packet& packet) { handleLootRollWon(packet); };
|
||||
table[Opcode::SMSG_LOOT_MASTER_LIST] = [this](network::Packet& packet) {
|
||||
masterLootCandidates_.clear();
|
||||
if (packet.getSize() - packet.getReadPos() < 1) return;
|
||||
if (!packet.hasRemaining(1)) return;
|
||||
uint8_t mlCount = packet.readUInt8();
|
||||
masterLootCandidates_.reserve(mlCount);
|
||||
for (uint8_t i = 0; i < mlCount; ++i) {
|
||||
if (packet.getSize() - packet.getReadPos() < 8) break;
|
||||
if (!packet.hasRemaining(8)) break;
|
||||
masterLootCandidates_.push_back(packet.readUInt64());
|
||||
}
|
||||
};
|
||||
|
||||
// ---- Loot money / misc consume ----
|
||||
table[Opcode::SMSG_LOOT_MONEY_NOTIFY] = [this](network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() < 4) return;
|
||||
if (!packet.hasRemaining(4)) return;
|
||||
uint32_t amount = packet.readUInt32();
|
||||
if (packet.getSize() - packet.getReadPos() >= 1)
|
||||
if (packet.hasRemaining(1))
|
||||
/*uint8_t soleLooter =*/ packet.readUInt8();
|
||||
owner_.playerMoneyCopper_ += amount;
|
||||
owner_.pendingMoneyDelta_ = amount;
|
||||
|
|
@ -103,7 +103,7 @@ void InventoryHandler::registerOpcodes(DispatchTable& table) {
|
|||
// randProp(4) + countdown(4) + voteMask(1)
|
||||
const bool hasMapId = isActiveExpansion("wotlk");
|
||||
const size_t minSz = hasMapId ? 33 : 29;
|
||||
if (packet.getSize() - packet.getReadPos() < minSz) return;
|
||||
if (packet.getRemainingSize() < minSz) return;
|
||||
uint64_t objectGuid = packet.readUInt64();
|
||||
if (hasMapId) packet.readUInt32(); // mapId
|
||||
uint32_t lootSlot = packet.readUInt32();
|
||||
|
|
@ -137,7 +137,7 @@ void InventoryHandler::registerOpcodes(DispatchTable& table) {
|
|||
|
||||
table[Opcode::SMSG_LOOT_ALL_PASSED] = [this](network::Packet& packet) {
|
||||
// objectGuid(8) + lootSlot(4) + itemId(4) + randSuffix(4) + randProp(4)
|
||||
if (packet.getSize() - packet.getReadPos() < 24) return;
|
||||
if (!packet.hasRemaining(24)) return;
|
||||
/*uint64_t objectGuid =*/ packet.readUInt64();
|
||||
/*uint32_t lootSlot =*/ packet.readUInt32();
|
||||
uint32_t itemId = packet.readUInt32();
|
||||
|
|
@ -154,13 +154,13 @@ void InventoryHandler::registerOpcodes(DispatchTable& table) {
|
|||
|
||||
table[Opcode::SMSG_LOOT_ITEM_NOTIFY] = [this](network::Packet& packet) {
|
||||
// objectGuid(8) + lootSlot(1) [Classic: uint32; WotLK: uint8]
|
||||
if (packet.getSize() - packet.getReadPos() < 9) return;
|
||||
if (!packet.hasRemaining(9)) return;
|
||||
/*uint64_t objectGuid =*/ packet.readUInt64();
|
||||
uint32_t lootSlot;
|
||||
if (isActiveExpansion("wotlk")) {
|
||||
lootSlot = packet.readUInt8();
|
||||
} else {
|
||||
if (packet.getSize() - packet.getReadPos() < 4) return;
|
||||
if (!packet.hasRemaining(4)) return;
|
||||
lootSlot = packet.readUInt32();
|
||||
}
|
||||
// Try to resolve item name
|
||||
|
|
@ -182,7 +182,7 @@ void InventoryHandler::registerOpcodes(DispatchTable& table) {
|
|||
};
|
||||
|
||||
table[Opcode::SMSG_LOOT_SLOT_CHANGED] = [this](network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() >= 1) {
|
||||
if (packet.hasRemaining(1)) {
|
||||
uint8_t slotIdx = packet.readUInt8();
|
||||
LOG_DEBUG("SMSG_LOOT_SLOT_CHANGED: slot=", (int)slotIdx);
|
||||
// The server re-sends loot info for this slot; we can refresh from
|
||||
|
|
@ -194,7 +194,7 @@ void InventoryHandler::registerOpcodes(DispatchTable& table) {
|
|||
table[Opcode::SMSG_ITEM_PUSH_RESULT] = [this](network::Packet& packet) {
|
||||
// WotLK 3.3.5a: guid(8)+received(4)+created(4)+displayInChat(4)+bagSlot(1)
|
||||
// +slot(4)+itemId(4)+suffixFactor(4)+randomPropertyId(4)+count(4)+countInInventory(4)
|
||||
if (packet.getSize() - packet.getReadPos() < 45) return;
|
||||
if (!packet.hasRemaining(45)) return;
|
||||
uint64_t guid = packet.readUInt64();
|
||||
if (guid != owner_.playerGuid) { packet.setReadPos(packet.getSize()); return; }
|
||||
/*uint32_t received =*/ packet.readUInt32();
|
||||
|
|
@ -238,7 +238,7 @@ void InventoryHandler::registerOpcodes(DispatchTable& table) {
|
|||
|
||||
// ---- Open container ----
|
||||
table[Opcode::SMSG_OPEN_CONTAINER] = [this](network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() >= 8) {
|
||||
if (packet.hasRemaining(8)) {
|
||||
uint64_t containerGuid = packet.readUInt64();
|
||||
LOG_DEBUG("SMSG_OPEN_CONTAINER: guid=0x", std::hex, containerGuid, std::dec);
|
||||
}
|
||||
|
|
@ -246,7 +246,7 @@ void InventoryHandler::registerOpcodes(DispatchTable& table) {
|
|||
|
||||
// ---- Sell / Buy / Inventory ----
|
||||
table[Opcode::SMSG_SELL_ITEM] = [this](network::Packet& packet) {
|
||||
if ((packet.getSize() - packet.getReadPos()) >= 17) {
|
||||
if ((packet.getRemainingSize()) >= 17) {
|
||||
uint64_t vendorGuid = packet.readUInt64();
|
||||
uint64_t itemGuid = packet.readUInt64();
|
||||
uint8_t result = packet.readUInt8();
|
||||
|
|
@ -307,16 +307,16 @@ void InventoryHandler::registerOpcodes(DispatchTable& table) {
|
|||
};
|
||||
|
||||
table[Opcode::SMSG_INVENTORY_CHANGE_FAILURE] = [this](network::Packet& packet) {
|
||||
if ((packet.getSize() - packet.getReadPos()) >= 1) {
|
||||
if ((packet.getRemainingSize()) >= 1) {
|
||||
uint8_t error = packet.readUInt8();
|
||||
if (error != 0) {
|
||||
LOG_WARNING("SMSG_INVENTORY_CHANGE_FAILURE: error=", (int)error);
|
||||
uint32_t requiredLevel = 0;
|
||||
if (packet.getSize() - packet.getReadPos() >= 17) {
|
||||
if (packet.hasRemaining(17)) {
|
||||
packet.readUInt64();
|
||||
packet.readUInt64();
|
||||
packet.readUInt8();
|
||||
if (error == 1 && packet.getSize() - packet.getReadPos() >= 4)
|
||||
if (error == 1 && packet.hasRemaining(4))
|
||||
requiredLevel = packet.readUInt32();
|
||||
}
|
||||
const char* errMsg = nullptr;
|
||||
|
|
@ -403,7 +403,7 @@ void InventoryHandler::registerOpcodes(DispatchTable& table) {
|
|||
};
|
||||
|
||||
table[Opcode::SMSG_BUY_FAILED] = [this](network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() >= 13) {
|
||||
if (packet.hasRemaining(13)) {
|
||||
uint64_t vendorGuid = packet.readUInt64();
|
||||
uint32_t itemIdOrSlot = packet.readUInt32();
|
||||
uint8_t errCode = packet.readUInt8();
|
||||
|
|
@ -460,7 +460,7 @@ void InventoryHandler::registerOpcodes(DispatchTable& table) {
|
|||
};
|
||||
|
||||
table[Opcode::SMSG_BUY_ITEM] = [this](network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() >= 20) {
|
||||
if (packet.hasRemaining(20)) {
|
||||
/*uint64_t vendorGuid =*/ packet.readUInt64();
|
||||
/*uint32_t vendorSlot =*/ packet.readUInt32();
|
||||
/*int32_t newCount =*/ static_cast<int32_t>(packet.readUInt32());
|
||||
|
|
@ -516,13 +516,13 @@ void InventoryHandler::registerOpcodes(DispatchTable& table) {
|
|||
table[Opcode::SMSG_AUCTION_COMMAND_RESULT] = [this](network::Packet& packet) { handleAuctionCommandResult(packet); };
|
||||
|
||||
table[Opcode::SMSG_AUCTION_OWNER_NOTIFICATION] = [this](network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() >= 16) {
|
||||
if (packet.hasRemaining(16)) {
|
||||
/*uint32_t auctionId =*/ packet.readUInt32();
|
||||
uint32_t action = packet.readUInt32();
|
||||
/*uint32_t error =*/ packet.readUInt32();
|
||||
uint32_t itemEntry = packet.readUInt32();
|
||||
int32_t ownerRandProp = 0;
|
||||
if (packet.getSize() - packet.getReadPos() >= 4)
|
||||
if (packet.hasRemaining(4))
|
||||
ownerRandProp = static_cast<int32_t>(packet.readUInt32());
|
||||
owner_.ensureItemInfo(itemEntry);
|
||||
auto* info = owner_.getItemInfo(itemEntry);
|
||||
|
|
@ -569,7 +569,7 @@ void InventoryHandler::registerOpcodes(DispatchTable& table) {
|
|||
};
|
||||
|
||||
table[Opcode::SMSG_AUCTION_REMOVED_NOTIFICATION] = [this](network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() >= 12) {
|
||||
if (packet.hasRemaining(12)) {
|
||||
/*uint32_t auctionId =*/ packet.readUInt32();
|
||||
uint32_t itemEntry = packet.readUInt32();
|
||||
int32_t itemRandom = static_cast<int32_t>(packet.readUInt32());
|
||||
|
|
@ -591,7 +591,7 @@ void InventoryHandler::registerOpcodes(DispatchTable& table) {
|
|||
table[Opcode::SMSG_EQUIPMENT_SET_LIST] = [this](network::Packet& packet) { handleEquipmentSetList(packet); };
|
||||
table[Opcode::SMSG_EQUIPMENT_SET_SAVED] = [this](network::Packet& packet) {
|
||||
std::string setName;
|
||||
if (packet.getSize() - packet.getReadPos() >= 12) {
|
||||
if (packet.hasRemaining(12)) {
|
||||
uint32_t setIndex = packet.readUInt32();
|
||||
uint64_t setGuid = packet.readUInt64();
|
||||
bool found = false;
|
||||
|
|
@ -637,7 +637,7 @@ void InventoryHandler::registerOpcodes(DispatchTable& table) {
|
|||
};
|
||||
|
||||
table[Opcode::SMSG_EQUIPMENT_SET_USE_RESULT] = [this](network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() >= 1) {
|
||||
if (packet.hasRemaining(1)) {
|
||||
uint8_t result = packet.readUInt8();
|
||||
if (result != 0) { owner_.addUIError("Failed to equip item set."); owner_.addSystemChatMessage("Failed to equip item set."); }
|
||||
}
|
||||
|
|
@ -796,7 +796,7 @@ void InventoryHandler::sendLootRoll(uint64_t objectGuid, uint32_t slot, uint8_t
|
|||
void InventoryHandler::handleLootRoll(network::Packet& packet) {
|
||||
// objectGuid(8) + lootSlot(4) + playerGuid(8) + itemId(4) + itemRandSuffix(4) +
|
||||
// itemRandProp(4) + rollNumber(1) + rollType(1) + autoPass(1)
|
||||
if (packet.getSize() - packet.getReadPos() < 35) return;
|
||||
if (!packet.hasRemaining(35)) return;
|
||||
uint64_t objectGuid = packet.readUInt64();
|
||||
uint32_t lootSlot = packet.readUInt32();
|
||||
uint64_t playerGuid = packet.readUInt64();
|
||||
|
|
@ -836,7 +836,7 @@ void InventoryHandler::handleLootRoll(network::Packet& packet) {
|
|||
|
||||
void InventoryHandler::handleLootRollWon(network::Packet& packet) {
|
||||
// objectGuid(8) + lootSlot(4) + itemId(4) + itemSuffix(4) + itemProp(4) + playerGuid(8) + rollNumber(1) + rollType(1)
|
||||
if (packet.getSize() - packet.getReadPos() < 34) return;
|
||||
if (!packet.hasRemaining(34)) return;
|
||||
/*uint64_t objectGuid =*/ packet.readUInt64();
|
||||
/*uint32_t lootSlot =*/ packet.readUInt32();
|
||||
uint32_t itemId = packet.readUInt32();
|
||||
|
|
@ -1610,7 +1610,7 @@ void InventoryHandler::mailMarkAsRead(uint32_t mailId) {
|
|||
}
|
||||
|
||||
void InventoryHandler::handleShowMailbox(network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() < 8) return;
|
||||
if (!packet.hasRemaining(8)) return;
|
||||
mailboxGuid_ = packet.readUInt64();
|
||||
mailboxOpen_ = true;
|
||||
selectedMailIndex_ = -1;
|
||||
|
|
@ -1629,7 +1629,7 @@ void InventoryHandler::handleMailListResult(network::Packet& packet) {
|
|||
}
|
||||
|
||||
void InventoryHandler::handleSendMailResult(network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() < 12) return;
|
||||
if (!packet.hasRemaining(12)) return;
|
||||
uint32_t mailId = packet.readUInt32();
|
||||
uint32_t action = packet.readUInt32();
|
||||
uint32_t error = packet.readUInt32();
|
||||
|
|
@ -1735,13 +1735,13 @@ void InventoryHandler::withdrawItem(uint8_t srcBag, uint8_t srcSlot) {
|
|||
}
|
||||
|
||||
void InventoryHandler::handleShowBank(network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() < 8) return;
|
||||
if (!packet.hasRemaining(8)) return;
|
||||
uint64_t guid = packet.readUInt64();
|
||||
openBank(guid);
|
||||
}
|
||||
|
||||
void InventoryHandler::handleBuyBankSlotResult(network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() < 4) return;
|
||||
if (!packet.hasRemaining(4)) return;
|
||||
uint32_t result = packet.readUInt32();
|
||||
if (result == 0) {
|
||||
owner_.addSystemChatMessage("Bank slot purchased.");
|
||||
|
|
@ -1887,7 +1887,7 @@ void InventoryHandler::auctionListBidderItems(uint32_t offset) {
|
|||
}
|
||||
|
||||
void InventoryHandler::handleAuctionHello(network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() < 12) return;
|
||||
if (!packet.hasRemaining(12)) return;
|
||||
uint64_t guid = packet.readUInt64();
|
||||
uint32_t houseId = packet.readUInt32();
|
||||
auctioneerGuid_ = guid;
|
||||
|
|
@ -1935,7 +1935,7 @@ void InventoryHandler::handleAuctionBidderListResult(network::Packet& packet) {
|
|||
}
|
||||
|
||||
void InventoryHandler::handleAuctionCommandResult(network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() < 12) return;
|
||||
if (!packet.hasRemaining(12)) return;
|
||||
uint32_t auctionId = packet.readUInt32();
|
||||
uint32_t action = packet.readUInt32();
|
||||
uint32_t error = packet.readUInt32();
|
||||
|
|
@ -1986,7 +1986,7 @@ void InventoryHandler::queryItemText(uint64_t itemGuid) {
|
|||
}
|
||||
|
||||
void InventoryHandler::handleItemTextQueryResponse(network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() < 1) return;
|
||||
if (!packet.hasRemaining(1)) return;
|
||||
std::string text = packet.readString();
|
||||
if (!text.empty()) {
|
||||
itemText_ = std::move(text);
|
||||
|
|
@ -2061,7 +2061,7 @@ void InventoryHandler::resetTradeState() {
|
|||
}
|
||||
|
||||
void InventoryHandler::handleTradeStatus(network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() < 4) return;
|
||||
if (!packet.hasRemaining(4)) return;
|
||||
uint32_t status = packet.readUInt32();
|
||||
LOG_WARNING("SMSG_TRADE_STATUS: status=", status, " size=", packet.getSize());
|
||||
switch (status) {
|
||||
|
|
@ -2070,7 +2070,7 @@ void InventoryHandler::handleTradeStatus(network::Packet& packet) {
|
|||
owner_.addSystemChatMessage("Trade failed: player is busy.");
|
||||
break;
|
||||
case 1: { // TRADE_STATUS_PROPOSED
|
||||
if (packet.getSize() - packet.getReadPos() >= 8)
|
||||
if (packet.hasRemaining(8))
|
||||
tradePeerGuid_ = packet.readUInt64();
|
||||
tradeStatus_ = TradeStatus::PendingIncoming;
|
||||
// Resolve name
|
||||
|
|
@ -2140,7 +2140,7 @@ void InventoryHandler::handleTradeStatusExtended(network::Packet& packet) {
|
|||
" readPos=", packet.getReadPos());
|
||||
// WotLK format: whichPlayer(4) + tradeCount(4) + N items × (slot(1)+64bytes) + gold(4)
|
||||
// Total for empty trade: 8 + 8×65 + 4 = 532 (matches observed packet size)
|
||||
if (packet.getSize() - packet.getReadPos() < 8) return;
|
||||
if (!packet.hasRemaining(8)) return;
|
||||
uint32_t whichPlayer = packet.readUInt32(); // 0=self, 1=peer (uint32 not uint8!)
|
||||
uint32_t tradeCount = packet.readUInt32();
|
||||
auto& slots = (whichPlayer == 0) ? myTradeSlots_ : peerTradeSlots_;
|
||||
|
|
@ -2148,12 +2148,12 @@ void InventoryHandler::handleTradeStatusExtended(network::Packet& packet) {
|
|||
LOG_WARNING(" whichPlayer=", whichPlayer, " tradeCount=", tradeCount);
|
||||
|
||||
for (uint32_t i = 0; i < tradeCount; ++i) {
|
||||
if (packet.getSize() - packet.getReadPos() < 1) break;
|
||||
if (!packet.hasRemaining(1)) break;
|
||||
uint8_t slotNum = packet.readUInt8();
|
||||
// Per-slot: 4(item)+4(display)+4(stack)+4(wrapped)+8(creator)
|
||||
// +4(enchant)+3×4(gems)+4(maxDur)+4(dur)+4(spellCharges)
|
||||
// +4(suffixFactor)+4(randomPropId)+4(lockId) = 64 bytes
|
||||
if (packet.getSize() - packet.getReadPos() < 64) { packet.setReadPos(packet.getSize()); return; }
|
||||
if (!packet.hasRemaining(64)) { packet.setReadPos(packet.getSize()); return; }
|
||||
uint32_t itemId = packet.readUInt32();
|
||||
uint32_t displayId = packet.readUInt32();
|
||||
uint32_t stackCnt = packet.readUInt32();
|
||||
|
|
@ -2177,7 +2177,7 @@ void InventoryHandler::handleTradeStatusExtended(network::Packet& packet) {
|
|||
}
|
||||
|
||||
// Gold
|
||||
if (packet.getSize() - packet.getReadPos() >= 4) {
|
||||
if (packet.hasRemaining(4)) {
|
||||
uint32_t gold = packet.readUInt32();
|
||||
if (whichPlayer == 0) myTradeGold_ = gold;
|
||||
else peerTradeGold_ = gold;
|
||||
|
|
@ -2287,7 +2287,7 @@ void InventoryHandler::deleteEquipmentSet(uint64_t setGuid) {
|
|||
}
|
||||
|
||||
void InventoryHandler::handleEquipmentSetList(network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() < 4) return;
|
||||
if (!packet.hasRemaining(4)) return;
|
||||
uint32_t count = packet.readUInt32();
|
||||
if (count > 10) {
|
||||
LOG_WARNING("SMSG_EQUIPMENT_SET_LIST: unexpected count ", count, ", ignoring");
|
||||
|
|
@ -2297,7 +2297,7 @@ void InventoryHandler::handleEquipmentSetList(network::Packet& packet) {
|
|||
equipmentSets_.clear();
|
||||
equipmentSets_.reserve(count);
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
if (packet.getSize() - packet.getReadPos() < 16) break;
|
||||
if (!packet.hasRemaining(16)) break;
|
||||
EquipmentSet es;
|
||||
es.setGuid = packet.readUInt64();
|
||||
es.setId = packet.readUInt32();
|
||||
|
|
@ -2305,7 +2305,7 @@ void InventoryHandler::handleEquipmentSetList(network::Packet& packet) {
|
|||
es.iconName = packet.readString();
|
||||
es.ignoreSlotMask = packet.readUInt32();
|
||||
for (int slot = 0; slot < 19; ++slot) {
|
||||
if (packet.getSize() - packet.getReadPos() < 8) break;
|
||||
if (!packet.hasRemaining(8)) break;
|
||||
es.itemGuids[slot] = packet.readUInt64();
|
||||
}
|
||||
equipmentSets_.push_back(std::move(es));
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ void MovementHandler::registerOpcodes(DispatchTable& table) {
|
|||
Opcode::SMSG_SPLINE_MOVE_ROOT,
|
||||
Opcode::SMSG_SPLINE_MOVE_SET_HOVER }) {
|
||||
table[op] = [this](network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() >= 1)
|
||||
if (packet.hasRemaining(1))
|
||||
(void)packet.readPackedGuid();
|
||||
};
|
||||
}
|
||||
|
|
@ -49,7 +49,7 @@ void MovementHandler::registerOpcodes(DispatchTable& table) {
|
|||
{
|
||||
auto makeSynthHandler = [this](uint32_t synthFlags) {
|
||||
return [this, synthFlags](network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() < 1) return;
|
||||
if (!packet.hasRemaining(1)) return;
|
||||
uint64_t guid = packet.readPackedGuid();
|
||||
if (guid == 0 || guid == owner_.playerGuid || !owner_.unitMoveFlagsCallback_) return;
|
||||
owner_.unitMoveFlagsCallback_(guid, synthFlags);
|
||||
|
|
@ -809,7 +809,7 @@ void MovementHandler::handleForceSpeedChange(network::Packet& packet, const char
|
|||
? packet.readUInt64() : packet.readPackedGuid();
|
||||
uint32_t counter = packet.readUInt32();
|
||||
|
||||
size_t remaining = packet.getSize() - packet.getReadPos();
|
||||
size_t remaining = packet.getRemainingSize();
|
||||
if (remaining >= 8) {
|
||||
packet.readUInt32();
|
||||
} else if (remaining >= 5) {
|
||||
|
|
@ -853,10 +853,10 @@ void MovementHandler::handleForceRunSpeedChange(network::Packet& packet) {
|
|||
|
||||
void MovementHandler::handleForceMoveRootState(network::Packet& packet, bool rooted) {
|
||||
const bool rootTbc = isClassicLikeExpansion() || isActiveExpansion("tbc");
|
||||
if (packet.getSize() - packet.getReadPos() < (rootTbc ? 8u : 2u)) return;
|
||||
if (packet.getRemainingSize() < (rootTbc ? 8u : 2u)) return;
|
||||
uint64_t guid = rootTbc
|
||||
? packet.readUInt64() : packet.readPackedGuid();
|
||||
if (packet.getSize() - packet.getReadPos() < 4) return;
|
||||
if (!packet.hasRemaining(4)) return;
|
||||
uint32_t counter = packet.readUInt32();
|
||||
|
||||
LOG_INFO(rooted ? "SMSG_FORCE_MOVE_ROOT" : "SMSG_FORCE_MOVE_UNROOT",
|
||||
|
|
@ -879,10 +879,10 @@ void MovementHandler::handleForceMoveRootState(network::Packet& packet, bool roo
|
|||
void MovementHandler::handleForceMoveFlagChange(network::Packet& packet, const char* name,
|
||||
Opcode ackOpcode, uint32_t flag, bool set) {
|
||||
const bool fmfTbcLike = isClassicLikeExpansion() || isActiveExpansion("tbc");
|
||||
if (packet.getSize() - packet.getReadPos() < (fmfTbcLike ? 8u : 2u)) return;
|
||||
if (packet.getRemainingSize() < (fmfTbcLike ? 8u : 2u)) return;
|
||||
uint64_t guid = fmfTbcLike
|
||||
? packet.readUInt64() : packet.readPackedGuid();
|
||||
if (packet.getSize() - packet.getReadPos() < 4) return;
|
||||
if (!packet.hasRemaining(4)) return;
|
||||
uint32_t counter = packet.readUInt32();
|
||||
|
||||
LOG_INFO("SMSG_FORCE_", name, ": guid=0x", std::hex, guid, std::dec, " counter=", counter);
|
||||
|
|
@ -904,9 +904,9 @@ void MovementHandler::handleForceMoveFlagChange(network::Packet& packet, const c
|
|||
|
||||
void MovementHandler::handleMoveSetCollisionHeight(network::Packet& packet) {
|
||||
const bool legacyGuid = isClassicLikeExpansion() || isActiveExpansion("tbc");
|
||||
if (packet.getSize() - packet.getReadPos() < (legacyGuid ? 8u : 2u)) return;
|
||||
if (packet.getRemainingSize() < (legacyGuid ? 8u : 2u)) return;
|
||||
uint64_t guid = legacyGuid ? packet.readUInt64() : packet.readPackedGuid();
|
||||
if (packet.getSize() - packet.getReadPos() < 8) return;
|
||||
if (!packet.hasRemaining(8)) return;
|
||||
uint32_t counter = packet.readUInt32();
|
||||
float height = packet.readFloat();
|
||||
|
||||
|
|
@ -926,10 +926,10 @@ void MovementHandler::handleMoveSetCollisionHeight(network::Packet& packet) {
|
|||
|
||||
void MovementHandler::handleMoveKnockBack(network::Packet& packet) {
|
||||
const bool mkbTbc = isClassicLikeExpansion() || isActiveExpansion("tbc");
|
||||
if (packet.getSize() - packet.getReadPos() < (mkbTbc ? 8u : 2u)) return;
|
||||
if (packet.getRemainingSize() < (mkbTbc ? 8u : 2u)) return;
|
||||
uint64_t guid = mkbTbc
|
||||
? packet.readUInt64() : packet.readPackedGuid();
|
||||
if (packet.getSize() - packet.getReadPos() < 20) return;
|
||||
if (!packet.hasRemaining(20)) return;
|
||||
uint32_t counter = packet.readUInt32();
|
||||
float vcos = packet.readFloat();
|
||||
float vsin = packet.readFloat();
|
||||
|
|
@ -960,7 +960,7 @@ void MovementHandler::handleMoveSetSpeed(network::Packet& packet) {
|
|||
uint64_t moverGuid = useFull
|
||||
? packet.readUInt64() : packet.readPackedGuid();
|
||||
|
||||
const size_t remaining = packet.getSize() - packet.getReadPos();
|
||||
const size_t remaining = packet.getRemainingSize();
|
||||
if (remaining < 4) return;
|
||||
if (remaining > 4) {
|
||||
packet.setReadPos(packet.getSize() - 4);
|
||||
|
|
@ -1466,7 +1466,7 @@ void MovementHandler::handleMonsterMove(network::Packet& packet) {
|
|||
}
|
||||
|
||||
void MovementHandler::handleMonsterMoveTransport(network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() < 8 + 1 + 8 + 12) return;
|
||||
if (packet.getRemainingSize() < 8 + 1 + 8 + 12) return;
|
||||
uint64_t moverGuid = packet.readUInt64();
|
||||
/*uint8_t unk =*/ packet.readUInt8();
|
||||
uint64_t transportGuid = packet.readUInt64();
|
||||
|
|
@ -1618,19 +1618,19 @@ void MovementHandler::handleMonsterMoveTransport(network::Packet& packet) {
|
|||
|
||||
void MovementHandler::handleTeleportAck(network::Packet& packet) {
|
||||
const bool taTbc = isClassicLikeExpansion() || isActiveExpansion("tbc");
|
||||
if (packet.getSize() - packet.getReadPos() < (taTbc ? 8u : 4u)) {
|
||||
if (packet.getRemainingSize() < (taTbc ? 8u : 4u)) {
|
||||
LOG_WARNING("MSG_MOVE_TELEPORT_ACK too short");
|
||||
return;
|
||||
}
|
||||
|
||||
uint64_t guid = taTbc
|
||||
? packet.readUInt64() : packet.readPackedGuid();
|
||||
if (packet.getSize() - packet.getReadPos() < 4) return;
|
||||
if (!packet.hasRemaining(4)) return;
|
||||
uint32_t counter = packet.readUInt32();
|
||||
|
||||
const bool taNoFlags2 = isClassicLikeExpansion() || isActiveExpansion("tbc");
|
||||
const size_t minMoveSz = taNoFlags2 ? (4 + 4 + 4 * 4) : (4 + 2 + 4 + 4 * 4);
|
||||
if (packet.getSize() - packet.getReadPos() < minMoveSz) {
|
||||
if (packet.getRemainingSize() < minMoveSz) {
|
||||
LOG_WARNING("MSG_MOVE_TELEPORT_ACK: not enough data for movement info");
|
||||
return;
|
||||
}
|
||||
|
|
@ -1679,7 +1679,7 @@ void MovementHandler::handleTeleportAck(network::Packet& packet) {
|
|||
}
|
||||
|
||||
void MovementHandler::handleNewWorld(network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() < 20) {
|
||||
if (!packet.hasRemaining(20)) {
|
||||
LOG_WARNING("SMSG_NEW_WORLD too short");
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -299,7 +299,7 @@ void QuestHandler::registerOpcodes(DispatchTable& table) {
|
|||
|
||||
// ---- SMSG_GOSSIP_POI ----
|
||||
table[Opcode::SMSG_GOSSIP_POI] = [this](network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() < 20) return;
|
||||
if (!packet.hasRemaining(20)) return;
|
||||
/*uint32_t flags =*/ packet.readUInt32();
|
||||
float poiX = packet.readFloat();
|
||||
float poiY = packet.readFloat();
|
||||
|
|
@ -335,7 +335,7 @@ void QuestHandler::registerOpcodes(DispatchTable& table) {
|
|||
|
||||
// ---- SMSG_QUESTGIVER_STATUS ----
|
||||
table[Opcode::SMSG_QUESTGIVER_STATUS] = [this](network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() >= 9) {
|
||||
if (packet.hasRemaining(9)) {
|
||||
uint64_t npcGuid = packet.readUInt64();
|
||||
uint8_t status = owner_.packetParsers_->readQuestGiverStatus(packet);
|
||||
npcQuestStatus_[npcGuid] = static_cast<QuestGiverStatus>(status);
|
||||
|
|
@ -344,10 +344,10 @@ void QuestHandler::registerOpcodes(DispatchTable& table) {
|
|||
|
||||
// ---- SMSG_QUESTGIVER_STATUS_MULTIPLE ----
|
||||
table[Opcode::SMSG_QUESTGIVER_STATUS_MULTIPLE] = [this](network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() < 4) return;
|
||||
if (!packet.hasRemaining(4)) return;
|
||||
uint32_t count = packet.readUInt32();
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
if (packet.getSize() - packet.getReadPos() < 9) break;
|
||||
if (!packet.hasRemaining(9)) break;
|
||||
uint64_t npcGuid = packet.readUInt64();
|
||||
uint8_t status = owner_.packetParsers_->readQuestGiverStatus(packet);
|
||||
npcQuestStatus_[npcGuid] = static_cast<QuestGiverStatus>(status);
|
||||
|
|
@ -356,7 +356,7 @@ void QuestHandler::registerOpcodes(DispatchTable& table) {
|
|||
|
||||
// ---- SMSG_QUESTUPDATE_FAILED ----
|
||||
table[Opcode::SMSG_QUESTUPDATE_FAILED] = [this](network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() >= 4) {
|
||||
if (packet.hasRemaining(4)) {
|
||||
uint32_t questId = packet.readUInt32();
|
||||
std::string questTitle;
|
||||
for (const auto& q : questLog_)
|
||||
|
|
@ -368,7 +368,7 @@ void QuestHandler::registerOpcodes(DispatchTable& table) {
|
|||
|
||||
// ---- SMSG_QUESTUPDATE_FAILEDTIMER ----
|
||||
table[Opcode::SMSG_QUESTUPDATE_FAILEDTIMER] = [this](network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() >= 4) {
|
||||
if (packet.hasRemaining(4)) {
|
||||
uint32_t questId = packet.readUInt32();
|
||||
std::string questTitle;
|
||||
for (const auto& q : questLog_)
|
||||
|
|
@ -381,7 +381,7 @@ void QuestHandler::registerOpcodes(DispatchTable& table) {
|
|||
// ---- SMSG_QUESTGIVER_QUEST_FAILED ----
|
||||
table[Opcode::SMSG_QUESTGIVER_QUEST_FAILED] = [this](network::Packet& packet) {
|
||||
// uint32 questId + uint32 reason
|
||||
if (packet.getSize() - packet.getReadPos() >= 8) {
|
||||
if (packet.hasRemaining(8)) {
|
||||
uint32_t questId = packet.readUInt32();
|
||||
uint32_t reason = packet.readUInt32();
|
||||
std::string questTitle;
|
||||
|
|
@ -407,7 +407,7 @@ void QuestHandler::registerOpcodes(DispatchTable& table) {
|
|||
|
||||
// ---- SMSG_QUESTGIVER_QUEST_INVALID ----
|
||||
table[Opcode::SMSG_QUESTGIVER_QUEST_INVALID] = [this](network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() >= 4) {
|
||||
if (packet.hasRemaining(4)) {
|
||||
uint32_t failReason = packet.readUInt32();
|
||||
pendingTurnInRewardRequest_ = false;
|
||||
const char* reasonStr = "Unknown";
|
||||
|
|
@ -454,7 +454,7 @@ void QuestHandler::registerOpcodes(DispatchTable& table) {
|
|||
|
||||
// ---- SMSG_QUESTGIVER_QUEST_COMPLETE ----
|
||||
table[Opcode::SMSG_QUESTGIVER_QUEST_COMPLETE] = [this](network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() >= 4) {
|
||||
if (packet.hasRemaining(4)) {
|
||||
uint32_t questId = packet.readUInt32();
|
||||
LOG_INFO("Quest completed: questId=", questId);
|
||||
if (pendingTurnInQuestId_ == questId) {
|
||||
|
|
@ -501,14 +501,14 @@ void QuestHandler::registerOpcodes(DispatchTable& table) {
|
|||
|
||||
// ---- SMSG_QUESTUPDATE_ADD_KILL ----
|
||||
table[Opcode::SMSG_QUESTUPDATE_ADD_KILL] = [this](network::Packet& packet) {
|
||||
size_t rem = packet.getSize() - packet.getReadPos();
|
||||
size_t rem = packet.getRemainingSize();
|
||||
if (rem >= 12) {
|
||||
uint32_t questId = packet.readUInt32();
|
||||
clearPendingQuestAccept(questId);
|
||||
uint32_t entry = packet.readUInt32();
|
||||
uint32_t count = packet.readUInt32();
|
||||
uint32_t reqCount = 0;
|
||||
if (packet.getSize() - packet.getReadPos() >= 4) {
|
||||
if (packet.hasRemaining(4)) {
|
||||
reqCount = packet.readUInt32();
|
||||
}
|
||||
|
||||
|
|
@ -575,7 +575,7 @@ void QuestHandler::registerOpcodes(DispatchTable& table) {
|
|||
|
||||
// ---- SMSG_QUESTUPDATE_ADD_ITEM ----
|
||||
table[Opcode::SMSG_QUESTUPDATE_ADD_ITEM] = [this](network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() >= 8) {
|
||||
if (packet.hasRemaining(8)) {
|
||||
uint32_t itemId = packet.readUInt32();
|
||||
uint32_t count = packet.readUInt32();
|
||||
owner_.queryItemInfo(itemId, 0);
|
||||
|
|
@ -640,14 +640,14 @@ void QuestHandler::registerOpcodes(DispatchTable& table) {
|
|||
|
||||
// ---- SMSG_QUESTUPDATE_COMPLETE ----
|
||||
table[Opcode::SMSG_QUESTUPDATE_COMPLETE] = [this](network::Packet& packet) {
|
||||
size_t rem = packet.getSize() - packet.getReadPos();
|
||||
size_t rem = packet.getRemainingSize();
|
||||
if (rem >= 12) {
|
||||
uint32_t questId = packet.readUInt32();
|
||||
clearPendingQuestAccept(questId);
|
||||
uint32_t entry = packet.readUInt32();
|
||||
uint32_t count = packet.readUInt32();
|
||||
uint32_t reqCount = 0;
|
||||
if (packet.getSize() - packet.getReadPos() >= 4) reqCount = packet.readUInt32();
|
||||
if (packet.hasRemaining(4)) reqCount = packet.readUInt32();
|
||||
if (reqCount == 0) reqCount = count;
|
||||
LOG_INFO("Quest kill update (compat via COMPLETE): questId=", questId,
|
||||
" entry=", entry, " count=", count, "/", reqCount);
|
||||
|
|
@ -677,7 +677,7 @@ void QuestHandler::registerOpcodes(DispatchTable& table) {
|
|||
|
||||
// ---- SMSG_QUEST_FORCE_REMOVE ----
|
||||
table[Opcode::SMSG_QUEST_FORCE_REMOVE] = [this](network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() < 4) {
|
||||
if (!packet.hasRemaining(4)) {
|
||||
LOG_WARNING("SMSG_QUEST_FORCE_REMOVE/SET_REST_START too short");
|
||||
return;
|
||||
}
|
||||
|
|
@ -832,12 +832,12 @@ void QuestHandler::registerOpcodes(DispatchTable& table) {
|
|||
|
||||
// ---- SMSG_QUESTUPDATE_ADD_PVP_KILL ----
|
||||
table[Opcode::SMSG_QUESTUPDATE_ADD_PVP_KILL] = [this](network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() >= 16) {
|
||||
if (packet.hasRemaining(16)) {
|
||||
/*uint64_t guid =*/ packet.readUInt64();
|
||||
uint32_t questId = packet.readUInt32();
|
||||
uint32_t count = packet.readUInt32();
|
||||
uint32_t reqCount = 0;
|
||||
if (packet.getSize() - packet.getReadPos() >= 4) {
|
||||
if (packet.hasRemaining(4)) {
|
||||
reqCount = packet.readUInt32();
|
||||
}
|
||||
|
||||
|
|
@ -1515,7 +1515,7 @@ void QuestHandler::handleGossipMessage(network::Packet& packet) {
|
|||
}
|
||||
|
||||
void QuestHandler::handleQuestgiverQuestList(network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() < 8) return;
|
||||
if (!packet.hasRemaining(8)) return;
|
||||
|
||||
GossipMessageData data;
|
||||
data.npcGuid = packet.readUInt64();
|
||||
|
|
@ -1523,7 +1523,7 @@ void QuestHandler::handleQuestgiverQuestList(network::Packet& packet) {
|
|||
data.titleTextId = 0;
|
||||
|
||||
std::string header = packet.readString();
|
||||
if (packet.getSize() - packet.getReadPos() >= 8) {
|
||||
if (packet.hasRemaining(8)) {
|
||||
(void)packet.readUInt32(); // emoteDelay / unk
|
||||
(void)packet.readUInt32(); // emote / unk
|
||||
}
|
||||
|
|
@ -1531,7 +1531,7 @@ void QuestHandler::handleQuestgiverQuestList(network::Packet& packet) {
|
|||
|
||||
// questCount is uint8 in all WoW versions for SMSG_QUESTGIVER_QUEST_LIST.
|
||||
uint32_t questCount = 0;
|
||||
if (packet.getSize() - packet.getReadPos() >= 1) {
|
||||
if (packet.hasRemaining(1)) {
|
||||
questCount = packet.readUInt8();
|
||||
}
|
||||
|
||||
|
|
@ -1539,13 +1539,13 @@ void QuestHandler::handleQuestgiverQuestList(network::Packet& packet) {
|
|||
|
||||
data.quests.reserve(questCount);
|
||||
for (uint32_t i = 0; i < questCount; ++i) {
|
||||
if (packet.getSize() - packet.getReadPos() < 12) break;
|
||||
if (!packet.hasRemaining(12)) break;
|
||||
GossipQuestItem q;
|
||||
q.questId = packet.readUInt32();
|
||||
q.questIcon = packet.readUInt32();
|
||||
q.questLevel = static_cast<int32_t>(packet.readUInt32());
|
||||
|
||||
if (hasQuestFlagsField && packet.getSize() - packet.getReadPos() >= 5) {
|
||||
if (hasQuestFlagsField && packet.hasRemaining(5)) {
|
||||
q.questFlags = packet.readUInt32();
|
||||
q.isRepeatable = packet.readUInt8();
|
||||
} else {
|
||||
|
|
@ -1643,10 +1643,10 @@ void QuestHandler::handleQuestPoiQueryResponse(network::Packet& packet) {
|
|||
// uint32 unk2
|
||||
// uint32 pointCount
|
||||
// per point: int32 x, int32 y
|
||||
if (packet.getSize() - packet.getReadPos() < 4) return;
|
||||
if (!packet.hasRemaining(4)) return;
|
||||
const uint32_t questCount = packet.readUInt32();
|
||||
for (uint32_t qi = 0; qi < questCount; ++qi) {
|
||||
if (packet.getSize() - packet.getReadPos() < 8) return;
|
||||
if (!packet.hasRemaining(8)) return;
|
||||
const uint32_t questId = packet.readUInt32();
|
||||
const uint32_t poiCount = packet.readUInt32();
|
||||
|
||||
|
|
@ -1665,7 +1665,7 @@ void QuestHandler::handleQuestPoiQueryResponse(network::Packet& packet) {
|
|||
}
|
||||
|
||||
for (uint32_t pi = 0; pi < poiCount; ++pi) {
|
||||
if (packet.getSize() - packet.getReadPos() < 28) return;
|
||||
if (!packet.hasRemaining(28)) return;
|
||||
packet.readUInt32(); // poiId
|
||||
packet.readUInt32(); // objIndex (int32)
|
||||
const uint32_t mapId = packet.readUInt32();
|
||||
|
|
@ -1675,7 +1675,7 @@ void QuestHandler::handleQuestPoiQueryResponse(network::Packet& packet) {
|
|||
packet.readUInt32(); // unk2
|
||||
const uint32_t pointCount = packet.readUInt32();
|
||||
if (pointCount == 0) continue;
|
||||
if (packet.getSize() - packet.getReadPos() < pointCount * 8) return;
|
||||
if (packet.getRemainingSize() < pointCount * 8) return;
|
||||
float sumX = 0.0f, sumY = 0.0f;
|
||||
for (uint32_t pt = 0; pt < pointCount; ++pt) {
|
||||
const int32_t px = static_cast<int32_t>(packet.readUInt32());
|
||||
|
|
@ -1816,12 +1816,12 @@ void QuestHandler::handleQuestOfferReward(network::Packet& packet) {
|
|||
}
|
||||
|
||||
void QuestHandler::handleQuestConfirmAccept(network::Packet& packet) {
|
||||
size_t rem = packet.getSize() - packet.getReadPos();
|
||||
size_t rem = packet.getRemainingSize();
|
||||
if (rem < 4) return;
|
||||
|
||||
sharedQuestId_ = packet.readUInt32();
|
||||
sharedQuestTitle_ = packet.readString();
|
||||
if (packet.getSize() - packet.getReadPos() >= 8) {
|
||||
if (packet.hasRemaining(8)) {
|
||||
sharedQuestSharerGuid_ = packet.readUInt64();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ void SocialHandler::registerOpcodes(DispatchTable& table) {
|
|||
readyCheckNotReadyCount_ = 0;
|
||||
readyCheckInitiator_.clear();
|
||||
readyCheckResults_.clear();
|
||||
if (packet.getSize() - packet.getReadPos() >= 8) {
|
||||
if (packet.hasRemaining(8)) {
|
||||
uint64_t initiatorGuid = packet.readUInt64();
|
||||
auto entity = owner_.getEntityManager().getEntity(initiatorGuid);
|
||||
if (auto* unit = dynamic_cast<Unit*>(entity.get()))
|
||||
|
|
@ -170,7 +170,7 @@ void SocialHandler::registerOpcodes(DispatchTable& table) {
|
|||
owner_.addonEventCallback_("READY_CHECK", {readyCheckInitiator_});
|
||||
};
|
||||
table[Opcode::MSG_RAID_READY_CHECK_CONFIRM] = [this](network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() < 9) { packet.setReadPos(packet.getSize()); return; }
|
||||
if (!packet.hasRemaining(9)) { packet.setReadPos(packet.getSize()); return; }
|
||||
uint64_t respGuid = packet.readUInt64();
|
||||
uint8_t isReady = packet.readUInt8();
|
||||
if (isReady) ++readyCheckReadyCount_; else ++readyCheckNotReadyCount_;
|
||||
|
|
@ -223,14 +223,14 @@ void SocialHandler::registerOpcodes(DispatchTable& table) {
|
|||
};
|
||||
table[Opcode::SMSG_DUEL_INBOUNDS] = [this](network::Packet& /*packet*/) {};
|
||||
table[Opcode::SMSG_DUEL_COUNTDOWN] = [this](network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() >= 4) {
|
||||
if (packet.hasRemaining(4)) {
|
||||
uint32_t ms = packet.readUInt32();
|
||||
duelCountdownMs_ = (ms > 0 && ms <= 30000) ? ms : 3000;
|
||||
duelCountdownStartedAt_ = std::chrono::steady_clock::now();
|
||||
}
|
||||
};
|
||||
table[Opcode::SMSG_PARTYKILLLOG] = [this](network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() < 16) return;
|
||||
if (!packet.hasRemaining(16)) return;
|
||||
uint64_t killerGuid = packet.readUInt64();
|
||||
uint64_t victimGuid = packet.readUInt64();
|
||||
auto nameFor = [this](uint64_t g) -> std::string {
|
||||
|
|
@ -261,7 +261,7 @@ void SocialHandler::registerOpcodes(DispatchTable& table) {
|
|||
table[Opcode::SMSG_PETITION_SHOWLIST] = [this](network::Packet& packet) { handlePetitionShowlist(packet); };
|
||||
table[Opcode::SMSG_TURN_IN_PETITION_RESULTS] = [this](network::Packet& packet) { handleTurnInPetitionResults(packet); };
|
||||
table[Opcode::SMSG_OFFER_PETITION_ERROR] = [this](network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() >= 4) {
|
||||
if (packet.hasRemaining(4)) {
|
||||
uint32_t err = packet.readUInt32();
|
||||
if (err == 1) owner_.addSystemChatMessage("Player is already in a guild.");
|
||||
else if (err == 2) owner_.addSystemChatMessage("Player already has a petition.");
|
||||
|
|
@ -282,9 +282,9 @@ void SocialHandler::registerOpcodes(DispatchTable& table) {
|
|||
table[Opcode::MSG_BATTLEGROUND_PLAYER_POSITIONS] = [this](network::Packet& packet) {
|
||||
bgPlayerPositions_.clear();
|
||||
for (int grp = 0; grp < 2; ++grp) {
|
||||
if (packet.getSize() - packet.getReadPos() < 4) break;
|
||||
if (!packet.hasRemaining(4)) break;
|
||||
uint32_t count = packet.readUInt32();
|
||||
for (uint32_t i = 0; i < count && packet.getSize() - packet.getReadPos() >= 16; ++i) {
|
||||
for (uint32_t i = 0; i < count && packet.getRemainingSize() >= 16; ++i) {
|
||||
BgPlayerPosition pos;
|
||||
pos.guid = packet.readUInt64();
|
||||
pos.wowX = packet.readFloat();
|
||||
|
|
@ -304,7 +304,7 @@ void SocialHandler::registerOpcodes(DispatchTable& table) {
|
|||
owner_.addSystemChatMessage("You have joined the battleground queue.");
|
||||
};
|
||||
table[Opcode::SMSG_BATTLEGROUND_PLAYER_JOINED] = [this](network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() >= 8) {
|
||||
if (packet.hasRemaining(8)) {
|
||||
uint64_t guid = packet.readUInt64();
|
||||
auto it = owner_.getPlayerNameCache().find(guid);
|
||||
if (it != owner_.getPlayerNameCache().end() && !it->second.empty())
|
||||
|
|
@ -312,7 +312,7 @@ void SocialHandler::registerOpcodes(DispatchTable& table) {
|
|||
}
|
||||
};
|
||||
table[Opcode::SMSG_BATTLEGROUND_PLAYER_LEFT] = [this](network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() >= 8) {
|
||||
if (packet.hasRemaining(8)) {
|
||||
uint64_t guid = packet.readUInt64();
|
||||
auto it = owner_.getPlayerNameCache().find(guid);
|
||||
if (it != owner_.getPlayerNameCache().end() && !it->second.empty())
|
||||
|
|
@ -369,13 +369,13 @@ void SocialHandler::registerOpcodes(DispatchTable& table) {
|
|||
owner_.addSystemChatMessage("You are now saved to this instance.");
|
||||
};
|
||||
table[Opcode::SMSG_RAID_INSTANCE_MESSAGE] = [this](network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() < 12) return;
|
||||
if (!packet.hasRemaining(12)) return;
|
||||
uint32_t msgType = packet.readUInt32();
|
||||
uint32_t mapId = packet.readUInt32();
|
||||
packet.readUInt32(); // diff
|
||||
std::string mapLabel = owner_.getMapName(mapId);
|
||||
if (mapLabel.empty()) mapLabel = "instance #" + std::to_string(mapId);
|
||||
if (msgType == 1 && packet.getSize() - packet.getReadPos() >= 4) {
|
||||
if (msgType == 1 && packet.hasRemaining(4)) {
|
||||
uint32_t timeLeft = packet.readUInt32();
|
||||
owner_.addSystemChatMessage(mapLabel + " will reset in " + std::to_string(timeLeft / 60) + " minute(s).");
|
||||
} else if (msgType == 2) {
|
||||
|
|
@ -385,7 +385,7 @@ void SocialHandler::registerOpcodes(DispatchTable& table) {
|
|||
}
|
||||
};
|
||||
table[Opcode::SMSG_INSTANCE_RESET] = [this](network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() < 4) return;
|
||||
if (!packet.hasRemaining(4)) return;
|
||||
uint32_t mapId = packet.readUInt32();
|
||||
auto it = std::remove_if(instanceLockouts_.begin(), instanceLockouts_.end(),
|
||||
[mapId](const InstanceLockout& lo){ return lo.mapId == mapId; });
|
||||
|
|
@ -395,7 +395,7 @@ void SocialHandler::registerOpcodes(DispatchTable& table) {
|
|||
owner_.addSystemChatMessage(mapLabel + " has been reset.");
|
||||
};
|
||||
table[Opcode::SMSG_INSTANCE_RESET_FAILED] = [this](network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() < 8) return;
|
||||
if (!packet.hasRemaining(8)) return;
|
||||
uint32_t mapId = packet.readUInt32();
|
||||
uint32_t reason = packet.readUInt32();
|
||||
static const char* resetFailReasons[] = {
|
||||
|
|
@ -409,7 +409,7 @@ void SocialHandler::registerOpcodes(DispatchTable& table) {
|
|||
owner_.addSystemChatMessage("Cannot reset " + mapLabel + ": " + reasonMsg);
|
||||
};
|
||||
table[Opcode::SMSG_INSTANCE_LOCK_WARNING_QUERY] = [this](network::Packet& packet) {
|
||||
if (!owner_.socket || packet.getSize() - packet.getReadPos() < 17) return;
|
||||
if (!owner_.socket || !packet.hasRemaining(17)) return;
|
||||
uint32_t ilMapId = packet.readUInt32();
|
||||
uint32_t ilDiff = packet.readUInt32();
|
||||
uint32_t ilTimeLeft = packet.readUInt32();
|
||||
|
|
@ -448,7 +448,7 @@ void SocialHandler::registerOpcodes(DispatchTable& table) {
|
|||
owner_.addSystemChatMessage("Dungeon Finder: You may continue your dungeon.");
|
||||
};
|
||||
table[Opcode::SMSG_LFG_ROLE_CHOSEN] = [this](network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() < 13) { packet.setReadPos(packet.getSize()); return; }
|
||||
if (!packet.hasRemaining(13)) { packet.setReadPos(packet.getSize()); return; }
|
||||
uint64_t roleGuid = packet.readUInt64();
|
||||
uint8_t ready = packet.readUInt8();
|
||||
uint32_t roles = packet.readUInt32();
|
||||
|
|
@ -558,12 +558,12 @@ void SocialHandler::inspectTarget() {
|
|||
}
|
||||
|
||||
void SocialHandler::handleInspectResults(network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() < 1) return;
|
||||
if (!packet.hasRemaining(1)) return;
|
||||
uint8_t talentType = packet.readUInt8();
|
||||
|
||||
if (talentType == 0) {
|
||||
// Own talent info
|
||||
if (packet.getSize() - packet.getReadPos() < 6) {
|
||||
if (!packet.hasRemaining(6)) {
|
||||
LOG_DEBUG("SMSG_TALENTS_INFO type=0: too short");
|
||||
return;
|
||||
}
|
||||
|
|
@ -573,20 +573,20 @@ void SocialHandler::handleInspectResults(network::Packet& packet) {
|
|||
if (activeTalentGroup > 1) activeTalentGroup = 0;
|
||||
owner_.activeTalentSpec_ = activeTalentGroup;
|
||||
for (uint8_t g = 0; g < talentGroupCount && g < 2; ++g) {
|
||||
if (packet.getSize() - packet.getReadPos() < 1) break;
|
||||
if (!packet.hasRemaining(1)) break;
|
||||
uint8_t talentCount = packet.readUInt8();
|
||||
owner_.learnedTalents_[g].clear();
|
||||
for (uint8_t t = 0; t < talentCount; ++t) {
|
||||
if (packet.getSize() - packet.getReadPos() < 5) break;
|
||||
if (!packet.hasRemaining(5)) break;
|
||||
uint32_t talentId = packet.readUInt32();
|
||||
uint8_t rank = packet.readUInt8();
|
||||
owner_.learnedTalents_[g][talentId] = rank + 1u;
|
||||
}
|
||||
if (packet.getSize() - packet.getReadPos() < 1) break;
|
||||
if (!packet.hasRemaining(1)) break;
|
||||
owner_.learnedGlyphs_[g].fill(0);
|
||||
uint8_t glyphCount = packet.readUInt8();
|
||||
for (uint8_t gl = 0; gl < glyphCount; ++gl) {
|
||||
if (packet.getSize() - packet.getReadPos() < 2) break;
|
||||
if (!packet.hasRemaining(2)) break;
|
||||
uint16_t glyphId = packet.readUInt16();
|
||||
if (gl < GameHandler::MAX_GLYPH_SLOTS) owner_.learnedGlyphs_[g][gl] = glyphId;
|
||||
}
|
||||
|
|
@ -608,12 +608,12 @@ void SocialHandler::handleInspectResults(network::Packet& packet) {
|
|||
|
||||
// talentType == 1: inspect result
|
||||
const bool talentTbc = isClassicLikeExpansion() || isActiveExpansion("tbc");
|
||||
if (packet.getSize() - packet.getReadPos() < (talentTbc ? 8u : 2u)) return;
|
||||
if (packet.getRemainingSize() < (talentTbc ? 8u : 2u)) return;
|
||||
uint64_t guid = talentTbc
|
||||
? packet.readUInt64() : packet.readPackedGuid();
|
||||
if (guid == 0) return;
|
||||
|
||||
size_t bytesLeft = packet.getSize() - packet.getReadPos();
|
||||
size_t bytesLeft = packet.getRemainingSize();
|
||||
if (bytesLeft < 6) {
|
||||
LOG_WARNING("SMSG_TALENTS_INFO: too short after guid, ", bytesLeft, " bytes");
|
||||
auto entity = owner_.getEntityManager().getEntity(guid);
|
||||
|
|
@ -639,33 +639,33 @@ void SocialHandler::handleInspectResults(network::Packet& packet) {
|
|||
|
||||
uint32_t totalTalents = 0;
|
||||
for (uint8_t g = 0; g < talentGroupCount && g < 2; ++g) {
|
||||
bytesLeft = packet.getSize() - packet.getReadPos();
|
||||
bytesLeft = packet.getRemainingSize();
|
||||
if (bytesLeft < 1) break;
|
||||
uint8_t talentCount = packet.readUInt8();
|
||||
for (uint8_t t = 0; t < talentCount; ++t) {
|
||||
bytesLeft = packet.getSize() - packet.getReadPos();
|
||||
bytesLeft = packet.getRemainingSize();
|
||||
if (bytesLeft < 5) break;
|
||||
packet.readUInt32();
|
||||
packet.readUInt8();
|
||||
totalTalents++;
|
||||
}
|
||||
bytesLeft = packet.getSize() - packet.getReadPos();
|
||||
bytesLeft = packet.getRemainingSize();
|
||||
if (bytesLeft < 1) break;
|
||||
uint8_t glyphCount = packet.readUInt8();
|
||||
for (uint8_t gl = 0; gl < glyphCount; ++gl) {
|
||||
bytesLeft = packet.getSize() - packet.getReadPos();
|
||||
bytesLeft = packet.getRemainingSize();
|
||||
if (bytesLeft < 2) break;
|
||||
packet.readUInt16();
|
||||
}
|
||||
}
|
||||
|
||||
std::array<uint16_t, 19> enchantIds{};
|
||||
bytesLeft = packet.getSize() - packet.getReadPos();
|
||||
bytesLeft = packet.getRemainingSize();
|
||||
if (bytesLeft >= 4) {
|
||||
uint32_t slotMask = packet.readUInt32();
|
||||
for (int slot = 0; slot < 19; ++slot) {
|
||||
if (slotMask & (1u << slot)) {
|
||||
bytesLeft = packet.getSize() - packet.getReadPos();
|
||||
bytesLeft = packet.getRemainingSize();
|
||||
if (bytesLeft < 2) break;
|
||||
enchantIds[slot] = packet.readUInt16();
|
||||
}
|
||||
|
|
@ -1031,7 +1031,7 @@ void SocialHandler::reportPlayer(uint64_t targetGuid, const std::string& reason)
|
|||
}
|
||||
|
||||
void SocialHandler::handleDuelRequested(network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() < 16) { packet.setReadPos(packet.getSize()); return; }
|
||||
if (!packet.hasRemaining(16)) { packet.setReadPos(packet.getSize()); return; }
|
||||
duelChallengerGuid_ = packet.readUInt64();
|
||||
duelFlagGuid_ = packet.readUInt64();
|
||||
duelChallengerName_.clear();
|
||||
|
|
@ -1055,7 +1055,7 @@ void SocialHandler::handleDuelRequested(network::Packet& packet) {
|
|||
}
|
||||
|
||||
void SocialHandler::handleDuelComplete(network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() < 1) return;
|
||||
if (!packet.hasRemaining(1)) return;
|
||||
uint8_t started = packet.readUInt8();
|
||||
pendingDuelRequest_ = false;
|
||||
duelCountdownMs_ = 0;
|
||||
|
|
@ -1064,7 +1064,7 @@ void SocialHandler::handleDuelComplete(network::Packet& packet) {
|
|||
}
|
||||
|
||||
void SocialHandler::handleDuelWinner(network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() < 3) return;
|
||||
if (!packet.hasRemaining(3)) return;
|
||||
uint8_t duelType = packet.readUInt8();
|
||||
std::string winner = packet.readString();
|
||||
std::string loser = packet.readString();
|
||||
|
|
@ -1300,7 +1300,7 @@ void SocialHandler::handlePartyCommandResult(network::Packet& packet) {
|
|||
}
|
||||
|
||||
void SocialHandler::handlePartyMemberStats(network::Packet& packet, bool isFull) {
|
||||
auto remaining = [&]() { return packet.getSize() - packet.getReadPos(); };
|
||||
auto remaining = [&]() { return packet.getRemainingSize(); };
|
||||
const bool isWotLK = isActiveExpansion("wotlk");
|
||||
|
||||
if (isFull) { if (remaining() < 1) return; packet.readUInt8(); }
|
||||
|
|
@ -1605,7 +1605,7 @@ void SocialHandler::handlePetitionShowlist(network::Packet& packet) {
|
|||
}
|
||||
|
||||
void SocialHandler::handlePetitionQueryResponse(network::Packet& packet) {
|
||||
auto rem = [&]() { return packet.getSize() - packet.getReadPos(); };
|
||||
auto rem = [&]() { return packet.getRemainingSize(); };
|
||||
if (rem() < 12) return;
|
||||
/*uint32_t entry =*/ packet.readUInt32();
|
||||
uint64_t petGuid = packet.readUInt64();
|
||||
|
|
@ -1616,7 +1616,7 @@ void SocialHandler::handlePetitionQueryResponse(network::Packet& packet) {
|
|||
}
|
||||
|
||||
void SocialHandler::handlePetitionShowSignatures(network::Packet& packet) {
|
||||
auto rem = [&]() { return packet.getSize() - packet.getReadPos(); };
|
||||
auto rem = [&]() { return packet.getRemainingSize(); };
|
||||
if (rem() < 21) return;
|
||||
petitionInfo_ = PetitionInfo{};
|
||||
petitionInfo_.petitionGuid = packet.readUInt64();
|
||||
|
|
@ -1636,7 +1636,7 @@ void SocialHandler::handlePetitionShowSignatures(network::Packet& packet) {
|
|||
}
|
||||
|
||||
void SocialHandler::handlePetitionSignResults(network::Packet& packet) {
|
||||
auto rem = [&]() { return packet.getSize() - packet.getReadPos(); };
|
||||
auto rem = [&]() { return packet.getRemainingSize(); };
|
||||
if (rem() < 20) return;
|
||||
uint64_t petGuid = packet.readUInt64();
|
||||
uint64_t playerGuid = packet.readUInt64();
|
||||
|
|
@ -1719,13 +1719,13 @@ void SocialHandler::handleWho(network::Packet& packet) {
|
|||
if (packet.getReadPos() >= packet.getSize()) break;
|
||||
std::string playerName = packet.readString();
|
||||
std::string guildName = packet.readString();
|
||||
if (packet.getSize() - packet.getReadPos() < 12) break;
|
||||
if (!packet.hasRemaining(12)) break;
|
||||
uint32_t level = packet.readUInt32();
|
||||
uint32_t classId = packet.readUInt32();
|
||||
uint32_t raceId = packet.readUInt32();
|
||||
if (hasGender && packet.getSize() - packet.getReadPos() >= 1) packet.readUInt8();
|
||||
if (hasGender && packet.hasRemaining(1)) packet.readUInt8();
|
||||
uint32_t zoneId = 0;
|
||||
if (packet.getSize() - packet.getReadPos() >= 4) zoneId = packet.readUInt32();
|
||||
if (packet.hasRemaining(4)) zoneId = packet.readUInt32();
|
||||
WhoEntry entry;
|
||||
entry.name = playerName; entry.guildName = guildName;
|
||||
entry.level = level; entry.classId = classId;
|
||||
|
|
@ -1739,7 +1739,7 @@ void SocialHandler::handleWho(network::Packet& packet) {
|
|||
// ============================================================
|
||||
|
||||
void SocialHandler::handleFriendList(network::Packet& packet) {
|
||||
auto rem = [&]() { return packet.getSize() - packet.getReadPos(); };
|
||||
auto rem = [&]() { return packet.getRemainingSize(); };
|
||||
if (rem() < 1) return;
|
||||
uint8_t count = packet.readUInt8();
|
||||
owner_.contacts_.erase(std::remove_if(owner_.contacts_.begin(), owner_.contacts_.end(),
|
||||
|
|
@ -1771,7 +1771,7 @@ void SocialHandler::handleFriendList(network::Packet& packet) {
|
|||
}
|
||||
|
||||
void SocialHandler::handleContactList(network::Packet& packet) {
|
||||
auto rem = [&]() { return packet.getSize() - packet.getReadPos(); };
|
||||
auto rem = [&]() { return packet.getRemainingSize(); };
|
||||
if (rem() < 8) { packet.setReadPos(packet.getSize()); return; }
|
||||
owner_.lastContactListMask_ = packet.readUInt32();
|
||||
owner_.lastContactListCount_ = packet.readUInt32();
|
||||
|
|
@ -1898,27 +1898,27 @@ void SocialHandler::handleLogoutComplete(network::Packet& /*packet*/) {
|
|||
// ============================================================
|
||||
|
||||
void SocialHandler::handleBattlefieldStatus(network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() < 4) return;
|
||||
if (!packet.hasRemaining(4)) return;
|
||||
uint32_t queueSlot = packet.readUInt32();
|
||||
const bool classicFormat = isClassicLikeExpansion();
|
||||
uint8_t arenaType = 0;
|
||||
if (!classicFormat) {
|
||||
if (packet.getSize() - packet.getReadPos() < 1) return;
|
||||
if (!packet.hasRemaining(1)) return;
|
||||
arenaType = packet.readUInt8();
|
||||
if (packet.getSize() - packet.getReadPos() < 1) return;
|
||||
if (!packet.hasRemaining(1)) return;
|
||||
packet.readUInt8();
|
||||
} else {
|
||||
if (packet.getSize() - packet.getReadPos() < 4) return;
|
||||
if (!packet.hasRemaining(4)) return;
|
||||
}
|
||||
if (packet.getSize() - packet.getReadPos() < 4) return;
|
||||
if (!packet.hasRemaining(4)) return;
|
||||
uint32_t bgTypeId = packet.readUInt32();
|
||||
if (packet.getSize() - packet.getReadPos() < 2) return;
|
||||
if (!packet.hasRemaining(2)) return;
|
||||
packet.readUInt16();
|
||||
if (packet.getSize() - packet.getReadPos() < 4) return;
|
||||
if (!packet.hasRemaining(4)) return;
|
||||
packet.readUInt32(); // instanceId
|
||||
if (packet.getSize() - packet.getReadPos() < 1) return;
|
||||
if (!packet.hasRemaining(1)) return;
|
||||
packet.readUInt8(); // isRated
|
||||
if (packet.getSize() - packet.getReadPos() < 4) return;
|
||||
if (!packet.hasRemaining(4)) return;
|
||||
uint32_t statusId = packet.readUInt32();
|
||||
|
||||
static const std::pair<uint32_t, const char*> kBgNames[] = {
|
||||
|
|
@ -1936,12 +1936,12 @@ void SocialHandler::handleBattlefieldStatus(network::Packet& packet) {
|
|||
}
|
||||
|
||||
uint32_t inviteTimeout = 80, avgWaitSec = 0, timeInQueueSec = 0;
|
||||
if (statusId == 1 && packet.getSize() - packet.getReadPos() >= 8) {
|
||||
if (statusId == 1 && packet.hasRemaining(8)) {
|
||||
avgWaitSec = packet.readUInt32() / 1000; timeInQueueSec = packet.readUInt32() / 1000;
|
||||
} else if (statusId == 2) {
|
||||
if (packet.getSize() - packet.getReadPos() >= 4) inviteTimeout = packet.readUInt32();
|
||||
if (packet.getSize() - packet.getReadPos() >= 4) packet.readUInt32();
|
||||
} else if (statusId == 3 && packet.getSize() - packet.getReadPos() >= 8) {
|
||||
if (packet.hasRemaining(4)) inviteTimeout = packet.readUInt32();
|
||||
if (packet.hasRemaining(4)) packet.readUInt32();
|
||||
} else if (statusId == 3 && packet.hasRemaining(8)) {
|
||||
packet.readUInt32(); packet.readUInt32();
|
||||
}
|
||||
|
||||
|
|
@ -1966,19 +1966,19 @@ void SocialHandler::handleBattlefieldStatus(network::Packet& packet) {
|
|||
}
|
||||
|
||||
void SocialHandler::handleBattlefieldList(network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() < 5) return;
|
||||
if (!packet.hasRemaining(5)) return;
|
||||
AvailableBgInfo info;
|
||||
info.bgTypeId = packet.readUInt32();
|
||||
info.isRegistered = packet.readUInt8() != 0;
|
||||
const bool isWotlk = isActiveExpansion("wotlk");
|
||||
const bool isTbc = isActiveExpansion("tbc");
|
||||
if (isTbc || isWotlk) { if (packet.getSize() - packet.getReadPos() < 1) return; info.isHoliday = packet.readUInt8() != 0; }
|
||||
if (isWotlk) { if (packet.getSize() - packet.getReadPos() < 8) return; info.minLevel = packet.readUInt32(); info.maxLevel = packet.readUInt32(); }
|
||||
if (packet.getSize() - packet.getReadPos() < 4) return;
|
||||
if (isTbc || isWotlk) { if (!packet.hasRemaining(1)) return; info.isHoliday = packet.readUInt8() != 0; }
|
||||
if (isWotlk) { if (!packet.hasRemaining(8)) return; info.minLevel = packet.readUInt32(); info.maxLevel = packet.readUInt32(); }
|
||||
if (!packet.hasRemaining(4)) return;
|
||||
uint32_t count = std::min(packet.readUInt32(), 256u);
|
||||
info.instanceIds.reserve(count);
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
if (packet.getSize() - packet.getReadPos() < 4) break;
|
||||
if (!packet.hasRemaining(4)) break;
|
||||
info.instanceIds.push_back(packet.readUInt32());
|
||||
}
|
||||
bool updated = false;
|
||||
|
|
@ -2035,13 +2035,13 @@ void SocialHandler::handleRaidInstanceInfo(network::Packet& packet) {
|
|||
const bool isTbc = isActiveExpansion("tbc");
|
||||
const bool isClassic = isClassicLikeExpansion();
|
||||
const bool useTbcFormat = isTbc || isClassic;
|
||||
if (packet.getSize() - packet.getReadPos() < 4) return;
|
||||
if (!packet.hasRemaining(4)) return;
|
||||
uint32_t count = packet.readUInt32();
|
||||
instanceLockouts_.clear();
|
||||
instanceLockouts_.reserve(count);
|
||||
const size_t kEntrySize = useTbcFormat ? 13 : 18;
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
if (packet.getSize() - packet.getReadPos() < kEntrySize) break;
|
||||
if (packet.getRemainingSize() < kEntrySize) break;
|
||||
InstanceLockout lo;
|
||||
lo.mapId = packet.readUInt32(); lo.difficulty = packet.readUInt32();
|
||||
if (useTbcFormat) { lo.resetTime = packet.readUInt32(); lo.locked = packet.readUInt8() != 0; lo.extended = false; }
|
||||
|
|
@ -2051,7 +2051,7 @@ void SocialHandler::handleRaidInstanceInfo(network::Packet& packet) {
|
|||
}
|
||||
|
||||
void SocialHandler::handleInstanceDifficulty(network::Packet& packet) {
|
||||
auto rem = [&]() { return packet.getSize() - packet.getReadPos(); };
|
||||
auto rem = [&]() { return packet.getRemainingSize(); };
|
||||
if (rem() < 4) return;
|
||||
uint32_t prevDifficulty = instanceDifficulty_;
|
||||
instanceDifficulty_ = packet.readUInt32();
|
||||
|
|
@ -2075,7 +2075,7 @@ void SocialHandler::handleInstanceDifficulty(network::Packet& packet) {
|
|||
// ============================================================
|
||||
|
||||
void SocialHandler::handleLfgJoinResult(network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() < 2) return;
|
||||
if (!packet.hasRemaining(2)) return;
|
||||
uint8_t result = packet.readUInt8();
|
||||
uint8_t state = packet.readUInt8();
|
||||
if (result == 0) {
|
||||
|
|
@ -2092,7 +2092,7 @@ void SocialHandler::handleLfgJoinResult(network::Packet& packet) {
|
|||
}
|
||||
|
||||
void SocialHandler::handleLfgQueueStatus(network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() < 33) return;
|
||||
if (!packet.hasRemaining(33)) return;
|
||||
lfgDungeonId_ = packet.readUInt32();
|
||||
int32_t avgWait = static_cast<int32_t>(packet.readUInt32());
|
||||
int32_t waitTime = static_cast<int32_t>(packet.readUInt32());
|
||||
|
|
@ -2104,7 +2104,7 @@ void SocialHandler::handleLfgQueueStatus(network::Packet& packet) {
|
|||
}
|
||||
|
||||
void SocialHandler::handleLfgProposalUpdate(network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() < 17) return;
|
||||
if (!packet.hasRemaining(17)) return;
|
||||
uint32_t dungeonId = packet.readUInt32();
|
||||
uint32_t proposalId = packet.readUInt32();
|
||||
uint32_t proposalState = packet.readUInt32();
|
||||
|
|
@ -2124,7 +2124,7 @@ void SocialHandler::handleLfgProposalUpdate(network::Packet& packet) {
|
|||
}
|
||||
|
||||
void SocialHandler::handleLfgRoleCheckUpdate(network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() < 6) return;
|
||||
if (!packet.hasRemaining(6)) return;
|
||||
packet.readUInt32();
|
||||
uint8_t roleCheckState = packet.readUInt8();
|
||||
packet.readUInt8();
|
||||
|
|
@ -2134,10 +2134,10 @@ void SocialHandler::handleLfgRoleCheckUpdate(network::Packet& packet) {
|
|||
}
|
||||
|
||||
void SocialHandler::handleLfgUpdatePlayer(network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() < 1) return;
|
||||
if (!packet.hasRemaining(1)) return;
|
||||
uint8_t updateType = packet.readUInt8();
|
||||
bool hasExtra = (updateType != 0 && updateType != 1 && updateType != 15 && updateType != 17 && updateType != 18);
|
||||
if (!hasExtra || packet.getSize() - packet.getReadPos() < 3) {
|
||||
if (!hasExtra || !packet.hasRemaining(3)) {
|
||||
switch (updateType) {
|
||||
case 8: lfgState_ = LfgState::None; owner_.addSystemChatMessage("Dungeon Finder: Removed from queue."); break;
|
||||
case 9: lfgState_ = LfgState::Queued; owner_.addSystemChatMessage("Dungeon Finder: Proposal failed — re-queuing."); break;
|
||||
|
|
@ -2149,9 +2149,9 @@ void SocialHandler::handleLfgUpdatePlayer(network::Packet& packet) {
|
|||
return;
|
||||
}
|
||||
packet.readUInt8(); packet.readUInt8(); packet.readUInt8();
|
||||
if (packet.getSize() - packet.getReadPos() >= 1) {
|
||||
if (packet.hasRemaining(1)) {
|
||||
uint8_t count = packet.readUInt8();
|
||||
for (uint8_t i = 0; i < count && packet.getSize() - packet.getReadPos() >= 4; ++i) {
|
||||
for (uint8_t i = 0; i < count && packet.getRemainingSize() >= 4; ++i) {
|
||||
uint32_t dungeonEntry = packet.readUInt32();
|
||||
if (i == 0) lfgDungeonId_ = dungeonEntry;
|
||||
}
|
||||
|
|
@ -2221,7 +2221,7 @@ void SocialHandler::handleLfgBootProposalUpdate(network::Packet& packet) {
|
|||
}
|
||||
|
||||
void SocialHandler::handleLfgTeleportDenied(network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() < 1) return;
|
||||
if (!packet.hasRemaining(1)) return;
|
||||
uint8_t reason = packet.readUInt8();
|
||||
owner_.addSystemChatMessage(std::string("Dungeon Finder: ") + lfgTeleportDeniedString(reason));
|
||||
}
|
||||
|
|
@ -2283,7 +2283,7 @@ void SocialHandler::lfgSetBootVote(bool vote) {
|
|||
// ============================================================
|
||||
|
||||
void SocialHandler::handleArenaTeamCommandResult(network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() < 8) return;
|
||||
if (!packet.hasRemaining(8)) return;
|
||||
uint32_t command = packet.readUInt32();
|
||||
std::string name = packet.readString();
|
||||
uint32_t error = packet.readUInt32();
|
||||
|
|
@ -2294,30 +2294,30 @@ void SocialHandler::handleArenaTeamCommandResult(network::Packet& packet) {
|
|||
}
|
||||
|
||||
void SocialHandler::handleArenaTeamQueryResponse(network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() < 4) return;
|
||||
if (!packet.hasRemaining(4)) return;
|
||||
uint32_t teamId = packet.readUInt32();
|
||||
std::string teamName = packet.readString();
|
||||
uint32_t teamType = 0;
|
||||
if (packet.getSize() - packet.getReadPos() >= 4) teamType = packet.readUInt32();
|
||||
if (packet.hasRemaining(4)) teamType = packet.readUInt32();
|
||||
for (auto& s : arenaTeamStats_) { if (s.teamId == teamId) { s.teamName = teamName; s.teamType = teamType; return; } }
|
||||
ArenaTeamStats stub; stub.teamId = teamId; stub.teamName = teamName; stub.teamType = teamType;
|
||||
arenaTeamStats_.push_back(std::move(stub));
|
||||
}
|
||||
|
||||
void SocialHandler::handleArenaTeamRoster(network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() < 9) return;
|
||||
if (!packet.hasRemaining(9)) return;
|
||||
uint32_t teamId = packet.readUInt32();
|
||||
packet.readUInt8();
|
||||
uint32_t memberCount = std::min(packet.readUInt32(), 100u);
|
||||
ArenaTeamRoster roster; roster.teamId = teamId; roster.members.reserve(memberCount);
|
||||
for (uint32_t i = 0; i < memberCount; ++i) {
|
||||
if (packet.getSize() - packet.getReadPos() < 12) break;
|
||||
if (!packet.hasRemaining(12)) break;
|
||||
ArenaTeamMember m;
|
||||
m.guid = packet.readUInt64(); m.online = (packet.readUInt8() != 0); m.name = packet.readString();
|
||||
if (packet.getSize() - packet.getReadPos() < 20) break;
|
||||
if (!packet.hasRemaining(20)) break;
|
||||
m.weekGames = packet.readUInt32(); m.weekWins = packet.readUInt32();
|
||||
m.seasonGames = packet.readUInt32(); m.seasonWins = packet.readUInt32(); m.personalRating = packet.readUInt32();
|
||||
if (packet.getSize() - packet.getReadPos() >= 8) { packet.readFloat(); packet.readFloat(); }
|
||||
if (packet.hasRemaining(8)) { packet.readFloat(); packet.readFloat(); }
|
||||
roster.members.push_back(std::move(m));
|
||||
}
|
||||
for (auto& r : arenaTeamRosters_) { if (r.teamId == teamId) { r = std::move(roster); return; } }
|
||||
|
|
@ -2331,10 +2331,10 @@ void SocialHandler::handleArenaTeamInvite(network::Packet& packet) {
|
|||
}
|
||||
|
||||
void SocialHandler::handleArenaTeamEvent(network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() < 1) return;
|
||||
if (!packet.hasRemaining(1)) return;
|
||||
uint8_t event = packet.readUInt8();
|
||||
uint8_t strCount = 0;
|
||||
if (packet.getSize() - packet.getReadPos() >= 1) strCount = packet.readUInt8();
|
||||
if (packet.hasRemaining(1)) strCount = packet.readUInt8();
|
||||
std::string param1, param2;
|
||||
if (strCount >= 1 && packet.getSize() > packet.getReadPos()) param1 = packet.readString();
|
||||
if (strCount >= 2 && packet.getSize() > packet.getReadPos()) param2 = packet.readString();
|
||||
|
|
@ -2352,7 +2352,7 @@ void SocialHandler::handleArenaTeamEvent(network::Packet& packet) {
|
|||
}
|
||||
|
||||
void SocialHandler::handleArenaTeamStats(network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() < 28) return;
|
||||
if (!packet.hasRemaining(28)) return;
|
||||
ArenaTeamStats stats;
|
||||
stats.teamId = packet.readUInt32(); stats.rating = packet.readUInt32();
|
||||
stats.weekGames = packet.readUInt32(); stats.weekWins = packet.readUInt32();
|
||||
|
|
@ -2372,7 +2372,7 @@ void SocialHandler::requestArenaTeamRoster(uint32_t teamId) {
|
|||
}
|
||||
|
||||
void SocialHandler::handleArenaError(network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() < 4) return;
|
||||
if (!packet.hasRemaining(4)) return;
|
||||
uint32_t error = packet.readUInt32();
|
||||
std::string msg;
|
||||
switch (error) {
|
||||
|
|
@ -2386,7 +2386,7 @@ void SocialHandler::handleArenaError(network::Packet& packet) {
|
|||
}
|
||||
|
||||
void SocialHandler::handlePvpLogData(network::Packet& packet) {
|
||||
auto remaining = [&]() { return packet.getSize() - packet.getReadPos(); };
|
||||
auto remaining = [&]() { return packet.getRemainingSize(); };
|
||||
if (remaining() < 1) return;
|
||||
bgScoreboard_ = BgScoreboardData{};
|
||||
bgScoreboard_.isArena = (packet.readUInt8() != 0);
|
||||
|
|
|
|||
|
|
@ -1045,16 +1045,16 @@ void SpellHandler::handleSpellGo(network::Packet& packet) {
|
|||
void SpellHandler::handleSpellCooldown(network::Packet& packet) {
|
||||
const bool isClassicFormat = isClassicLikeExpansion();
|
||||
|
||||
if (packet.getSize() - packet.getReadPos() < 8) return;
|
||||
if (!packet.hasRemaining(8)) return;
|
||||
/*guid*/ packet.readUInt64();
|
||||
|
||||
if (!isClassicFormat) {
|
||||
if (packet.getSize() - packet.getReadPos() < 1) return;
|
||||
if (!packet.hasRemaining(1)) return;
|
||||
/*flags*/ packet.readUInt8();
|
||||
}
|
||||
|
||||
const size_t entrySize = isClassicFormat ? 12u : 8u;
|
||||
while (packet.getSize() - packet.getReadPos() >= entrySize) {
|
||||
while (packet.getRemainingSize() >= entrySize) {
|
||||
uint32_t spellId = packet.readUInt32();
|
||||
uint32_t cdItemId = 0;
|
||||
if (isClassicFormat) cdItemId = packet.readUInt32();
|
||||
|
|
@ -1099,9 +1099,9 @@ void SpellHandler::handleSpellCooldown(network::Packet& packet) {
|
|||
}
|
||||
|
||||
void SpellHandler::handleCooldownEvent(network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() < 4) return;
|
||||
if (!packet.hasRemaining(4)) return;
|
||||
uint32_t spellId = packet.readUInt32();
|
||||
if (packet.getSize() - packet.getReadPos() >= 8)
|
||||
if (packet.hasRemaining(8))
|
||||
packet.readUInt64();
|
||||
spellCooldowns_.erase(spellId);
|
||||
for (auto& slot : owner_.actionBar) {
|
||||
|
|
@ -1171,7 +1171,7 @@ void SpellHandler::handleAuraUpdate(network::Packet& packet, bool isAll) {
|
|||
void SpellHandler::handleLearnedSpell(network::Packet& packet) {
|
||||
const bool classicSpellId = isClassicLikeExpansion();
|
||||
const size_t minSz = classicSpellId ? 2u : 4u;
|
||||
if (packet.getSize() - packet.getReadPos() < minSz) return;
|
||||
if (packet.getRemainingSize() < minSz) return;
|
||||
uint32_t spellId = classicSpellId ? packet.readUInt16() : packet.readUInt32();
|
||||
|
||||
const bool alreadyKnown = knownSpells_.count(spellId) > 0;
|
||||
|
|
@ -1218,7 +1218,7 @@ void SpellHandler::handleLearnedSpell(network::Packet& packet) {
|
|||
void SpellHandler::handleRemovedSpell(network::Packet& packet) {
|
||||
const bool classicSpellId = isClassicLikeExpansion();
|
||||
const size_t minSz = classicSpellId ? 2u : 4u;
|
||||
if (packet.getSize() - packet.getReadPos() < minSz) return;
|
||||
if (packet.getRemainingSize() < minSz) return;
|
||||
uint32_t spellId = classicSpellId ? packet.readUInt16() : packet.readUInt32();
|
||||
knownSpells_.erase(spellId);
|
||||
LOG_INFO("Removed spell: ", spellId);
|
||||
|
|
@ -1243,7 +1243,7 @@ void SpellHandler::handleRemovedSpell(network::Packet& packet) {
|
|||
void SpellHandler::handleSupercededSpell(network::Packet& packet) {
|
||||
const bool classicSpellId = isClassicLikeExpansion();
|
||||
const size_t minSz = classicSpellId ? 4u : 8u;
|
||||
if (packet.getSize() - packet.getReadPos() < minSz) return;
|
||||
if (packet.getRemainingSize() < minSz) return;
|
||||
uint32_t oldSpellId = classicSpellId ? packet.readUInt16() : packet.readUInt32();
|
||||
uint32_t newSpellId = classicSpellId ? packet.readUInt16() : packet.readUInt32();
|
||||
|
||||
|
|
@ -1279,12 +1279,12 @@ void SpellHandler::handleSupercededSpell(network::Packet& packet) {
|
|||
}
|
||||
|
||||
void SpellHandler::handleUnlearnSpells(network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() < 4) return;
|
||||
if (!packet.hasRemaining(4)) return;
|
||||
uint32_t spellCount = packet.readUInt32();
|
||||
LOG_INFO("Unlearning ", spellCount, " spells");
|
||||
|
||||
bool barChanged = false;
|
||||
for (uint32_t i = 0; i < spellCount && packet.getSize() - packet.getReadPos() >= 4; ++i) {
|
||||
for (uint32_t i = 0; i < spellCount && packet.getRemainingSize() >= 4; ++i) {
|
||||
uint32_t spellId = packet.readUInt32();
|
||||
knownSpells_.erase(spellId);
|
||||
LOG_INFO(" Unlearned spell: ", spellId);
|
||||
|
|
@ -1303,12 +1303,12 @@ void SpellHandler::handleUnlearnSpells(network::Packet& packet) {
|
|||
}
|
||||
|
||||
void SpellHandler::handleTalentsInfo(network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() < 1) return;
|
||||
if (!packet.hasRemaining(1)) return;
|
||||
uint8_t talentType = packet.readUInt8();
|
||||
if (talentType != 0) {
|
||||
return;
|
||||
}
|
||||
if (packet.getSize() - packet.getReadPos() < 6) {
|
||||
if (!packet.hasRemaining(6)) {
|
||||
LOG_WARNING("handleTalentsInfo: packet too short for header");
|
||||
return;
|
||||
}
|
||||
|
|
@ -1323,20 +1323,20 @@ void SpellHandler::handleTalentsInfo(network::Packet& packet) {
|
|||
activeTalentSpec_ = activeTalentGroup;
|
||||
|
||||
for (uint8_t g = 0; g < talentGroupCount && g < 2; ++g) {
|
||||
if (packet.getSize() - packet.getReadPos() < 1) break;
|
||||
if (!packet.hasRemaining(1)) break;
|
||||
uint8_t talentCount = packet.readUInt8();
|
||||
learnedTalents_[g].clear();
|
||||
for (uint8_t t = 0; t < talentCount; ++t) {
|
||||
if (packet.getSize() - packet.getReadPos() < 5) break;
|
||||
if (!packet.hasRemaining(5)) break;
|
||||
uint32_t talentId = packet.readUInt32();
|
||||
uint8_t rank = packet.readUInt8();
|
||||
learnedTalents_[g][talentId] = rank + 1u;
|
||||
}
|
||||
learnedGlyphs_[g].fill(0);
|
||||
if (packet.getSize() - packet.getReadPos() < 1) break;
|
||||
if (!packet.hasRemaining(1)) break;
|
||||
uint8_t glyphCount = packet.readUInt8();
|
||||
for (uint8_t gl = 0; gl < glyphCount; ++gl) {
|
||||
if (packet.getSize() - packet.getReadPos() < 2) break;
|
||||
if (!packet.hasRemaining(2)) break;
|
||||
uint16_t glyphId = packet.readUInt16();
|
||||
if (gl < MAX_GLYPH_SLOTS) learnedGlyphs_[g][gl] = glyphId;
|
||||
}
|
||||
|
|
@ -1365,7 +1365,7 @@ void SpellHandler::handleTalentsInfo(network::Packet& packet) {
|
|||
}
|
||||
|
||||
void SpellHandler::handleAchievementEarned(network::Packet& packet) {
|
||||
size_t remaining = packet.getSize() - packet.getReadPos();
|
||||
size_t remaining = packet.getRemainingSize();
|
||||
if (remaining < 16) return;
|
||||
|
||||
uint64_t guid = packet.readUInt64();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue