diff --git a/Database/QuestieDB.lua b/Database/QuestieDB.lua index f121194..ad3dd21 100644 --- a/Database/QuestieDB.lua +++ b/Database/QuestieDB.lua @@ -204,6 +204,16 @@ QuestieDB.NPCPointers = _dummyHandle.pointers QuestieDB.ObjectPointers = _dummyHandle.pointers QuestieDB.ItemPointers = _dummyHandle.pointers +-- Set by QuestieInit when the compiled/static base DB fails to load. +-- When this is true, learner should force itself on so the addon still works +-- even if the static database is unavailable or partially missing. +QuestieDB.baseDatabaseMissing = false +QuestieDB.baseDatabaseMissingKeys = {} + +function QuestieDB:IsBaseDatabaseMissing() + return QuestieDB.baseDatabaseMissing == true +end + ---@type QuestieQuest local QuestieQuest = QuestieLoader:ImportModule("QuestieQuest") ---@type QuestieQuestPrivate diff --git a/Modules/Options/DatabaseTab/QuestieOptionsDatabase.lua b/Modules/Options/DatabaseTab/QuestieOptionsDatabase.lua index ceb6d3a..a4ba6b4 100644 --- a/Modules/Options/DatabaseTab/QuestieOptionsDatabase.lua +++ b/Modules/Options/DatabaseTab/QuestieOptionsDatabase.lua @@ -63,6 +63,22 @@ local function ApplyLearnerMode() end end +local function GetLearnerRuntimeMode() + local QuestieLearner = QuestieLoader:ImportModule("QuestieLearner") + if QuestieLearner and QuestieLearner.GetDataSourceMode then + return QuestieLearner:GetDataSourceMode() + end + return (Questie.dbLearner.global and Questie.dbLearner.global.settings and Questie.dbLearner.global.settings.dataSourceMode) or "auto" +end + +local function IsLearnerRuntimeEnabled() + local QuestieLearner = QuestieLoader:ImportModule("QuestieLearner") + if QuestieLearner and QuestieLearner.IsEnabled then + return QuestieLearner:IsEnabled() + end + return Questie.dbLearner.global and Questie.dbLearner.global.settings and Questie.dbLearner.global.settings.enabled +end + ----------------------------------------------------------------------- -- Export Dialog ----------------------------------------------------------------------- @@ -225,8 +241,8 @@ function QuestieOptions.tabs.database:Initialize() type = "toggle", order = 2.05, name = function() return l10n("Enable Learner Recording") end, - desc = function() return l10n("Record live learner data. Disable this to stop recording and live learner injection.") end, - get = function() return Questie.dbLearner.global and Questie.dbLearner.global.settings and Questie.dbLearner.global.settings.enabled end, + desc = function() return l10n("Record live learner data. Disable this to stop recording and live learner injection. Learner will still auto-enable if the static DB is missing.") end, + get = function() return IsLearnerRuntimeEnabled() end, set = function(_, v) if Questie.dbLearner.global and Questie.dbLearner.global.settings then Questie.dbLearner.global.settings.enabled = v @@ -246,9 +262,7 @@ function QuestieOptions.tabs.database:Initialize() static = l10n("Static Only"), none = l10n("Neither (base DB only)"), }, - get = function() - return (Questie.dbLearner.global and Questie.dbLearner.global.settings and Questie.dbLearner.global.settings.dataSourceMode) or "auto" - end, + get = function() return GetLearnerRuntimeMode() end, set = function(_, v) if Questie.dbLearner.global and Questie.dbLearner.global.settings then Questie.dbLearner.global.settings.dataSourceMode = v diff --git a/Modules/QuestieInit.lua b/Modules/QuestieInit.lua index d7d62d6..6a496e9 100644 --- a/Modules/QuestieInit.lua +++ b/Modules/QuestieInit.lua @@ -508,6 +508,12 @@ end function QuestieInit:LoadDatabase(key) + local function MarkBaseDatabaseMissing() + QuestieDB.baseDatabaseMissing = true + QuestieDB.baseDatabaseMissingKeys = QuestieDB.baseDatabaseMissingKeys or {} + QuestieDB.baseDatabaseMissingKeys[key] = true + end + if type(QuestieDB[key]) == "string" then -- Fix #6: `loadstring` at LOAD TIME is safe, but calling it here during -- event-driven runtime taints any tables produced on WotLK/Era clients. @@ -530,6 +536,7 @@ function QuestieInit:LoadDatabase(key) "[DBDiag] LEGACY DB ('" .. key .. "' is string) on modern client. " .. "Runtime loadstring() would taint this data. " .. "Please reinstall the Questie-X-WotLKDB addon in split-file format.") + MarkBaseDatabaseMissing() QuestieDB[key] = {} return end @@ -543,16 +550,19 @@ function QuestieInit:LoadDatabase(key) QuestieDB[key] = result else Questie:Debug(Questie.DEBUG_DEVELOP, "[DBDiag] ERROR executing('" .. key .. "'): " .. tostring(result)) + MarkBaseDatabaseMissing() QuestieDB[key] = nil end else Questie:Debug(Questie.DEBUG_DEVELOP, "[DBDiag] ERROR loadstring('" .. key .. "'): " .. tostring(loadErr) .. " | len=" .. string.len(QuestieDB[key] or "")) + MarkBaseDatabaseMissing() QuestieDB[key] = nil end elseif type(QuestieDB[key]) == "table" then Questie:Debug(Questie.DEBUG_DEVELOP, "[LoadDatabase] '" .. key .. "' already a table (split-file format), skipping loadstring") else Questie:Debug(Questie.DEBUG_DEVELOP, "Database is missing, this is likely do to era vs tbc: ", key) + MarkBaseDatabaseMissing() end if not QuestieDB[key] then QuestieDB[key] = {} @@ -566,6 +576,9 @@ function QuestieInit:LoadBaseDB() -- Pointer compilation will look at npcDataOverrides etc, which are populated by plugins. -- Base tables (Classic) are loaded here. + QuestieDB.baseDatabaseMissing = false + QuestieDB.baseDatabaseMissingKeys = {} + QuestieInit:LoadDatabase("npcData") QuestieInit:LoadDatabase("objectData") QuestieInit:LoadDatabase("questData") diff --git a/Modules/QuestieLearner.lua b/Modules/QuestieLearner.lua index 2e855f5..0d3a593 100644 --- a/Modules/QuestieLearner.lua +++ b/Modules/QuestieLearner.lua @@ -51,7 +51,17 @@ local function HasAscensionQuestObjectiveData(questId) return IsAscensionProtected("QUEST", questId, 10) end +local function IsBaseDatabaseMissing() + return QuestieDB + and QuestieDB.IsBaseDatabaseMissing + and QuestieDB:IsBaseDatabaseMissing() +end + local function GetDataSourceMode() + if IsBaseDatabaseMissing() then + return "learner" + end + local settings = Questie and Questie.dbLearner and Questie.dbLearner.global @@ -470,6 +480,9 @@ end function QuestieLearner:IsEnabled() if not EnsureLearnedData() then return false end + if IsBaseDatabaseMissing() then + return true + end return Questie.dbLearner.global.settings.enabled end diff --git a/Tests/QuestieLearnerDataSourceMode_spec.lua b/Tests/QuestieLearnerDataSourceMode_spec.lua index ff7b804..932af56 100644 --- a/Tests/QuestieLearnerDataSourceMode_spec.lua +++ b/Tests/QuestieLearnerDataSourceMode_spec.lua @@ -37,3 +37,23 @@ describe("QuestieLearner data source mode", function() assert.is_true(has(tip, "mode ~= \"static\" and mode ~= \"none\"")) end) end) + +describe("QuestieLearner missing base DB fallback", function() + local QuestieLearner + + before_each(function() + dofile("Tests/wow_api_mock.lua") + Questie.dbLearner.global.settings.enabled = false + Questie.dbLearner.global.settings.dataSourceMode = "static" + QuestieDB.baseDatabaseMissing = true + QuestieDB.IsBaseDatabaseMissing = function() + return true + end + QuestieLearner = dofile("Modules/QuestieLearner.lua") + end) + + it("forces learner mode and live recording when the base DB is missing", function() + assert.equals("learner", QuestieLearner:GetDataSourceMode()) + assert.is_true(QuestieLearner:IsEnabled()) + end) +end)