From 568cd44af8465b34228be8de6f9b150e482b5dea Mon Sep 17 00:00:00 2001 From: Xurkon Date: Fri, 12 Jun 2026 06:48:53 -0500 Subject: [PATCH] fix: port Phase 1 perf/correctness audit fixes onto main Brings the still-needed changes from questie-phase1perf that main lacked. Main already had the Lua 5.0 shims (QuestieLoader bit/strsplit, QuestieStream and QuestieSerializer math.mod sweep), so those are omitted. - QuestieNameplate: skip missing entries instead of return-aborting the whole activeGUIDs loop (one bad unit no longer stalls every nameplate update) - QuestieQuest.ClearAllNotes: skip DB-missing quests instead of aborting, so remaining quests' notes still get cleared - QuestieOptionsTracker: fix fadeTickerValue:Cancel -> fadeTicker:Cancel (3x); fadeTickerValue is a number, the ticker handle is fadeTicker - QuestieCommsData: nil-guard GetNPC/GetObject before reading .name - QuestieAnnounce: bound the alreadySentBandaid dedup cache (reset at 1000) - QuestieDB.IsComplete: hoist GetQuest into expectedQuest (one call, not two) - QuestieFramePool/QuestieFrame: drop the dead BaseOnUpdate ticker branch (BaseOnUpdate was never defined; behavior was always OnUpdate=nil) - QuestieLib: document unused questId arg on Ascension_IsScalingEnabled - Database/Corrections x3: strip stray UTF-8 BOM - Questie-X.toc: remove duplicate QuestieSlash.lua load line --- Database/Corrections/tbcQuestFixes.lua | 2 +- Database/Corrections/wotlkItemFixes.lua | 2 +- Database/Corrections/wotlkQuestFixes.lua | 2 +- Database/QuestieDB.lua | 3 +- Modules/FramePool/QuestieFrame.lua | 1 - Modules/FramePool/QuestieFramePool.lua | 8 ++--- Modules/Libs/QuestieLib.lua | 2 +- Modules/Network/QuestieCommsData.lua | 6 ++-- .../TrackerTab/QuestieOptionsTracker.lua | 6 ++-- Modules/Quest/QuestieQuest.lua | 28 ++++++++--------- Modules/QuestieAnnounce.lua | 13 +++++++- Modules/QuestieNameplate.lua | 30 +++++++++---------- Questie-X.toc | 1 - 13 files changed, 57 insertions(+), 47 deletions(-) diff --git a/Database/Corrections/tbcQuestFixes.lua b/Database/Corrections/tbcQuestFixes.lua index 61a9336..9188576 100644 --- a/Database/Corrections/tbcQuestFixes.lua +++ b/Database/Corrections/tbcQuestFixes.lua @@ -1,4 +1,4 @@ ----@class QuestieTBCQuestFixes +---@class QuestieTBCQuestFixes local QuestieTBCQuestFixes = QuestieLoader:CreateModule("QuestieTBCQuestFixes") local _QuestieTBCQuestFixes = {} diff --git a/Database/Corrections/wotlkItemFixes.lua b/Database/Corrections/wotlkItemFixes.lua index cc6af06..30308ea 100644 --- a/Database/Corrections/wotlkItemFixes.lua +++ b/Database/Corrections/wotlkItemFixes.lua @@ -1,4 +1,4 @@ ----@class QuestieWotlkItemFixes +---@class QuestieWotlkItemFixes local QuestieWotlkItemFixes = QuestieLoader:CreateModule("QuestieWotlkItemFixes") local _QuestieWotlkItemFixes = {} diff --git a/Database/Corrections/wotlkQuestFixes.lua b/Database/Corrections/wotlkQuestFixes.lua index 38ff73d..9e6bbc0 100644 --- a/Database/Corrections/wotlkQuestFixes.lua +++ b/Database/Corrections/wotlkQuestFixes.lua @@ -1,4 +1,4 @@ ----@class QuestieWotlkQuestFixes +---@class QuestieWotlkQuestFixes local QuestieWotlkQuestFixes = QuestieLoader:CreateModule("QuestieWotlkQuestFixes") local _QuestieWotlkQuestFixes = {} diff --git a/Database/QuestieDB.lua b/Database/QuestieDB.lua index 1d3c5b5..bfef8ee 100644 --- a/Database/QuestieDB.lua +++ b/Database/QuestieDB.lua @@ -1656,7 +1656,8 @@ function QuestieDB.IsComplete(questId) -- Before assuming an empty objective list means the quest is done, check if we *expect* objectives from the DB. -- On WotLK private servers, GetQuestObjectives sometimes transiently returns nil during cache rebuilds, -- which leads to IsComplete prematurely returning 1 and unloading map icons in the middle of a quest. - local expectedObjectives = QuestieDB.GetQuest(questId) and QuestieDB.GetQuest(questId).ObjectiveData + local expectedQuest = QuestieDB.GetQuest(questId) + local expectedObjectives = expectedQuest and expectedQuest.ObjectiveData if expectedObjectives and table.getn(expectedObjectives) > 0 then return 0 end diff --git a/Modules/FramePool/QuestieFrame.lua b/Modules/FramePool/QuestieFrame.lua index bfb2298..3593210 100644 --- a/Modules/FramePool/QuestieFrame.lua +++ b/Modules/FramePool/QuestieFrame.lua @@ -130,7 +130,6 @@ if not QuestieCompat.Is335 then newFrame:SetScript("OnClick", _Qframe.OnClick); newFrame.GlowUpdate = _Qframe.GlowUpdate - newFrame.BaseOnUpdate = _Qframe.BaseOnUpdate newFrame.BaseOnShow = _Qframe.BaseOnShow newFrame.BaseOnHide = _Qframe.BaseOnHide diff --git a/Modules/FramePool/QuestieFramePool.lua b/Modules/FramePool/QuestieFramePool.lua index dd75ba3..6924d04 100644 --- a/Modules/FramePool/QuestieFramePool.lua +++ b/Modules/FramePool/QuestieFramePool.lua @@ -106,11 +106,9 @@ function QuestieFramePool:GetFrame() returnFrame:SetScript("OnShow", returnFrame.BaseOnShow) end - if returnFrame.BaseOnUpdate then - returnFrame.glowLogicTimer = C_Timer.NewTicker(1, returnFrame.BaseOnUpdate); - else - returnFrame:SetScript("OnUpdate", nil) - end + -- BaseOnUpdate was never defined, so the glowLogicTimer branch was always dead + -- and this always cleared OnUpdate. Preserve that effect, drop the dead branch. + returnFrame:SetScript("OnUpdate", nil) if returnFrame.BaseOnHide then returnFrame:SetScript("OnHide", returnFrame.BaseOnHide) diff --git a/Modules/Libs/QuestieLib.lua b/Modules/Libs/QuestieLib.lua index 96c56da..6b7283f 100644 --- a/Modules/Libs/QuestieLib.lua +++ b/Modules/Libs/QuestieLib.lua @@ -30,7 +30,7 @@ local tonumber = tonumber -- ================================= -- Ascension Level Scaling (Core) -- ================================= -local function Ascension_IsScalingEnabled() +local function Ascension_IsScalingEnabled(questId) -- questId accepted (unused) to match call sites and clear the arity lint return Questie.db and Questie.db.profile and Questie.db.profile.enableAscensionScaling end diff --git a/Modules/Network/QuestieCommsData.lua b/Modules/Network/QuestieCommsData.lua index f825774..1267fd7 100644 --- a/Modules/Network/QuestieCommsData.lua +++ b/Modules/Network/QuestieCommsData.lua @@ -46,9 +46,11 @@ function QuestieComms.data:GetTooltip(tooltipKey) end local oName = ""; if((objective.type == "monster" or objective.type == "m") and objective.id) then - oName = QuestieDB:GetNPC(objective.id).name; + local npc = QuestieDB:GetNPC(objective.id); + oName = (npc and npc.name) or oName; elseif((objective.type == "object" or objective.type == "o") and objective.id) then - oName = QuestieDB:GetObject(objective.id).name; + local obj = QuestieDB:GetObject(objective.id); + oName = (obj and obj.name) or oName; elseif((objective.type == "item" or objective.type == "i") and objective.id) then local dbItem = QuestieDB:GetItem(objective.id); if(dbItem and dbItem.name and (not dbItem.Hidden)) then diff --git a/Modules/Options/TrackerTab/QuestieOptionsTracker.lua b/Modules/Options/TrackerTab/QuestieOptionsTracker.lua index 2eb9e8a..80647bb 100644 --- a/Modules/Options/TrackerTab/QuestieOptionsTracker.lua +++ b/Modules/Options/TrackerTab/QuestieOptionsTracker.lua @@ -483,7 +483,7 @@ function QuestieOptions.tabs.tracker:Initialize() TrackerLinePool.SetAllExpandQuestAlpha(fadeTickerValue) end else - fadeTickerValue:Cancel() + fadeTicker:Cancel() TrackerLinePool.SetAllExpandQuestAlpha(0) end end) @@ -519,7 +519,7 @@ function QuestieOptions.tabs.tracker:Initialize() TrackerLinePool.SetAllItemButtonAlpha(fadeTickerValue) end else - fadeTickerValue:Cancel() + fadeTicker:Cancel() TrackerLinePool.SetAllItemButtonAlpha(0) end end) @@ -794,7 +794,7 @@ function QuestieOptions.tabs.tracker:Initialize() end end else - fadeTickerValue:Cancel() + fadeTicker:Cancel() end end) end diff --git a/Modules/Quest/QuestieQuest.lua b/Modules/Quest/QuestieQuest.lua index d7e1f38..bf1b63a 100644 --- a/Modules/Quest/QuestieQuest.lua +++ b/Modules/Quest/QuestieQuest.lua @@ -225,21 +225,21 @@ function QuestieQuest:ClearAllNotes() while questId do local quest = QuestieDB.GetQuest(questId) - if not quest then - return - end - - local index, s = next(quest.Objectives) - while index do - s.AlreadySpawned = {} - index, s = next(quest.Objectives, index) - end - - if next(quest.SpecialObjectives) then - local sIndex, s = next(quest.SpecialObjectives) - while sIndex do + -- Skip quests missing from the DB instead of aborting the whole loop, + -- otherwise the remaining quests' notes would never be cleared. + if quest then + local index, s = next(quest.Objectives) + while index do s.AlreadySpawned = {} - sIndex, s = next(quest.SpecialObjectives, sIndex) + index, s = next(quest.Objectives, index) + end + + if next(quest.SpecialObjectives) then + local sIndex, s = next(quest.SpecialObjectives) + while sIndex do + s.AlreadySpawned = {} + sIndex, s = next(quest.SpecialObjectives, sIndex) + end end end questId, _ = next(QuestiePlayer.currentQuestlog, questId) diff --git a/Modules/QuestieAnnounce.lua b/Modules/QuestieAnnounce.lua index de0c864..e530275 100644 --- a/Modules/QuestieAnnounce.lua +++ b/Modules/QuestieAnnounce.lua @@ -17,6 +17,7 @@ local LE_PARTY_CATEGORY_INSTANCE = QuestieCompat.LE_PARTY_CATEGORY_INSTANCE local itemCache = {} -- cache data since this happens on item looted it could happen a lot with auto loot local alreadySentBandaid = {} -- TODO: rewrite the entire thing its a lost cause +local alreadySentBandaidCount = 0 -- bound the dedup cache so it can't grow unbounded across a session local _GetAnnounceMarker @@ -120,7 +121,17 @@ function _QuestieAnnounce:AnnounceToChannel(message) return end - alreadySentBandaid[message] = true + if not alreadySentBandaid[message] then + alreadySentBandaid[message] = true + alreadySentBandaidCount = alreadySentBandaidCount + 1 + -- Reset the dedup cache after enough distinct messages so it cannot grow + -- unbounded over a long session. Reassigning ({}) instead of wipe() keeps + -- this Lua 5.0 (Turtle) safe. + if alreadySentBandaidCount >= 1000 then + alreadySentBandaid = {} + alreadySentBandaidCount = 0 + end + end if IsInRaid() or IsInGroup() then SendChatMessage(message, _QuestieAnnounce.GetChatMessageChannel()) diff --git a/Modules/QuestieNameplate.lua b/Modules/QuestieNameplate.lua index a7b6a3e..249e0ec 100644 --- a/Modules/QuestieNameplate.lua +++ b/Modules/QuestieNameplate.lua @@ -85,23 +85,23 @@ function QuestieNameplate:UpdateNameplate() local unitName, _ = UnitName(token) local _, _, _, _, _, npcId, _ = strsplit("-", guid) - if (not unitName) or (not npcId) then - return - end + -- Skip this entry (not the whole loop) if data is missing, otherwise one + -- unavailable unit would abort updates for every remaining nameplate. + if unitName and npcId then + local icon = _QuestieNameplate.GetValidIcon(QuestieTooltips.lookupByKey["m_" .. npcId]) - local icon = _QuestieNameplate.GetValidIcon(QuestieTooltips.lookupByKey["m_" .. npcId]) - - if icon then - local frame = _QuestieNameplate.GetFrame(guid) - -- check if the texture needs to be changed - if frame.lastIcon ~= icon then - frame.lastIcon = icon - frame.Icon:SetTexture(icon) + if icon then + local frame = _QuestieNameplate.GetFrame(guid) + -- check if the texture needs to be changed + if frame.lastIcon ~= icon then + frame.lastIcon = icon + frame.Icon:SetTexture(icon) + end + else + -- tooltip removed but we still have the frame active, remove it + activeGUIDs[guid] = nil + _QuestieNameplate.RemoveFrame(guid) end - else - -- tooltip removed but we still have the frame active, remove it - activeGUIDs[guid] = nil - _QuestieNameplate.RemoveFrame(guid) end end end diff --git a/Questie-X.toc b/Questie-X.toc index 2415387..b70fdd3 100644 --- a/Questie-X.toc +++ b/Questie-X.toc @@ -179,7 +179,6 @@ Modules\Tracker\TrackerLinePool.lua Modules\Tutorial\ChooseObjectiveType.lua Modules\Tutorial\Tutorial.lua #Modules\QuestieDBMIntegration.lua -Modules\QuestieSlash.lua # Options Modules\Options\QuestieOptions.lua Modules\Options\QuestieOptionsDefaults.lua