mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-22 23:30:14 +00:00
feat: cache player class/race from name queries for UnitClass/UnitRace
Add playerClassRaceCache_ that stores classId and raceId from SMSG_NAME_QUERY_RESPONSE. This enables UnitClass and UnitRace to return correct data for players who were previously seen but are now out of UPDATE_OBJECT range. Fallback chain for UnitClass/UnitRace is now: 1. Entity update fields (UNIT_FIELD_BYTES_0) — for nearby entities 2. Name query cache — for previously queried players 3. getPlayerClass/Race() — for the local player This improves class-colored names in chat, unit frames, and nameplates for players who move out of view range.
This commit is contained in:
parent
d6a25ca8f2
commit
cfb9e09e1d
3 changed files with 21 additions and 7 deletions
|
|
@ -1235,6 +1235,16 @@ public:
|
||||||
// Player GUID
|
// Player GUID
|
||||||
uint64_t getPlayerGuid() const { return playerGuid; }
|
uint64_t getPlayerGuid() const { return playerGuid; }
|
||||||
|
|
||||||
|
// Look up class/race for a player GUID from name query cache. Returns 0 if unknown.
|
||||||
|
uint8_t lookupPlayerClass(uint64_t guid) const {
|
||||||
|
auto it = playerClassRaceCache_.find(guid);
|
||||||
|
return it != playerClassRaceCache_.end() ? it->second.classId : 0;
|
||||||
|
}
|
||||||
|
uint8_t lookupPlayerRace(uint64_t guid) const {
|
||||||
|
auto it = playerClassRaceCache_.find(guid);
|
||||||
|
return it != playerClassRaceCache_.end() ? it->second.raceId : 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Look up a display name for any guid: checks playerNameCache then entity manager.
|
// Look up a display name for any guid: checks playerNameCache then entity manager.
|
||||||
// Returns empty string if unknown. Used by chat display to resolve names at render time.
|
// Returns empty string if unknown. Used by chat display to resolve names at render time.
|
||||||
const std::string& lookupName(uint64_t guid) const {
|
const std::string& lookupName(uint64_t guid) const {
|
||||||
|
|
@ -2710,6 +2720,9 @@ private:
|
||||||
|
|
||||||
// ---- Phase 1: Name caches ----
|
// ---- Phase 1: Name caches ----
|
||||||
std::unordered_map<uint64_t, std::string> playerNameCache;
|
std::unordered_map<uint64_t, std::string> playerNameCache;
|
||||||
|
// Class/race cache from SMSG_NAME_QUERY_RESPONSE (guid → {classId, raceId})
|
||||||
|
struct PlayerClassRace { uint8_t classId = 0; uint8_t raceId = 0; };
|
||||||
|
std::unordered_map<uint64_t, PlayerClassRace> playerClassRaceCache_;
|
||||||
std::unordered_set<uint64_t> pendingNameQueries;
|
std::unordered_set<uint64_t> pendingNameQueries;
|
||||||
std::unordered_map<uint32_t, CreatureQueryResponseData> creatureInfoCache;
|
std::unordered_map<uint32_t, CreatureQueryResponseData> creatureInfoCache;
|
||||||
std::unordered_set<uint32_t> pendingCreatureQueries;
|
std::unordered_set<uint32_t> pendingCreatureQueries;
|
||||||
|
|
|
||||||
|
|
@ -295,14 +295,9 @@ static int lua_UnitClass(lua_State* L) {
|
||||||
classId = static_cast<uint8_t>((bytes0 >> 8) & 0xFF);
|
classId = static_cast<uint8_t>((bytes0 >> 8) & 0xFF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Fallback: check party/raid member data
|
// Fallback: check name query class/race cache
|
||||||
if (classId == 0 && guid != 0) {
|
if (classId == 0 && guid != 0) {
|
||||||
for (const auto& m : gh->getPartyData().members) {
|
classId = gh->lookupPlayerClass(guid);
|
||||||
if (m.guid == guid && m.hasPartyStats) {
|
|
||||||
// Party stats don't have class, but check guild roster
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const char* name = (classId > 0 && classId < 12) ? kClasses[classId] : "Unknown";
|
const char* name = (classId > 0 && classId < 12) ? kClasses[classId] : "Unknown";
|
||||||
|
|
@ -493,6 +488,8 @@ static int lua_UnitRace(lua_State* L) {
|
||||||
game::fieldIndex(game::UF::UNIT_FIELD_BYTES_0));
|
game::fieldIndex(game::UF::UNIT_FIELD_BYTES_0));
|
||||||
raceId = static_cast<uint8_t>(bytes0 & 0xFF);
|
raceId = static_cast<uint8_t>(bytes0 & 0xFF);
|
||||||
}
|
}
|
||||||
|
// Fallback: name query class/race cache
|
||||||
|
if (raceId == 0) raceId = gh->lookupPlayerRace(guid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const char* name = (raceId > 0 && raceId < 12) ? kRaces[raceId] : "Unknown";
|
const char* name = (raceId > 0 && raceId < 12) ? kRaces[raceId] : "Unknown";
|
||||||
|
|
|
||||||
|
|
@ -14819,6 +14819,10 @@ void GameHandler::handleNameQueryResponse(network::Packet& packet) {
|
||||||
|
|
||||||
if (data.isValid()) {
|
if (data.isValid()) {
|
||||||
playerNameCache[data.guid] = data.name;
|
playerNameCache[data.guid] = data.name;
|
||||||
|
// Cache class/race from name query for UnitClass/UnitRace fallback
|
||||||
|
if (data.classId != 0 || data.race != 0) {
|
||||||
|
playerClassRaceCache_[data.guid] = {data.classId, data.race};
|
||||||
|
}
|
||||||
// Update entity name
|
// Update entity name
|
||||||
auto entity = entityManager.getEntity(data.guid);
|
auto entity = entityManager.getEntity(data.guid);
|
||||||
if (entity && entity->getType() == ObjectType::PLAYER) {
|
if (entity && entity->getType() == ObjectType::PLAYER) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue