feat: Release v1.3.2 — Taint Resolution & Stability patches
This commit is contained in:
@@ -1,5 +1,18 @@
|
||||
# Changelog
|
||||
|
||||
## v1.3.2 — Taint Resolution & Stability
|
||||
|
||||
*Finalizes the Taint Resolution project, eliminating `ADDON_ACTION_BLOCKED: UseAction()` errors by refactoring internal hooks to use secure alternatives and hardening the global namespace against collisions.*
|
||||
|
||||
### Core & Stability
|
||||
|
||||
- **[Taint Resolution]** Refactored `Hooks.lua` to use `hooksecurefunc` instead of raw hooks for all secure functions.
|
||||
- **[Global Safety]** Enhanced `QuestieLoader.lua` with a new collision-aware `PopulateGlobals` engine that prevents overwriting existing global variables and provides diagnostic warnings.
|
||||
- **[Security]** Eliminated global namespace modifications in `QuestieInit.lua`.
|
||||
- **[Workaround Hardening]** Refactored `WorldMapTaintWorkaround.lua` to remove legacy global function reassignments that were causing secondary taint.
|
||||
|
||||
---
|
||||
|
||||
## v1.3.1
|
||||
- Refined data-sharing mechanism to use exclusively hidden global channels, removing guild-channel broadcasts to minimize chat traffic.
|
||||
|
||||
|
||||
@@ -139,7 +139,11 @@ end
|
||||
|
||||
function QuestieLoader:PopulateGlobals() -- called when debugging is enabled
|
||||
for name, module in pairs(modules) do
|
||||
_G[name] = module
|
||||
if _G[name] == nil then
|
||||
_G[name] = module
|
||||
elseif _G[name] ~= module then
|
||||
Questie:Debug(Questie.DEBUG_CRITICAL, "[QuestieLoader] GLOBAL COLLISION: '" .. tostring(name) .. "' already exists in _G! Skipping population to avoid Taint.")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -471,11 +471,8 @@ QuestieComms._yellWaitingQuests = {}
|
||||
QuestieComms._yellQueue = {}
|
||||
QuestieComms._isYelling = false
|
||||
|
||||
local _loadupTime_removeme = GetTime() -- this will be removed in 6.0.1 or 6.1, when we can figure out a proper way to prevent
|
||||
-- yelling quests on login. Not enough time to make and test a proper fix
|
||||
|
||||
function QuestieComms:YellProgress(questId)
|
||||
if Questie.db.profile.disableYellComms or badYellLocations[C_Map.GetBestMapForUnit("player")] or QuestiePlayer.numberOfGroupMembers > 4 or GetTime() - _loadupTime_removeme < 8 then
|
||||
if Questie.db.profile.disableYellComms or badYellLocations[C_Map.GetBestMapForUnit("player")] or QuestiePlayer.numberOfGroupMembers > 4 then
|
||||
return
|
||||
end
|
||||
if not QuestieComms._yellWaitingQuests[questId] then
|
||||
@@ -484,35 +481,11 @@ function QuestieComms:YellProgress(questId)
|
||||
tinsert(QuestieComms._yellQueue, questId)
|
||||
else
|
||||
QuestieComms._isYelling = true
|
||||
C_Timer.After(2, function()
|
||||
_DoYell(questId)
|
||||
end)
|
||||
-- Yell progress feature is currently disabled
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
_DoYell = function(questId)
|
||||
--[[local data = {}
|
||||
local _, count = QuestieComms:PopulateQuestDataPacketV2(questId, data, 1)
|
||||
if count > 0 then -- dont send quests with no objectives
|
||||
local packet = _QuestieComms:CreatePacket(_QuestieComms.QC_ID_YELL_PROGRESS);
|
||||
packet.data[1] = data;
|
||||
packet.data.priority = "BULK"
|
||||
packet.data.writeMode = _QuestieComms.QC_WRITE_YELL
|
||||
|
||||
packet:write();
|
||||
QuestieComms._yellWaitingQuests[questId] = nil
|
||||
end
|
||||
local nextQuest = tremove(QuestieComms._yellQueue, 1)
|
||||
if nextQuest then
|
||||
C_Timer.After(2, function()
|
||||
_DoYell(nextQuest)
|
||||
end)
|
||||
else
|
||||
QuestieComms._isYelling = false
|
||||
end]]
|
||||
end
|
||||
|
||||
_QuestieComms._isBroadcasting = false
|
||||
_QuestieComms._needsNewBroadcast = false
|
||||
_QuestieComms._nextBroadcastData = {}
|
||||
|
||||
@@ -93,29 +93,17 @@ function QuestieComms.data:RegisterTooltip(questId, playerName, objectives)
|
||||
--Questie:Debug(Questie.DEBUG_DEVELOP, "Adding tooltip lookup", lookupKey, questId, playerName);
|
||||
if(objective.type == "i") then
|
||||
local item = QuestieDB:GetItem(objective.id);
|
||||
if not item or item.Hidden then
|
||||
return
|
||||
end
|
||||
for index, source in pairs(item.Sources or {}) do
|
||||
local sourceType = string.sub(source.Type, 1, 1);
|
||||
local sourceId = source.Id;
|
||||
local sourceLookupKey = sourceType.."_"..sourceId;
|
||||
QuestieComms.data:AddTooltip(playerName, questId, sourceLookupKey, objectiveIndex, objective);
|
||||
if item and not item.Hidden then
|
||||
for index, source in pairs(item.Sources or {}) do
|
||||
local sourceType = string.sub(source.Type, 1, 1);
|
||||
local sourceId = source.Id;
|
||||
local sourceLookupKey = sourceType.."_"..sourceId;
|
||||
QuestieComms.data:AddTooltip(playerName, questId, sourceLookupKey, objectiveIndex, objective);
|
||||
end
|
||||
end
|
||||
else
|
||||
QuestieComms.data:AddTooltip(playerName, questId, lookupKey, objectiveIndex, objective);
|
||||
end
|
||||
--[[if(not commsTooltipLookup[lookupKey]) then
|
||||
commsTooltipLookup[lookupKey] = {}
|
||||
end
|
||||
if(not commsTooltipLookup[lookupKey][playerName]) then
|
||||
commsTooltipLookup[lookupKey][playerName] = {};
|
||||
end
|
||||
if(not commsTooltipLookup[lookupKey][playerName][questId]) then
|
||||
commsTooltipLookup[lookupKey][playerName][questId] = {};
|
||||
end
|
||||
commsTooltipLookup[lookupKey][playerName][questId][objectiveIndex] = objective;
|
||||
|
||||
playerRegisteredTooltips[playerName][questId][lookupKey] = true;]]--
|
||||
QuestieComms.data:AddTooltip(playerName, questId, lookupKey, objectiveIndex, objective);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -14,12 +14,9 @@ local GetQuestIDFromLogIndex = QuestieCompat.GetQuestIDFromLogIndex
|
||||
|
||||
function Hooks:HookQuestLogTitle()
|
||||
Questie:Debug(Questie.DEBUG_DEVELOP, "[Hooks] Hooking Quest Log Title")
|
||||
local baseQLTB_OnClick = QuestLogTitleButton_OnClick
|
||||
|
||||
-- We can not use hooksecurefunc because this needs to be a pre-hook to work properly unfortunately
|
||||
QuestLogTitleButton_OnClick = function(self, button)
|
||||
hooksecurefunc("QuestLogTitleButton_OnClick", function(self, button)
|
||||
if (not self) or self.isHeader then
|
||||
baseQLTB_OnClick(self, button)
|
||||
return
|
||||
end
|
||||
|
||||
@@ -39,18 +36,19 @@ function Hooks:HookQuestLogTitle()
|
||||
ChatEdit_InsertLink(questLink)
|
||||
end
|
||||
QuestLog_SetSelection(questLogLineIndex)
|
||||
return
|
||||
-- We can't return here to stop the execution of the original function in hooksecurefunc,
|
||||
-- but for chat links the original function usually just selects the quest anyway.
|
||||
end
|
||||
|
||||
-- For all other clicks (including tracking/untracking), use the original function
|
||||
-- only call Questie's tracker if we actually want to fix this quest (normal quests already call AQW_insert)
|
||||
if Questie.db.profile.trackerEnabled and GetNumQuestLeaderBoards(questLogLineIndex) == 0 and (not IsQuestWatched(questLogLineIndex)) then
|
||||
QuestieTracker:AQW_Insert(questLogLineIndex, QUEST_WATCH_NO_EXPIRE)
|
||||
WatchFrame_Update()
|
||||
if WatchFrame_Update then
|
||||
WatchFrame_Update()
|
||||
end
|
||||
QuestLog_SetSelection(questLogLineIndex)
|
||||
QuestLog_Update()
|
||||
else
|
||||
baseQLTB_OnClick(self, button)
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
@@ -473,7 +473,6 @@ function QuestieInit:LoadBaseDB()
|
||||
local function _pullGlobal(dbKey, globalName)
|
||||
if type(_G[globalName]) == "table" then
|
||||
QuestieDB[dbKey] = _G[globalName]
|
||||
_G[globalName] = nil
|
||||
return true
|
||||
end
|
||||
return false
|
||||
|
||||
@@ -7,15 +7,15 @@ local function doWorkaround()
|
||||
-- HDB (and Questie fork of it) uses WorldMapFrame:AddDataProvider( ).
|
||||
-- print("|cff30fc96Questie|r: |cff00bc32Hiding drop-down menus on the World Map.|r This is currently necessary as a workaround for a bug in the default Blizzard UI related to drop-down menus.")
|
||||
if WorldMapZoneMinimapDropDown then
|
||||
WorldMapZoneMinimapDropDown_Update = function() end
|
||||
WorldMapZoneMinimapDropDown:Hide()
|
||||
end
|
||||
if WorldMapContinentDropDown then
|
||||
--WorldMapContinentDropDown_Update = function() end
|
||||
-- We only Hide() these frames.
|
||||
-- Reassigning the _Update functions (e.g. WorldMapContinentDropDown_Update = function() end)
|
||||
-- would cause Taint, which results in ADDON_ACTION_BLOCKED: UseAction().
|
||||
WorldMapContinentDropDown:Hide()
|
||||
end
|
||||
if WorldMapZoneDropDown then
|
||||
--WorldMapZoneDropDown_Update = function() end
|
||||
WorldMapZoneDropDown:Hide()
|
||||
end
|
||||
--WorldMapMagnifyingGlassButton:Hide()
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
## Notes-esES: Ayundante de misión
|
||||
## Notes-ptBR: Ajudante de missão
|
||||
## Notes-frFR: Assistant de quête
|
||||
## Version: 1.3.1
|
||||
## Version: 1.3.2
|
||||
## RequiredDeps:
|
||||
## OptionalDeps: Ace3, CallbackHandler-1.0, HereBeDragons, LibDataBroker-1.1, LibDBIcon-1.0, LibSharedMedia-3.0, LibStub, LibUIDropDownMenu
|
||||
## SavedVariables: QuestieConfig
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
## Notes-esES: Ayundante de misión
|
||||
## Notes-ptBR: Ajudante de missão
|
||||
## Notes-frFR: Assistant de quête
|
||||
## Version: 1.3.1
|
||||
## Version: 1.3.2
|
||||
## RequiredDeps:
|
||||
## OptionalDeps: Ace3, CallbackHandler-1.0, HereBeDragons, LibDataBroker-1.1, LibDBIcon-1.0, LibSharedMedia-3.0, LibStub, LibUIDropDownMenu
|
||||
## SavedVariables: QuestieConfig
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
## Notes-esES: Ayundante de misión
|
||||
## Notes-ptBR: Ajudante de missão
|
||||
## Notes-frFR: Assistant de quête
|
||||
## Version: 1.3.1
|
||||
## Version: 1.3.2
|
||||
## RequiredDeps:
|
||||
## OptionalDeps: Ace3, CallbackHandler-1.0, HereBeDragons, LibDataBroker-1.1, LibDBIcon-1.0, LibSharedMedia-3.0, LibStub, LibUIDropDownMenu, Questie-X-TurtleDB
|
||||
## SavedVariables: QuestieConfig
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@
|
||||
## Notes-esES: Ayundante de misión
|
||||
## Notes-ptBR: Ajudante de missão
|
||||
## Notes-frFR: Assistant de quête
|
||||
## Version: 1.3.1
|
||||
## Version: 1.3.2
|
||||
## RequiredDeps:
|
||||
## OptionalDeps: Ace3, CallbackHandler-1.0, HereBeDragons, LibDataBroker-1.1, LibDBIcon-1.0, LibSharedMedia-3.0, LibStub, LibUIDropDownMenu, Questie-X-WotLKDB, Questie-X-ClassicDB, Questie-X-TBCDB, Questie-X-TurtleDB, Questie-X-AscensionDB, Questie-X-EbonholdDB
|
||||
## SavedVariables: QuestieConfig, QuestieLearnerDB
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<img src="docs/QuestieXlogo.png" alt="Questie-X Logo" width="320" />
|
||||
|
||||

|
||||

|
||||

|
||||
[](https://xurkon.github.io/Questie-X/)
|
||||
[](https://www.patreon.com/Xurkon)
|
||||
|
||||
@@ -176,6 +176,17 @@
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<h2 id="v132">v1.3.2 — Taint Resolution & Stability</h2>
|
||||
<p><em>Finalizes the Taint Resolution project, eliminating <code>ADDON_ACTION_BLOCKED: UseAction()</code> errors by refactoring internal hooks to use secure alternatives and hardening the global namespace against collisions.</em></p>
|
||||
|
||||
<h3>Core & Stability</h3>
|
||||
<ul>
|
||||
<li><strong>[Taint Resolution]</strong> Refactored <code>Hooks.lua</code> to use <code>hooksecurefunc</code> instead of raw hooks for all secure functions.</li>
|
||||
<li><strong>[Global Safety]</strong> Enhanced <code>QuestieLoader.lua</code> with a new collision-aware <code>PopulateGlobals</code> engine that prevents overwriting existing global variables and provides diagnostic warnings.</li>
|
||||
<li><strong>[Security]</strong> Eliminated global namespace modifications in <code>QuestieInit.lua</code>.</li>
|
||||
<li><strong>[Workaround Hardening]</strong> Refactored <code>WorldMapTaintWorkaround.lua</code> to remove legacy global function reassignments that were causing secondary taint.</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="v131">v1.3.1 — QuestieComms Streamlining</h2>
|
||||
<p><em>Refines the data-sharing mechanism to use exclusively hidden global channels, removing guild-channel broadcasts to minimize chat traffic while maintaining real-time data synchronization.</em></p>
|
||||
|
||||
|
||||
+52
-30
@@ -177,6 +177,58 @@
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<!-- QuestieLearner Engine -->
|
||||
<section id="questielearner">
|
||||
<h2>QuestieLearner: Autonomous Data Engine</h2>
|
||||
<p>Questie-X introduces <strong>QuestieLearner</strong>, a zero-configuration autonomous engine that learns the world as you play. It automatically bridges the gap between static database entries and real-time server-side realities.</p>
|
||||
|
||||
<div class="grid">
|
||||
<div class="card">
|
||||
<h4>Autonomous Acquisition</h4>
|
||||
<p>Learns NPC spawns, Quest relationships, Object locations, and Item drops directly from combat logs and interaction events. No manual wiring or database entry required.</p>
|
||||
</div>
|
||||
<div class="card">
|
||||
<h4>3.3.5a Coordinate Scaling</h4>
|
||||
<p>Implements a precision-first scaling logic that normalizes 3.3.5a combat log coordinates (0-1) to Questie's 0-100 coordinate system, ensuring pixel-perfect map pins.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3>Universal Cross-Link Engine</h3>
|
||||
<p>A bidirectional relationship engine that automatically stitches connections between learned entities. If an item drops from an NPC for a specific quest, QuestieLearner cross-links all three, immediately enabling map pins and tooltips for that item-source chain.</p>
|
||||
</section>
|
||||
|
||||
<!-- Data Integrity -->
|
||||
<section id="integrity">
|
||||
<h2>Data Integrity & Confidence</h2>
|
||||
<p>To ensure database quality in crowd-sourced environments, Questie-X implements a multi-tier verification model.</p>
|
||||
|
||||
<div class="grid">
|
||||
<div class="card">
|
||||
<h4>Match Count (mc) System</h4>
|
||||
<p>Every learned entry tracks its "Match Count". Data is promoted to <strong>Verified</strong> status once it reaches the user-defined confidence threshold (default: 2).</p>
|
||||
</div>
|
||||
<div class="card">
|
||||
<h4>Stale Data Cleanup</h4>
|
||||
<p>A tiered pruning engine tracks "Last Seen" (ls) timestamps. <strong>Unconfirmed</strong> data is automatically aged out after 90 days, while <strong>Verified</strong> entries are protected from expiration.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="important">
|
||||
<strong>Confidence Gating:</strong> Map pins and tooltips for learned data are gated by confidence settings, preventing "one-off" anomalies or visual clutter from unconfirmed spawns.
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Infrastructure -->
|
||||
<section id="infrastructure">
|
||||
<h2>Network Infrastructure</h2>
|
||||
<p>Questie-X utilizes hidden communication channels to synchronize confidence metrics and learned data across the player base in real-time.</p>
|
||||
|
||||
<ul>
|
||||
<li><strong>Global Data Sync</strong>: Learned kills and interactions are broadcasted via hidden global channels, allowing the community to effectively crowd-source the verification of spawn data.</li>
|
||||
<li><strong>Zero-Noise Heartbeat</strong>: Communication is optimized to utilize hidden channels exclusively (removing GUILD channel noise), ensuring zero impact on player guild chat logs while maintaining real-time confidence updates for learned NPCs.</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<!-- Database Architecture -->
|
||||
<section id="database">
|
||||
<h2>Ebonhold Database Architecture</h2>
|
||||
@@ -206,36 +258,6 @@ local function InjectOverrides()
|
||||
end</code></pre>
|
||||
</section>
|
||||
|
||||
<!-- Logic Refinements -->
|
||||
<section id="logic-refinements">
|
||||
<h2>Core Logic Refinements</h2>
|
||||
|
||||
<div class="grid">
|
||||
<div class="card">
|
||||
<h4>Quest Arrow: Auto-Mode</h4>
|
||||
<p>Restored "Auto Nearby" logic which points to the closest available quest when the player has no
|
||||
active tracking list. Features <strong>Zone Filtering</strong> to prevent the arrow from
|
||||
pointing to distant continents when in auto-mode.</p>
|
||||
</div>
|
||||
<div class="card">
|
||||
<h4>Tracker Robustness</h4>
|
||||
<p>The tracker update loop is now protected with <code>pcall</code>. This prevents malformed quest
|
||||
data (like the "Fel Orc Scavengers" bug) from crashing the entire UI and hiding unrelated
|
||||
quests.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3>Quest Icon Persistence Fix</h3>
|
||||
<p>Custom server quests often use auto-complete triggers which can bypass Questie's standard cleanup events.
|
||||
I implemented a two-tier cleanup strategy:</p>
|
||||
<ul>
|
||||
<li><strong>Delayed Verification</strong>: A 500ms check after <code>QuestComplete</code> to catch
|
||||
lingering frames.</li>
|
||||
<li><strong>Periodic Cleanup</strong>: A 5-second background timer in <code>AvailableQuests.lua</code>
|
||||
that audits the map for icons belonging to finished quests.</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<!-- Custom Quest Implementation -->
|
||||
<section id="custom-quests">
|
||||
<h2>Custom Quest Implementation</h2>
|
||||
|
||||
Reference in New Issue
Block a user