diff --git a/include/game/game_handler.hpp b/include/game/game_handler.hpp index 5208bc53..145f2f48 100644 --- a/include/game/game_handler.hpp +++ b/include/game/game_handler.hpp @@ -1235,6 +1235,16 @@ public: // Player GUID 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. // Returns empty string if unknown. Used by chat display to resolve names at render time. const std::string& lookupName(uint64_t guid) const { @@ -2710,6 +2720,9 @@ private: // ---- Phase 1: Name caches ---- std::unordered_map 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 playerClassRaceCache_; std::unordered_set pendingNameQueries; std::unordered_map creatureInfoCache; std::unordered_set pendingCreatureQueries; diff --git a/src/addons/lua_engine.cpp b/src/addons/lua_engine.cpp index c0759ebd..b3ad636e 100644 --- a/src/addons/lua_engine.cpp +++ b/src/addons/lua_engine.cpp @@ -295,14 +295,9 @@ static int lua_UnitClass(lua_State* L) { classId = static_cast((bytes0 >> 8) & 0xFF); } } - // Fallback: check party/raid member data + // Fallback: check name query class/race cache if (classId == 0 && guid != 0) { - for (const auto& m : gh->getPartyData().members) { - if (m.guid == guid && m.hasPartyStats) { - // Party stats don't have class, but check guild roster - break; - } - } + classId = gh->lookupPlayerClass(guid); } } 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)); raceId = static_cast(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"; diff --git a/src/game/game_handler.cpp b/src/game/game_handler.cpp index 60706f69..03365c10 100644 --- a/src/game/game_handler.cpp +++ b/src/game/game_handler.cpp @@ -14819,6 +14819,10 @@ void GameHandler::handleNameQueryResponse(network::Packet& packet) { if (data.isValid()) { 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 auto entity = entityManager.getEntity(data.guid); if (entity && entity->getType() == ObjectType::PLAYER) {