perf: batch learner updates and remove Turtle support
This commit is contained in:
+3
-3
@@ -109,7 +109,7 @@
|
||||
|
||||
### Maintenance
|
||||
|
||||
- **Removed Turtle WoW references** — Deleted Turtle WoW row from the server compatibility table and removed Turtle WoW load tip from installation instructions in README.md. Turtle WoW is shutting down and no longer has a supported plugin.
|
||||
- **Removed unsupported legacy server references** — Deleted an unsupported legacy server row from the server compatibility table and removed its load tip from installation instructions in README.md.
|
||||
|
||||
### Documentation
|
||||
|
||||
@@ -282,7 +282,7 @@ Addressed micro-stutters and FPS drops (190 → sub-100) reported during high-fr
|
||||
- **[Feature — Enhanced Logging]** Improved Stage 3 initialization logging to provide detailed reporting on custom data injection. Developers can now verify the exact number of NPCs, Objects, and Items injected by plugins directly from the `DEVELOP` log.
|
||||
- **[Fix — Ascension Zone Mapping]** Fixed a regression in `QuestieCompat` where `uiMapData` for Ascension-specific zones was not correctly propagating to the global mapping table, restoring map pin functionality for seasonal and custom zones.
|
||||
- **[Fix — QuestieLearner]** Centralized zone/area ID lookup in `l10n` module to prevent `GetAreaIdByLocalName` nil errors (Fixes Project Ebonhold runtime crash).
|
||||
- **[Fix — Custom Server Compilation]** Fixed database compilation not running on custom servers (Ascension, Ebonhold, Turtle WoW, etc.) where plugins inject data after initial load.
|
||||
- **[Fix — Custom Server Compilation]** Fixed database compilation not running on custom servers (Ascension, Ebonhold, etc.) where plugins inject data after initial load.
|
||||
- Modified `Modules/QuestieInit.lua` Stage1 to defer compilation to Stage3 for custom servers, ensuring plugins finish injecting data before compilation runs.
|
||||
- Added `l10n:Initialize()` and `QuestieCorrections:MinimalInit()` calls when deferring to Stage3, as Stage2 (`QuestieJourney:Initialize()`) requires `hiddenQuests` to be populated.
|
||||
- Added "Bronzebeard" and "Warcraft Reborn" to Ascension realm detection patterns in `Modules/QuestieServer.lua`.
|
||||
@@ -593,7 +593,7 @@ Addressed micro-stutters and FPS drops (190 → sub-100) reported during high-fr
|
||||
|
||||
### Core & Stability (v1.3.5)
|
||||
|
||||
- **[Lua 5.0]** Globally polyfilled `string.match` and `string.gmatch` using `string.find` and `string.gfind` to ensure universal compatibility with legacy WoW clients (e.g., Turtle WoW).
|
||||
- **[Lua 5.0]** Globally polyfilled `string.match` and `string.gmatch` using `string.find` and `string.gfind` to ensure universal compatibility with legacy WoW clients.
|
||||
- **[AceTimer]** Patched embedded `AceTimer-3.0` instances in ElvUI and OG-RaidHelper to resolve `math.mod` errors on Lua 5.0 clients.
|
||||
- **[Colors]** Updated `CreateColor` polyfill with `SetRGB`, `SetRGBA`, `SetColor`, and `GetColor` methods.
|
||||
- **[Comm]** Improved cross-client data sharing stability.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
-- Shim for Lua 5.2+ (Retail) where table.getn was removed.
|
||||
-- We cannot use the '#' length operator directly because Lua 5.0 (Turtle WoW)
|
||||
-- We cannot use the '#' length operator directly because Lua 5.0
|
||||
-- will trigger a compile-time syntax error parsing the file.
|
||||
-- Using loadstring bypasses the 5.0 compiler and safely injects the # operator in 5.2+.
|
||||
if not table.getn then
|
||||
@@ -19,7 +19,7 @@ if not math.mod then
|
||||
end
|
||||
end
|
||||
|
||||
-- Shim for Lua 5.0 (Turtle WoW) where string.match is missing.
|
||||
-- Shim for Lua 5.0 where string.match is missing.
|
||||
-- Supports up to 5 captures (sufficient for all Questie uses).
|
||||
if not string.match then
|
||||
string.match = function(str, pattern, init)
|
||||
@@ -41,7 +41,7 @@ if not string.gmatch then
|
||||
string.gmatch = string.gfind
|
||||
end
|
||||
|
||||
-- Shim for Lua 5.0 (Turtle WoW) where select() was not yet implemented.
|
||||
-- Shim for Lua 5.0 where select() was not yet implemented.
|
||||
-- Fix #7: The original used a `while n > 0` loop that never decremented n,
|
||||
-- making the loop body run exactly once before returning. Use a plain
|
||||
-- sequential block instead so the intent is obvious.
|
||||
@@ -136,4 +136,3 @@ function Questie:Colorize(str, color)
|
||||
-- Initial stub: just return the string without color or with basic color
|
||||
return str
|
||||
end
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ function QuestiePluginAPI:HasPendingPlugins()
|
||||
return self.pendingPluginsCount > 0
|
||||
end
|
||||
|
||||
--- Returns the flavor key of the loaded DB plugin ("WotLK", "Classic", "TBC", "Turtle", "Ascension", etc.)
|
||||
--- Returns the flavor key of the loaded DB plugin ("WotLK", "Classic", "TBC", "Ascension", etc.)
|
||||
---@return string|nil
|
||||
function QuestiePluginAPI:GetLoadedFlavor()
|
||||
return self.loadedDBFlavor
|
||||
@@ -276,7 +276,7 @@ function QuestiePlugin:InjectUiMapData(customUiMapData)
|
||||
end
|
||||
|
||||
--- Signals that the plugin has finished loading. This automatically cleans up necessary caches.
|
||||
---@param flavorKey string|nil Optional flavor label e.g. "WotLK", "Classic", "Turtle"
|
||||
---@param flavorKey string|nil Optional flavor label e.g. "WotLK", "Classic", "Ascension"
|
||||
function QuestiePlugin:FinishLoading(flavorKey)
|
||||
local QuestieDB = QuestieLoader:ImportModule("QuestieDB")
|
||||
if not QuestieDB then
|
||||
|
||||
@@ -95,7 +95,7 @@ function QuestieOptions.tabs.credits:Initialize()
|
||||
thanks = {
|
||||
type = "description",
|
||||
order = 1,
|
||||
name = function() return 'The Turtle WoW, Project Ascension, and Project Ebonhold communities for their ongoing support and feedback.'; end,
|
||||
name = function() return 'The Project Ascension, Project Ebonhold, and custom server communities for their ongoing support and feedback.'; end,
|
||||
fontSize = "medium",
|
||||
},
|
||||
},
|
||||
|
||||
@@ -20,7 +20,6 @@ end
|
||||
|
||||
local function GetServer()
|
||||
if Questie.IsAscension then return "Ascension" end
|
||||
if Questie.IsTurtle then return "Turtle" end
|
||||
if Questie.IsEbonhold then return "Ebonhold" end
|
||||
if Questie.IsEra then return "Era" end
|
||||
if Questie.Is335 then return "WotLK" end
|
||||
|
||||
@@ -241,7 +241,7 @@ end
|
||||
-- old Lua 5.0 host with no secure-call protection), addon code can still call it
|
||||
-- but it will simply be a no-op that prints a warning rather than injecting taint.
|
||||
if not hooksecurefunc then
|
||||
-- Lua 5.0 hosts (Turtle WoW pre-2.0 or custom servers) have no secure-call model,
|
||||
-- Lua 5.0 hosts and older custom servers have no secure-call model,
|
||||
-- so raw-hooking is equivalent to what Blizzard would do internally anyway.
|
||||
-- Use a local to avoid polluting _G unnecessarily.
|
||||
local function _rawHook(arg1, arg2, arg3)
|
||||
@@ -278,7 +278,7 @@ end
|
||||
if C_Timer then
|
||||
QuestieCompat.C_Timer = C_Timer
|
||||
else
|
||||
-- C_Timer polyfill for Lua 5.0/5.1 clients that don't have it (e.g. Turtle WoW pre-2.0).
|
||||
-- C_Timer polyfill for Lua 5.0/5.1 clients that don't have it.
|
||||
-- Only stored in QuestieCompat namespace, NOT in bare _G.
|
||||
local TickerFrame = CreateFrame("Frame")
|
||||
local tickers = {}
|
||||
@@ -626,4 +626,3 @@ end
|
||||
QuestieCompat.LibUIDropDownMenu = QuestieCompat.LibUIDropDownMenu or {}
|
||||
QuestieCompat.LibUIDropDownMenu.UIDropDownMenu_Menu_NewSize = function()
|
||||
end
|
||||
|
||||
|
||||
@@ -279,7 +279,7 @@ QuestieInit.Stages[1] = function() -- run as a coroutine
|
||||
needsCompilation = (not dbIsCompiled) or (QuestieLib:GetAddonVersionString() ~= dbCompiledOnVersion) or (l10n:GetUILocale() ~= dbCompiledLang) or (Questie.db.global.dbCompiledExpansion ~= WOW_PROJECT_ID)
|
||||
|
||||
-- Custom servers or presence of DB plugins: always defer to Stage3 to wait for plugin data injection
|
||||
if Questie.IsAscension or Questie.IsEbonhold or Questie.IsValanior or Questie.IsTurtle or QuestieServer:IsAnyDBPluginEnabled() then
|
||||
if Questie.IsAscension or Questie.IsEbonhold or Questie.IsValanior or QuestieServer:IsAnyDBPluginEnabled() then
|
||||
compilationDeferred = true
|
||||
l10n:Initialize()
|
||||
coYield()
|
||||
@@ -390,7 +390,7 @@ QuestieInit.Stages[3] = function() -- run as a coroutine
|
||||
|
||||
-- Always re-compile on custom servers to pick up QuestieLearner changes from SavedVariables,
|
||||
-- or if compilation was explicitly deferred/needed.
|
||||
local isCustomServer = Questie.IsAscension or Questie.IsEbonhold or Questie.IsValanior or Questie.IsTurtle or QuestieServer:IsAnyDBPluginEnabled()
|
||||
local isCustomServer = Questie.IsAscension or Questie.IsEbonhold or Questie.IsValanior or QuestieServer:IsAnyDBPluginEnabled()
|
||||
if isCustomServer or needsCompilation or (not Questie.db.global.dbIsCompiled) then
|
||||
Questie:Debug(Questie.DEBUG_CRITICAL, "[QuestieInit:Stage3] Starting compilation (Server=" .. tostring(isCustomServer) .. ", Needed=" .. tostring(needsCompilation) .. ")")
|
||||
if not QuestieDB.questData then
|
||||
|
||||
+137
-47
@@ -210,6 +210,16 @@ local function CopyWithoutField(data, skippedKey)
|
||||
return copy
|
||||
end
|
||||
|
||||
local function DeepCopy(value)
|
||||
if type(value) ~= "table" then return value end
|
||||
|
||||
local copy = {}
|
||||
for key, child in pairs(value) do
|
||||
copy[key] = DeepCopy(child)
|
||||
end
|
||||
return copy
|
||||
end
|
||||
|
||||
-- Returns the grid-bucket key for a coordinate so nearby points share the same slot
|
||||
local function CoordBucket(x, y)
|
||||
return floor(x / COORD_GRID) * COORD_GRID, floor(y / COORD_GRID) * COORD_GRID
|
||||
@@ -565,6 +575,89 @@ local function _InvalidateSpawnListsForNPC(npcId)
|
||||
end
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- Live learner update batching
|
||||
--
|
||||
-- Kill/loot bursts can call LearnNPC multiple times for the same NPC:
|
||||
-- combat-log kill, quest-log objective progress, and loot correlation may all
|
||||
-- arrive within a few frames. Saved learner evidence is updated immediately,
|
||||
-- but live QuestieDB override/cache invalidation is batched so the large DB
|
||||
-- layer is not churned on every single kill.
|
||||
local LIVE_NPC_UPDATE_DELAY = 0.5
|
||||
|
||||
local function _ApplyNpcLiveUpdate(npcId)
|
||||
local existing = Questie.dbLearner
|
||||
and Questie.dbLearner.global
|
||||
and Questie.dbLearner.global.npcs
|
||||
and Questie.dbLearner.global.npcs[npcId]
|
||||
if not existing then return false end
|
||||
|
||||
local threshold = (Questie.dbLearner.global.settings and Questie.dbLearner.global.settings.minConfidencePins) or MIN_CONFIDENCE_PINS
|
||||
if existing.mc < threshold then return false end
|
||||
if not (QuestieDB and QuestieDB.npcDataOverrides and existing[7] and next(existing[7])) then return false end
|
||||
|
||||
local ovr = QuestieDB.npcDataOverrides[npcId]
|
||||
if not ovr then
|
||||
if IsAscensionProtected("NPC", npcId, 7) then
|
||||
QuestieDB.npcDataOverrides[npcId] = DeepCopy(CopyWithoutField(existing, 7))
|
||||
else
|
||||
QuestieDB.npcDataOverrides[npcId] = DeepCopy(existing)
|
||||
end
|
||||
else
|
||||
-- Merge: fill missing fields; also overwrite empty-string names.
|
||||
for k, v in pairs(existing) do
|
||||
if k ~= 7 and not IsAscensionProtected("NPC", npcId, k) and (ovr[k] == nil or (k == 1 and ovr[k] == "")) then
|
||||
ovr[k] = DeepCopy(v)
|
||||
end
|
||||
end
|
||||
-- Always merge spawn coords.
|
||||
if existing[7] and not IsAscensionProtected("NPC", npcId, 7) then
|
||||
ovr[7] = ovr[7] or {}
|
||||
for zid, coords in pairs(existing[7]) do
|
||||
ovr[7][zid] = ovr[7][zid] or {}
|
||||
for _, coord in ipairs(coords) do
|
||||
InsertIfNewBucket(ovr[7][zid], coord[1], coord[2], GetCoordGridForZone(zid))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Clear the compiled DB cache once per flush so GetNPC rebuilds with the
|
||||
-- latest coalesced override data instead of once per kill.
|
||||
if QuestieDB.private and QuestieDB.private.npcCache then
|
||||
QuestieDB.private.npcCache[npcId] = nil
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
local function _FlushNpcLiveUpdates()
|
||||
local pending = _Learner.pendingNpcLiveUpdates
|
||||
_Learner.pendingNpcLiveUpdates = {}
|
||||
_Learner.pendingNpcLiveUpdateTimer = nil
|
||||
|
||||
for npcId in pairs(pending) do
|
||||
if _ApplyNpcLiveUpdate(npcId) then
|
||||
_InvalidateSpawnListsForNPC(npcId)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function _QueueNpcLiveUpdate(npcId)
|
||||
_Learner.pendingNpcLiveUpdates = _Learner.pendingNpcLiveUpdates or {}
|
||||
_Learner.pendingNpcLiveUpdates[npcId] = true
|
||||
|
||||
if _Learner.pendingNpcLiveUpdateTimer then return end
|
||||
|
||||
local timer = QuestieCompat and QuestieCompat.C_Timer
|
||||
if timer and timer.After then
|
||||
_Learner.pendingNpcLiveUpdateTimer = true
|
||||
timer.After(LIVE_NPC_UPDATE_DELAY, _FlushNpcLiveUpdates)
|
||||
else
|
||||
_FlushNpcLiveUpdates()
|
||||
end
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- CrossLinkAfterNPC: called when a new NPC is first learned.
|
||||
-- Scans all learned quests for any reference to this npcId and stitches
|
||||
@@ -887,48 +980,14 @@ function QuestieLearner:LearnNPC(npcId, name, level, subName, npcFlags, factionS
|
||||
existing.ls = time() -- Update last seen
|
||||
existing.mc = (existing.mc or 0) + 1
|
||||
|
||||
local threshold = (Questie.dbLearner.global.settings and Questie.dbLearner.global.settings.minConfidencePins) or MIN_CONFIDENCE_PINS
|
||||
|
||||
-- Live injection: update npcDataOverrides only if confidence threshold is met
|
||||
-- and only if the NPC has actual spawn data from kills (not just player-position fallback)
|
||||
if existing.mc >= threshold and QuestieDB and QuestieDB.npcDataOverrides and existing[7] and next(existing[7]) then
|
||||
local ovr = QuestieDB.npcDataOverrides[npcId]
|
||||
if not ovr then
|
||||
if IsAscensionProtected("NPC", npcId, 7) then
|
||||
QuestieDB.npcDataOverrides[npcId] = CopyWithoutField(existing, 7)
|
||||
else
|
||||
QuestieDB.npcDataOverrides[npcId] = existing
|
||||
end
|
||||
else
|
||||
-- Merge: fill missing fields; also overwrite empty-string names
|
||||
for k, v in pairs(existing) do
|
||||
if not IsAscensionProtected("NPC", npcId, k) and (ovr[k] == nil or (k == 1 and ovr[k] == "")) then ovr[k] = v end
|
||||
end
|
||||
-- Always merge spawn coords
|
||||
if existing[7] and not IsAscensionProtected("NPC", npcId, 7) then
|
||||
ovr[7] = ovr[7] or {}
|
||||
for zid, coords in pairs(existing[7]) do
|
||||
ovr[7][zid] = ovr[7][zid] or {}
|
||||
for _, coord in ipairs(coords) do
|
||||
InsertIfNewBucket(ovr[7][zid], coord[1], coord[2], GetCoordGridForZone(zid))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
-- Clear the compiled DB cache so GetNPC rebuilds with the new override data.
|
||||
if QuestieDB.private and QuestieDB.private.npcCache then
|
||||
QuestieDB.private.npcCache[npcId] = nil
|
||||
end
|
||||
end
|
||||
-- Live injection is intentionally batched: repeated kill/log/loot events for
|
||||
-- the same NPC update saved evidence immediately, then flush QuestieDB once.
|
||||
_QueueNpcLiveUpdate(npcId)
|
||||
|
||||
if isNew then
|
||||
Questie:Debug(Questie.DEBUG_LEARNER, "[QuestieLearner] New NPC learned:", npcId, name or "?")
|
||||
CrossLinkAfterNPC(npcId)
|
||||
end
|
||||
-- Existing NPC got new spawn data: invalidate cached spawnLists
|
||||
-- for any active quest objective that references this NPC so the
|
||||
-- map system rebuilds them with fresh data on next update.
|
||||
_InvalidateSpawnListsForNPC(npcId)
|
||||
_Learner:BroadcastIfCommsAvailable("NPC", npcId, existing)
|
||||
end
|
||||
|
||||
@@ -1196,9 +1255,7 @@ local function _MergeSpawnEvidence(npcId)
|
||||
"duplicates", duplicates,
|
||||
"zone", tostring(topEvidence.zoneId))
|
||||
|
||||
if QuestieDB.private and QuestieDB.private.npcCache then
|
||||
QuestieDB.private.npcCache[npcId] = nil
|
||||
end
|
||||
_QueueNpcLiveUpdate(npcId)
|
||||
|
||||
return promoted > 0 or duplicates > 0
|
||||
end
|
||||
@@ -1287,10 +1344,8 @@ local function _MergeSpawnEvidence(npcId)
|
||||
"zone " .. topEvidence.zoneId .. " at " .. floor(topPct + 0.5) .. "% confidence",
|
||||
spawned and "SPAM" or "IGNORED_DUPLICATE")
|
||||
|
||||
-- Clear npcCache so GetNPC returns fresh data
|
||||
if QuestieDB.private and QuestieDB.private.npcCache then
|
||||
QuestieDB.private.npcCache[npcId] = nil
|
||||
end
|
||||
-- Clear/rebuild cache through the same coalesced path used by kill learning.
|
||||
_QueueNpcLiveUpdate(npcId)
|
||||
|
||||
return true
|
||||
end
|
||||
@@ -3568,9 +3623,44 @@ end
|
||||
|
||||
function _Learner:BroadcastIfCommsAvailable(typ, id, data)
|
||||
local QuestieLearnerComms = QuestieLoader:ImportModule("QuestieLearnerComms")
|
||||
if QuestieLearnerComms and QuestieLearnerComms.BroadcastLearnedData then
|
||||
local op = (data.mc and data.mc > 1) and "UPDATE" or "NEW"
|
||||
QuestieLearnerComms:BroadcastLearnedData(op, typ, id, data)
|
||||
if not (QuestieLearnerComms and QuestieLearnerComms.BroadcastLearnedData) then
|
||||
return
|
||||
end
|
||||
|
||||
_Learner.pendingBroadcasts = _Learner.pendingBroadcasts or {}
|
||||
local key = typ .. ":" .. tostring(id)
|
||||
local op = (data.mc and data.mc > 1) and "UPDATE" or "NEW"
|
||||
local existingPending = _Learner.pendingBroadcasts[key]
|
||||
_Learner.pendingBroadcasts[key] = {
|
||||
typ = typ,
|
||||
id = id,
|
||||
data = data,
|
||||
-- Preserve the first-discovery signal while still sending the latest
|
||||
-- coalesced payload for the entity.
|
||||
op = (existingPending and existingPending.op == "NEW") and "NEW" or op,
|
||||
}
|
||||
|
||||
if _Learner.pendingBroadcastTimer then return end
|
||||
|
||||
local timer = QuestieCompat and QuestieCompat.C_Timer
|
||||
local function FlushBroadcasts()
|
||||
local pending = _Learner.pendingBroadcasts
|
||||
_Learner.pendingBroadcasts = {}
|
||||
_Learner.pendingBroadcastTimer = nil
|
||||
|
||||
local comms = QuestieLoader:ImportModule("QuestieLearnerComms")
|
||||
if not (comms and comms.BroadcastLearnedData) then return end
|
||||
|
||||
for _, entry in pairs(pending) do
|
||||
comms:BroadcastLearnedData(entry.op, entry.typ, entry.id, entry.data)
|
||||
end
|
||||
end
|
||||
|
||||
if timer and timer.After then
|
||||
_Learner.pendingBroadcastTimer = true
|
||||
timer.After(2, FlushBroadcasts)
|
||||
else
|
||||
FlushBroadcasts()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -39,7 +39,6 @@ end
|
||||
local function GetServerKey()
|
||||
if QuestieServer then
|
||||
if Questie.IsAscension then return "Ascension" end
|
||||
if Questie.IsTurtle then return "Turtle" end
|
||||
if Questie.IsEbonhold then return "Ebonhold" end
|
||||
if Questie.IsEra then return "Era" end
|
||||
if Questie.Is335 then return "WotLK" end
|
||||
|
||||
@@ -17,11 +17,6 @@ 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
|
||||
@@ -41,7 +36,6 @@ 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
|
||||
@@ -53,7 +47,7 @@ function QuestieServer:Init()
|
||||
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),
|
||||
"IsClassicEra:", tostring(Questie.IsClassicEra),
|
||||
"IsAscension:", tostring(Questie.IsAscension), "IsEbonhold:", tostring(Questie.IsEbonhold))
|
||||
end
|
||||
|
||||
@@ -64,7 +58,6 @@ function QuestieServer:IsAnyDBPluginEnabled()
|
||||
"Questie-X-WotLKDB",
|
||||
"Questie-X-ClassicDB",
|
||||
"Questie-X-TBCDB",
|
||||
"Questie-X-TurtleDB",
|
||||
"Questie-X-AscensionDB",
|
||||
"Questie-X-EbonholdDB",
|
||||
"Questie-X-ValaniorDB",
|
||||
|
||||
+6
-6
@@ -278,9 +278,9 @@
|
||||
|
||||
<hr>
|
||||
|
||||
<h2 id="session-34">Session 34 — Turtle WoW Cleanup (2026-05-04)</h2>
|
||||
<h2 id="session-34">Session 34 — Unsupported Legacy Server Cleanup (2026-05-04)</h2>
|
||||
<ul>
|
||||
<li><strong>[Maintenance]</strong> Removed Turtle WoW references — Deleted Turtle WoW row from the server compatibility table and removed Turtle WoW load tip from installation instructions in README.md. Turtle WoW is shutting down and no longer has a supported plugin.</li>
|
||||
<li><strong>[Maintenance]</strong> Removed unsupported legacy server references — Deleted an unsupported legacy server row from the server compatibility table and removed its load tip from installation instructions in README.md.</li>
|
||||
<li><strong>[Documentation]</strong> Clarified two-addon installation requirement — Updated README.md installation instructions to explicitly state that Questie-X requires BOTH the core addon AND a server-specific database plugin to function.</li>
|
||||
</ul>
|
||||
|
||||
@@ -426,7 +426,7 @@
|
||||
<li><strong>[Fix — Ascension Zone Mapping]</strong> Fixed a regression in <code>QuestieCompat</code> where <code>uiMapData</code> for Ascension-specific zones was not correctly propagating to the global mapping table, restoring map pin functionality for seasonal and custom zones.</li>
|
||||
<li><strong>[Fix — QuestieLearner]</strong> Centralized zone/area ID lookup in <code>l10n</code> module to prevent <code>GetAreaIdByLocalName</code> nil errors (Fixes Project Ebonhold runtime crash).</li>
|
||||
<li><strong>[Feature — Session Export]</strong> Added <code>session_export</code> skill for standardized documentation and session artifact exports.</li>
|
||||
<li><strong>[Fix — Custom Server Compilation]</strong> Fixed database compilation not running on custom servers (Ascension, Ebonhold, Turtle WoW, etc.) where plugins inject data after initial load.</li>
|
||||
<li><strong>[Fix — Custom Server Compilation]</strong> Fixed database compilation not running on custom servers (Ascension, Ebonhold, etc.) where plugins inject data after initial load.</li>
|
||||
<li><strong>[Fix — Zone Mapping Bug]</strong> Fixed incorrect key assignment in <code>QuestiePluginAPI:InjectZoneTables()</code>. This caused zone lookups to fail, resulting in "No UiMapID or fitting parentAreaId" errors for custom zone IDs.</li>
|
||||
</ul>
|
||||
|
||||
@@ -450,7 +450,7 @@
|
||||
<h2 id="v148">v1.4.8 — Plugin Synchronization & Lua 5.0 Refactor</h2>
|
||||
<ul>
|
||||
<li><strong>[Plugin Synchronization]</strong> Overhauled the Questie-X plugin loading architecture. Introduced <code>QuestiePluginAPI:FinishLoading()</code> and a registration handshake to resolve race conditions during addon initialization. By ensuring that database plugins report their data-injection status before <code>QuestieInit</code> Stage 3 completes, we eliminated "ghost maps" where pins and statistics would fail to render until a manual <code>/reload</code>.</li>
|
||||
<li><strong>[Universal Lua 5.0 Refactor]</strong> Executed a codebase-wide transition from <code>pairs()</code> and <code>ipairs()</code> to <code>next()</code> and numeric loops. This refactor targets the Lua 5.0 engine used by legacy clients (e.g., Turtle WoW), which can exhibit inconsistent behavior or performance degradation when using standard iterators in high-frequency database sweeps. This change guarantees stable, universal performance across all WoW versions from 1.12 to 3.3.5+.</li>
|
||||
<li><strong>[Universal Lua 5.0 Refactor]</strong> Executed a codebase-wide transition from <code>pairs()</code> and <code>ipairs()</code> to <code>next()</code> and numeric loops. This refactor targets the Lua 5.0 engine used by legacy clients, which can exhibit inconsistent behavior or performance degradation when using standard iterators in high-frequency database sweeps. This change guarantees stable, universal performance across supported WoW versions.</li>
|
||||
<li><strong>[Fix — MapIconTooltip]</strong> Fixed a critical syntax error in <code>MapIconTooltip.lua</code> at line 239. A malformed <code>if</code> statement was trapping execution, preventing tooltips from updating when hovering over Quest objectives on the World Map.</li>
|
||||
<li><strong>[Fix — AscensionDB]</strong> Enhanced realm-specific logic in <code>AscensionLoader.lua</code>. The loader now utilizes an pattern-matching check against <code>GetRealmName()</code> to correctly identify and apply custom database overrides for all Project Ascension realms, including seasonal and specialized rule-set servers.</li>
|
||||
<li><strong>[Performance]</strong> Refined the background loading throttler in <code>QuestieInit</code>. The initialization sequence now yields more efficiently to the main UI thread during massive database injections, reducing "frame-stutter" during the initial login sequence while strictly maintaining loading priority for essential UI modules.</li>
|
||||
@@ -594,7 +594,7 @@
|
||||
|
||||
<h3>Core & Stability</h3>
|
||||
<ul>
|
||||
<li><strong>[Fix]</strong> Resolved <code>attempt to call local 'l10n' (a table value)</code> in <code>GameVersionError.lua</code> and implemented a <code>tocVersion</code> guard to prevent the "unsupported client" error on Classic-era private servers (e.g., Turtle WoW).</li>
|
||||
<li><strong>[Fix]</strong> Resolved <code>attempt to call local 'l10n' (a table value)</code> in <code>GameVersionError.lua</code> and implemented a <code>tocVersion</code> guard to prevent the "unsupported client" error on Classic-era private servers.</li>
|
||||
<li><strong>[Fix]</strong> Updated <code>GameVersionError.lua</code> strings to correctly identify Questie-X as supporting Classic and private servers.</li>
|
||||
<li><strong>[Taint Analysis]</strong> Completed a full audit of <code>Questie-X-WotLKDB</code>. No direct taint vectors or secure function overrides were found.</li>
|
||||
<li><strong>[Version Sync]</strong> Synchronized versions to v1.3.4 across all components.</li>
|
||||
@@ -935,7 +935,7 @@
|
||||
|
||||
<h3>Core & Compatibility</h3>
|
||||
<ul>
|
||||
<li><strong>[Lua 5.0]</strong> Globally polyfilled <code>string.match</code> and <code>string.gmatch</code> using <code>string.find</code> and <code>string.gfind</code> to ensure universal compatibility with legacy WoW clients (e.g., Turtle WoW).</li>
|
||||
<li><strong>[Lua 5.0]</strong> Globally polyfilled <code>string.match</code> and <code>string.gmatch</code> using <code>string.find</code> and <code>string.gfind</code> to ensure universal compatibility with legacy WoW clients.</li>
|
||||
<li><strong>[AceTimer]</strong> Patched embedded <code>AceTimer-3.0</code> instances in ElvUI and OG-RaidHelper to resolve <code>math.mod</code> errors on Lua 5.0 clients.</li>
|
||||
<li><strong>[Colors]</strong> Updated <code>CreateColor</code> polyfill with <code>SetRGB</code>, <code>SetRGBA</code>, <code>SetColor</code>, and <code>GetColor</code> methods.</li>
|
||||
<li><strong>[Comm]</strong> Improved cross-client data sharing stability.</li>
|
||||
|
||||
Reference in New Issue
Block a user