fix(p1): restore Lua 5.0 polyfills, hooksecurefunc, C_Timer, LibDeflate, and XXH load lines

- QuestieLoader.lua: add table.getn, math.mod, string.match, string.gmatch, select polyfills
- QuestieCompat.lua: add string.match, select, math.mod shims; hooksecurefunc polyfill;
  full C_Timer polyfill; fix Is335 to use do/end block safe for Lua 5.0
- embeds.xml: add LibDeflate lib.xml include
- Questie-X.toc, Questie-X-Classic.toc, Questie-X-Turtle.toc: add XXH_Lua_Lib load line
This commit is contained in:
Xurkon
2026-03-15 17:50:50 -05:00
parent 5582f310eb
commit 6d3189b608
6 changed files with 232 additions and 2 deletions
+59
View File
@@ -1,3 +1,62 @@
-- Shim for Lua 5.2+ (Retail) where table.getn was removed.
-- We cannot use the '#' length operator directly because Lua 5.0 (Turtle WoW)
-- 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
local loadFunc = loadstring or load
if loadFunc then
table.getn = loadFunc("return function(t) return table.getn(t) end")()
end
end
-- Shim for Lua 5.1+ (Ascension/Ebonhold/Retail) where math.mod was renamed/removed.
-- We cannot use the '%' modulo operator directly because Lua 5.0
-- will trigger a compile-time syntax error parsing the file.
if not math.mod then
local loadFunc = loadstring or load
if loadFunc then
math.mod = loadFunc("return function(a, b) return a % b end")()
end
end
-- Shim for Lua 5.0 (Turtle WoW) where string.match is missing.
if not string.match then
string.match = function(str, pattern, init)
if not str then return nil end
local start_idx, end_idx, capture1, capture2, capture3, capture4, capture5 = string.find(str, pattern, init)
if start_idx then
if capture1 then
return capture1, capture2, capture3, capture4, capture5
else
return string.sub(str, start_idx, end_idx)
end
end
return nil
end
end
-- Shim for Lua 5.0 where string.gmatch is called string.gfind.
if not string.gmatch then
string.gmatch = string.gfind
end
-- Shim for Lua 5.0 (Turtle WoW) where select() was not yet implemented.
if not select then
select = function(index, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25)
if index == "#" then
return arg and arg.n or table.getn(arg or {})
end
index = tonumber(index) or 1
if index < 1 then error("bad argument #1 to 'select' (index out of range)") end
if index > (arg and arg.n or table.getn(arg or {})) then return end
local result = {}
for i = index, (arg and arg.n or table.getn(arg or {})) do
table.insert(result, arg[i])
end
return unpack(result)
end
end
-- The only public class except for Questie -- The only public class except for Questie
---@class QuestieLoader ---@class QuestieLoader
QuestieLoader = {} QuestieLoader = {}
+168 -1
View File
@@ -2,8 +2,95 @@
---@class QuestieCompat ---@class QuestieCompat
QuestieCompat = setmetatable({}, { __index = _G }) QuestieCompat = setmetatable({}, { __index = _G })
------------------------------------------
-- Lua 5.0 string compatibility (e.g. Turtle)
------------------------------------------
if type(string) == "table" and type(string.match) ~= "function" then
function string.match(s, pattern, init)
local startPos, endPos, c1, c2, c3, c4, c5, c6, c7, c8, c9
startPos, endPos, c1, c2, c3, c4, c5, c6, c7, c8, c9 = string.find(s, pattern, init or 1)
if not startPos then
return nil
end
if c1 ~= nil then
return c1, c2, c3, c4, c5, c6, c7, c8, c9
end
return string.sub(s, startPos, endPos)
end
end
if not select then
function select(index, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25)
if index == "#" then
local n = 25
while n > 0 do
if n == 25 and a25 ~= nil then return 25 end
if n == 24 and a24 ~= nil then return 24 end
if n == 23 and a23 ~= nil then return 23 end
if n == 22 and a22 ~= nil then return 22 end
if n == 21 and a21 ~= nil then return 21 end
if n == 20 and a20 ~= nil then return 20 end
if n == 19 and a19 ~= nil then return 19 end
if n == 18 and a18 ~= nil then return 18 end
if n == 17 and a17 ~= nil then return 17 end
if n == 16 and a16 ~= nil then return 16 end
if n == 15 and a15 ~= nil then return 15 end
if n == 14 and a14 ~= nil then return 14 end
if n == 13 and a13 ~= nil then return 13 end
if n == 12 and a12 ~= nil then return 12 end
if n == 11 and a11 ~= nil then return 11 end
if n == 10 and a10 ~= nil then return 10 end
if n == 9 and a9 ~= nil then return 9 end
if n == 8 and a8 ~= nil then return 8 end
if n == 7 and a7 ~= nil then return 7 end
if n == 6 and a6 ~= nil then return 6 end
if n == 5 and a5 ~= nil then return 5 end
if n == 4 and a4 ~= nil then return 4 end
if n == 3 and a3 ~= nil then return 3 end
if n == 2 and a2 ~= nil then return 2 end
if n == 1 and a1 ~= nil then return 1 end
return 0
end
return 0
end
if index == 1 then return a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25 end
if index == 2 then return a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25 end
if index == 3 then return a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25 end
if index == 4 then return a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25 end
if index == 5 then return a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25 end
if index == 6 then return a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25 end
if index == 7 then return a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25 end
if index == 8 then return a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25 end
if index == 9 then return a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25 end
if index == 10 then return a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25 end
if index == 11 then return a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25 end
if index == 12 then return a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25 end
if index == 13 then return a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25 end
if index == 14 then return a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25 end
if index == 15 then return a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25 end
if index == 16 then return a16, a17, a18, a19, a20, a21, a22, a23, a24, a25 end
if index == 17 then return a17, a18, a19, a20, a21, a22, a23, a24, a25 end
if index == 18 then return a18, a19, a20, a21, a22, a23, a24, a25 end
if index == 19 then return a19, a20, a21, a22, a23, a24, a25 end
if index == 20 then return a20, a21, a22, a23, a24, a25 end
if index == 21 then return a21, a22, a23, a24, a25 end
if index == 22 then return a22, a23, a24, a25 end
if index == 23 then return a23, a24, a25 end
if index == 24 then return a24, a25 end
if index == 25 then return a25 end
return nil
end
end
if not math.mod and math.fmod then
math.mod = math.fmod
end
-- addon is running on 3.3.5 WotLK client -- addon is running on 3.3.5 WotLK client
QuestieCompat.Is335 = (select(4, GetBuildInfo()) == 30300) do
local _, _, _, build = GetBuildInfo()
QuestieCompat.Is335 = (build == 30300)
end
local errorMsg = "Questie tried to call a blizzard API function that does not exist..." local errorMsg = "Questie tried to call a blizzard API function that does not exist..."
@@ -36,6 +123,86 @@ end
-- API difference compatibility (Era/Wotlk) -- API difference compatibility (Era/Wotlk)
------------------------------------------- -------------------------------------------
if not hooksecurefunc then
function hooksecurefunc(arg1, arg2, arg3)
local t, name, func
if type(arg1) == "string" then
t = _G
name = arg1
func = arg2
elseif type(arg1) == "table" then
t = arg1
name = arg2
func = arg3
end
local original = t[name]
t[name] = function(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25)
local ret1, ret2, ret3, ret4
if original then
ret1, ret2, ret3, ret4 = original(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25)
end
func(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25)
return ret1, ret2, ret3, ret4
end
end
end
QuestieCompat.hooksecurefunc = hooksecurefunc
if not C_Timer then
local TickerFrame = CreateFrame("Frame")
local tickers = {}
TickerFrame:SetScript("OnUpdate", function()
local elapsed = 1 / GetFramerate()
for i = table.getn(tickers), 1, -1 do
local ticker = tickers[i]
if not ticker._cancelled then
ticker._elapsed = ticker._elapsed + elapsed
if ticker._elapsed >= ticker._duration then
ticker._elapsed = ticker._elapsed - ticker._duration
ticker._callback()
if ticker._iterations then
ticker._iterations = ticker._iterations - 1
if ticker._iterations <= 0 then
ticker._cancelled = true
table.remove(tickers, i)
end
end
end
else
table.remove(tickers, i)
end
end
end)
C_Timer = {
After = function(duration, callback)
table.insert(tickers, {
_duration = duration,
_elapsed = 0,
_callback = callback,
_iterations = 1,
_cancelled = false
})
end,
NewTicker = function(duration, callback, iterations)
local ticker = {
_duration = duration,
_elapsed = 0,
_callback = callback,
_iterations = iterations,
_cancelled = false,
Cancel = function(self)
self._cancelled = true
end
}
table.insert(tickers, ticker)
return ticker
end
}
end
QuestieCompat.C_Timer = C_Timer
---[SetMinResize Documentation](https://wowpedia.fandom.com/wiki/API_Frame_SetMinResize) ---[SetMinResize Documentation](https://wowpedia.fandom.com/wiki/API_Frame_SetMinResize)
---[SetMaxResize Documentation](https://wowpedia.fandom.com/wiki/API_Frame_SetMaxResize) ---[SetMaxResize Documentation](https://wowpedia.fandom.com/wiki/API_Frame_SetMaxResize)
---[SetResizeBounds Documentation](https://wowpedia.fandom.com/wiki/API_Frame_SetMinResize) ---[SetResizeBounds Documentation](https://wowpedia.fandom.com/wiki/API_Frame_SetMinResize)
+1
View File
@@ -20,6 +20,7 @@ Modules\Libs\QuestieLoader.lua
# COMPATIBILITY # COMPATIBILITY
Modules\QuestieCompat.lua Modules\QuestieCompat.lua
Compat\embeds.xml Compat\embeds.xml
Libs\XXH_Lua_Lib\XXH_Lua_Lib.lua
Modules\VersionCheck.lua Modules\VersionCheck.lua
+1
View File
@@ -21,6 +21,7 @@ Modules\Libs\QuestieLoader.lua
Modules\QuestieCompat.lua Modules\QuestieCompat.lua
Libs\LibStub\LibStub.lua Libs\LibStub\LibStub.lua
embeds.xml embeds.xml
Libs\XXH_Lua_Lib\XXH_Lua_Lib.lua
Libs\LibDataBroker-1.1\LibDataBroker-1.1.lua Libs\LibDataBroker-1.1\LibDataBroker-1.1.lua
Libs\LibDBIcon-1.0\LibDBIcon-1.0.lua Libs\LibDBIcon-1.0\LibDBIcon-1.0.lua
Libs\Krowi_WorldMapButtons\Krowi_WorldMapButtons-1.4.lua Libs\Krowi_WorldMapButtons\Krowi_WorldMapButtons-1.4.lua
+1
View File
@@ -29,6 +29,7 @@ Modules\Libs\QuestiePluginAPI.lua
# COMPATIBILITY # COMPATIBILITY
Modules\QuestieCompat.lua Modules\QuestieCompat.lua
Compat\embeds.xml Compat\embeds.xml
Libs\XXH_Lua_Lib\XXH_Lua_Lib.lua
Modules\VersionCheck.lua Modules\VersionCheck.lua
+1
View File
@@ -18,6 +18,7 @@
<!-- Ace3 frame work end --> <!-- Ace3 frame work end -->
<Include file="Libs\LibSharedMedia-3.0\lib.xml"/> <Include file="Libs\LibSharedMedia-3.0\lib.xml"/>
<Include file="Libs\AceGUI-3.0-SharedMediaWidgets\widget.xml"/> <Include file="Libs\AceGUI-3.0-SharedMediaWidgets\widget.xml"/>
<Include file="Libs\LibDeflate\lib.xml"/>
<Script file="Libs\LibDataBroker-1.1\LibDataBroker-1.1.lua"/> <Script file="Libs\LibDataBroker-1.1\LibDataBroker-1.1.lua"/>
<Script file="Libs\LibDBIcon-1.0\LibDBIcon-1.0.lua"/> <Script file="Libs\LibDBIcon-1.0\LibDBIcon-1.0.lua"/>