From 6078989cb106d398cb0cedcc933da18a07b557fe Mon Sep 17 00:00:00 2001 From: Florian Berthold Date: Sun, 24 May 2026 17:38:22 +0200 Subject: [PATCH] fix(login): defer downgrade popup, guard data, include CoA classes Three fixes addressing the reported 'auras silently vanish on next save' bug, plus collateral robustness in the same code path: 1. WeakAuras.lua PLAYER_LOGIN handler (~L1297-1308): the downgrade branch fired StaticPopup_Show('WEAKAURAS_CONFIRM_REPAIR', ...) synchronously inside the event handler. On the CoA reworked StaticPopup system this fires too early and silently fails to show the dialog, which means neither OnAccept nor OnCancel ever runs, so Private.Login() is never called. With no displays loaded, the next PLAYER_LOGOUT serializes an empty table over WeakAurasSaved and the user loses all their auras. Wrap the call in C_Timer.After(0, ...) so it fires after the event frame stack has unwound and the popup system is ready. This is the most likely root cause of the user report 'my auras don't save anymore' that surfaced on the PTR last week. 2. WeakAuras.lua WEAKAURAS_CONFIRM_REPAIR popup (~L2263-2277): OnShow and OnCancel both unconditionally dereferenced self.data.reason. If the popup is ever fired with nil or malformed data this throws and blocks Private.Login() from running via the OnCancel fallback. Guard with a nil check and default reason to 'unknown' (treated as the automatic / downgrade path, which is the safe default that still invokes Login). 3. Types.lua WeakAuras.class_types (~L1187): only populated from CLASS_SORT_ORDER, which on CoA contains only the 11 vanilla classes. The 21 custom CoA classes were silently missing from every class filter dropdown in the options UI. Add a fallback loop over LOCALIZED_CLASS_NAMES_MALE for anything CLASS_SORT_ORDER didn't already register, mirroring the pattern the spec builder uses at ~L3829. --- WeakAuras/Types.lua | 10 ++++++++++ WeakAuras/WeakAuras.lua | 27 +++++++++++++++++++++++---- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/WeakAuras/Types.lua b/WeakAuras/Types.lua index 428e594..214b6e3 100644 --- a/WeakAuras/Types.lua +++ b/WeakAuras/Types.lua @@ -1187,6 +1187,16 @@ WeakAuras.class_types = {} for i, class in ipairs(CLASS_SORT_ORDER) do WeakAuras.class_types[class] = WrapTextInColorCode(LOCALIZED_CLASS_NAMES_MALE[class], WA_GetClassColor(class)) end +-- CoA: CLASS_SORT_ORDER only contains the 11 vanilla classes, missing the 21 +-- custom CoA classes. Fall back to LOCALIZED_CLASS_NAMES_MALE for anything not +-- yet registered. Same pattern used by the spec builder further down this file. +if LOCALIZED_CLASS_NAMES_MALE then + for class in pairs(LOCALIZED_CLASS_NAMES_MALE) do + if not WeakAuras.class_types[class] then + WeakAuras.class_types[class] = WrapTextInColorCode(LOCALIZED_CLASS_NAMES_MALE[class], WA_GetClassColor(class)) + end + end +end if WeakAuras.IsClassicPlus() then WeakAuras.class_types["DEATHKNIGHT"] = nil end diff --git a/WeakAuras/WeakAuras.lua b/WeakAuras/WeakAuras.lua index df00e53..0358bb2 100644 --- a/WeakAuras/WeakAuras.lua +++ b/WeakAuras/WeakAuras.lua @@ -1304,8 +1304,16 @@ loadedFrame:SetScript("OnEvent", function(self, event, ...) if dbIsValid then Private.Login(takeNewSnapshots) else - -- db isn't valid. Request permission to run repair tool before logging in - StaticPopup_Show("WEAKAURAS_CONFIRM_REPAIR", nil, nil, {reason = "downgrade"}) + -- db isn't valid. Request permission to run repair tool before logging in. + -- CoA: defer the StaticPopup_Show by one frame so it fires after the + -- PLAYER_LOGIN event-frame stack has unwound. On the CoA reworked + -- StaticPopup system, firing this synchronously during PLAYER_LOGIN + -- silently fails to show the popup, which means Private.Login() is + -- never invoked, no auras load, and the next logout writes an empty + -- WeakAurasSaved over the user's profile. + C_Timer.After(0, function() + StaticPopup_Show("WEAKAURAS_CONFIRM_REPAIR", nil, nil, {reason = "downgrade"}) + end) end elseif event == "PLAYER_LOGOUT" then for id in pairs(db.displays) do @@ -2264,14 +2272,25 @@ StaticPopupDialogs["WEAKAURAS_CONFIRM_REPAIR"] = { local AutomaticRepairText = L["WeakAuras has detected that it has been downgraded.\nYour saved auras may no longer work properly.\nWould you like to run the |cffff0000EXPERIMENTAL|r repair tool? This will overwrite any changes you have made since the last database upgrade.\nLast upgrade: %s\n\n|cffff0000You should BACKUP your WTF folder BEFORE pressing this button.|r"] local ManualRepairText = L["Are you sure you want to run the |cffff0000EXPERIMENTAL|r repair tool?\nThis will overwrite any changes you have made since the last database upgrade.\nLast upgrade: %s"] - if self.data.reason == "user" then + -- CoA: guard against malformed data; default reason to "unknown" so the + -- popup can't error out and block Private.Login() from ever running. + local reason = "unknown" + if self.data then + reason = self.data.reason or "unknown" + end + + if reason == "user" then self.text:SetText(ManualRepairText:format(LastUpgrade())) else self.text:SetText(AutomaticRepairText:format(LastUpgrade())) end end, OnCancel = function(self) - if self.data.reason ~= "user" then + local reason = "unknown" + if self.data then + reason = self.data.reason or "unknown" + end + if reason ~= "user" then Private.Login() end end,