Refactor Buff Ending Announcer to Aura Expiry

- Deleted LibGroupInSpecT-1.1.toc, LibStub.lua, and lib.xml files as they are no longer needed.
- Updated localization files (deDE.lua, enUS.lua) to reflect the change from "Buff Ending" to "Aura Expiry".
- Renamed BuffEndingAnnouncer module to AuraExpiry and updated references throughout the codebase.
- Adjusted options and configuration to align with the new module name.
- Updated readme to describe the new Aura Expiry feature instead of Buff Ending Announcer.
This commit is contained in:
Torsten Brendgen
2026-04-11 23:21:34 +02:00
parent 8f2f66e3a6
commit 01eeae9603
14 changed files with 26 additions and 1417 deletions

View File

@@ -29,7 +29,7 @@
<!-- AceGUI -->
<Include file="Libs\AceGUI-3.0\AceGUI-3.0.xml"/>
<!-- AceConfig (depends on AceGUI via AceConfigDialog) -->
<!-- AceConfig -->
<Include file="Libs\AceConfig-3.0\AceConfig-3.0.xml"/>
<!-- AceConsole -->

View File

@@ -41,7 +41,7 @@ Modules\Tracker\NormalTrackerFrames.lua
Modules\Tracker\GroupTrackerFrames.lua
Modules\Tracker\TrackerOptions.lua
# ────── BuffEndingAnnouncer ──────────────────────────────────────────
# ────── AuraExpiry ───────────────────────────────────────────────────
Modules\BuffEndingAnnouncer\BuffEndingAnnouncer.lua
Modules\BuffEndingAnnouncer\BuffEndingAnnouncerOptions.lua

View File

@@ -1974,8 +1974,8 @@ function HMGT_Config:Initialize()
end
local buffEndingGroup = BuildNamedModuleGroup(
"announcer.buffEndingAnnouncer",
L["OPT_MODULE_BUFF_ENDING"] or "Buff Ending",
"announcer.auraExpiry",
L["OPT_MODULE_AURA_EXPIRY"] or L["OPT_MODULE_BUFF_ENDING"] or "Aura Expiry",
20
)
if buffEndingGroup then

View File

@@ -1,23 +0,0 @@
------------------------------------------------------------------------
r106 | nebula169 | 2024-08-23 12:53:29 +0000 (Fri, 23 Aug 2024) | 1 line
Changed paths:
M /trunk/LibGroupInSpecT-1.1.lua
Update talent string decoding for v2
------------------------------------------------------------------------
r105 | nebula169 | 2024-08-20 06:44:07 +0000 (Tue, 20 Aug 2024) | 2 lines
Changed paths:
M /trunk/LibGroupInSpecT-1.1.lua
- Handle heroic talents
- Remove tier/column
------------------------------------------------------------------------
r104 | nebula169 | 2024-07-25 01:08:28 +0000 (Thu, 25 Jul 2024) | 1 line
Changed paths:
M /trunk/LibGroupInSpecT-1.1.lua
M /trunk/LibGroupInSpecT-1.1.toc
D /trunk/embeds.xml
Update TOC for 11.0
------------------------------------------------------------------------

View File

