mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-04-03 20:03:50 +00:00
fix: SMSG_IGNORE_LIST read phantom string field after each GUID
The packet only contains uint8 count + count×uint64 GUIDs, but the handler called readString() after each GUID. This consumed raw bytes of subsequent GUIDs as a string, corrupting all entries after the first. Now stores GUIDs in ignoreListGuids_ and resolves names asynchronously via SMSG_NAME_QUERY_RESPONSE, matching the friends list pattern. Also fixes unsafe static_pointer_cast in ready check (no type guard) and removes redundant packetHasRemaining wrapper (duplicates Packet API).
This commit is contained in:
parent
0e814e9c4a
commit
35b952bc6f
3 changed files with 27 additions and 15 deletions
|
|
@ -2420,7 +2420,8 @@ private:
|
||||||
std::vector<FactionStandingInit> initialFactions_;
|
std::vector<FactionStandingInit> initialFactions_;
|
||||||
|
|
||||||
// ---- Ignore list cache ----
|
// ---- Ignore list cache ----
|
||||||
std::unordered_map<std::string, uint64_t> ignoreCache; // name -> guid
|
std::unordered_map<std::string, uint64_t> ignoreCache; // name -> guid (UI display)
|
||||||
|
std::unordered_set<uint64_t> ignoreListGuids_; // authoritative GUID set from server
|
||||||
|
|
||||||
// ---- Logout state ----
|
// ---- Logout state ----
|
||||||
bool loggingOut_ = false;
|
bool loggingOut_ = false;
|
||||||
|
|
|
||||||
|
|
@ -1996,6 +1996,12 @@ void EntityController::handleNameQueryResponse(network::Packet& packet) {
|
||||||
owner_.friendsCache[data.name] = data.guid;
|
owner_.friendsCache[data.name] = data.guid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Backfill ignore list: SMSG_IGNORE_LIST only contains GUIDs, so
|
||||||
|
// ignoreCache (name→guid for UI) is populated here once names resolve.
|
||||||
|
if (owner_.ignoreListGuids_.count(data.guid)) {
|
||||||
|
owner_.ignoreCache[data.name] = data.guid;
|
||||||
|
}
|
||||||
|
|
||||||
// Fire UNIT_NAME_UPDATE so nameplate/unit frame addons know the name is available
|
// Fire UNIT_NAME_UPDATE so nameplate/unit frame addons know the name is available
|
||||||
if (owner_.addonEventCallback_) {
|
if (owner_.addonEventCallback_) {
|
||||||
std::string unitId;
|
std::string unitId;
|
||||||
|
|
|
||||||
|
|
@ -18,11 +18,7 @@ namespace wowee {
|
||||||
namespace game {
|
namespace game {
|
||||||
|
|
||||||
|
|
||||||
static bool packetHasRemaining(const network::Packet& packet, size_t need) {
|
|
||||||
const size_t size = packet.getSize();
|
|
||||||
const size_t pos = packet.getReadPos();
|
|
||||||
return pos <= size && need <= (size - pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char* lfgJoinResultString(uint8_t result) {
|
static const char* lfgJoinResultString(uint8_t result) {
|
||||||
switch (result) {
|
switch (result) {
|
||||||
|
|
@ -98,13 +94,19 @@ void SocialHandler::registerOpcodes(DispatchTable& table) {
|
||||||
table[Opcode::SMSG_CONTACT_LIST] = [this](network::Packet& packet) { handleContactList(packet); };
|
table[Opcode::SMSG_CONTACT_LIST] = [this](network::Packet& packet) { handleContactList(packet); };
|
||||||
table[Opcode::SMSG_FRIEND_LIST] = [this](network::Packet& packet) { handleFriendList(packet); };
|
table[Opcode::SMSG_FRIEND_LIST] = [this](network::Packet& packet) { handleFriendList(packet); };
|
||||||
table[Opcode::SMSG_IGNORE_LIST] = [this](network::Packet& packet) {
|
table[Opcode::SMSG_IGNORE_LIST] = [this](network::Packet& packet) {
|
||||||
if (packet.getSize() - packet.getReadPos() < 1) return;
|
// Format: uint8 count + count × uint64 guid (no name strings in packet).
|
||||||
|
// Names are resolved via SMSG_NAME_QUERY_RESPONSE after the list arrives.
|
||||||
|
if (!packet.hasRemaining(1)) return;
|
||||||
uint8_t ignCount = packet.readUInt8();
|
uint8_t ignCount = packet.readUInt8();
|
||||||
|
owner_.ignoreListGuids_.clear();
|
||||||
for (uint8_t i = 0; i < ignCount; ++i) {
|
for (uint8_t i = 0; i < ignCount; ++i) {
|
||||||
if (packet.getSize() - packet.getReadPos() < 8) break;
|
if (!packet.hasRemaining(8)) break;
|
||||||
uint64_t ignGuid = packet.readUInt64();
|
uint64_t ignGuid = packet.readUInt64();
|
||||||
std::string ignName = packet.readString();
|
if (ignGuid != 0) {
|
||||||
if (!ignName.empty() && ignGuid != 0) owner_.ignoreCache[ignName] = ignGuid;
|
owner_.ignoreListGuids_.insert(ignGuid);
|
||||||
|
// Query name so UI can display it later
|
||||||
|
owner_.queryPlayerName(ignGuid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
LOG_DEBUG("SMSG_IGNORE_LIST: loaded ", (int)ignCount, " ignored players");
|
LOG_DEBUG("SMSG_IGNORE_LIST: loaded ", (int)ignCount, " ignored players");
|
||||||
};
|
};
|
||||||
|
|
@ -176,8 +178,11 @@ void SocialHandler::registerOpcodes(DispatchTable& table) {
|
||||||
std::string rname;
|
std::string rname;
|
||||||
if (nit != owner_.getPlayerNameCache().end()) rname = nit->second;
|
if (nit != owner_.getPlayerNameCache().end()) rname = nit->second;
|
||||||
else {
|
else {
|
||||||
|
// Only cast to Unit if the entity actually is one — a raw
|
||||||
|
// static_pointer_cast on a GameObject would be undefined behavior.
|
||||||
auto ent = owner_.getEntityManager().getEntity(respGuid);
|
auto ent = owner_.getEntityManager().getEntity(respGuid);
|
||||||
if (ent) rname = std::static_pointer_cast<game::Unit>(ent)->getName();
|
if (ent && (ent->getType() == ObjectType::UNIT || ent->getType() == ObjectType::PLAYER))
|
||||||
|
rname = std::static_pointer_cast<game::Unit>(ent)->getName();
|
||||||
}
|
}
|
||||||
if (!rname.empty()) {
|
if (!rname.empty()) {
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
@ -2151,7 +2156,7 @@ void SocialHandler::handleLfgUpdatePlayer(network::Packet& packet) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SocialHandler::handleLfgPlayerReward(network::Packet& packet) {
|
void SocialHandler::handleLfgPlayerReward(network::Packet& packet) {
|
||||||
if (!packetHasRemaining(packet, 13)) return;
|
if (!packet.hasRemaining( 13)) return;
|
||||||
packet.readUInt32(); packet.readUInt32(); packet.readUInt8();
|
packet.readUInt32(); packet.readUInt32(); packet.readUInt8();
|
||||||
uint32_t money = packet.readUInt32();
|
uint32_t money = packet.readUInt32();
|
||||||
uint32_t xp = packet.readUInt32();
|
uint32_t xp = packet.readUInt32();
|
||||||
|
|
@ -2161,9 +2166,9 @@ void SocialHandler::handleLfgPlayerReward(network::Packet& packet) {
|
||||||
else if (silver > 0) snprintf(moneyBuf, sizeof(moneyBuf), "%us %uc", silver, copper);
|
else if (silver > 0) snprintf(moneyBuf, sizeof(moneyBuf), "%us %uc", silver, copper);
|
||||||
else snprintf(moneyBuf, sizeof(moneyBuf), "%uc", copper);
|
else snprintf(moneyBuf, sizeof(moneyBuf), "%uc", copper);
|
||||||
std::string rewardMsg = std::string("Dungeon Finder reward: ") + moneyBuf + ", " + std::to_string(xp) + " XP";
|
std::string rewardMsg = std::string("Dungeon Finder reward: ") + moneyBuf + ", " + std::to_string(xp) + " XP";
|
||||||
if (packetHasRemaining(packet, 4)) {
|
if (packet.hasRemaining( 4)) {
|
||||||
uint32_t rewardCount = packet.readUInt32();
|
uint32_t rewardCount = packet.readUInt32();
|
||||||
for (uint32_t i = 0; i < rewardCount && packetHasRemaining(packet, 9); ++i) {
|
for (uint32_t i = 0; i < rewardCount && packet.hasRemaining( 9); ++i) {
|
||||||
uint32_t itemId = packet.readUInt32();
|
uint32_t itemId = packet.readUInt32();
|
||||||
uint32_t itemCount = packet.readUInt32();
|
uint32_t itemCount = packet.readUInt32();
|
||||||
packet.readUInt8();
|
packet.readUInt8();
|
||||||
|
|
@ -2184,7 +2189,7 @@ void SocialHandler::handleLfgPlayerReward(network::Packet& packet) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SocialHandler::handleLfgBootProposalUpdate(network::Packet& packet) {
|
void SocialHandler::handleLfgBootProposalUpdate(network::Packet& packet) {
|
||||||
if (!packetHasRemaining(packet, 23)) return;
|
if (!packet.hasRemaining( 23)) return;
|
||||||
bool inProgress = packet.readUInt8() != 0;
|
bool inProgress = packet.readUInt8() != 0;
|
||||||
packet.readUInt8(); packet.readUInt8();
|
packet.readUInt8(); packet.readUInt8();
|
||||||
uint32_t totalVotes = packet.readUInt32();
|
uint32_t totalVotes = packet.readUInt32();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue