mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-22 23:30:14 +00:00
ui: resolve chat sender names at render time to fix [Say] prefix
When SMSG_MESSAGECHAT arrives before the entity has spawned or its name is cached, senderName is empty and messages fell through to the generic '[Say] message' branch. Fix: - GameHandler::lookupName(guid): checks playerNameCache then entity manager (Unit subclass cast) at call time - Chat display: resolves senderName via lookupName() at render time so messages show "Name says: msg" even if the name was unavailable when the packet was first parsed
This commit is contained in:
parent
4987388ce7
commit
942df21c66
2 changed files with 34 additions and 8 deletions
|
|
@ -823,6 +823,22 @@ public:
|
||||||
|
|
||||||
// Player GUID
|
// Player GUID
|
||||||
uint64_t getPlayerGuid() const { return playerGuid; }
|
uint64_t getPlayerGuid() const { return playerGuid; }
|
||||||
|
|
||||||
|
// 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 {
|
||||||
|
static const std::string kEmpty;
|
||||||
|
auto it = playerNameCache.find(guid);
|
||||||
|
if (it != playerNameCache.end()) return it->second;
|
||||||
|
auto entity = entityManager.getEntity(guid);
|
||||||
|
if (entity) {
|
||||||
|
if (auto* unit = dynamic_cast<const Unit*>(entity.get())) {
|
||||||
|
if (!unit->getName().empty()) return unit->getName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return kEmpty;
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t getPlayerClass() const {
|
uint8_t getPlayerClass() const {
|
||||||
const Character* ch = getActiveCharacter();
|
const Character* ch = getActiveCharacter();
|
||||||
return ch ? static_cast<uint8_t>(ch->characterClass) : 0;
|
return ch ? static_cast<uint8_t>(ch->characterClass) : 0;
|
||||||
|
|
|
||||||
|
|
@ -1181,6 +1181,16 @@ void GameScreen::renderChatWindow(game::GameHandler& gameHandler) {
|
||||||
if (!shouldShowMessage(msg, activeChatTab_)) continue;
|
if (!shouldShowMessage(msg, activeChatTab_)) continue;
|
||||||
std::string processedMessage = replaceGenderPlaceholders(msg.message, gameHandler);
|
std::string processedMessage = replaceGenderPlaceholders(msg.message, gameHandler);
|
||||||
|
|
||||||
|
// Resolve sender name at render time in case it wasn't available at parse time.
|
||||||
|
// This handles the race where SMSG_MESSAGECHAT arrives before the entity spawns.
|
||||||
|
const std::string& resolvedSenderName = [&]() -> const std::string& {
|
||||||
|
if (!msg.senderName.empty()) return msg.senderName;
|
||||||
|
if (msg.senderGuid == 0) return msg.senderName;
|
||||||
|
const std::string& cached = gameHandler.lookupName(msg.senderGuid);
|
||||||
|
if (!cached.empty()) return cached;
|
||||||
|
return msg.senderName;
|
||||||
|
}();
|
||||||
|
|
||||||
ImVec4 color = getChatTypeColor(msg.type);
|
ImVec4 color = getChatTypeColor(msg.type);
|
||||||
|
|
||||||
// Optional timestamp prefix
|
// Optional timestamp prefix
|
||||||
|
|
@ -1208,36 +1218,36 @@ void GameScreen::renderChatWindow(game::GameHandler& gameHandler) {
|
||||||
renderTextWithLinks(tsPrefix + processedMessage, color);
|
renderTextWithLinks(tsPrefix + processedMessage, color);
|
||||||
} else if (msg.type == game::ChatType::TEXT_EMOTE) {
|
} else if (msg.type == game::ChatType::TEXT_EMOTE) {
|
||||||
renderTextWithLinks(tsPrefix + processedMessage, color);
|
renderTextWithLinks(tsPrefix + processedMessage, color);
|
||||||
} else if (!msg.senderName.empty()) {
|
} else if (!resolvedSenderName.empty()) {
|
||||||
if (msg.type == game::ChatType::SAY ||
|
if (msg.type == game::ChatType::SAY ||
|
||||||
msg.type == game::ChatType::MONSTER_SAY || msg.type == game::ChatType::MONSTER_PARTY) {
|
msg.type == game::ChatType::MONSTER_SAY || msg.type == game::ChatType::MONSTER_PARTY) {
|
||||||
std::string fullMsg = tsPrefix + tagPrefix + msg.senderName + " says: " + processedMessage;
|
std::string fullMsg = tsPrefix + tagPrefix + resolvedSenderName + " says: " + processedMessage;
|
||||||
renderTextWithLinks(fullMsg, color);
|
renderTextWithLinks(fullMsg, color);
|
||||||
} else if (msg.type == game::ChatType::YELL || msg.type == game::ChatType::MONSTER_YELL) {
|
} else if (msg.type == game::ChatType::YELL || msg.type == game::ChatType::MONSTER_YELL) {
|
||||||
std::string fullMsg = tsPrefix + tagPrefix + msg.senderName + " yells: " + processedMessage;
|
std::string fullMsg = tsPrefix + tagPrefix + resolvedSenderName + " yells: " + processedMessage;
|
||||||
renderTextWithLinks(fullMsg, color);
|
renderTextWithLinks(fullMsg, color);
|
||||||
} else if (msg.type == game::ChatType::WHISPER ||
|
} else if (msg.type == game::ChatType::WHISPER ||
|
||||||
msg.type == game::ChatType::MONSTER_WHISPER || msg.type == game::ChatType::RAID_BOSS_WHISPER) {
|
msg.type == game::ChatType::MONSTER_WHISPER || msg.type == game::ChatType::RAID_BOSS_WHISPER) {
|
||||||
std::string fullMsg = tsPrefix + tagPrefix + msg.senderName + " whispers: " + processedMessage;
|
std::string fullMsg = tsPrefix + tagPrefix + resolvedSenderName + " whispers: " + processedMessage;
|
||||||
renderTextWithLinks(fullMsg, color);
|
renderTextWithLinks(fullMsg, color);
|
||||||
} else if (msg.type == game::ChatType::WHISPER_INFORM) {
|
} else if (msg.type == game::ChatType::WHISPER_INFORM) {
|
||||||
// Outgoing whisper — show "To Name: message" (WoW-style)
|
// Outgoing whisper — show "To Name: message" (WoW-style)
|
||||||
const std::string& target = !msg.receiverName.empty() ? msg.receiverName : msg.senderName;
|
const std::string& target = !msg.receiverName.empty() ? msg.receiverName : resolvedSenderName;
|
||||||
std::string fullMsg = tsPrefix + "To " + target + ": " + processedMessage;
|
std::string fullMsg = tsPrefix + "To " + target + ": " + processedMessage;
|
||||||
renderTextWithLinks(fullMsg, color);
|
renderTextWithLinks(fullMsg, color);
|
||||||
} else if (msg.type == game::ChatType::EMOTE ||
|
} else if (msg.type == game::ChatType::EMOTE ||
|
||||||
msg.type == game::ChatType::MONSTER_EMOTE || msg.type == game::ChatType::RAID_BOSS_EMOTE) {
|
msg.type == game::ChatType::MONSTER_EMOTE || msg.type == game::ChatType::RAID_BOSS_EMOTE) {
|
||||||
std::string fullMsg = tsPrefix + tagPrefix + msg.senderName + " " + processedMessage;
|
std::string fullMsg = tsPrefix + tagPrefix + resolvedSenderName + " " + processedMessage;
|
||||||
renderTextWithLinks(fullMsg, color);
|
renderTextWithLinks(fullMsg, color);
|
||||||
} else if (msg.type == game::ChatType::CHANNEL && !msg.channelName.empty()) {
|
} else if (msg.type == game::ChatType::CHANNEL && !msg.channelName.empty()) {
|
||||||
int chIdx = gameHandler.getChannelIndex(msg.channelName);
|
int chIdx = gameHandler.getChannelIndex(msg.channelName);
|
||||||
std::string chDisplay = chIdx > 0
|
std::string chDisplay = chIdx > 0
|
||||||
? "[" + std::to_string(chIdx) + ". " + msg.channelName + "]"
|
? "[" + std::to_string(chIdx) + ". " + msg.channelName + "]"
|
||||||
: "[" + msg.channelName + "]";
|
: "[" + msg.channelName + "]";
|
||||||
std::string fullMsg = tsPrefix + chDisplay + " [" + tagPrefix + msg.senderName + "]: " + processedMessage;
|
std::string fullMsg = tsPrefix + chDisplay + " [" + tagPrefix + resolvedSenderName + "]: " + processedMessage;
|
||||||
renderTextWithLinks(fullMsg, color);
|
renderTextWithLinks(fullMsg, color);
|
||||||
} else {
|
} else {
|
||||||
std::string fullMsg = tsPrefix + "[" + std::string(getChatTypeName(msg.type)) + "] " + tagPrefix + msg.senderName + ": " + processedMessage;
|
std::string fullMsg = tsPrefix + "[" + std::string(getChatTypeName(msg.type)) + "] " + tagPrefix + resolvedSenderName + ": " + processedMessage;
|
||||||
renderTextWithLinks(fullMsg, color);
|
renderTextWithLinks(fullMsg, color);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue