File Details
TOGTools-v0.3.0
- R
- May 5, 2026
- 1.92 MB
- 12
- 12.0.1+7
- Retail + 3
File Name
TOGTools-TOGTools-v0.3.0.zip
Supported Versions
- 12.0.1
- 12.0.0
- 11.2.7
- 5.5.3
- 4.4.2
- 3.4.5
- 2.5.5
- 1.15.8
Changelog
[v0.3.0] (2026-05-04) - Mailbox Stale Watcher
New Features
- Mailbox Stale Watcher — New tab (
/togt mail/mb/mailbox) tracking mail expiration across every alt on the account so mail never gets auto-deleted at the 30-day mark for an unvisited character. Captures a per-alt inbox snapshot on eachMAIL_INBOX_UPDATEevent, stamping absoluteexpiresAt = GetServerTime() + (daysLeft * 86400)per item so the time-remaining math stays accurate even when the alt does not re-visit a mailbox for several days (same content-derived-timestamp pattern TOGPM uses). Login chat alert prints once when any alt has mail expiring within the configured threshold (default 2 days, slider-configurable 1–7 in the tab). Tab lists each alt with a row-per-mail breakdown of expiring items (sender, subject, time remaining), snapshot age display, and a- staleflag for snapshots older than 7 days. Live-refresh onMAIL_INBOX_UPDATEwhile the tab is active, so opening a mailbox in-game while the Mailbox tab is showing updates the rows in real time without forcing a manual tab-switch (addon.MainWindow:Refresh()is called from the engine's event handler whenaddon.MainWindow.activeTab == "mailbox"). Account-wide storage indb.global.mailbox.snapshots[Name-Realm]so every alt's data is visible from any character, fullName-Realmkeys throughout to prevent collisions across connected-realm clusters. Location:Modules/Mailbox/Mailbox.lua,GUI/MailboxTab.lua.
Improvements
- AceDB schema — Added
globalnamespace toDB_DEFAULTSwithmailbox = { thresholdDays, snapshots }. Account-wide scope so cross-alt mail data persists across every physical realm in a connected-realm cluster (per-db.realmwould silo each physical realm of the cluster into a separate notes table — wrong for our use case). Location:TOGTools.lua. - Slash commands —
/togt mb//togt mail//togt mailboxopen the Mailbox tab directly; help output updated. Location:SlashCommands.lua. .luarc.json— AddedGetInboxNumItems,GetInboxHeaderInfo, andChatEdit_OnEnterPressedtodiagnostics.globalsso the new mail API calls and the relocated NamePrefix hook target resolve cleanly under the Lua LSP.- TOC files — All six TOC variants (Vanilla, BCC, Wrath, Cata, Mists, Mainline) updated to load
Modules\Mailbox\Mailbox.luaandGUI\MailboxTab.luaafter the AddonLoad pair.
Bug Fixes
- NamePrefix broke OPie macrotext ring entries (custom mounts,
/castmacros) — On Classic clients, NamePrefix wrapped the globalChatEdit_SendTextto enable pre-send text modification. OPie'sLibs/ActionBook/Rewire.luadispatches each line of macro ring entries viasecurecall(ChatEdit_SendText, box, false). Replacing the global with a wrapper created in our (insecure) addon loading context tainted that function reference, so OPie's secure dispatch path picked up taint when calling it — failing for any ring slot delivered as macrotext (custom mount macros,/castslots), while direct spell-cast slots that bypass macrotext (most tradeskills) kept working. Fix: relocated the Classic hook target fromChatEdit_SendTexttoChatEdit_OnEnterPressed, which is upstream ofChatEdit_SendTextin the user-typed Enter-key flow but is not on OPie's Rewire dispatch path. The user-facing prefixing behavior is unchanged. The replaced-global pattern itself stays (hooksecurefuncfires post-call, so it can't be used to modify text before send); we just no longer taint the function OPie depends on. Location:Modules/NamePrefix/NamePrefix.lua.
[v0.2.0] (2026-05-04) - Addon Load Monitor
New Features
- Addon Load Monitor — New tab (
/togt al) showing every installed addon's memory usage, load status, and load timing. Sortable by name, memory, load time, and status (failures-first when descending). Summary bar shows totals (loaded / failed / disabled / on-demand) and total memory. Requires the!TOGTcompanion addon for full timing coverage across all addons. Location:Modules/AddonLoad/AddonLoad.lua,GUI/AddonLoadTab.lua. - !TOGT companion integration —
!TOGT(companion addon) added as a required dependency. Loads before all other addons at the very start of the loading screen (the!prefix sorts before all letters) and records load order and per-addon offset into theTOGToolsEarlyDataglobal. The Addon Load Monitor reads it at display time and shows a status-bar indicator (!TOGT active/!TOGT missing). - Shared
addon.RowListcomponent — New fileGUI/RowList.lua, ported and trimmed from FastGuildInvite'sGUI/RowList.lua. Reusable sortable-row list for any tab that needs a tabular data view: brand-colored clickable header bar, click-toggle ASC/DESC sort with per-columnsortKey/sortDescDefault/sortable/gapBeforeopts and tie-break onentry.name, alternating row banding, virtual-scroll pool that grows with the parent's height, custom Blizzard-textured scrollbar, mouse-wheel scroll. Cells useSetWordWrap(false)+SetMaxLines(1)and anchorLEFT/RIGHTto the parent so column layouts compact elastically when the user shrinks the window — no row-wrap. Public API::New(parent, opts),:SetData(arr),:SetSort(key, desc),:Refresh(),:Detach(). Registered to all six TOC files afterCompat.lua, beforeMainWindow.lua. Compat.luashared GUI helpers —addon.Tooltip.Owner/AnchorFrame(smart anchor flipping based on screen half),addon.AceGUIFrameScripts(leak-safe raw frame scripts that restore prior handlers on pooled-widget release),addon.GUI.AttachTooltip,addon.GUI.MakeColumnHeader,addon.GUI.ApplyMinResize,addon.GUI.DetachPool. Used by every tab.
Bug Fixes
- Load times reporting
0.000s—GetTime()is frame-locked, so everyADDON_LOADEDevent fired in the same loading-screen frame returned the same timestamp. Per-addon deltas collapsed to zero. Switched the timing capture in!TOGT.luaand the fallback capture inModules/AddonLoad/AddonLoad.luatodebugprofilestop(), which has sub-millisecond precision. Offsets are stored in seconds (ms / 1000) so downstream consumers are unchanged. - Load Time column sort produced random-looking order — The sort comparator in
GUI/AddonLoadTab.luawas readingrow.offset(cumulative seconds since the first event) instead ofrow.loadTime(per-addon delta). Becauseoffsetis monotonic with load order, clicking the header effectively sorted by load order regardless of direction. Comparator now readsrow.loadTime. - Addon Load tab wrapped to multiple lines on horizontal shrink — The tab used AceGUI Flow with
widget:SetWidth(...)per cell, so when the user shrunk the window narrower than the column-width sum AceGUI moved cells to a new line and the layout fell apart. Replaced the row-rendering path withaddon.RowList, whose anchor-based cells truncate instead of wrapping. The window'sminWidthwas tightened from 640 to 520 now that compaction is graceful. - Tab status bar leaked between tabs —
MainWindow:DrawTabnow resets the status text to the version string before delegating to the tab module, so a tab that overrides the status (e.g. Addon Load showing!TOGT active/missing) doesn't bleed that text into the next tab the user opens. - Tab content didn't reflow on tab switch —
MainWindow:ApplyTabSizenow callsf:DoLayout()after sizing, so when switching between tabs whoseWINDOW_SIZEdiffers, the new tab's content reflows immediately instead of inheriting stale layout.
Improvements
- Addon Load tab column widths tightened — Status reduced from 175 → 85 px (fits "Wrong Version"); Memory reduced from 110 → 65 px (fits "999.9 MB"); Load Time reduced from 110 → 60 px. The auto-width Addon Name column reclaims the freed space.
RowList'sSCROLLBAR_GUTTERreduced fromSCROLLBAR_WIDTH + 6toSCROLLBAR_WIDTH + 2so the rightmost column sits ~5 px from the scrollbar. Status column getsgapBefore = 5to break the visual collision between right-justified Load Time text and left-justified Status text. - Sort indicator removed from active column header —
RowList:_updateHeaderTextno longer appends a glyph (v/^) to the active sort column; WoW's default font doesn't render unicode triangles cleanly and ASCII letters look like typos. Click affordance is communicated via the column tooltip. - AceGUI pool-bleed protection —
RowList:Detach()orphans the row pool, header, and scrollbar toUIParenton host-widget release; a_detachedguard on:Refresh()makes sure a recycled host doesn't trigger a pool grow that would re-attach rows into the next addon's widget. Wired viabody:SetCallback("OnRelease", ...)inGUI/AddonLoadTab.lua. .luarc.jsonupdated — Addeddebugprofilestoptodiagnostics.globalsin bothTOGTools/.luarc.jsonand!TOGT/.luarc.jsonso the new timer call resolves cleanly under the Lua LSP.
[v0.1.0] (2026-05-04) - Initial Release
New Features
- Project scaffolding — TOC files for all WoW versions (Vanilla 11508, TBC 20505, Wrath 30405, Cata 40402, Mists 50503, Retail 110207/120001/120000),
.pkgmetawith BigWigs packager config,.luarc.json(Lua 5.1 LSP),.markdownlint.json, and.github/workflows/release.ymlfor tag-triggered CurseForge releases. - Core addon —
TOGTools.lua: AceAddon-3.0 instance with AceConsole-3.0, AceEvent-3.0, AceHook-3.0 mixins; AceDB-3.0 schema (charscope); version detection flags (gv.isVanilla,gv.isTBC,gv.isWrath,gv.isCata,gv.isMists,gv.isClassic,gv.isRetail,gv.isRetail120Plus). - Slash commands —
SlashCommands.lua: all/togtcommand registration and handling in a dedicated file, separate from core addon logic. Subcommands:/togt(toggle window),/togt np(Name Prefix tab),/togt settings(open settings),/togt vc(version check). - Tabbed main window —
GUI/MainWindow.lua: dynamic AceGUI Frame + TabGroup; tabs auto-populate fromaddon.modulessorted alphabetically bylabel; per-tab locked/unlocked window sizing viaWINDOW_SIZE; ESC-to-close proxy; position persistence via AceDB. - Name Prefix module —
Modules/NamePrefix/NamePrefix.lua+GUI/NamePrefixTab.lua: wrapsChatEdit_SendText(Classic) or hooksEventRegistry(Retail 12.0+) to prepend a configurable nickname to outgoing chat messages. Settings: enable/disable, nickname, format string with live preview, per-channel toggles (Guild, Officer, Party, Raid, Instance, custom channel), skip-exclamation option, suppress-if-char-name option. Per-character DB scope. Skips messages beginning with/(slash commands/macros) unconditionally. - Minimap button —
GUI/MinimapButton.lua: LibDataBroker-1.1 launcher + LibDBIcon-1.0 registration. Left-click toggles the main window; right-click opens the native addon settings panel. Icon:textures/ToGTools_PH_MMB.tga. Button show/hide state and position persisted inDB.char. - Addon settings panel —
GUI/Settings.lua: AceConfig-3.0 options table registered under ESC → Interface → Addons → TOG Tools (native Blizzard panel).addon:OpenSettings()usesSettings.OpenToCategory(Classic Era 1.15+ / Retail 10+),InterfaceOptionsFrame_OpenToCategory(older builds), orInterfaceOptionsFrame:Show()as a final fallback — detected by API presence, not version flag. - VersionCheck-1.0 integration —
VC:Enable(Ace)called on all non-Retail versions inOnInitialize;/togt vcbroadcasts a guild-wide version check and prints responses after 21 seconds. - Embedded libs —
libs/LibDataBroker-1.1.lua,libs/LibDBIcon-1.0.lua(single-file embeds, copied from TOGProfessionMaster). - MIT License —
LICENSEfile added; referenced in.pkgmetavialicense-output. - CurseForge project — Project ID
1533830set in.pkgmetaand all TOC files. - Governance files —
.github/copilot-instructions.mdandCLAUDE.mdwith full project rules (module pattern, commit/tag process, changelog format, HTML doc rules, no-tag rule).
Bug Fixes
- Name Prefix not reaching other players —
hooksecurefuncfires afterSendChatMessagehas already been called. Fixed by wrappingChatEdit_SendTextdirectly (local orig = ...; ChatEdit_SendText = function(...) ... return orig(...) end) so the prefix is applied before the message is sent. Location:Modules/NamePrefix/NamePrefix.lua. - Macros/slash commands being prefixed — Added an unconditional early-return in
ModifyMessagewhen the message starts with/. Location:Modules/NamePrefix/NamePrefix.lua.

