Upload files to "/"

This commit is contained in:
2026-07-23 12:29:47 +00:00
parent 7b57a45a1b
commit fc4dbc4fb3
+91 -5
View File
@@ -6,7 +6,7 @@ RelationshipsAttune = RelationshipsAttune or {}
local RA = RelationshipsAttune local RA = RelationshipsAttune
local L = RelationshipsAttune_L local L = RelationshipsAttune_L
RA.VERSION = "1.4.3" RA.VERSION = "1.4.4"
RA.COMM_PREFIX = "RATTUNE" RA.COMM_PREFIX = "RATTUNE"
RA.playerName = nil RA.playerName = nil
@@ -183,6 +183,75 @@ function RA:ScanQuestLog()
end end
end end
-- ---------------------------------------------------------------
-- Completed-quest scan (server-side completed quest cache).
--
-- Turtle WoW / OctoWoW backport QueryQuestsCompleted() +
-- GetQuestsCompleted(t), which return every quest the character has
-- ever turned in -- including quests completed BEFORE the addon was
-- installed. Without this, the addon can only see quests that are
-- currently in the log (or that were "complete" in a previous scan
-- and then vanished), so a player who is already half-way through a
-- chain shows no progress until they accept the next quest.
--
-- We pcall everything so stock 1.12 clients that don't expose these
-- APIs simply skip the scan and keep the existing behaviour.
-- ---------------------------------------------------------------
function RA:ScanCompletedQuests()
-- Build the set of quest ids we actually care about so we don't
-- pollute the DB with thousands of unrelated turn-ins.
if not RelationshipsAttune_Data then return end
local wanted = {}
for i = 1, table.getn(RelationshipsAttune_Data) do
local att = RelationshipsAttune_Data[i]
if att and att.steps then
for j = 1, table.getn(att.steps) do
local s = att.steps[j]
if s and s.type == "quest" and s.id then
wanted[s.id] = true
end
end
end
end
local completed = {}
local haveAny = false
-- Preferred: bulk table fill.
if type(GetQuestsCompleted) == "function" then
local ok = pcall(GetQuestsCompleted, completed)
if ok then
for _ in pairs(completed) do haveAny = true break end
end
end
-- Fallback: per-id check (Turtle exposes IsQuestCompleted on some builds).
if not haveAny and type(IsQuestCompleted) == "function" then
for qid in pairs(wanted) do
local ok, res = pcall(IsQuestCompleted, qid)
if ok and res then
completed[qid] = true
haveAny = true
end
end
end
if not haveAny then
-- Kick the server to populate the cache; the QUEST_QUERY_COMPLETE
-- event handler will re-run this scan when the reply arrives.
if type(QueryQuestsCompleted) == "function" then
pcall(QueryQuestsCompleted)
end
return
end
for qid in pairs(wanted) do
if completed[qid] and RelationshipsAttuneCharDB.quests[qid] ~= "turnedin" then
RelationshipsAttuneCharDB.quests[qid] = "turnedin"
end
end
end
function RA:MarkQuestTurnedIn(questId) function RA:MarkQuestTurnedIn(questId)
if not questId then return end if not questId then return end
@@ -610,6 +679,7 @@ function RA:MarkDirty() RA._dirty = true end
-- Full periodic rescan (quest log + bags + recompute + UI refresh). -- Full periodic rescan (quest log + bags + recompute + UI refresh).
function RA:AutoScan() function RA:AutoScan()
RA:ScanQuestLog() RA:ScanQuestLog()
RA:ScanCompletedQuests()
RA:ScanBags() RA:ScanBags()
RA:RecomputeAll() RA:RecomputeAll()
if RA.UI and RA.UI.Refresh then RA.UI:Refresh() end if RA.UI and RA.UI.Refresh then RA.UI:Refresh() end
@@ -651,6 +721,7 @@ function RA:_OnUpdate(elapsed)
end end
if fired then if fired then
RA:WarmItemCache() RA:WarmItemCache()
RA:ScanCompletedQuests()
RA:ScanBags() RA:ScanBags()
RA:RecomputeAll() RA:RecomputeAll()
if RA.UI and RA.UI.Refresh then RA.UI:Refresh() end if RA.UI and RA.UI.Refresh then RA.UI:Refresh() end
@@ -740,13 +811,13 @@ local function slashHandler(msg)
if RA.Comm then RA.Comm:RequestSync() end if RA.Comm then RA.Comm:RequestSync() end
print(L.MSG_SYNC_SENT) print(L.MSG_SYNC_SENT)
elseif msg == "scan" then elseif msg == "scan" then
RA:ScanQuestLog(); RA:ScanBags(); RA:RecomputeAll() RA:ScanQuestLog(); RA:ScanCompletedQuests(); RA:ScanBags(); RA:RecomputeAll()
if RA.UI and RA.UI.Refresh then RA.UI:Refresh() end if RA.UI and RA.UI.Refresh then RA.UI:Refresh() end
print(L.MSG_SCANNED) print(L.MSG_SCANNED)
elseif msg == "reset" then elseif msg == "reset" then
RelationshipsAttuneCharDB = nil RelationshipsAttuneCharDB = nil
RA:InitDB() RA:InitDB()
RA:ScanQuestLog(); RA:ScanBags(); RA:RecomputeAll() RA:ScanQuestLog(); RA:ScanCompletedQuests(); RA:ScanBags(); RA:RecomputeAll()
if RA.UI and RA.UI.Refresh then RA.UI:Refresh() end if RA.UI and RA.UI.Refresh then RA.UI:Refresh() end
print(L.MSG_RESET) print(L.MSG_RESET)
elseif msg == "debug" or string.find(msg, "^find") then elseif msg == "debug" or string.find(msg, "^find") then
@@ -822,6 +893,7 @@ pcall(function() ef:RegisterEvent("ITEM_PUSH") end)
pcall(function() ef:RegisterEvent("PLAYER_XP_UPDATE") end) pcall(function() ef:RegisterEvent("PLAYER_XP_UPDATE") end)
pcall(function() ef:RegisterEvent("ZONE_CHANGED_NEW_AREA") end) pcall(function() ef:RegisterEvent("ZONE_CHANGED_NEW_AREA") end)
pcall(function() ef:RegisterEvent("SKILL_LINES_CHANGED") end) pcall(function() ef:RegisterEvent("SKILL_LINES_CHANGED") end)
pcall(function() ef:RegisterEvent("QUEST_QUERY_COMPLETE") end)
ef:SetScript("OnEvent", function() ef:SetScript("OnEvent", function()
local e = event local e = event
@@ -833,8 +905,15 @@ ef:SetScript("OnEvent", function()
RA.playerFaction = UnitFactionGroup("player") or "Neutral" RA.playerFaction = UnitFactionGroup("player") or "Neutral"
RA:BuildNameIndex() RA:BuildNameIndex()
RA:WarmItemCache() RA:WarmItemCache()
RA:ScanQuestLog(); RA:ScanBags(); RA:RecomputeAll() -- ScanCompletedQuests seeds the "already turned-in" state from the
RA._retryAt = { GetTime() + 3, GetTime() + 10 } -- server's completed-quest cache so mid-chain attunements show the
-- player's actual current step immediately at load, instead of
-- waiting until the next quest in the chain is accepted.
RA:ScanQuestLog(); RA:ScanCompletedQuests(); RA:ScanBags(); RA:RecomputeAll()
-- The completed-quest cache is often empty on first login until
-- QueryQuestsCompleted() round-trips to the server. Schedule extra
-- rescans so the UI catches up as soon as the cache is populated.
RA._retryAt = { GetTime() + 2, GetTime() + 5, GetTime() + 10 }
if RA.Comm and RA.Comm.Init then RA.Comm:Init() end if RA.Comm and RA.Comm.Init then RA.Comm:Init() end
if RA.UI and RA.UI.Init then RA.UI:Init() end if RA.UI and RA.UI.Init then RA.UI:Init() end
if RA.Minimap and RA.Minimap.Init then RA.Minimap:Init() end if RA.Minimap and RA.Minimap.Init then RA.Minimap:Init() end
@@ -863,6 +942,13 @@ ef:SetScript("OnEvent", function()
elseif e == "QUEST_TURNED_IN" then elseif e == "QUEST_TURNED_IN" then
if arg1 then RA:MarkQuestTurnedIn(arg1) end if arg1 then RA:MarkQuestTurnedIn(arg1) end
elseif e == "QUEST_QUERY_COMPLETE" then
if RA.initialized then
RA:ScanCompletedQuests()
RA:RecomputeAll()
if RA.UI and RA.UI.Refresh then RA.UI:Refresh() end
end
elseif e == "CHAT_MSG_ADDON" then elseif e == "CHAT_MSG_ADDON" then
if arg1 == RA.COMM_PREFIX and RA.Comm and RA.Comm.OnMessage then if arg1 == RA.COMM_PREFIX and RA.Comm and RA.Comm.OnMessage then
RA.Comm:OnMessage(arg2, arg3, arg4) RA.Comm:OnMessage(arg2, arg3, arg4)