From aed0daf4ce75827c31cb582893309a02c2e06cd4 Mon Sep 17 00:00:00 2001 From: Xurkon Date: Wed, 18 Mar 2026 15:08:52 -0500 Subject: [PATCH] =?UTF-8?q?feat:=20Release=20v1.3.2=20=E2=80=94=20Taint=20?= =?UTF-8?q?Resolution=20&=20Stability=20patches?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 13 +++++ Modules/Libs/QuestieLoader.lua | 6 +- Modules/Network/QuestieComms.lua | 31 +---------- Modules/Network/QuestieCommsData.lua | 30 +++------- Modules/QuestLinks/Hooks.lua | 16 +++--- Modules/QuestieInit.lua | 1 - Modules/WorldMapTaintWorkaround.lua | 6 +- Questie-X-Classic.toc | 2 +- Questie-X-TBC.toc | 2 +- Questie-X-Turtle.toc | 2 +- Questie-X.toc | 2 +- README.md | 2 +- docs/changelog.html | 11 ++++ docs/index.html | 82 ++++++++++++++++++---------- 14 files changed, 107 insertions(+), 99 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c0fe8a2..58c5546 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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. diff --git a/Modules/Libs/QuestieLoader.lua b/Modules/Libs/QuestieLoader.lua index c86225b..4fd69c3 100644 --- a/Modules/Libs/QuestieLoader.lua +++ b/Modules/Libs/QuestieLoader.lua @@ -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 diff --git a/Modules/Network/QuestieComms.lua b/Modules/Network/QuestieComms.lua index 71288e9..5369a64 100644 --- a/Modules/Network/QuestieComms.lua +++ b/Modules/Network/QuestieComms.lua @@ -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 = {} diff --git a/Modules/Network/QuestieCommsData.lua b/Modules/Network/QuestieCommsData.lua index 50d9781..f825774 100644 --- a/Modules/Network/QuestieCommsData.lua +++ b/Modules/Network/QuestieCommsData.lua @@ -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 diff --git a/Modules/QuestLinks/Hooks.lua b/Modules/QuestLinks/Hooks.lua index 86a4c4c..e8e53ef 100644 --- a/Modules/QuestLinks/Hooks.lua +++ b/Modules/QuestLinks/Hooks.lua @@ -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 diff --git a/Modules/QuestieInit.lua b/Modules/QuestieInit.lua index a6949d1..ee8d4ec 100644 --- a/Modules/QuestieInit.lua +++ b/Modules/QuestieInit.lua @@ -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 diff --git a/Modules/WorldMapTaintWorkaround.lua b/Modules/WorldMapTaintWorkaround.lua index bc3607d..eb455f7 100644 --- a/Modules/WorldMapTaintWorkaround.lua +++ b/Modules/WorldMapTaintWorkaround.lua @@ -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() diff --git a/Questie-X-Classic.toc b/Questie-X-Classic.toc index 7f7a749..0097d01 100644 --- a/Questie-X-Classic.toc +++ b/Questie-X-Classic.toc @@ -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 diff --git a/Questie-X-TBC.toc b/Questie-X-TBC.toc index b9b7ae7..73afa53 100644 --- a/Questie-X-TBC.toc +++ b/Questie-X-TBC.toc @@ -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 diff --git a/Questie-X-Turtle.toc b/Questie-X-Turtle.toc index f728ee7..b06d5b8 100644 --- a/Questie-X-Turtle.toc +++ b/Questie-X-Turtle.toc @@ -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 diff --git a/Questie-X.toc b/Questie-X.toc index 202211d..e1d04a2 100644 --- a/Questie-X.toc +++ b/Questie-X.toc @@ -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 diff --git a/README.md b/README.md index a32f2f5..ad0adf0 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Questie-X Logo -![Version](https://img.shields.io/badge/Questie--X-v1.3.1-blue.svg?style=for-the-badge) +![Version](https://img.shields.io/badge/Questie--X-v1.3.2-blue.svg?style=for-the-badge) ![Downloads](https://img.shields.io/github/downloads/Xurkon/Questie-X/total?style=for-the-badge&color=e67e22) [![Documentation](https://img.shields.io/badge/Documentation-View%20Docs-58a6ff?style=for-the-badge)](https://xurkon.github.io/Questie-X/) [![Patreon](https://img.shields.io/badge/Patreon-F96854?style=for-the-badge&logo=patreon&logoColor=white)](https://www.patreon.com/Xurkon) diff --git a/docs/changelog.html b/docs/changelog.html index a2b6bd0..51970f4 100644 --- a/docs/changelog.html +++ b/docs/changelog.html @@ -176,6 +176,17 @@
+

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

+ +

v1.3.1 — QuestieComms Streamlining

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.

diff --git a/docs/index.html b/docs/index.html index 402d027..51d4e7c 100644 --- a/docs/index.html +++ b/docs/index.html @@ -177,6 +177,58 @@
+ +
+

QuestieLearner: Autonomous Data Engine

+

Questie-X introduces QuestieLearner, 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.

+ +
+
+

Autonomous Acquisition

+

Learns NPC spawns, Quest relationships, Object locations, and Item drops directly from combat logs and interaction events. No manual wiring or database entry required.

+
+
+

3.3.5a Coordinate Scaling

+

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.

+
+
+ +

Universal Cross-Link Engine

+

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.

+
+ + +
+

Data Integrity & Confidence

+

To ensure database quality in crowd-sourced environments, Questie-X implements a multi-tier verification model.

+ +
+
+

Match Count (mc) System

+

Every learned entry tracks its "Match Count". Data is promoted to Verified status once it reaches the user-defined confidence threshold (default: 2).

+
+
+

Stale Data Cleanup

+

A tiered pruning engine tracks "Last Seen" (ls) timestamps. Unconfirmed data is automatically aged out after 90 days, while Verified entries are protected from expiration.

+
+
+ +
+ Confidence Gating: Map pins and tooltips for learned data are gated by confidence settings, preventing "one-off" anomalies or visual clutter from unconfirmed spawns. +
+
+ + +
+

Network Infrastructure

+

Questie-X utilizes hidden communication channels to synchronize confidence metrics and learned data across the player base in real-time.

+ +
    +
  • Global Data Sync: Learned kills and interactions are broadcasted via hidden global channels, allowing the community to effectively crowd-source the verification of spawn data.
  • +
  • Zero-Noise Heartbeat: 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.
  • +
+
+

Ebonhold Database Architecture

@@ -206,36 +258,6 @@ local function InjectOverrides() end
- -
-

Core Logic Refinements

- -
-
-

Quest Arrow: Auto-Mode

-

Restored "Auto Nearby" logic which points to the closest available quest when the player has no - active tracking list. Features Zone Filtering to prevent the arrow from - pointing to distant continents when in auto-mode.

-
-
-

Tracker Robustness

-

The tracker update loop is now protected with pcall. This prevents malformed quest - data (like the "Fel Orc Scavengers" bug) from crashing the entire UI and hiding unrelated - quests.

-
-
- -

Quest Icon Persistence Fix

-

Custom server quests often use auto-complete triggers which can bypass Questie's standard cleanup events. - I implemented a two-tier cleanup strategy:

-
    -
  • Delayed Verification: A 500ms check after QuestComplete to catch - lingering frames.
  • -
  • Periodic Cleanup: A 5-second background timer in AvailableQuests.lua - that audits the map for icons belonging to finished quests.
  • -
-
-

Custom Quest Implementation