From 82d3abe5dab90e4d7874916455608f46a685780b Mon Sep 17 00:00:00 2001 From: Kelsi Date: Sat, 21 Mar 2026 05:13:28 -0700 Subject: [PATCH] feat: add GetAddOnMetadata for reading TOC directives from Lua Implement GetAddOnMetadata(addonNameOrIndex, key) which reads arbitrary TOC file directives. All directives are now stored in the addon info registry table under a "metadata" sub-table. This enables addons to read their own version, author, X-* custom fields, and other TOC metadata at runtime. Used by addon managers, version checkers, and self-updating addons. --- src/addons/lua_engine.cpp | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/addons/lua_engine.cpp b/src/addons/lua_engine.cpp index 1b47bc91..0c54d838 100644 --- a/src/addons/lua_engine.cpp +++ b/src/addons/lua_engine.cpp @@ -600,6 +600,37 @@ static int lua_GetAddOnInfo(lua_State* L) { return 5; } +// GetAddOnMetadata(addonNameOrIndex, key) → value +static int lua_GetAddOnMetadata(lua_State* L) { + lua_getfield(L, LUA_REGISTRYINDEX, "wowee_addon_info"); + if (!lua_istable(L, -1)) { lua_pop(L, 1); lua_pushnil(L); return 1; } + + int idx = 0; + if (lua_isnumber(L, 1)) { + idx = static_cast(lua_tonumber(L, 1)); + } else if (lua_isstring(L, 1)) { + const char* name = lua_tostring(L, 1); + int count = static_cast(lua_objlen(L, -1)); + for (int i = 1; i <= count; i++) { + lua_rawgeti(L, -1, i); + lua_getfield(L, -1, "name"); + const char* aName = lua_tostring(L, -1); + lua_pop(L, 1); + if (aName && strcmp(aName, name) == 0) { idx = i; lua_pop(L, 1); break; } + lua_pop(L, 1); + } + } + if (idx < 1) { lua_pop(L, 1); lua_pushnil(L); return 1; } + + const char* key = luaL_checkstring(L, 2); + lua_rawgeti(L, -1, idx); + if (!lua_istable(L, -1)) { lua_pop(L, 2); lua_pushnil(L); return 1; } + lua_getfield(L, -1, "metadata"); + if (!lua_istable(L, -1)) { lua_pop(L, 3); lua_pushnil(L); return 1; } + lua_getfield(L, -1, key); + return 1; +} + // UnitBuff(unitId, index) / UnitDebuff(unitId, index) // Returns: name, rank, icon, count, debuffType, duration, expirationTime, caster, isStealable, shouldConsolidate, spellId static int lua_UnitAura(lua_State* L, bool wantBuff) { @@ -3081,6 +3112,7 @@ void LuaEngine::registerCoreAPI() { {"UnitAura", lua_UnitAuraGeneric}, {"GetNumAddOns", lua_GetNumAddOns}, {"GetAddOnInfo", lua_GetAddOnInfo}, + {"GetAddOnMetadata", lua_GetAddOnMetadata}, {"GetSpellInfo", lua_GetSpellInfo}, {"GetSpellTexture", lua_GetSpellTexture}, {"GetItemInfo", lua_GetItemInfo}, @@ -3995,6 +4027,13 @@ void LuaEngine::setAddonList(const std::vector& addons) { auto notesIt = addons[i].directives.find("Notes"); lua_pushstring(L_, notesIt != addons[i].directives.end() ? notesIt->second.c_str() : ""); lua_setfield(L_, -2, "notes"); + // Store all TOC directives for GetAddOnMetadata + lua_newtable(L_); + for (const auto& [key, val] : addons[i].directives) { + lua_pushstring(L_, val.c_str()); + lua_setfield(L_, -2, key.c_str()); + } + lua_setfield(L_, -2, "metadata"); lua_rawseti(L_, -2, static_cast(i + 1)); } lua_setfield(L_, LUA_REGISTRYINDEX, "wowee_addon_info");