From 60f953178fec03659ea678ae5aa6cae073c4f0ea Mon Sep 17 00:00:00 2001 From: Brues <5278969+brues-code@users.noreply.github.com> Date: Wed, 2 Sep 2026 10:56:46 -0500 Subject: [PATCH] nameplates: validate unitstr before filling the per-unit cache cache.player and cache.minion were filled from unitstr before the two guards that validate it, so a stale identifier poisoned the cache -- and because the fill is gated on `== nil`, the wrong answer was never recomputed. Players read back as cache.player == false until the plate was hidden and shown again, which only appeared to fix it because pool reuse tripped the name/guid wipe. Two paths produce a stale unitstr: OnUpdate dispatches a targetUpdate to OnDataChanged before it refreshes plate.istarget, and frameState.mouseoverGuid is only updated on gaining mouseover, never on losing it. Hoist the PLAYER_TARGET_CHANGED distrust and the UnitName mismatch check above the cache fill so an unverified unitstr leaves the cache nil for the next tick instead of locking in a wrong answer. --- modules/nameplates.lua | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/modules/nameplates.lua b/modules/nameplates.lua index 5a46e307..b9a94b27 100644 --- a/modules/nameplates.lua +++ b/modules/nameplates.lua @@ -1039,6 +1039,16 @@ nameplates:RegisterEvent("PLAYER_GUILD_UPDATE") local mouseover = plate.cachedGuid and plate.cachedGuid == frameState.mouseoverGuid or nil local unitstr = target and "target" or mouseover and "mouseover" or plate.cachedGuid or nil + -- target event sometimes fires too quickly, where nameplate identifiers are not + -- yet updated. So while being inside this event, we cannot trust the unitstr. + if event == "PLAYER_TARGET_CHANGED" then unitstr = nil end + + -- remove unitstr when it doesn't resolve to this plate's unit (stale istarget, + -- stale mouseover guid or a despawned unit). Must run before the cache fills + -- below -- an unrelated unitstr would poison cache.player/minion with the + -- *other* unit's answer, and the nil-gate would then never recompute it. + if unitstr and UnitName(unitstr) ~= name then unitstr = nil end + -- resolve player vs npc from plate's own unit so libunitscan can't return -- a player record for an NPC sharing the same name (e.g. Chromie). Stored -- as true/false/nil so it doubles as the GetUnitInfo hint. @@ -1076,13 +1086,6 @@ nameplates:RegisterEvent("PLAYER_GUILD_UPDATE") -- skip data updates on invisible frames if not visible then return end - -- target event sometimes fires too quickly, where nameplate identifiers are not - -- yet updated. So while being inside this event, we cannot trust the unitstr. - if event == "PLAYER_TARGET_CHANGED" then unitstr = nil end - - -- remove unitstr on unit name mismatch - if unitstr and UnitName(unitstr) ~= name then unitstr = nil end - -- always make sure to keep plate visible plate:Show()