promotional bannermobile promotional banner

TOGTools

ToGTools is a convenient place to aggregate one off tools that don't make sense to have it's own addon.

File Details

TOGTools-v0.3.1

  • R
  • May 6, 2026
  • 1.92 MB
  • 16
  • 12.0.1+7
  • Retail + 3

File Name

TOGTools-TOGTools-v0.3.1.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.1] (2026-05-06) - TBC Compatibility Fix

Bug Fixes

  • Addon Load tab crashed on TBC (and Wrath/Cata/Mists/Retail)GetNumAddOns, GetAddOnInfo, IsAddOnLoaded, GetAddOnMemoryUsage, and UpdateAddOnMemoryUsage were called as bare globals, but TBC+ moved them all into C_AddOns.*. Added five compat locals at the top of the module that prefer C_AddOns.* when available and fall back to the bare globals for Classic Era, matching the pattern already used elsewhere in the addon. Location: Modules/AddonLoad/AddonLoad.lua.

[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 each MAIL_INBOX_UPDATE event, stamping absolute expiresAt = 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 - stale flag for snapshots older than 7 days. Live-refresh on MAIL_INBOX_UPDATE while 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 when addon.MainWindow.activeTab == "mailbox"). Account-wide storage in db.global.mailbox.snapshots[Name-Realm] so every alt's data is visible from any character, full Name-Realm keys throughout to prevent collisions across connected-realm clusters. Location: Modules/Mailbox/Mailbox.lua, GUI/MailboxTab.lua.

Improvements

  • AceDB schema — Added global namespace to DB_DEFAULTS with mailbox = { thresholdDays, snapshots }. Account-wide scope so cross-alt mail data persists across every physical realm in a connected-realm cluster (per-db.realm would 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 mailbox open the Mailbox tab directly; help output updated. Location: SlashCommands.lua.
  • .luarc.json — Added GetInboxNumItems, GetInboxHeaderInfo, and ChatEdit_OnEnterPressed to diagnostics.globals so 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.lua and GUI\MailboxTab.lua after the AddonLoad pair.

Bug Fixes

  • NamePrefix broke OPie macrotext ring entries (custom mounts, /cast macros) — On Classic clients, NamePrefix wrapped the global ChatEdit_SendText to enable pre-send text modification. OPie's Libs/ActionBook/Rewire.lua dispatches each line of macro ring entries via securecall(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, /cast slots), while direct spell-cast slots that bypass macrotext (most tradeskills) kept working. Fix: relocated the Classic hook target from ChatEdit_SendText to ChatEdit_OnEnterPressed, which is upstream of ChatEdit_SendText in 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 (hooksecurefunc fires 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 !TOGT companion 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 the TOGToolsEarlyData global. The Addon Load Monitor reads it at display time and shows a status-bar indicator (!TOGT active / !TOGT missing).
  • Shared addon.RowList component — New file GUI/RowList.lua, ported and trimmed from FastGuildInvite's GUI/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-column sortKey/sortDescDefault/sortable/gapBefore opts and tie-break on entry.name, alternating row banding, virtual-scroll pool that grows with the parent's height, custom Blizzard-textured scrollbar, mouse-wheel scroll. Cells use SetWordWrap(false) + SetMaxLines(1) and anchor LEFT/RIGHT to 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 after Compat.lua, before MainWindow.lua.
  • Compat.lua shared GUI helpersaddon.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.000sGetTime() is frame-locked, so every ADDON_LOADED event fired in the same loading-screen frame returned the same timestamp. Per-addon deltas collapsed to zero. Switched the timing capture in !TOGT.lua and the fallback capture in Modules/AddonLoad/AddonLoad.lua to debugprofilestop(), 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.lua was reading row.offset (cumulative seconds since the first event) instead of row.loadTime (per-addon delta). Because offset is monotonic with load order, clicking the header effectively sorted by load order regardless of direction. Comparator now reads row.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 with addon.RowList, whose anchor-based cells truncate instead of wrapping. The window's minWidth was tightened from 640 to 520 now that compaction is graceful.
  • Tab status bar leaked between tabsMainWindow:DrawTab now 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 switchMainWindow:ApplyTabSize now calls f:DoLayout() after sizing, so when switching between tabs whose WINDOW_SIZE differs, 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's SCROLLBAR_GUTTER reduced from SCROLLBAR_WIDTH + 6 to SCROLLBAR_WIDTH + 2 so the rightmost column sits ~5 px from the scrollbar. Status column gets gapBefore = 5 to break the visual collision between right-justified Load Time text and left-justified Status text.
  • Sort indicator removed from active column headerRowList:_updateHeaderText no 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 protectionRowList:Detach() orphans the row pool, header, and scrollbar to UIParent on host-widget release; a _detached guard 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 via body:SetCallback("OnRelease", ...) in GUI/AddonLoadTab.lua.
  • .luarc.json updated — Added debugprofilestop to diagnostics.globals in both TOGTools/.luarc.json and !TOGT/.luarc.json so 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), .pkgmeta with BigWigs packager config, .luarc.json (Lua 5.1 LSP), .markdownlint.json, and .github/workflows/release.yml for tag-triggered CurseForge releases.
  • Core addonTOGTools.lua: AceAddon-3.0 instance with AceConsole-3.0, AceEvent-3.0, AceHook-3.0 mixins; AceDB-3.0 schema (char scope); version detection flags (gv.isVanilla, gv.isTBC, gv.isWrath, gv.isCata, gv.isMists, gv.isClassic, gv.isRetail, gv.isRetail120Plus).
  • Slash commandsSlashCommands.lua: all /togt command 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 windowGUI/MainWindow.lua: dynamic AceGUI Frame + TabGroup; tabs auto-populate from addon.modules sorted alphabetically by label; per-tab locked/unlocked window sizing via WINDOW_SIZE; ESC-to-close proxy; position persistence via AceDB.
  • Name Prefix moduleModules/NamePrefix/NamePrefix.lua + GUI/NamePrefixTab.lua: wraps ChatEdit_SendText (Classic) or hooks EventRegistry (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 buttonGUI/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 in DB.char.
  • Addon settings panelGUI/Settings.lua: AceConfig-3.0 options table registered under ESC → Interface → Addons → TOG Tools (native Blizzard panel). addon:OpenSettings() uses Settings.OpenToCategory (Classic Era 1.15+ / Retail 10+), InterfaceOptionsFrame_OpenToCategory (older builds), or InterfaceOptionsFrame:Show() as a final fallback — detected by API presence, not version flag.
  • VersionCheck-1.0 integrationVC:Enable(Ace) called on all non-Retail versions in OnInitialize; /togt vc broadcasts a guild-wide version check and prints responses after 21 seconds.
  • Embedded libslibs/LibDataBroker-1.1.lua, libs/LibDBIcon-1.0.lua (single-file embeds, copied from TOGProfessionMaster).
  • MIT LicenseLICENSE file added; referenced in .pkgmeta via license-output.
  • CurseForge project — Project ID 1533830 set in .pkgmeta and all TOC files.
  • Governance files.github/copilot-instructions.md and CLAUDE.md with full project rules (module pattern, commit/tag process, changelog format, HTML doc rules, no-tag rule).

Bug Fixes

  • Name Prefix not reaching other playershooksecurefunc fires after SendChatMessage has already been called. Fixed by wrapping ChatEdit_SendText directly (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 ModifyMessage when the message starts with /. Location: Modules/NamePrefix/NamePrefix.lua.