@@ -1,240 +0,0 @@
--[[ $Id: CallbackHandler-1.0.lua 14 2010-08-09 00:43:38Z mikk $ ]]
local MAJOR, MINOR = "CallbackHandler-1.0", 6
local CallbackHandler = LibStub:NewLibrary(MAJOR, MINOR)
if not CallbackHandler then return end -- No upgrade needed
local meta = {__index = function(tbl, key) tbl[key] = {} return tbl[key] end}
-- Lua APIs
local tconcat = table.concat
local assert, error, loadstring = assert, error, loadstring
local setmetatable, rawset, rawget = setmetatable, rawset, rawget
local next, select, pairs, type, tostring = next, select, pairs, type, tostring
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
-- List them here for Mikk's FindGlobals script
-- GLOBALS: geterrorhandler
local xpcall = xpcall
local function errorhandler(err)
return geterrorhandler()(err)
end
local function CreateDispatcher(argCount)
local code = [[
local next, xpcall, eh = ...
local method, ARGS
local function call() method(ARGS) end
local function dispatch(handlers, ...)
local index
index, method = next(handlers)
if not method then return end
local OLD_ARGS = ARGS
ARGS = ...
repeat
xpcall(call, eh)
index, method = next(handlers, index)
until not method
ARGS = OLD_ARGS
end
return dispatch
]]
local ARGS, OLD_ARGS = {}, {}
for i = 1, argCount do ARGS[i], OLD_ARGS[i] = "arg"..i, "old_arg"..i end
code = code:gsub("OLD_ARGS", tconcat(OLD_ARGS, ", ")):gsub("ARGS", tconcat(ARGS, ", "))
return assert(loadstring(code, "safecall Dispatcher["..argCount.."]"))(next, xpcall, errorhandler)
end
local Dispatchers = setmetatable({}, {__index=function(self, argCount)
local dispatcher = CreateDispatcher(argCount)
rawset(self, argCount, dispatcher)
return dispatcher
end})
--------------------------------------------------------------------------
-- CallbackHandler:New
--
-- target - target object to embed public APIs in
-- RegisterName - name of the callback registration API, default "RegisterCallback"
-- UnregisterName - name of the callback unregistration API, default "UnregisterCallback"
-- UnregisterAllName - name of the API to unregister all callbacks, default "UnregisterAllCallbacks". false == don't publish this API.
function CallbackHandler:New(target, RegisterName, UnregisterName, UnregisterAllName, OnUsed, OnUnused)
-- TODO: Remove this after beta has gone out
assert(not OnUsed and not OnUnused, "ACE-80: OnUsed/OnUnused are deprecated. Callbacks are now done to registry.OnUsed and registry.OnUnused")
RegisterName = RegisterName or "RegisterCallback"
UnregisterName = UnregisterName or "UnregisterCallback"
if UnregisterAllName==nil then -- false is used to indicate "don't want this method"
UnregisterAllName = "UnregisterAllCallbacks"
end
-- we declare all objects and exported APIs inside this closure to quickly gain access
-- to e.g. function names, the "target" parameter, etc
-- Create the registry object
local events = setmetatable({}, meta)
local registry = { recurse=0, events=events }
-- registry:Fire() - fires the given event/message into the registry
function registry:Fire(eventname, ...)
if not rawget(events, eventname) or not next(events[eventname]) then return end
local oldrecurse = registry.recurse
registry.recurse = oldrecurse + 1
Dispatchers[select('#', ...) + 1](events[eventname], eventname, ...)
registry.recurse = oldrecurse
if registry.insertQueue and oldrecurse==0 then
-- Something in one of our callbacks wanted to register more callbacks; they got queued
for eventname,callbacks in pairs(registry.insertQueue) do
local first = not rawget(events, eventname) or not next(events[eventname]) -- test for empty before. not test for one member after. that one member may have been overwritten.
for self,func in pairs(callbacks) do
events[eventname][self] = func
-- fire OnUsed callback?
if first and registry.OnUsed then
registry.OnUsed(registry, target, eventname)
first = nil
end
end
end
registry.insertQueue = nil
end
end
-- Registration of a callback, handles:
-- self["method"], leads to self["method"](self, ...)
-- self with function ref, leads to functionref(...)
-- "addonId" (instead of self) with function ref, leads to functionref(...)
-- all with an optional arg, which, if present, gets passed as first argument (after self if present)
target[RegisterName] = function(self, eventname, method, ... --[[actually just a single arg]])
if type(eventname) ~= "string" then
error("Usage: "..RegisterName.."(eventname, method[, arg]): 'eventname' - string expected.", 2)
end
method = method or eventname
local first = not rawget(events, eventname) or not next(events[eventname]) -- test for empty before. not test for one member after. that one member may have been overwritten.
if type(method) ~= "string" and type(method) ~= "function" then
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): 'methodname' - string or function expected.", 2)
end
local regfunc
if type(method) == "string" then
-- self["method"] calling style
if type(self) ~= "table" then
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): self was not a table?", 2)
elseif self==target then
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): do not use Library:"..RegisterName.."(), use your own 'self'", 2)
elseif type(self[method]) ~= "function" then
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): 'methodname' - method '"..tostring(method).."' not found on self.", 2)
end
if select("#",...)>=1 then -- this is not the same as testing for arg==nil!
local arg=select(1,...)
regfunc = function(...) self[method](self,arg,...) end
else
regfunc = function(...) self[method](self,...) end
end
else
-- function ref with self=object or self="addonId" or self=thread
if type(self)~="table" and type(self)~="string" and type(self)~="thread" then
error("Usage: "..RegisterName.."(self or \"addonId\", eventname, method): 'self or addonId': table or string or thread expected.", 2)
end
if select("#",...)>=1 then -- this is not the same as testing for arg==nil!
local arg=select(1,...)
regfunc = function(...) method(arg,...) end
else
regfunc = method
end
end
if events[eventname][self] or registry.recurse<1 then
-- if registry.recurse<1 then
-- we're overwriting an existing entry, or not currently recursing. just set it.
events[eventname][self] = regfunc
-- fire OnUsed callback?
if registry.OnUsed and first then
registry.OnUsed(registry, target, eventname)
end
else
-- we're currently processing a callback in this registry, so delay the registration of this new entry!
-- yes, we're a bit wasteful on garbage, but this is a fringe case, so we're picking low implementation overhead over garbage efficiency
registry.insertQueue = registry.insertQueue or setmetatable({},meta)
registry.insertQueue[eventname][self] = regfunc
end
end
-- Unregister a callback
target[UnregisterName] = function(self, eventname)
if not self or self==target then
error("Usage: "..UnregisterName.."(eventname): bad 'self'", 2)
end
if type(eventname) ~= "string" then
error("Usage: "..UnregisterName.."(eventname): 'eventname' - string expected.", 2)
end
if rawget(events, eventname) and events[eventname][self] then
events[eventname][self] = nil
-- Fire OnUnused callback?
if registry.OnUnused and not next(events[eventname]) then
registry.OnUnused(registry, target, eventname)
end
end
if registry.insertQueue and rawget(registry.insertQueue, eventname) and registry.insertQueue[eventname][self] then
registry.insertQueue[eventname][self] = nil
end
end
-- OPTIONAL: Unregister all callbacks for given selfs/addonIds
if UnregisterAllName then
target[UnregisterAllName] = function(...)
if select("#",...)<1 then
error("Usage: "..UnregisterAllName.."([whatFor]): missing 'self' or \"addonId\" to unregister events for.", 2)
end
if select("#",...)==1 and ...==target then
error("Usage: "..UnregisterAllName.."([whatFor]): supply a meaningful 'self' or \"addonId\"", 2)
end
for i=1,select("#",...) do
local self = select(i,...)
if registry.insertQueue then
for eventname, callbacks in pairs(registry.insertQueue) do
if callbacks[self] then
callbacks[self] = nil
end
end
end
for eventname, callbacks in pairs(events) do
if callbacks[self] then
callbacks[self] = nil
-- Fire OnUnused callback?
if registry.OnUnused and not next(callbacks) then
registry.OnUnused(registry, target, eventname)
end
end
end
end
end
end
return registry
end
-- CallbackHandler purposefully does NOT do explicit embedding. Nor does it
-- try to upgrade old implicit embeds since the system is selfcontained and
-- relies on closures to work.

File diff suppressed because it is too large Load Diff

View File

@@ -1,10 +0,0 @@
## Interface: 110000, 110002
## Title: Lib: GroupInSpecT-1.1
## Notes: Keeps track of group members and keeps an up-to-date cache of their specialization and talents.
## Version: 1.5.1
## Author: Anyia of HordeYakka (Jubei'Thos)
## X-Category: Library
LibStub\LibStub.lua
CallbackHandler-1.0\CallbackHandler-1.0.lua
lib.xml

View File

@@ -1,51 +0,0 @@
-- $Id: LibStub.lua 76 2007-09-03 01:50:17Z mikk $
-- LibStub is a simple versioning stub meant for use in Libraries. http://www.wowace.com/wiki/LibStub for more info
-- LibStub is hereby placed in the Public Domain
-- Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel, joshborke
local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 2 -- NEVER MAKE THIS AN SVN REVISION! IT NEEDS TO BE USABLE IN ALL REPOS!
local LibStub = _G[LIBSTUB_MAJOR]
-- Check to see is this version of the stub is obsolete
if not LibStub or LibStub.minor < LIBSTUB_MINOR then
LibStub = LibStub or {libs = {}, minors = {} }
_G[LIBSTUB_MAJOR] = LibStub
LibStub.minor = LIBSTUB_MINOR
-- LibStub:NewLibrary(major, minor)
-- major (string) - the major version of the library
-- minor (string or number ) - the minor version of the library
--
-- returns nil if a newer or same version of the lib is already present
-- returns empty library object or old library object if upgrade is needed
function LibStub:NewLibrary(major, minor)
assert(type(major) == "string", "Bad argument #2 to `NewLibrary' (string expected)")
minor = assert(tonumber(strmatch(minor, "%d+")), "Minor version must either be a number or contain a number.")
local oldminor = self.minors[major]
if oldminor and oldminor >= minor then return nil end
self.minors[major], self.libs[major] = minor, self.libs[major] or {}
return self.libs[major], oldminor
end
-- LibStub:GetLibrary(major, [silent])
-- major (string) - the major version of the library
-- silent (boolean) - if true, library is optional, silently return nil if its not found
--
-- throws an error if the library can not be found (except silent is set)
-- returns the library object if found
function LibStub:GetLibrary(major, silent)
if not self.libs[major] and not silent then
error(("Cannot find a library instance of %q."):format(tostring(major)), 2)
end
return self.libs[major], self.minors[major]
end
-- LibStub:IterateLibraries()
--
-- Returns an iterator for the currently registered libraries
function LibStub:IterateLibraries()
return pairs(self.libs)
end
setmetatable(LibStub, { __call = LibStub.GetLibrary })
end

View File

@@ -1,6 +0,0 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="LibGroupInSpecT-1.1.lua"/>
</Ui>

View File

@@ -129,7 +129,8 @@ L["OPT_SHOW_MINIMAP_ICON"] = "Minimap-Icon anzeigen"
L["OPT_COMMANDS"] = "Commands"
L["OPT_MODULES"] = "Modules"
L["OPT_MODULE_TRACKER"] = "Tracker"
L["OPT_MODULE_BUFF_ENDING"] = "Buff Ending"
L["OPT_MODULE_BUFF_ENDING"] = "Aura-Ablauf"
L["OPT_MODULE_AURA_EXPIRY"] = "Aura-Ablauf"
L["OPT_MODULE_MAP_OVERLAY"] = "Map Overlay"
-- ── Options: tracker shared ───────────────────────────────────
@@ -341,11 +342,12 @@ L["GCD_TITLE"] = "|cff77dd77Gruppen-Cooldowns|r"
L["IT_NAME"] = "Interrupt Tracker"
L["RCD_NAME"] = "Raid Cooldown Tracker"
L["GCD_NAME"] = "Gruppen-Cooldown-Tracker"
L["BEA_NAME"] = "Buff-Ende-Ansager"
L["BEA_NAME"] = "Aura-Ablauf"
L["AE_NAME"] = "Aura-Ablauf"
L["AEM_NAME"] = "Auto-Gegner-Markierung"
L["OPT_BEA_ENABLED"] = "Buff-Ende-Ansager aktivieren"
L["OPT_BEA_ENABLED_DESC"] = "Sagt Countdown fuer verfolgte Buffs in /say an"
L["OPT_BEA_ENABLED"] = "Aura-Ablauf aktivieren"
L["OPT_BEA_ENABLED_DESC"] = "Sagt Countdowns fuer verfolgte Auren und Kanaele in /say an"
L["OPT_BEA_ANNOUNCE_AT"] = "Ansage ab (Sek.)"
L["OPT_BEA_ANNOUNCE_AT_DESC"] = "Startet die Countdown-Ansage, sobald die Restdauer darunter liegt"
L["OPT_BEA_DEFAULT_THRESHOLD"] = "Standard-Threshold (Sek.)"

View File

@@ -129,7 +129,8 @@ L["OPT_SHOW_MINIMAP_ICON"] = "Show Minimap Icon"
L["OPT_COMMANDS"] = "Commands"
L["OPT_MODULES"] = "Modules"
L["OPT_MODULE_TRACKER"] = "Tracker"
L["OPT_MODULE_BUFF_ENDING"] = "Buff Ending"
L["OPT_MODULE_BUFF_ENDING"] = "Aura Expiry"
L["OPT_MODULE_AURA_EXPIRY"] = "Aura Expiry"
L["OPT_MODULE_MAP_OVERLAY"] = "Map Overlay"
-- ── Options: tracker shared ───────────────────────────────────
@@ -341,11 +342,12 @@ L["GCD_TITLE"] = "|cff77dd77Group Cooldowns|r"
L["IT_NAME"] = "Interrupt Tracker"
L["RCD_NAME"] = "Raid Cooldown Tracker"
L["GCD_NAME"] = "Group Cooldown Tracker"
L["BEA_NAME"] = "Buff Ending Announcer"
L["BEA_NAME"] = "Aura Expiry"
L["AE_NAME"] = "Aura Expiry"
L["AEM_NAME"] = "Auto Enemy Marker"
L["OPT_BEA_ENABLED"] = "Enable buff ending announcer"
L["OPT_BEA_ENABLED_DESC"] = "Announce tracked buff countdowns in /say"
L["OPT_BEA_ENABLED"] = "Enable aura expiry"
L["OPT_BEA_ENABLED_DESC"] = "Announce countdowns for tracked auras and channels in /say"
L["OPT_BEA_ANNOUNCE_AT"] = "Announce from (sec)"
L["OPT_BEA_ANNOUNCE_AT_DESC"] = "Start countdown announcements when remaining buff duration is at or below this value"
L["OPT_BEA_DEFAULT_THRESHOLD"] = "Default threshold (sec)"

View File

@@ -7,7 +7,8 @@ if not HMGT then return end
local L = LibStub("AceLocale-3.0"):GetLocale(ADDON_NAME, true) or {}
local BEA = HMGT:NewModule("BuffEndingAnnouncer")
local BEA = HMGT:NewModule("AuraExpiry")
HMGT.AuraExpiry = BEA
HMGT.BuffEndingAnnouncer = BEA
BEA.runtimeEnabled = false
@@ -426,6 +427,7 @@ function BEA:StopRuntime()
end
function BEA:OnInitialize()
HMGT.AuraExpiry = self
HMGT.BuffEndingAnnouncer = self
end

View File

@@ -3,7 +3,7 @@
local ADDON_NAME = "HailMaryGuildTools"
local HMGT = LibStub("AceAddon-3.0"):GetAddon(ADDON_NAME)
if not HMGT then return end
local BEA = HMGT.BuffEndingAnnouncer
local BEA = HMGT.AuraExpiry or HMGT.BuffEndingAnnouncer
if not BEA then return end
if not HMGT_Config or not HMGT_Config.RegisterOptionsProvider then return end
@@ -197,7 +197,7 @@ function BEA:BuildOptionsGroup()
local group = {
type = "group",
name = L["BEA_NAME"] or "Buff Ending Announcer",
name = L["AE_NAME"] or L["BEA_NAME"] or "Aura Expiry",
order = 3,
childGroups = "tree",
args = {
@@ -400,7 +400,7 @@ function BEA:GetOptionsGroup()
return beaOptionsGroup
end
HMGT_Config:RegisterOptionsProvider("announcer.buffEndingAnnouncer", function()
HMGT_Config:RegisterOptionsProvider("announcer.auraExpiry", function()
return {
path = "announcer",
order = 3,

View File

@@ -14,7 +14,7 @@ It combines cooldown tracking, encounter reminders, notes, and map utilities in
- Custom tracker system with individual tracker configs
- Interrupt, raid cooldown, and group cooldown tracking
- Per-tracker bar and icon layouts
- Buff Ending Announcer for selected buffs and channels
- Aura Expiry for selected buffs and channels
- Raid Timeline for encounter-based text reminders and raid cooldown assignments
- Notes window for raid or personal note management
- Map Overlay with custom world map POIs
@@ -28,7 +28,7 @@ It combines cooldown tracking, encounter reminders, notes, and map utilities in
The tracker system is the core feature of HMGT.
It supports multiple independent tracker bars with custom spell categories, display modes, growth directions, party-frame attachment, and demo/test modes.
### Buff Ending Announcer
### Aura Expiry
Tracks selected buffs and channel-based spells and warns before they expire.
@@ -84,7 +84,7 @@ Provides a dedicated notes window for raid notes, personal notes, and drafts.
- `Modules/Tracker/`
Tracker rendering, data, and options
- `Modules/BuffEndingAnnouncer/`
Buff ending module and options
Aura expiry module and options
- `Modules/MapOverlay/`
World map POIs, icon config, and options
- `Modules/RaidTimeline/`