mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-22 23:30:14 +00:00
Fix name query parsing for Classic/TBC
This commit is contained in:
parent
bf39c0b900
commit
6af9d6ba2d
3 changed files with 86 additions and 2 deletions
|
|
@ -102,6 +102,11 @@ public:
|
|||
return MessageChatParser::parse(packet, data);
|
||||
}
|
||||
|
||||
/** Parse SMSG_NAME_QUERY_RESPONSE */
|
||||
virtual bool parseNameQueryResponse(network::Packet& packet, NameQueryResponseData& data) {
|
||||
return NameQueryResponseParser::parse(packet, data);
|
||||
}
|
||||
|
||||
// --- Destroy Object ---
|
||||
|
||||
/** Parse SMSG_DESTROY_OBJECT */
|
||||
|
|
@ -158,6 +163,7 @@ public:
|
|||
bool parseUpdateObject(network::Packet& packet, UpdateObjectData& data) override;
|
||||
bool parseCharEnum(network::Packet& packet, CharEnumResponse& response) override;
|
||||
bool parseAuraUpdate(network::Packet& packet, AuraUpdateData& data, bool isAll = false) override;
|
||||
bool parseNameQueryResponse(network::Packet& packet, NameQueryResponseData& data) override;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -995,8 +995,10 @@ void GameHandler::handlePacket(network::Packet& packet) {
|
|||
case Opcode::SMSG_PERIODICAURALOG:
|
||||
case Opcode::SMSG_SPELLENERGIZELOG:
|
||||
case Opcode::SMSG_ENVIRONMENTALDAMAGELOG:
|
||||
break;
|
||||
|
||||
case Opcode::SMSG_LOOT_MONEY_NOTIFY: {
|
||||
// uint32 money + uint8 soleLooter
|
||||
// Format: uint32 money + uint8 soleLooter
|
||||
if (packet.getSize() - packet.getReadPos() >= 4) {
|
||||
uint32_t amount = packet.readUInt32();
|
||||
playerMoneyCopper_ += amount;
|
||||
|
|
@ -4873,7 +4875,10 @@ std::string GameHandler::getCachedCreatureName(uint32_t entry) const {
|
|||
|
||||
void GameHandler::handleNameQueryResponse(network::Packet& packet) {
|
||||
NameQueryResponseData data;
|
||||
if (!NameQueryResponseParser::parse(packet, data)) return;
|
||||
if (!packetParsers_ || !packetParsers_->parseNameQueryResponse(packet, data)) {
|
||||
LOG_WARNING("Failed to parse SMSG_NAME_QUERY_RESPONSE (size=", packet.getSize(), ")");
|
||||
return;
|
||||
}
|
||||
|
||||
pendingNameQueries.erase(data.guid);
|
||||
|
||||
|
|
|
|||
|
|
@ -459,5 +459,78 @@ bool TbcPacketParsers::parseAuraUpdate(network::Packet& /*packet*/, AuraUpdateDa
|
|||
return false;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// TBC/Classic parseNameQueryResponse
|
||||
//
|
||||
// WotLK uses: packedGuid + uint8 found + name + realmName + u8 race + u8 gender + u8 class
|
||||
// Classic/TBC commonly use: uint64 guid + [optional uint8 found] + CString name + uint32 race + uint32 gender + uint32 class
|
||||
//
|
||||
// Implement a robust parser that handles both classic-era variants.
|
||||
// ============================================================================
|
||||
static bool hasNullWithin(const network::Packet& p, size_t start, size_t maxLen) {
|
||||
const auto& d = p.getData();
|
||||
size_t end = std::min(d.size(), start + maxLen);
|
||||
for (size_t i = start; i < end; i++) {
|
||||
if (d[i] == 0) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TbcPacketParsers::parseNameQueryResponse(network::Packet& packet, NameQueryResponseData& data) {
|
||||
// Default all fields
|
||||
data = NameQueryResponseData{};
|
||||
|
||||
size_t start = packet.getReadPos();
|
||||
if (packet.getSize() - start < 8) return false;
|
||||
|
||||
// Variant A: guid(u64) + name + race(u32) + gender(u32) + class(u32)
|
||||
{
|
||||
packet.setReadPos(start);
|
||||
data.guid = packet.readUInt64();
|
||||
data.found = 0;
|
||||
data.name = packet.readString();
|
||||
if (!data.name.empty() && (packet.getSize() - packet.getReadPos()) >= 12) {
|
||||
uint32_t race = packet.readUInt32();
|
||||
uint32_t gender = packet.readUInt32();
|
||||
uint32_t cls = packet.readUInt32();
|
||||
data.race = static_cast<uint8_t>(race & 0xFF);
|
||||
data.gender = static_cast<uint8_t>(gender & 0xFF);
|
||||
data.classId = static_cast<uint8_t>(cls & 0xFF);
|
||||
data.realmName.clear();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Variant B: guid(u64) + found(u8) + [if found==0: name + race(u32)+gender(u32)+class(u32)]
|
||||
{
|
||||
packet.setReadPos(start);
|
||||
data.guid = packet.readUInt64();
|
||||
if (packet.getSize() - packet.getReadPos() < 1) {
|
||||
packet.setReadPos(start);
|
||||
return false;
|
||||
}
|
||||
uint8_t found = packet.readUInt8();
|
||||
// Guard: only treat it as a found flag if a CString likely follows.
|
||||
if ((found == 0 || found == 1) && hasNullWithin(packet, packet.getReadPos(), 64)) {
|
||||
data.found = found;
|
||||
if (data.found != 0) return true;
|
||||
data.name = packet.readString();
|
||||
if (!data.name.empty() && (packet.getSize() - packet.getReadPos()) >= 12) {
|
||||
uint32_t race = packet.readUInt32();
|
||||
uint32_t gender = packet.readUInt32();
|
||||
uint32_t cls = packet.readUInt32();
|
||||
data.race = static_cast<uint8_t>(race & 0xFF);
|
||||
data.gender = static_cast<uint8_t>(gender & 0xFF);
|
||||
data.classId = static_cast<uint8_t>(cls & 0xFF);
|
||||
data.realmName.clear();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
packet.setReadPos(start);
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace game
|
||||
} // namespace wowee
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue