ClassicAPI cleanup and safe hooks

This commit is contained in:
Dusk-92
2026-08-30 09:10:12 +02:00
parent 4af510e3dc
commit 279417bd54
11 changed files with 164 additions and 325 deletions
+10 -6
View File
@@ -1,5 +1,6 @@
local _G = ShaguTweaks.GetGlobalEnv()
local T = ShaguTweaks.T
local hooksecurefunc = ShaguTweaks.hooksecurefunc
local module = ShaguTweaks:register({
title = T["Floating Actionbar"],
@@ -52,13 +53,13 @@ module.enable = function(self)
-- replace experience bar texture
MainMenuExpBar:SetStatusBarTexture("Interface\\AddOns\\ShaguTweaks-extras\\img\\xpbar")
local _, _, _, _, _, background = MainMenuExpBar:GetRegions()
background:SetTexture("Interface\\AddOns\\ShaguTweaks-extras\\img\\xpbar")
background:SetVertexColor(0, 0, 0, .5)
if background then
background:SetTexture("Interface\\AddOns\\ShaguTweaks-extras\\img\\xpbar")
background:SetVertexColor(0, 0, 0, .5)
end
-- update reputation bar position
local HookReputationWatchBar_Update = ReputationWatchBar_Update
ReputationWatchBar_Update = function(newLevel)
HookReputationWatchBar_Update(newLevel)
-- keep the custom reputation position without replacing Blizzard's updater
local function UpdateReputationPosition()
if MainMenuExpBar:IsShown() then
ReputationWatchBar:SetPoint("BOTTOM", MainMenuBar, "TOP", 0, -7)
else
@@ -66,6 +67,9 @@ module.enable = function(self)
end
end
hooksecurefunc("ReputationWatchBar_Update", UpdateReputationPosition)
UpdateReputationPosition()
-- hide max level top frame
MainMenuBarMaxLevelBar:SetAlpha(0)
+32 -17
View File
@@ -26,19 +26,31 @@ module.enable = function(self)
reagentcounter:RegisterEvent("UPDATE_BONUS_ACTIONBAR")
reagentcounter:RegisterEvent("BAG_UPDATE")
-- Hidden frames still receive events, but do not execute OnUpdate.
-- Wake for one frame only when work is pending.
reagentcounter:Hide()
reagentcounter:SetScript("OnEvent", function()
this.event = true
this.pending = true
if event ~= "BAG_UPDATE" then
this.rescan = true
end
this:Show()
end)
reagentcounter:SetScript("OnUpdate", function()
if not this.event then return end
-- update all slots after each event
for slot = 1, 120 do
reagentcounter.ScanSlot(slot)
if not this.pending then
this:Hide()
return
end
-- scan for all reagent item counts
-- Tooltip scans are only required when the action layout changed.
if this.rescan then
for slot = 1, 120 do
reagentcounter.ScanSlot(slot)
end
end
-- Bag changes only need fresh counts for reagents already discovered.
for item in pairs(reagent_counts) do
reagent_counts[item] = GetItemCount(item)
end
@@ -47,24 +59,27 @@ module.enable = function(self)
for _, prefix in pairs(bars) do
for i = 1, NUM_ACTIONBAR_BUTTONS do
local button = _G[prefix .. "Button" .. i]
local text = _G[button:GetName().."Count"]
local slot = ActionButton_GetPagedID(button)
if button then
local text = _G[button:GetName().."Count"]
local slot = ActionButton_GetPagedID(button)
if reagent_slots[slot] then
text:SetText(reagent_counts[reagent_slots[slot]])
elseif not IsConsumableAction(slot) then
text:SetText()
if text then
if reagent_slots[slot] then
text:SetText(reagent_counts[reagent_slots[slot]])
elseif not IsConsumableAction(slot) then
text:SetText()
end
end
end
end
end
-- remove event trigger
this.event = nil
this.pending = nil
this.rescan = nil
this:Hide()
end)
reagentcounter.ScanSlot = function(slot)
local texture = GetActionTexture(slot)
-- update buttons that previously had an reagent
if reagent_slots[slot] and not HasAction(slot) then
reagent_slots[slot] = nil
+17 -19
View File
@@ -1,5 +1,7 @@
local _G = ShaguTweaks.GetGlobalEnv()
local T = ShaguTweaks.T
local API = ShaguTweaks.API or {}
local hooksecurefunc = ShaguTweaks.hooksecurefunc
local module = ShaguTweaks:register({
title = T["Bag Item Click"],
@@ -23,10 +25,16 @@ module.enable = function(self)
return AuctionFrame and AuctionFrame:IsShown() and AuctionFrameAuctions and AuctionFrameAuctions:IsShown()
end
-- overwrite use/trade logic unless shift is pressed
local function ShiftDown()
if API.IsShiftKeyDown then return API.IsShiftKeyDown() end
return IsShiftKeyDown()
end
-- Interception is intentional here: the feature must be able to suppress the
-- default item use while trade/auction actions are active.
local pfHookUseContainerItem = _G.UseContainerItem
function _G.UseContainerItem(bag, slot)
if IsTrading() and not IsShiftKeyDown() then
if IsTrading() and not ShiftDown() then
-- move item to trade window
PickupContainerItem(bag, slot)
local slot = TradeFrame_GetAvailableSlot()
@@ -34,13 +42,13 @@ module.enable = function(self)
if CursorHasItem() then
ClearCursor()
end
elseif IsAuctionBrowsing() and not IsShiftKeyDown() then
elseif IsAuctionBrowsing() and not ShiftDown() then
-- search item in auction house
local link = GetContainerItemLink(bag, slot)
local name = link and string.sub(link, string.find(link, "%[")+1, string.find(link, "%]")-1) or ""
BrowseName:SetText(name)
AuctionFrameBrowse_Search()
elseif IsAuctionSelling() and not IsShiftKeyDown() then
elseif IsAuctionSelling() and not ShiftDown() then
-- sell item to auction house
PickupContainerItem(bag, slot)
AuctionsItemButton:Click()
@@ -53,21 +61,11 @@ module.enable = function(self)
end
end
-- detect bag button tooltips
local showHelperNextTooltip = false
local pfHookSetBagItem = GameTooltip.SetBagItem
function GameTooltip.SetBagItem(self, container, slot)
showHelperNextTooltip = IsTrading() or IsAuctionBrowsing() or IsAuctionSelling()
return pfHookSetBagItem(self, container, slot)
end
-- add helper text to tooltips
local tooltip = CreateFrame("Frame", "pfItemClickHelpMessage", GameTooltip)
tooltip:SetScript("OnShow", function()
if showHelperNextTooltip then
GameTooltip:AddLine(T["Hold [Shift] to use item."], 0.50, 0.75, 1.00)
GameTooltip:Show()
showHelperNextTooltip = false
-- Append helper text after the native tooltip method instead of replacing it.
hooksecurefunc(GameTooltip, "SetBagItem", function(self, container, slot)
if IsTrading() or IsAuctionBrowsing() or IsAuctionSelling() then
self:AddLine(T["Hold [Shift] to use item."], 0.50, 0.75, 1.00)
self:Show()
end
end)
end
+24 -10
View File
@@ -1,5 +1,6 @@
local _G = ShaguTweaks.GetGlobalEnv()
local T = ShaguTweaks.T
local API = ShaguTweaks.API or {}
local module = ShaguTweaks:register({
title = T["Bag Search Bar"],
@@ -50,8 +51,24 @@ module.enable = function(self)
disable()
end
local function GetContainerItemName(bag, slot)
if API.GetContainerItemID and API.GetItemNameByID then
local itemID = API.GetContainerItemID(bag, slot)
local name = itemID and API.GetItemNameByID(itemID)
if name then return name end
end
local link = GetContainerItemLink(bag, slot)
if not link then return "" end
local startPos = string.find(link, "%[")
local endPos = string.find(link, "%]")
if not startPos or not endPos or endPos <= startPos then return "" end
return string.sub(link, startPos + 1, endPos - 1)
end
local query = function()
local text = strlower(search:GetText())
local text = strlower(search:GetText() or "")
-- bag search
for i = 1, 12 do
@@ -62,19 +79,17 @@ module.enable = function(self)
for j = 1, MAX_CONTAINER_ITEMS do
local button = _G[name.."Item"..j]
local texture = _G[button:GetName().."IconTexture"]
if button then
local slot = button and button:GetID()
local texture = _G[button:GetName().."IconTexture"]
local slot = button:GetID()
local link = GetContainerItemLink(bag, slot)
button:SetAlpha(.25)
texture:SetDesaturated(1)
if texture then texture:SetDesaturated(1) end
local item = link and string.sub(link, string.find(link, "%[")+1, string.find(link, "%]")-1) or ""
local item = GetContainerItemName(bag, slot)
if strfind(strlower(item), text, 1, true) then
button:SetAlpha(1)
texture:SetDesaturated(0)
if texture then texture:SetDesaturated(0) end
end
end
end
@@ -87,11 +102,10 @@ module.enable = function(self)
local button = _G["BankFrameItem"..i]
local texture = button and _G[button:GetName().."IconTexture"]
if button and texture then
local link = GetContainerItemLink(-1, i)
button:SetAlpha(.25)
texture:SetDesaturated(1)
local item = link and string.sub(link, string.find(link, "%[")+1, string.find(link, "%]")-1) or ""
local item = GetContainerItemName(-1, i)
if strfind(strlower(item), text, 1, true) then
button:SetAlpha(1)
texture:SetDesaturated(0)
-81
View File
@@ -1,81 +0,0 @@
local _G = ShaguTweaks.GetGlobalEnv()
local T = ShaguTweaks.T
local rgbhex = ShaguTweaks.rgbhex
local module = ShaguTweaks:register({
title = T["Chat History"],
description = T["Save chat history of all non-combatlog windows and restore it on login."],
expansions = { ["vanilla"] = true, ["tbc"] = false },
category = T["Chat"],
maintainer = "@shagu (GitHub)",
enabled = true,
})
module.enable = function(self)
local realm = GetRealmName()
local player = UnitName("player")
local history
local function SaveChatHistory(id, msg, r, g, b)
-- create cache tables if not existing
ShaguTweaks_cache = ShaguTweaks_cache or {}
ShaguTweaks_cache["chathistory"] = ShaguTweaks_cache["chathistory"] or {}
ShaguTweaks_cache["chathistory"][realm] = ShaguTweaks_cache["chathistory"][realm] or {}
ShaguTweaks_cache["chathistory"][realm][player] = ShaguTweaks_cache["chathistory"][realm][player] or {}
ShaguTweaks_cache["chathistory"][realm][player][id] = ShaguTweaks_cache["chathistory"][realm][player][id] or {}
if r and g and b then
local color = rgbhex(r*.5+.2, g*.5+.2, b*.5+.2)
msg = string.gsub(msg, "^", color)
msg = string.gsub(msg, "|r", "|r" .. color)
end
history = ShaguTweaks_cache["chathistory"][realm][player][id]
table.insert(history, 1, msg)
if history[30] then table.remove(history, 30) end
end
local function GetChatHistory(id)
-- create cache tables if not existing
ShaguTweaks_cache = ShaguTweaks_cache or {}
ShaguTweaks_cache["chathistory"] = ShaguTweaks_cache["chathistory"] or {}
ShaguTweaks_cache["chathistory"][realm] = ShaguTweaks_cache["chathistory"][realm] or {}
ShaguTweaks_cache["chathistory"][realm][player] = ShaguTweaks_cache["chathistory"][realm][player] or {}
ShaguTweaks_cache["chathistory"][realm][player][id] = ShaguTweaks_cache["chathistory"][realm][player][id] or {}
return ShaguTweaks_cache["chathistory"][realm][player][id]
end
local function AddMessage(frame, text, a1, a2, a3, a4, a5)
if not text then return end
-- save chat history
SaveChatHistory(frame:GetID(), text, a1, a2, a3)
frame:ShaguTweaksChatHistoryAddMessage(text, a1, a2, a3, a4, a5)
end
for i=1,NUM_CHAT_WINDOWS do
-- detect combat log message groups
local combat = 0
for _, msg in pairs(_G["ChatFrame"..i].messageTypeList) do
if strfind(msg, "SPELL", 1) or strfind(msg, "COMBAT", 1) then
combat = combat + 1
end
end
-- apply hooks and restore history on non-combat log frames
if combat <= 5 and not _G["ChatFrame"..i].ShaguTweaksChatHistoryAddMessage then
-- write history to chat
local history = GetChatHistory(i)
for j=30,0,-1 do
if history[j] then
_G["ChatFrame"..i]:AddMessage(history[j], .7,.7,.7)
end
end
-- add chat history hooks
_G["ChatFrame"..i].ShaguTweaksChatHistoryAddMessage = _G["ChatFrame"..i].AddMessage
_G["ChatFrame"..i].AddMessage = AddMessage
end
end
end
+8 -11
View File
@@ -1,6 +1,6 @@
local _G = ShaguTweaks.GetGlobalEnv()
local T = ShaguTweaks.T
local rgbhex = ShaguTweaks.rgbhex
local hooksecurefunc = ShaguTweaks.hooksecurefunc
local module = ShaguTweaks:register({
title = T["Center Text Input Box"],
@@ -19,21 +19,18 @@ module.enable = function(self)
ChatFrameEditBox:ClearAllPoints()
ChatFrameEditBox:SetWidth(300)
-- reload custom frame positions after original frame manage runs
local hookUIParent_ManageFramePositions = UIParent_ManageFramePositions
UIParent_ManageFramePositions = function(a1, a2, a3)
-- run original function
hookUIParent_ManageFramePositions(a1, a2, a3)
-- let inputbox dodge certain frames
local function UpdateInputPosition()
local top = 0
for id, frame in pairs(dodge_frames) do
if frame:IsVisible() and frame:GetTop() then
for _, frame in pairs(dodge_frames) do
if frame and frame:IsVisible() and frame:GetTop() then
top = math.max(top, frame:GetTop())
end
end
-- set new position
ChatFrameEditBox:ClearAllPoints()
ChatFrameEditBox:SetPoint("BOTTOM", UIParent, "BOTTOM", 0, top)
end
hooksecurefunc("UIParent_ManageFramePositions", UpdateInputPosition)
UpdateInputPosition()
end
+8 -7
View File
@@ -30,14 +30,15 @@ module.enable = function(self)
-- add hooks to each frame
for i=1,NUM_CHAT_WINDOWS do
local original = _G["ChatFrame"..i].AddMessage
_G["ChatFrame"..i].AddMessage = function(frame, msg, a1, a2, a3, a4, a5)
-- ignore empty messages
if not msg then return end
local frame = _G["ChatFrame"..i]
if frame and not frame.ShaguTweaksExtrasTimestampAddMessage then
frame.ShaguTweaksExtrasTimestampAddMessage = frame.AddMessage
frame.AddMessage = function(self, msg, a1, a2, a3, a4, a5)
if not msg then return end
-- add timestamp to chat
msg = color .. left .. date(format) .. right .. "|r " .. msg
original(frame, msg, a1, a2, a3, a4, a5)
msg = color .. left .. date(format) .. right .. "|r " .. msg
self:ShaguTweaksExtrasTimestampAddMessage(msg, a1, a2, a3, a4, a5)
end
end
end
end
-78
View File
@@ -1,78 +0,0 @@
local T = ShaguTweaks.T
local module = ShaguTweaks:register({
title = T["Show Energy Ticks"],
description = T["Show energy and mana ticks on the player unit frame."],
expansions = { ["vanilla"] = true, ["tbc"] = nil },
maintainer = "@shagu (GitHub)",
enabled = nil,
})
module.enable = function(self)
local energytick = CreateFrame("Frame", nil, PlayerFrameManaBar)
energytick:SetAllPoints(PlayerFrameManaBar)
energytick:RegisterEvent("PLAYER_ENTERING_WORLD")
energytick:RegisterEvent("UNIT_DISPLAYPOWER")
energytick:RegisterEvent("UNIT_ENERGY")
energytick:RegisterEvent("UNIT_MANA")
energytick:SetScript("OnEvent", function()
if UnitPowerType("player") == 0 then
this.mode = "MANA"
this:Show()
elseif UnitPowerType("player") == 3 then
this.mode = "ENERGY"
this:Show()
else
this:Hide()
end
if event == "PLAYER_ENTERING_WORLD" then
this.lastMana = UnitMana("player")
end
if (event == "UNIT_MANA" or event == "UNIT_ENERGY") and arg1 == "player" then
this.currentMana = UnitMana("player")
local diff = 0
if this.lastMana then
diff = this.currentMana - this.lastMana
end
if this.mode == "MANA" and diff < 0 then
this.target = 5
elseif this.mode == "MANA" and diff > 0 then
if this.max ~= 5 and diff > (this.badtick and this.badtick*1.2 or 5) then
this.target = 2
else
this.badtick = diff
end
elseif this.mode == "ENERGY" and diff > 0 then
this.target = 2
end
this.lastMana = this.currentMana
end
end)
energytick:SetScript("OnUpdate", function()
if this.target then
this.start, this.max = GetTime(), this.target
this.target = nil
end
if not this.start then return end
this.current = GetTime() - this.start
if this.current > this.max then
this.start, this.max, this.current = GetTime(), 2, 0
end
local pos = 120 * (this.current / this.max)
this.spark:SetPoint("LEFT", pos - 8.5, 0)
end)
energytick.spark = energytick:CreateTexture(nil, 'OVERLAY')
energytick.spark:SetTexture("Interface\\CastingBar\\UI-CastingBar-Spark")
energytick.spark:SetHeight(27)
energytick.spark:SetWidth(17)
energytick.spark:SetBlendMode('ADD')
end