chore: stage all pending changes (DB cleanup, corrections, compiler, init, plugin API)

This commit is contained in:
Xurkon
2026-03-16 19:41:52 -05:00
parent aad7972814
commit 4db9737a35
43 changed files with 350 additions and 226573 deletions
+91 -34
View File
@@ -1,17 +1,34 @@
---@class QuestieServer
local QuestieServer = QuestieLoader:CreateModule("QuestieServer")
-- Check for runtime server globals or profile matches early in the initialization phase.
-- We do this BEFORE any database tables evaluate so their memory isn't allocated if unused.
---@type string
local realmName = GetRealmName() or ""
Questie.IsEbonhold = false
Questie.IsAscension = false
Questie.IsValanior = false
-- Client flavor detection from WoW globals
local WOW_PROJECT_ID = WOW_PROJECT_ID or -1
local WOW_PROJECT_CLASSIC = WOW_PROJECT_CLASSIC or 2
local WOW_PROJECT_BURNING_CRUSADE_CLASSIC = WOW_PROJECT_BURNING_CRUSADE_CLASSIC or 5
local WOW_PROJECT_WRATH_CLASSIC = WOW_PROJECT_WRATH_CLASSIC or 11
local WOW_PROJECT_MAINLINE = WOW_PROJECT_MAINLINE or 1
if _G.IsAscensionServer or realmName == "Ascension" or realmName:find("Area 52") or realmName:find("Al'ar") or realmName:find("Thrall") then
-- Expansion detection
Questie.IsRetail = (WOW_PROJECT_ID == WOW_PROJECT_MAINLINE)
Questie.IsWotLK = (WOW_PROJECT_ID == WOW_PROJECT_WRATH_CLASSIC)
Questie.IsTBC = (WOW_PROJECT_ID == WOW_PROJECT_BURNING_CRUSADE_CLASSIC)
Questie.IsClassicEra = (WOW_PROJECT_ID == WOW_PROJECT_CLASSIC)
-- Try GetBuildInfo for Turtle WoW (Interface: 11200, no WOW_PROJECT globals)
local _, _, _, tocVersion = GetBuildInfo()
Questie.IsTurtle = (not Questie.IsRetail and not Questie.IsWotLK and not Questie.IsTBC and
not Questie.IsClassicEra and tocVersion and tocVersion < 20000)
-- Custom server detection
Questie.IsEbonhold = false
Questie.IsAscension = false
Questie.IsValanior = false
if _G.IsAscensionServer or realmName:find("Ascension") or realmName:find("Area 52") or
realmName:find("Al'ar") or realmName:find("Thrall") then
Questie.IsAscension = true
elseif realmName == "Ebonhold" or realmName == "Test Ebonhold" then
Questie.IsEbonhold = true
@@ -19,23 +36,69 @@ elseif realmName == "Valanior" then
Questie.IsValanior = true
end
-- Also check QuestieConfig if it was loaded (fallback for forcing a profile)
if QuestieConfig and QuestieConfig.profileKeys then
-- It's theoretically possible a player has explicitly overridden the profile in Ace3 Options
-- but usually we trust the dynamic realm name detection over saved profiles for the core loader.
-- Derive expected DB plugin name for this client
local function GetExpectedPluginFlavor()
if Questie.IsAscension then return "AscensionDB", "Questie-X-AscensionDB" end
if Questie.IsEbonhold then return "EbonholdDB", "Questie-X-EbonholdDB" end
if Questie.IsValanior then return "ValaniorDB", "Questie-X-ValaniorDB" end
if Questie.IsTurtle then return "TurtleDB", "Questie-X-TurtleDB" end
if Questie.IsWotLK then return "WotLKDB", "Questie-X-WotLKDB" end
if Questie.IsTBC then return "TBCDB", "Questie-X-TBCDB" end
if Questie.IsClassicEra then return "ClassicDB", "Questie-X-ClassicDB" end
if Questie.IsRetail then return "RetailDB", "Questie-X-RetailDB" end
return nil, nil
end
function QuestieServer:Init()
-- This handles any universal server logic before Database Init
Questie:Debug(Questie.DEBUG_INFO, "[QuestieServer] Detected Realm:", realmName)
Questie:Debug(Questie.DEBUG_INFO, "[QuestieServer] IsAscension:", Questie.IsAscension)
Questie:Debug(Questie.DEBUG_INFO, "[QuestieServer] IsEbonhold:", Questie.IsEbonhold)
Questie:Debug(Questie.DEBUG_INFO, "[QuestieServer] IsValanior:", Questie.IsValanior)
Questie:Debug(Questie.DEBUG_INFO, "[QuestieServer] Realm:", realmName)
Questie:Debug(Questie.DEBUG_INFO, "[QuestieServer] WOW_PROJECT_ID:", tostring(WOW_PROJECT_ID))
Questie:Debug(Questie.DEBUG_INFO, "[QuestieServer] IsWotLK:", tostring(Questie.IsWotLK), "IsTBC:", tostring(Questie.IsTBC),
"IsClassicEra:", tostring(Questie.IsClassicEra), "IsTurtle:", tostring(Questie.IsTurtle),
"IsAscension:", tostring(Questie.IsAscension), "IsEbonhold:", tostring(Questie.IsEbonhold))
end
--- Checks if the correct DB plugin is loaded for the detected client/server.
--- Prints a friendly actionable warning to the chat frame if none is found.
function QuestieServer:WarnIfMissingPlugin()
local QuestiePluginAPI = QuestieLoader:ImportModule("QuestiePluginAPI")
if not QuestiePluginAPI then return end
if QuestiePluginAPI:IsAnyPluginLoaded() then
local flavor, addonName = GetExpectedPluginFlavor()
local loadedFlavor = QuestiePluginAPI:GetLoadedFlavor()
if flavor and loadedFlavor and loadedFlavor ~= flavor then
Questie:Print(string.format(
"|cFFFF8800[Questie-X]|r Warning: loaded database is |cFFFFFFFF%s|r but this client expects |cFFFFFFFF%s|r. " ..
"Quest data may be incorrect. Install |cFF5EBAF3%s|r for best results.",
loadedFlavor, flavor, addonName or flavor
))
end
return
end
-- No plugin at all
local flavor, addonName = GetExpectedPluginFlavor()
local msg
if addonName then
msg = string.format(
"|cFFFF4444[Questie-X]|r No database plugin loaded. " ..
"Download and install |cFF5EBAF3%s|r into your |cFFFFFFFFInterface/AddOns/|r folder, then reload. " ..
"Questie-X will show no quest data until a database is installed.",
addonName
)
else
msg = "|cFFFF4444[Questie-X]|r No database plugin loaded and server type is unknown. " ..
"Install the appropriate Questie-X database plugin for your server."
end
if DEFAULT_CHAT_FRAME then
DEFAULT_CHAT_FRAME:AddMessage(msg)
end
Questie:Debug(Questie.DEBUG_CRITICAL, msg)
end
function QuestieServer:GetCustomQuest(questId)
-- This provides a formal API for fetching quests injected by custom server DBs
-- that bypasses the binary stream without using function monkeypatching.
local QuestieDB = QuestieLoader:ImportModule("QuestieDB")
if not QuestieDB.questDataOverrides or not QuestieDB.questDataOverrides[questId] then
return nil
@@ -44,30 +107,24 @@ function QuestieServer:GetCustomQuest(questId)
local name = QuestieDB.QueryQuestSingle(questId, "name")
if not name then return nil end
local level = QuestieDB.QueryQuestSingle(questId, "level") or QuestieDB.QueryQuestSingle(questId, "questLevel")
local level = QuestieDB.QueryQuestSingle(questId, "level") or QuestieDB.QueryQuestSingle(questId, "questLevel")
local reqLevel = QuestieDB.QueryQuestSingle(questId, "requiredLevel") or QuestieDB.QueryQuestSingle(questId, "minLevel")
local desc = QuestieDB.QueryQuestSingle(questId, "objectiveText") or QuestieDB.QueryQuestSingle(questId, "description") or QuestieDB.QueryQuestSingle(questId, "details")
local startedBy = QuestieDB.QueryQuestSingle(questId, "startedBy")
local starts = {
NPC = startedBy and startedBy[1] or {},
GameObject = startedBy and startedBy[2] or {},
Item = startedBy and startedBy[3] or {},
}
local desc = QuestieDB.QueryQuestSingle(questId, "objectiveText") or QuestieDB.QueryQuestSingle(questId, "description")
local startedBy = QuestieDB.QueryQuestSingle(questId, "startedBy")
local finishedBy = QuestieDB.QueryQuestSingle(questId, "finishedBy")
local specialFlags = QuestieDB.QueryQuestSingle(questId, "specialFlags")
local isRepeatable = specialFlags and (bit.band(specialFlags, 1) ~= 0) or false
return {
Id = questId,
id = questId,
name = name,
level = level or reqLevel or 0,
Id = questId,
id = questId,
name = name,
level = level or reqLevel or 0,
requiredLevel = reqLevel or 0,
Description = desc,
Starts = starts,
finishedBy = finishedBy,
Description = desc,
Starts = { NPC = startedBy and startedBy[1] or {}, GameObject = startedBy and startedBy[2] or {}, Item = startedBy and startedBy[3] or {} },
finishedBy = finishedBy,
IsRepeatable = isRepeatable,
}
end