diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml new file mode 100644 index 0000000..2f93975 --- /dev/null +++ b/.gitea/workflows/release.yml @@ -0,0 +1,75 @@ +name: release + +on: + push: + tags: + - '*-coa.*' # Asc-1.1.6-coa.2, 9.1.40-coa.3, etc. + - 'v*' # v0.3.0 for repos without an upstream version + +jobs: + release: + runs-on: linux-amd64 + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 # build_zip uses git archive HEAD; full history is fine + + - name: Build per-addon zip(s) + run: bash tools/build_zip.sh + + - name: Publish release (Gitea API direct; no action dependency) + env: + GITEA_TOKEN: ${{ secrets.GITHUB_TOKEN }} + REPO: ${{ github.repository }} + TAG: ${{ github.ref_name }} + API: ${{ github.server_url }}/api/v1 + # Gitea attachment ceiling is 200 MiB (see roles/gitea config). + # Skip anything larger so one oversized asset doesn't fail the job. + MAX_BYTES: 209715200 + run: | + set -euo pipefail + # Create the release (or reuse if it already exists for this tag). + RID=$(curl -s -H "Authorization: token $GITEA_TOKEN" \ + "$API/repos/$REPO/releases/tags/$TAG" 2>/dev/null \ + | jq -r '.id // empty') + if [ -z "$RID" ]; then + RID=$(curl -sf -X POST -H "Authorization: token $GITEA_TOKEN" \ + -H "Content-Type: application/json" \ + "$API/repos/$REPO/releases" \ + -d "$(jq -nc --arg t "$TAG" '{tag_name:$t,name:$t,draft:false,prerelease:false,hide_archive_links:true}')" \ + | jq -r '.id') + fi + echo "release id: $RID" + # Gitea honors hide_archive_links only on edit, not create — PATCH it + # so the auto-generated Source Code (zip/tar.gz) links stay hidden. + curl -sf -X PATCH -H "Authorization: token $GITEA_TOKEN" -H "Content-Type: application/json" \ + "$API/repos/$REPO/releases/$RID" -d '{"hide_archive_links":true}' >/dev/null || true + # Upload every dist/*.zip. Per-asset failures don't fail the job — + # we want partial releases to still publish rather than block the + # whole pipeline on one big file. + failed=0 + uploaded=0 + for f in dist/*.zip; do + name=$(basename "$f") + size=$(stat -c '%s' "$f") + if [ "$size" -gt "$MAX_BYTES" ]; then + echo "::warning::skip $name (${size} B > ${MAX_BYTES} B Gitea limit; host on CDN instead)" + failed=$((failed+1)) + continue + fi + echo "uploading $name ($(numfmt --to=iec "$size"))" + if curl -sf -X POST -H "Authorization: token $GITEA_TOKEN" \ + -F "attachment=@$f" \ + "$API/repos/$REPO/releases/$RID/assets?name=$name" \ + | jq -r '" -> " + .browser_download_url'; then + uploaded=$((uploaded+1)) + else + echo "::warning::upload failed for $name" + failed=$((failed+1)) + fi + done + echo "release published: $uploaded uploaded, $failed skipped/failed" + # Only fail the job if NO assets uploaded — a release with zero + # attachments isn't useful to anyone. + [ "$uploaded" -gt 0 ] diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..24f4ba8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +.env +.DS_Store +.release +.install +.lua/* +.vscode +.idea + +dist/ diff --git a/Ace3.lua b/Ace3/Ace3.lua similarity index 100% rename from Ace3.lua rename to Ace3/Ace3.lua diff --git a/Ace3.toc b/Ace3/Ace3.toc similarity index 84% rename from Ace3.toc rename to Ace3/Ace3.toc index 1583f96..1e4c58c 100644 --- a/Ace3.toc +++ b/Ace3/Ace3.toc @@ -1,4 +1,4 @@ -## Interface: 11508, 11507, 20505, 30405, 38001, 40402, 50503, 50504, 120001, 120005, 120007 +## Interface: 30300 ## Title: Lib: Ace3 ## Notes: AddOn development framework @@ -6,7 +6,7 @@ ## X-Website: http://www.wowace.com ## X-Category: Library ## X-License: Limited BSD -## Version: @project-version@ +## Version: master-52e5f2c LibStub\LibStub.lua CallbackHandler-1.0\CallbackHandler-1.0.xml diff --git a/AceAddon-3.0/AceAddon-3.0.lua b/Ace3/AceAddon-3.0/AceAddon-3.0.lua similarity index 100% rename from AceAddon-3.0/AceAddon-3.0.lua rename to Ace3/AceAddon-3.0/AceAddon-3.0.lua diff --git a/AceAddon-3.0/AceAddon-3.0.xml b/Ace3/AceAddon-3.0/AceAddon-3.0.xml similarity index 100% rename from AceAddon-3.0/AceAddon-3.0.xml rename to Ace3/AceAddon-3.0/AceAddon-3.0.xml diff --git a/AceBucket-3.0/AceBucket-3.0.lua b/Ace3/AceBucket-3.0/AceBucket-3.0.lua similarity index 100% rename from AceBucket-3.0/AceBucket-3.0.lua rename to Ace3/AceBucket-3.0/AceBucket-3.0.lua diff --git a/AceBucket-3.0/AceBucket-3.0.xml b/Ace3/AceBucket-3.0/AceBucket-3.0.xml similarity index 100% rename from AceBucket-3.0/AceBucket-3.0.xml rename to Ace3/AceBucket-3.0/AceBucket-3.0.xml diff --git a/AceComm-3.0/AceComm-3.0.lua b/Ace3/AceComm-3.0/AceComm-3.0.lua similarity index 100% rename from AceComm-3.0/AceComm-3.0.lua rename to Ace3/AceComm-3.0/AceComm-3.0.lua diff --git a/AceComm-3.0/AceComm-3.0.xml b/Ace3/AceComm-3.0/AceComm-3.0.xml similarity index 100% rename from AceComm-3.0/AceComm-3.0.xml rename to Ace3/AceComm-3.0/AceComm-3.0.xml diff --git a/AceComm-3.0/ChatThrottleLib.lua b/Ace3/AceComm-3.0/ChatThrottleLib.lua similarity index 100% rename from AceComm-3.0/ChatThrottleLib.lua rename to Ace3/AceComm-3.0/ChatThrottleLib.lua diff --git a/AceConfig-3.0/AceConfig-3.0.lua b/Ace3/AceConfig-3.0/AceConfig-3.0.lua similarity index 100% rename from AceConfig-3.0/AceConfig-3.0.lua rename to Ace3/AceConfig-3.0/AceConfig-3.0.lua diff --git a/AceConfig-3.0/AceConfig-3.0.xml b/Ace3/AceConfig-3.0/AceConfig-3.0.xml similarity index 100% rename from AceConfig-3.0/AceConfig-3.0.xml rename to Ace3/AceConfig-3.0/AceConfig-3.0.xml diff --git a/AceConfig-3.0/AceConfigCmd-3.0/AceConfigCmd-3.0.lua b/Ace3/AceConfig-3.0/AceConfigCmd-3.0/AceConfigCmd-3.0.lua similarity index 100% rename from AceConfig-3.0/AceConfigCmd-3.0/AceConfigCmd-3.0.lua rename to Ace3/AceConfig-3.0/AceConfigCmd-3.0/AceConfigCmd-3.0.lua diff --git a/AceConfig-3.0/AceConfigCmd-3.0/AceConfigCmd-3.0.xml b/Ace3/AceConfig-3.0/AceConfigCmd-3.0/AceConfigCmd-3.0.xml similarity index 100% rename from AceConfig-3.0/AceConfigCmd-3.0/AceConfigCmd-3.0.xml rename to Ace3/AceConfig-3.0/AceConfigCmd-3.0/AceConfigCmd-3.0.xml diff --git a/AceConfig-3.0/AceConfigDialog-3.0/AceConfigDialog-3.0.lua b/Ace3/AceConfig-3.0/AceConfigDialog-3.0/AceConfigDialog-3.0.lua similarity index 97% rename from AceConfig-3.0/AceConfigDialog-3.0/AceConfigDialog-3.0.lua rename to Ace3/AceConfig-3.0/AceConfigDialog-3.0/AceConfigDialog-3.0.lua index 1b6c10e..19772f0 100644 --- a/AceConfig-3.0/AceConfigDialog-3.0/AceConfigDialog-3.0.lua +++ b/Ace3/AceConfig-3.0/AceConfigDialog-3.0/AceConfigDialog-3.0.lua @@ -585,11 +585,11 @@ do button:SetSize(128, 21) button:SetNormalFontObject(GameFontNormal) button:SetHighlightFontObject(GameFontHighlight) - button:SetNormalTexture(130763) -- "Interface\\Buttons\\UI-DialogBox-Button-Up" + button:SetNormalTexture("Interface\\Buttons\\UI-DialogBox-Button-Up") button:GetNormalTexture():SetTexCoord(0.0, 1.0, 0.0, 0.71875) - button:SetPushedTexture(130761) -- "Interface\\Buttons\\UI-DialogBox-Button-Down" + button:SetPushedTexture("Interface\\Buttons\\UI-DialogBox-Button-Down") button:GetPushedTexture():SetTexCoord(0.0, 1.0, 0.0, 0.71875) - button:SetHighlightTexture(130762) -- "Interface\\Buttons\\UI-DialogBox-Button-Highlight" + button:SetHighlightTexture("Interface\\Buttons\\UI-DialogBox-Button-Highlight") button:GetHighlightTexture():SetTexCoord(0.0, 1.0, 0.0, 0.71875) button:SetText(newText) return button @@ -2014,28 +2014,37 @@ function AceConfigDialog:AddToBlizOptions(appName, name, parent, ...) group:SetCallback("OnHide", ClearBlizPanel) local categoryName = name or appName - if parent then - local parentID = BlizOptionsIDMap[parent] or parent - local category = Settings.GetCategory(parentID) - if not category then - error(("The parent category '%s' was not found"):format(parent), 2) - end - local subcategory = Settings.RegisterCanvasLayoutSubcategory(category, group.frame, categoryName) - group:SetName(subcategory.ID, parentID) - else - if BlizOptionsIDMap[categoryName] then - error(("%s has already been added to the Blizzard Options Window with the given name: %s"):format(appName, categoryName), 2) - end + -- CoA-compat: the Settings.* API (GetCategory / RegisterCanvasLayoutCategory / + -- RegisterCanvasLayoutSubcategory / RegisterAddOnCategory) is a retail-only + -- (Dragonflight+) replacement for the WotLK-era InterfaceOptions_AddCategory. + -- On the 3.3.5-based CoA client Settings is nil, so fall back to the legacy API. + if Settings and Settings.GetCategory then + if parent then + local parentID = BlizOptionsIDMap[parent] or parent + local category = Settings.GetCategory(parentID) + if not category then + error(("The parent category '%s' was not found"):format(parent), 2) + end + local subcategory = Settings.RegisterCanvasLayoutSubcategory(category, group.frame, categoryName) + group:SetName(subcategory.ID, parentID) + else + if BlizOptionsIDMap[categoryName] then + error(("%s has already been added to the Blizzard Options Window with the given name: %s"):format(appName, categoryName), 2) + end - local category = Settings.RegisterCanvasLayoutCategory(group.frame, categoryName) - if not (C_SettingsUtil and C_SettingsUtil.OpenSettingsPanel) then - -- override the ID so the name can be used in Settings.OpenToCategory - -- unfortunately with incoming API changes in 12.0 (and likely classic at some point) this override is no longer possible - category.ID = categoryName + local category = Settings.RegisterCanvasLayoutCategory(group.frame, categoryName) + if not (C_SettingsUtil and C_SettingsUtil.OpenSettingsPanel) then + -- override the ID so the name can be used in Settings.OpenToCategory + -- unfortunately with incoming API changes in 12.0 (and likely classic at some point) this override is no longer possible + category.ID = categoryName + end + group:SetName(category.ID) + BlizOptionsIDMap[categoryName] = category.ID + Settings.RegisterAddOnCategory(category) end - group:SetName(category.ID) - BlizOptionsIDMap[categoryName] = category.ID - Settings.RegisterAddOnCategory(category) + else + group:SetName(name or appName, parent) + InterfaceOptions_AddCategory(group.frame) end return group.frame, group.frame.name diff --git a/AceConfig-3.0/AceConfigDialog-3.0/AceConfigDialog-3.0.xml b/Ace3/AceConfig-3.0/AceConfigDialog-3.0/AceConfigDialog-3.0.xml similarity index 100% rename from AceConfig-3.0/AceConfigDialog-3.0/AceConfigDialog-3.0.xml rename to Ace3/AceConfig-3.0/AceConfigDialog-3.0/AceConfigDialog-3.0.xml diff --git a/AceConfig-3.0/AceConfigRegistry-3.0/AceConfigRegistry-3.0.lua b/Ace3/AceConfig-3.0/AceConfigRegistry-3.0/AceConfigRegistry-3.0.lua similarity index 100% rename from AceConfig-3.0/AceConfigRegistry-3.0/AceConfigRegistry-3.0.lua rename to Ace3/AceConfig-3.0/AceConfigRegistry-3.0/AceConfigRegistry-3.0.lua diff --git a/AceConfig-3.0/AceConfigRegistry-3.0/AceConfigRegistry-3.0.xml b/Ace3/AceConfig-3.0/AceConfigRegistry-3.0/AceConfigRegistry-3.0.xml similarity index 100% rename from AceConfig-3.0/AceConfigRegistry-3.0/AceConfigRegistry-3.0.xml rename to Ace3/AceConfig-3.0/AceConfigRegistry-3.0/AceConfigRegistry-3.0.xml diff --git a/AceConsole-3.0/AceConsole-3.0.lua b/Ace3/AceConsole-3.0/AceConsole-3.0.lua similarity index 100% rename from AceConsole-3.0/AceConsole-3.0.lua rename to Ace3/AceConsole-3.0/AceConsole-3.0.lua diff --git a/AceConsole-3.0/AceConsole-3.0.xml b/Ace3/AceConsole-3.0/AceConsole-3.0.xml similarity index 100% rename from AceConsole-3.0/AceConsole-3.0.xml rename to Ace3/AceConsole-3.0/AceConsole-3.0.xml diff --git a/AceDB-3.0/AceDB-3.0.lua b/Ace3/AceDB-3.0/AceDB-3.0.lua similarity index 98% rename from AceDB-3.0/AceDB-3.0.lua rename to Ace3/AceDB-3.0/AceDB-3.0.lua index 231196c..f83a715 100644 --- a/AceDB-3.0/AceDB-3.0.lua +++ b/Ace3/AceDB-3.0/AceDB-3.0.lua @@ -111,7 +111,15 @@ local function copyDefaults(dest, src) end else -- Values are not tables, so this is just a simple return - local mt = {__index = function(t,k2) return k2~=nil and v or nil end} + -- (PR #10 backport: the old `k2~=nil and v or nil` short-circuits to + -- nil whenever the default `v` itself is falsy — so `["*"] = false` + -- defaults silently became nil. Make the read explicit instead.) + local mt = { + __index = function(t,k2) + if k2 == nil then return nil end + return v + end, + } setmetatable(dest, mt) end elseif type(v) == "table" then diff --git a/AceDB-3.0/AceDB-3.0.xml b/Ace3/AceDB-3.0/AceDB-3.0.xml similarity index 100% rename from AceDB-3.0/AceDB-3.0.xml rename to Ace3/AceDB-3.0/AceDB-3.0.xml diff --git a/AceDBOptions-3.0/AceDBOptions-3.0.lua b/Ace3/AceDBOptions-3.0/AceDBOptions-3.0.lua similarity index 100% rename from AceDBOptions-3.0/AceDBOptions-3.0.lua rename to Ace3/AceDBOptions-3.0/AceDBOptions-3.0.lua diff --git a/AceDBOptions-3.0/AceDBOptions-3.0.xml b/Ace3/AceDBOptions-3.0/AceDBOptions-3.0.xml similarity index 100% rename from AceDBOptions-3.0/AceDBOptions-3.0.xml rename to Ace3/AceDBOptions-3.0/AceDBOptions-3.0.xml diff --git a/AceEvent-3.0/AceEvent-3.0.lua b/Ace3/AceEvent-3.0/AceEvent-3.0.lua similarity index 100% rename from AceEvent-3.0/AceEvent-3.0.lua rename to Ace3/AceEvent-3.0/AceEvent-3.0.lua diff --git a/AceEvent-3.0/AceEvent-3.0.xml b/Ace3/AceEvent-3.0/AceEvent-3.0.xml similarity index 100% rename from AceEvent-3.0/AceEvent-3.0.xml rename to Ace3/AceEvent-3.0/AceEvent-3.0.xml diff --git a/AceGUI-3.0/AceGUI-3.0.lua b/Ace3/AceGUI-3.0/AceGUI-3.0.lua similarity index 100% rename from AceGUI-3.0/AceGUI-3.0.lua rename to Ace3/AceGUI-3.0/AceGUI-3.0.lua diff --git a/AceGUI-3.0/AceGUI-3.0.xml b/Ace3/AceGUI-3.0/AceGUI-3.0.xml similarity index 100% rename from AceGUI-3.0/AceGUI-3.0.xml rename to Ace3/AceGUI-3.0/AceGUI-3.0.xml diff --git a/AceGUI-3.0/widgets/AceGUIContainer-BlizOptionsGroup.lua b/Ace3/AceGUI-3.0/widgets/AceGUIContainer-BlizOptionsGroup.lua similarity index 90% rename from AceGUI-3.0/widgets/AceGUIContainer-BlizOptionsGroup.lua rename to Ace3/AceGUI-3.0/widgets/AceGUIContainer-BlizOptionsGroup.lua index d95db58..4f635d8 100644 --- a/AceGUI-3.0/widgets/AceGUIContainer-BlizOptionsGroup.lua +++ b/Ace3/AceGUI-3.0/widgets/AceGUIContainer-BlizOptionsGroup.lua @@ -99,7 +99,11 @@ local methods = { Constructor -------------------------------------------------------------------------------]] local function Constructor() - local frame = CreateFrame("Frame", nil, InterfaceOptionsFramePanelContainer) + -- CoA-compat: InterfaceOptionsFramePanelContainer is a global from the stock 3.3.5 + -- Interface Options frame; on the CoA reworked FrameXML it can be nil at the time + -- AceGUI widgets are constructed. Fall back to UIParent so CreateFrame doesn't blow up. + local _parent = InterfaceOptionsFramePanelContainer or UIParent + local frame = CreateFrame("Frame", nil, _parent) frame:Hide() -- support functions for the Blizzard Interface Options diff --git a/AceGUI-3.0/widgets/AceGUIContainer-DropDownGroup.lua b/Ace3/AceGUI-3.0/widgets/AceGUIContainer-DropDownGroup.lua similarity index 100% rename from AceGUI-3.0/widgets/AceGUIContainer-DropDownGroup.lua rename to Ace3/AceGUI-3.0/widgets/AceGUIContainer-DropDownGroup.lua diff --git a/AceGUI-3.0/widgets/AceGUIContainer-Frame.lua b/Ace3/AceGUI-3.0/widgets/AceGUIContainer-Frame.lua similarity index 96% rename from AceGUI-3.0/widgets/AceGUIContainer-Frame.lua rename to Ace3/AceGUI-3.0/widgets/AceGUIContainer-Frame.lua index 39a1004..0065c70 100644 --- a/AceGUI-3.0/widgets/AceGUIContainer-Frame.lua +++ b/Ace3/AceGUI-3.0/widgets/AceGUIContainer-Frame.lua @@ -221,7 +221,7 @@ local function Constructor() statustext:SetText("") local titlebg = frame:CreateTexture(nil, "OVERLAY") - titlebg:SetTexture(131080) -- Interface\\DialogFrame\\UI-DialogBox-Header + titlebg:SetTexture("Interface\\DialogFrame\\UI-DialogBox-Header") titlebg:SetTexCoord(0.31, 0.67, 0, 0.63) titlebg:SetPoint("TOP", 0, 12) titlebg:SetWidth(100) @@ -237,14 +237,14 @@ local function Constructor() titletext:SetPoint("TOP", titlebg, "TOP", 0, -14) local titlebg_l = frame:CreateTexture(nil, "OVERLAY") - titlebg_l:SetTexture(131080) -- Interface\\DialogFrame\\UI-DialogBox-Header + titlebg_l:SetTexture("Interface\\DialogFrame\\UI-DialogBox-Header") titlebg_l:SetTexCoord(0.21, 0.31, 0, 0.63) titlebg_l:SetPoint("RIGHT", titlebg, "LEFT") titlebg_l:SetWidth(30) titlebg_l:SetHeight(40) local titlebg_r = frame:CreateTexture(nil, "OVERLAY") - titlebg_r:SetTexture(131080) -- Interface\\DialogFrame\\UI-DialogBox-Header + titlebg_r:SetTexture("Interface\\DialogFrame\\UI-DialogBox-Header") titlebg_r:SetTexCoord(0.67, 0.77, 0, 0.63) titlebg_r:SetPoint("LEFT", titlebg, "RIGHT") titlebg_r:SetWidth(30) @@ -262,7 +262,7 @@ local function Constructor() line1:SetWidth(14) line1:SetHeight(14) line1:SetPoint("BOTTOMRIGHT", -8, 8) - line1:SetTexture(137057) -- Interface\\Tooltips\\UI-Tooltip-Border + line1:SetTexture("Interface\\Tooltips\\UI-Tooltip-Border") local x = 0.1 * 14/17 line1:SetTexCoord(0.05 - x, 0.5, 0.05, 0.5 + x, 0.05, 0.5 - x, 0.5 + x, 0.5) @@ -270,7 +270,7 @@ local function Constructor() line2:SetWidth(8) line2:SetHeight(8) line2:SetPoint("BOTTOMRIGHT", -8, 8) - line2:SetTexture(137057) -- Interface\\Tooltips\\UI-Tooltip-Border + line2:SetTexture("Interface\\Tooltips\\UI-Tooltip-Border") x = 0.1 * 8/17 line2:SetTexCoord(0.05 - x, 0.5, 0.05, 0.5 + x, 0.05, 0.5 - x, 0.5 + x, 0.5) diff --git a/AceGUI-3.0/widgets/AceGUIContainer-InlineGroup.lua b/Ace3/AceGUI-3.0/widgets/AceGUIContainer-InlineGroup.lua similarity index 100% rename from AceGUI-3.0/widgets/AceGUIContainer-InlineGroup.lua rename to Ace3/AceGUI-3.0/widgets/AceGUIContainer-InlineGroup.lua diff --git a/AceGUI-3.0/widgets/AceGUIContainer-ScrollFrame.lua b/Ace3/AceGUI-3.0/widgets/AceGUIContainer-ScrollFrame.lua similarity index 100% rename from AceGUI-3.0/widgets/AceGUIContainer-ScrollFrame.lua rename to Ace3/AceGUI-3.0/widgets/AceGUIContainer-ScrollFrame.lua diff --git a/AceGUI-3.0/widgets/AceGUIContainer-SimpleGroup.lua b/Ace3/AceGUI-3.0/widgets/AceGUIContainer-SimpleGroup.lua similarity index 100% rename from AceGUI-3.0/widgets/AceGUIContainer-SimpleGroup.lua rename to Ace3/AceGUI-3.0/widgets/AceGUIContainer-SimpleGroup.lua diff --git a/AceGUI-3.0/widgets/AceGUIContainer-TabGroup.lua b/Ace3/AceGUI-3.0/widgets/AceGUIContainer-TabGroup.lua similarity index 100% rename from AceGUI-3.0/widgets/AceGUIContainer-TabGroup.lua rename to Ace3/AceGUI-3.0/widgets/AceGUIContainer-TabGroup.lua diff --git a/AceGUI-3.0/widgets/AceGUIContainer-TreeGroup.lua b/Ace3/AceGUI-3.0/widgets/AceGUIContainer-TreeGroup.lua similarity index 98% rename from AceGUI-3.0/widgets/AceGUIContainer-TreeGroup.lua rename to Ace3/AceGUI-3.0/widgets/AceGUIContainer-TreeGroup.lua index fef4557..b282e19 100644 --- a/AceGUI-3.0/widgets/AceGUIContainer-TreeGroup.lua +++ b/Ace3/AceGUI-3.0/widgets/AceGUIContainer-TreeGroup.lua @@ -105,11 +105,11 @@ local function UpdateButton(button, treeline, selected, canExpand, isExpanded) if canExpand then if not isExpanded then - toggle:SetNormalTexture(130838) -- Interface\\Buttons\\UI-PlusButton-UP - toggle:SetPushedTexture(130836) -- Interface\\Buttons\\UI-PlusButton-DOWN + toggle:SetNormalTexture("Interface\\Buttons\\UI-PlusButton-UP") + toggle:SetPushedTexture("Interface\\Buttons\\UI-PlusButton-DOWN") else - toggle:SetNormalTexture(130821) -- Interface\\Buttons\\UI-MinusButton-UP - toggle:SetPushedTexture(130820) -- Interface\\Buttons\\UI-MinusButton-DOWN + toggle:SetNormalTexture("Interface\\Buttons\\UI-MinusButton-UP") + toggle:SetPushedTexture("Interface\\Buttons\\UI-MinusButton-DOWN") end toggle:Show() else diff --git a/AceGUI-3.0/widgets/AceGUIContainer-Window.lua b/Ace3/AceGUI-3.0/widgets/AceGUIContainer-Window.lua similarity index 89% rename from AceGUI-3.0/widgets/AceGUIContainer-Window.lua rename to Ace3/AceGUI-3.0/widgets/AceGUIContainer-Window.lua index f378d93..90af2e1 100644 --- a/AceGUI-3.0/widgets/AceGUIContainer-Window.lua +++ b/Ace3/AceGUI-3.0/widgets/AceGUIContainer-Window.lua @@ -190,67 +190,67 @@ do frame:SetToplevel(true) local titlebg = frame:CreateTexture(nil, "BACKGROUND") - titlebg:SetTexture(251966) -- Interface\\PaperDollInfoFrame\\UI-GearManager-Title-Background + titlebg:SetTexture("Interface\\PaperDollInfoFrame\\UI-GearManager-Title-Background") titlebg:SetPoint("TOPLEFT", 9, -6) titlebg:SetPoint("BOTTOMRIGHT", frame, "TOPRIGHT", -28, -24) local dialogbg = frame:CreateTexture(nil, "BACKGROUND") - dialogbg:SetTexture(137056) -- Interface\\Tooltips\\UI-Tooltip-Background + dialogbg:SetTexture("Interface\\Tooltips\\UI-Tooltip-Background") dialogbg:SetPoint("TOPLEFT", 8, -24) dialogbg:SetPoint("BOTTOMRIGHT", -6, 8) dialogbg:SetVertexColor(0, 0, 0, .75) local topleft = frame:CreateTexture(nil, "BORDER") - topleft:SetTexture(251963) -- Interface\\PaperDollInfoFrame\\UI-GearManager-Border + topleft:SetTexture("Interface\\PaperDollInfoFrame\\UI-GearManager-Border") topleft:SetWidth(64) topleft:SetHeight(64) topleft:SetPoint("TOPLEFT") topleft:SetTexCoord(0.501953125, 0.625, 0, 1) local topright = frame:CreateTexture(nil, "BORDER") - topright:SetTexture(251963) -- Interface\\PaperDollInfoFrame\\UI-GearManager-Border + topright:SetTexture("Interface\\PaperDollInfoFrame\\UI-GearManager-Border") topright:SetWidth(64) topright:SetHeight(64) topright:SetPoint("TOPRIGHT") topright:SetTexCoord(0.625, 0.75, 0, 1) local top = frame:CreateTexture(nil, "BORDER") - top:SetTexture(251963) -- Interface\\PaperDollInfoFrame\\UI-GearManager-Border + top:SetTexture("Interface\\PaperDollInfoFrame\\UI-GearManager-Border") top:SetHeight(64) top:SetPoint("TOPLEFT", topleft, "TOPRIGHT") top:SetPoint("TOPRIGHT", topright, "TOPLEFT") top:SetTexCoord(0.25, 0.369140625, 0, 1) local bottomleft = frame:CreateTexture(nil, "BORDER") - bottomleft:SetTexture(251963) -- Interface\\PaperDollInfoFrame\\UI-GearManager-Border + bottomleft:SetTexture("Interface\\PaperDollInfoFrame\\UI-GearManager-Border") bottomleft:SetWidth(64) bottomleft:SetHeight(64) bottomleft:SetPoint("BOTTOMLEFT") bottomleft:SetTexCoord(0.751953125, 0.875, 0, 1) local bottomright = frame:CreateTexture(nil, "BORDER") - bottomright:SetTexture(251963) -- Interface\\PaperDollInfoFrame\\UI-GearManager-Border + bottomright:SetTexture("Interface\\PaperDollInfoFrame\\UI-GearManager-Border") bottomright:SetWidth(64) bottomright:SetHeight(64) bottomright:SetPoint("BOTTOMRIGHT") bottomright:SetTexCoord(0.875, 1, 0, 1) local bottom = frame:CreateTexture(nil, "BORDER") - bottom:SetTexture(251963) -- Interface\\PaperDollInfoFrame\\UI-GearManager-Border + bottom:SetTexture("Interface\\PaperDollInfoFrame\\UI-GearManager-Border") bottom:SetHeight(64) bottom:SetPoint("BOTTOMLEFT", bottomleft, "BOTTOMRIGHT") bottom:SetPoint("BOTTOMRIGHT", bottomright, "BOTTOMLEFT") bottom:SetTexCoord(0.376953125, 0.498046875, 0, 1) local left = frame:CreateTexture(nil, "BORDER") - left:SetTexture(251963) -- Interface\\PaperDollInfoFrame\\UI-GearManager-Border + left:SetTexture("Interface\\PaperDollInfoFrame\\UI-GearManager-Border") left:SetWidth(64) left:SetPoint("TOPLEFT", topleft, "BOTTOMLEFT") left:SetPoint("BOTTOMLEFT", bottomleft, "TOPLEFT") left:SetTexCoord(0.001953125, 0.125, 0, 1) local right = frame:CreateTexture(nil, "BORDER") - right:SetTexture(251963) -- Interface\\PaperDollInfoFrame\\UI-GearManager-Border + right:SetTexture("Interface\\PaperDollInfoFrame\\UI-GearManager-Border") right:SetWidth(64) right:SetPoint("TOPRIGHT", topright, "BOTTOMRIGHT") right:SetPoint("BOTTOMRIGHT", bottomright, "TOPRIGHT") @@ -290,7 +290,7 @@ do line1:SetWidth(14) line1:SetHeight(14) line1:SetPoint("BOTTOMRIGHT", -8, 8) - line1:SetTexture(137057) -- Interface\\Tooltips\\UI-Tooltip-Border + line1:SetTexture("Interface\\Tooltips\\UI-Tooltip-Border") local x = 0.1 * 14/17 line1:SetTexCoord(0.05 - x, 0.5, 0.05, 0.5 + x, 0.05, 0.5 - x, 0.5 + x, 0.5) @@ -299,7 +299,7 @@ do line2:SetWidth(8) line2:SetHeight(8) line2:SetPoint("BOTTOMRIGHT", -8, 8) - line2:SetTexture(137057) -- Interface\\Tooltips\\UI-Tooltip-Border + line2:SetTexture("Interface\\Tooltips\\UI-Tooltip-Border") x = 0.1 * 8/17 line2:SetTexCoord(0.05 - x, 0.5, 0.05, 0.5 + x, 0.05, 0.5 - x, 0.5 + x, 0.5) diff --git a/AceGUI-3.0/widgets/AceGUIWidget-Button.lua b/Ace3/AceGUI-3.0/widgets/AceGUIWidget-Button.lua similarity index 100% rename from AceGUI-3.0/widgets/AceGUIWidget-Button.lua rename to Ace3/AceGUI-3.0/widgets/AceGUIWidget-Button.lua diff --git a/AceGUI-3.0/widgets/AceGUIWidget-CheckBox.lua b/Ace3/AceGUI-3.0/widgets/AceGUIWidget-CheckBox.lua similarity index 92% rename from AceGUI-3.0/widgets/AceGUIWidget-CheckBox.lua rename to Ace3/AceGUI-3.0/widgets/AceGUIWidget-CheckBox.lua index fe17e03..d03296d 100644 --- a/AceGUI-3.0/widgets/AceGUIWidget-CheckBox.lua +++ b/Ace3/AceGUI-3.0/widgets/AceGUIWidget-CheckBox.lua @@ -151,21 +151,21 @@ local methods = { local size if type == "radio" then size = 16 - checkbg:SetTexture(130843) -- Interface\\Buttons\\UI-RadioButton + checkbg:SetTexture("Interface\\Buttons\\UI-RadioButton") checkbg:SetTexCoord(0, 0.25, 0, 1) - check:SetTexture(130843) -- Interface\\Buttons\\UI-RadioButton + check:SetTexture("Interface\\Buttons\\UI-RadioButton") check:SetTexCoord(0.25, 0.5, 0, 1) check:SetBlendMode("ADD") - highlight:SetTexture(130843) -- Interface\\Buttons\\UI-RadioButton + highlight:SetTexture("Interface\\Buttons\\UI-RadioButton") highlight:SetTexCoord(0.5, 0.75, 0, 1) else size = 24 - checkbg:SetTexture(130755) -- Interface\\Buttons\\UI-CheckBox-Up + checkbg:SetTexture("Interface\\Buttons\\UI-CheckBox-Up") checkbg:SetTexCoord(0, 1, 0, 1) - check:SetTexture(130751) -- Interface\\Buttons\\UI-CheckBox-Check + check:SetTexture("Interface\\Buttons\\UI-CheckBox-Check") check:SetTexCoord(0, 1, 0, 1) check:SetBlendMode("BLEND") - highlight:SetTexture(130753) -- Interface\\Buttons\\UI-CheckBox-Highlight + highlight:SetTexture("Interface\\Buttons\\UI-CheckBox-Highlight") highlight:SetTexCoord(0, 1, 0, 1) end checkbg:SetHeight(size) @@ -251,11 +251,11 @@ local function Constructor() checkbg:SetWidth(24) checkbg:SetHeight(24) checkbg:SetPoint("TOPLEFT") - checkbg:SetTexture(130755) -- Interface\\Buttons\\UI-CheckBox-Up + checkbg:SetTexture("Interface\\Buttons\\UI-CheckBox-Up") local check = frame:CreateTexture(nil, "OVERLAY") check:SetAllPoints(checkbg) - check:SetTexture(130751) -- Interface\\Buttons\\UI-CheckBox-Check + check:SetTexture("Interface\\Buttons\\UI-CheckBox-Check") local text = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlight") text:SetJustifyH("LEFT") @@ -264,7 +264,7 @@ local function Constructor() text:SetPoint("RIGHT") local highlight = frame:CreateTexture(nil, "HIGHLIGHT") - highlight:SetTexture(130753) -- Interface\\Buttons\\UI-CheckBox-Highlight + highlight:SetTexture("Interface\\Buttons\\UI-CheckBox-Highlight") highlight:SetBlendMode("ADD") highlight:SetAllPoints(checkbg) diff --git a/AceGUI-3.0/widgets/AceGUIWidget-ColorPicker.lua b/Ace3/AceGUI-3.0/widgets/AceGUIWidget-ColorPicker.lua similarity index 96% rename from AceGUI-3.0/widgets/AceGUIWidget-ColorPicker.lua rename to Ace3/AceGUI-3.0/widgets/AceGUIWidget-ColorPicker.lua index ec811d0..a8aeca5 100644 --- a/AceGUI-3.0/widgets/AceGUIWidget-ColorPicker.lua +++ b/Ace3/AceGUI-3.0/widgets/AceGUIWidget-ColorPicker.lua @@ -180,7 +180,7 @@ local function Constructor() local colorSwatch = frame:CreateTexture(nil, "OVERLAY") colorSwatch:SetWidth(19) colorSwatch:SetHeight(19) - colorSwatch:SetTexture(130939) -- Interface\\ChatFrame\\ChatFrameColorSwatch + colorSwatch:SetTexture("Interface\\ChatFrame\\ChatFrameColorSwatch") colorSwatch:SetPoint("LEFT") local texture = frame:CreateTexture(nil, "BACKGROUND") @@ -195,7 +195,7 @@ local function Constructor() colorSwatch.checkers = checkers checkers:SetWidth(14) checkers:SetHeight(14) - checkers:SetTexture(188523) -- Tileset\\Generic\\Checkers + checkers:SetTexture("Tileset\\Generic\\Checkers") checkers:SetTexCoord(.25, 0, 0.5, .25) checkers:SetDesaturated(true) checkers:SetVertexColor(1, 1, 1, 0.75) @@ -210,7 +210,7 @@ local function Constructor() text:SetPoint("RIGHT") --local highlight = frame:CreateTexture(nil, "HIGHLIGHT") - --highlight:SetTexture(136810) -- Interface\\QuestFrame\\UI-QuestTitleHighlight + --highlight:SetTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight") --highlight:SetBlendMode("ADD") --highlight:SetAllPoints(frame) diff --git a/AceGUI-3.0/widgets/AceGUIWidget-DropDown-Items.lua b/Ace3/AceGUI-3.0/widgets/AceGUIWidget-DropDown-Items.lua similarity index 97% rename from AceGUI-3.0/widgets/AceGUIWidget-DropDown-Items.lua rename to Ace3/AceGUI-3.0/widgets/AceGUIWidget-DropDown-Items.lua index 6fe30ea..a737697 100644 --- a/AceGUI-3.0/widgets/AceGUIWidget-DropDown-Items.lua +++ b/Ace3/AceGUI-3.0/widgets/AceGUIWidget-DropDown-Items.lua @@ -169,7 +169,7 @@ function ItemBase.Create(type) self.text = text local highlight = frame:CreateTexture(nil, "OVERLAY") - highlight:SetTexture(136810) -- Interface\\QuestFrame\\UI-QuestTitleHighlight + highlight:SetTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight") highlight:SetBlendMode("ADD") highlight:SetHeight(14) highlight:ClearAllPoints() @@ -182,7 +182,7 @@ function ItemBase.Create(type) check:SetWidth(16) check:SetHeight(16) check:SetPoint("LEFT",frame,"LEFT",3,-1) - check:SetTexture(130751) -- Interface\\Buttons\\UI-CheckBox-Check + check:SetTexture("Interface\\Buttons\\UI-CheckBox-Check") check:Hide() self.check = check @@ -190,7 +190,7 @@ function ItemBase.Create(type) sub:SetWidth(16) sub:SetHeight(16) sub:SetPoint("RIGHT",frame,"RIGHT",-3,-1) - sub:SetTexture(130940) -- Interface\\ChatFrame\\ChatFrameExpandArrow + sub:SetTexture("Interface\\ChatFrame\\ChatFrameExpandArrow") sub:Hide() self.sub = sub diff --git a/AceGUI-3.0/widgets/AceGUIWidget-DropDown.lua b/Ace3/AceGUI-3.0/widgets/AceGUIWidget-DropDown.lua similarity index 100% rename from AceGUI-3.0/widgets/AceGUIWidget-DropDown.lua rename to Ace3/AceGUI-3.0/widgets/AceGUIWidget-DropDown.lua diff --git a/AceGUI-3.0/widgets/AceGUIWidget-EditBox.lua b/Ace3/AceGUI-3.0/widgets/AceGUIWidget-EditBox.lua similarity index 100% rename from AceGUI-3.0/widgets/AceGUIWidget-EditBox.lua rename to Ace3/AceGUI-3.0/widgets/AceGUIWidget-EditBox.lua diff --git a/AceGUI-3.0/widgets/AceGUIWidget-Heading.lua b/Ace3/AceGUI-3.0/widgets/AceGUIWidget-Heading.lua similarity index 93% rename from AceGUI-3.0/widgets/AceGUIWidget-Heading.lua rename to Ace3/AceGUI-3.0/widgets/AceGUIWidget-Heading.lua index 862ae88..1aaf3f5 100644 --- a/AceGUI-3.0/widgets/AceGUIWidget-Heading.lua +++ b/Ace3/AceGUI-3.0/widgets/AceGUIWidget-Heading.lua @@ -51,14 +51,14 @@ local function Constructor() left:SetHeight(8) left:SetPoint("LEFT", 3, 0) left:SetPoint("RIGHT", label, "LEFT", -5, 0) - left:SetTexture(137057) -- Interface\\Tooltips\\UI-Tooltip-Border + left:SetTexture("Interface\\Tooltips\\UI-Tooltip-Border") left:SetTexCoord(0.81, 0.94, 0.5, 1) local right = frame:CreateTexture(nil, "BACKGROUND") right:SetHeight(8) right:SetPoint("RIGHT", -3, 0) right:SetPoint("LEFT", label, "RIGHT", 5, 0) - right:SetTexture(137057) -- Interface\\Tooltips\\UI-Tooltip-Border + right:SetTexture("Interface\\Tooltips\\UI-Tooltip-Border") right:SetTexCoord(0.81, 0.94, 0.5, 1) local widget = { diff --git a/AceGUI-3.0/widgets/AceGUIWidget-Icon.lua b/Ace3/AceGUI-3.0/widgets/AceGUIWidget-Icon.lua similarity index 97% rename from AceGUI-3.0/widgets/AceGUIWidget-Icon.lua rename to Ace3/AceGUI-3.0/widgets/AceGUIWidget-Icon.lua index 378e813..94d6774 100644 --- a/AceGUI-3.0/widgets/AceGUIWidget-Icon.lua +++ b/Ace3/AceGUI-3.0/widgets/AceGUIWidget-Icon.lua @@ -118,7 +118,7 @@ local function Constructor() local highlight = frame:CreateTexture(nil, "HIGHLIGHT") highlight:SetAllPoints(image) - highlight:SetTexture(136580) -- Interface\\PaperDollInfoFrame\\UI-Character-Tab-Highlight + highlight:SetTexture("Interface\\PaperDollInfoFrame\\UI-Character-Tab-Highlight") highlight:SetTexCoord(0, 1, 0.23, 0.77) highlight:SetBlendMode("ADD") diff --git a/AceGUI-3.0/widgets/AceGUIWidget-InteractiveLabel.lua b/Ace3/AceGUI-3.0/widgets/AceGUIWidget-InteractiveLabel.lua similarity index 100% rename from AceGUI-3.0/widgets/AceGUIWidget-InteractiveLabel.lua rename to Ace3/AceGUI-3.0/widgets/AceGUIWidget-InteractiveLabel.lua diff --git a/AceGUI-3.0/widgets/AceGUIWidget-Keybinding.lua b/Ace3/AceGUI-3.0/widgets/AceGUIWidget-Keybinding.lua similarity index 98% rename from AceGUI-3.0/widgets/AceGUIWidget-Keybinding.lua rename to Ace3/AceGUI-3.0/widgets/AceGUIWidget-Keybinding.lua index ee5a83b..07c8f76 100644 --- a/AceGUI-3.0/widgets/AceGUIWidget-Keybinding.lua +++ b/Ace3/AceGUI-3.0/widgets/AceGUIWidget-Keybinding.lua @@ -199,7 +199,7 @@ local function Constructor() button:SetScript("OnKeyDown", Keybinding_OnKeyDown) button:SetScript("OnMouseDown", Keybinding_OnMouseDown) button:SetScript("OnMouseWheel", Keybinding_OnMouseWheel) - button:SetScript("OnGamePadButtonDown", Keybinding_OnKeyDown) + pcall(button.SetScript, button, "OnGamePadButtonDown", Keybinding_OnKeyDown) button:SetPoint("BOTTOMLEFT") button:SetPoint("BOTTOMRIGHT") button:SetHeight(24) diff --git a/AceGUI-3.0/widgets/AceGUIWidget-Label.lua b/Ace3/AceGUI-3.0/widgets/AceGUIWidget-Label.lua similarity index 100% rename from AceGUI-3.0/widgets/AceGUIWidget-Label.lua rename to Ace3/AceGUI-3.0/widgets/AceGUIWidget-Label.lua diff --git a/AceGUI-3.0/widgets/AceGUIWidget-MultiLineEditBox.lua b/Ace3/AceGUI-3.0/widgets/AceGUIWidget-MultiLineEditBox.lua similarity index 100% rename from AceGUI-3.0/widgets/AceGUIWidget-MultiLineEditBox.lua rename to Ace3/AceGUI-3.0/widgets/AceGUIWidget-MultiLineEditBox.lua diff --git a/AceGUI-3.0/widgets/AceGUIWidget-Slider.lua b/Ace3/AceGUI-3.0/widgets/AceGUIWidget-Slider.lua similarity index 100% rename from AceGUI-3.0/widgets/AceGUIWidget-Slider.lua rename to Ace3/AceGUI-3.0/widgets/AceGUIWidget-Slider.lua diff --git a/AceHook-3.0/AceHook-3.0.lua b/Ace3/AceHook-3.0/AceHook-3.0.lua similarity index 100% rename from AceHook-3.0/AceHook-3.0.lua rename to Ace3/AceHook-3.0/AceHook-3.0.lua diff --git a/AceHook-3.0/AceHook-3.0.xml b/Ace3/AceHook-3.0/AceHook-3.0.xml similarity index 100% rename from AceHook-3.0/AceHook-3.0.xml rename to Ace3/AceHook-3.0/AceHook-3.0.xml diff --git a/AceLocale-3.0/AceLocale-3.0.lua b/Ace3/AceLocale-3.0/AceLocale-3.0.lua similarity index 100% rename from AceLocale-3.0/AceLocale-3.0.lua rename to Ace3/AceLocale-3.0/AceLocale-3.0.lua diff --git a/AceLocale-3.0/AceLocale-3.0.xml b/Ace3/AceLocale-3.0/AceLocale-3.0.xml similarity index 100% rename from AceLocale-3.0/AceLocale-3.0.xml rename to Ace3/AceLocale-3.0/AceLocale-3.0.xml diff --git a/AceSerializer-3.0/AceSerializer-3.0.lua b/Ace3/AceSerializer-3.0/AceSerializer-3.0.lua similarity index 100% rename from AceSerializer-3.0/AceSerializer-3.0.lua rename to Ace3/AceSerializer-3.0/AceSerializer-3.0.lua diff --git a/AceSerializer-3.0/AceSerializer-3.0.xml b/Ace3/AceSerializer-3.0/AceSerializer-3.0.xml similarity index 100% rename from AceSerializer-3.0/AceSerializer-3.0.xml rename to Ace3/AceSerializer-3.0/AceSerializer-3.0.xml diff --git a/AceTab-3.0/AceTab-3.0.lua b/Ace3/AceTab-3.0/AceTab-3.0.lua similarity index 100% rename from AceTab-3.0/AceTab-3.0.lua rename to Ace3/AceTab-3.0/AceTab-3.0.lua diff --git a/AceTab-3.0/AceTab-3.0.xml b/Ace3/AceTab-3.0/AceTab-3.0.xml similarity index 100% rename from AceTab-3.0/AceTab-3.0.xml rename to Ace3/AceTab-3.0/AceTab-3.0.xml diff --git a/AceTimer-3.0/AceTimer-3.0.lua b/Ace3/AceTimer-3.0/AceTimer-3.0.lua similarity index 100% rename from AceTimer-3.0/AceTimer-3.0.lua rename to Ace3/AceTimer-3.0/AceTimer-3.0.lua diff --git a/AceTimer-3.0/AceTimer-3.0.xml b/Ace3/AceTimer-3.0/AceTimer-3.0.xml similarity index 100% rename from AceTimer-3.0/AceTimer-3.0.xml rename to Ace3/AceTimer-3.0/AceTimer-3.0.xml diff --git a/CallbackHandler-1.0/CallbackHandler-1.0.lua b/Ace3/CallbackHandler-1.0/CallbackHandler-1.0.lua similarity index 100% rename from CallbackHandler-1.0/CallbackHandler-1.0.lua rename to Ace3/CallbackHandler-1.0/CallbackHandler-1.0.lua diff --git a/CallbackHandler-1.0/CallbackHandler-1.0.xml b/Ace3/CallbackHandler-1.0/CallbackHandler-1.0.xml similarity index 100% rename from CallbackHandler-1.0/CallbackHandler-1.0.xml rename to Ace3/CallbackHandler-1.0/CallbackHandler-1.0.xml diff --git a/LibStub/LibStub.lua b/Ace3/LibStub/LibStub.lua similarity index 100% rename from LibStub/LibStub.lua rename to Ace3/LibStub/LibStub.lua diff --git a/README.md b/README.md index 875ba3f..4416f1f 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,20 @@ Canonical [Ace3](https://www.wowace.com/projects/ace3) bundle for the CoA Guild 'Exiles' addon forks. -Lifted verbatim from upstream [WoWUIDev/Ace3](https://github.com/WoWUIDev/Ace3) at commit +Lifted from upstream [WoWUIDev/Ace3](https://github.com/WoWUIDev/Ace3) at commit [`52e5f2c`](https://github.com/WoWUIDev/Ace3/commit/52e5f2c7101b6edb02b48ea232bdda2df09d2960) -(2026-05-17). Every fork in the `Exiles` org should converge on this bundle so the runtime -LibStub resolution is predictable and addons can't quietly regress when one of them is disabled. +(2026-05-17), with a small stack of CoA-compat patches on top (see below). Every fork in the `Exiles` +org should converge on this bundle so the runtime LibStub resolution is predictable and addons +can't quietly regress when one of them is disabled. + +## CoA-compat patches on top of upstream + +| # | Issue | Fix | +|---|-------|-----| +| 1 | Upstream Ace3 calls `Texture:Set*Texture()` with numeric FileDataIDs in 42 places across `AceGUI-3.0/widgets/*` and `AceConfigDialog-3.0`. FileDataIDs are a retail-only API (post WoD/Legion). On the WoW 3.3.5-based CoA client, `SetTexture` only accepts string paths — passing a number silently fails and the engine renders a red placeholder. Symptom: solid-red squares where color swatches / checkboxes / window chrome should be. | Each FDID call was substituted with the string path that already lived in the trailing comment, e.g. `colorSwatch:SetTexture(130939)` → `colorSwatch:SetTexture("Interface\\ChatFrame\\ChatFrameColorSwatch")`. | +| 2 | `AceGUI-3.0/widgets/AceGUIContainer-BlizOptionsGroup.lua` Constructor parents its frame to the global `InterfaceOptionsFramePanelContainer`. On the CoA reworked FrameXML that global is nil at AceGUI widget-construction time, and `CreateFrame("Frame", nil, nil)` is fine, but downstream code that calls `:SetPoint` against the parent / `:Show` it via the options tree relies on a real parent. Symptom: every addon that registers a Blizzard Interface Options panel via AceConfigDialog errors during load. | Guard at line 102: `local _parent = InterfaceOptionsFramePanelContainer or UIParent` and pass `_parent` to `CreateFrame`. Widget behaviour is unchanged on retail; on CoA the panel parents to `UIParent` so the rest of the widget works. | +| 3 | `AceConfig-3.0/AceConfigDialog-3.0/AceConfigDialog-3.0.lua` `:AddToBlizOptions` uses the Dragonflight+ `Settings.*` API (`Settings.GetCategory`, `Settings.RegisterCanvasLayoutCategory`, `Settings.RegisterCanvasLayoutSubcategory`, `Settings.RegisterAddOnCategory`). The `Settings` table doesn't exist on the 3.3.5-based CoA client, so every AceConfig-driven options panel errors out the moment it's registered. | Wrap the whole `Settings.*` block in `if Settings and Settings.GetCategory then … else … end`. The `else` branch falls back to the WotLK-era `InterfaceOptions_AddCategory(group.frame)` after stamping the category name via `group:SetName(name or appName, parent)`. | +| 4 | `AceDB-3.0/AceDB-3.0.lua:114` — the simple-value `__index` metatable for defaults is `function(t,k2) return k2~=nil and v or nil end`. Whenever the default value `v` is itself falsy (`false`, `0`, `""`), the `and` short-circuits and the `or nil` resolves to `nil`, so `["*"] = false` and similar falsy defaults are silently lost when read. | Replaces the one-liner with an explicit `if k2 == nil then return nil end; return v` so falsy defaults round-trip correctly. Backport of [WoWUIDev/Ace3 PR #10](https://github.com/WoWUIDev/Ace3/pull/10) (open since 2023-11-04, not merged upstream). Drop this patch if/when upstream merges. | ## Versions @@ -47,14 +57,35 @@ Or replace the entire `Libs/Ace3/` tree in one go. ### Option 2: standalone addon -Drop the contents (except `README.md` / `.gitattributes`) into -`Interface/AddOns/Ace3/` and the loadable `Ace3.toc` will register every library at top +Drop the **`Ace3/`** directory from this repo straight into +`Interface/AddOns/` and the loadable `Ace3.toc` will register every library at top priority via LibStub. Useful for non-bundling forks (`chatter`, `sexymap`, `clique`, …) to get Ace without each one carrying its own copy. +(The canonical bundle lives under `Ace3/` at the repo root so this repo follows the same +"each addon in its own folder" layout as every other `Exiles/coa-*` fork.) + ## Sync policy -Bumping upstream means a single PR here, then a sweep across every fork that embeds these -libs. Note the new upstream commit in the README's commit-pin line above. Never edit a -library file in place; if a CoA-specific patch is genuinely needed, ship it as a separate -loadable addon that registers a higher MINOR via LibStub, leaving this bundle pristine. +Bumping upstream means a single commit here, then a sweep across every fork that embeds these +libs. Note the new upstream commit in the README's commit-pin line above, and re-apply +the CoA-compat patches listed above against the new revision (the FDID one is mechanical — +see `/tmp/fix_fdid.py` history). Keep patches **minimal and documented in this README**; +prefer fixing them upstream where reasonable. + +Run the sweep via `tools/sweep.py` from this repo — it walks every sibling `coa-*` fork +under `/home/sub/repos/coa`, finds each fork's bundled `LibStub` / `CallbackHandler-1.0` / +`Ace*-3.0` dirs, and rsyncs them from this bundle. Use `--dry-run` first. + +### Forks excluded from sweep + +`coa-elvui` is excluded from the sweep — see `EXCLUDED_FORKS` in `tools/sweep.py`. ElvUI +ships its own bundled Ace3 stack with ElvUI-specific patches inside otherwise-stock-named +files (`AceLocale-3.0.lua`, `AceConfigDialog-3.0.lua`, every `AceGUI-3.0/widgets/*.lua`) +**plus** `-ElvUI`-suffixed widgets that don't exist in canonical at all (e.g. +`AceGUIWidget-Button-ElvUI.lua`). `rsync --delete` obliterates the latter; an in-place +sync overwrites the former. Either failure breaks `/ec` and floods locale errors. ElvUI +maintains its own bundle on its own cadence and must never be touched by this tool. + +The sweep also passes `--exclude='*-ElvUI*'` to every rsync as a belt-and-braces guard +against future forks that happen to carry an ElvUI-namespaced file we didn't anticipate. diff --git a/tools/build_zip.sh b/tools/build_zip.sh new file mode 100755 index 0000000..45d1400 --- /dev/null +++ b/tools/build_zip.sh @@ -0,0 +1,71 @@ +#!/usr/bin/env bash +# Build per-addon zip artefacts from HEAD via git-archive. +# +# - Discovers top-level addon folders (Foo/Foo.toc). +# - Re-creates dist/ each run. +# - Always archives HEAD, so the working tree state is irrelevant. +# - If more than one addon folder is present, also emits -all.zip +# with every addon folder side-by-side at the zip root. +# - When run inside Gitea Actions the working tree lives under a +# per-job dir like /var/lib/act_runner/work/.../hostexecutor, so the +# repo name comes from $GITHUB_REPOSITORY (set by the runner) and +# only falls back to the toplevel basename for local invocations. +set -euo pipefail + +root=$(git rev-parse --show-toplevel) +cd "$root" + +# Gitea Actions sets GITHUB_REPOSITORY=owner/repo. The basename of +# `git rev-parse --show-toplevel` inside the runner is the worker dir +# (e.g. `hostexecutor`), which would name the bundle wrong. +if [ -n "${GITHUB_REPOSITORY:-}" ]; then + repo_name="${GITHUB_REPOSITORY##*/}" +else + repo_name=$(basename "$root") +fi +dist="$root/dist" + +# Find Foo/Foo.toc pairs at depth 1; ignore libs nested deeper. +addons=() +while IFS= read -r toc; do + dir=$(dirname "$toc") + folder=$(basename "$dir") + base=$(basename "$toc" .toc) + # Accept Foo.toc and Foo_Wrath.toc style flavour variants; folder must match + # at least one toc basename prefix (Foo). + case "$base" in + "$folder"|"$folder"_*) addons+=("$folder") ;; + esac +done < <(command find . -mindepth 2 -maxdepth 2 -type f -name '*.toc' | sed 's|^\./||' | sort) + +# Dedupe (a folder with Foo.toc + Foo_Wrath.toc shows up twice). +if [ ${#addons[@]} -gt 0 ]; then + mapfile -t addons < <(printf '%s\n' "${addons[@]}" | awk '!seen[$0]++') +fi + +if [ ${#addons[@]} -eq 0 ]; then + echo "no addon folders found (looking for */Foo.toc with matching folder name)" >&2 + exit 1 +fi + +rm -rf "$dist" +mkdir -p "$dist" + +for folder in "${addons[@]}"; do + out="$dist/$folder.zip" + # No --prefix: the folder already sits at the repo root, so git-archive + # emits entries as /... which is exactly what + # Interface/AddOns/ expects after extraction. + git archive HEAD --format=zip -o "$out" -- "$folder" + echo "built dist/$folder.zip" +done + +# Combined bundle only makes sense when there are multiple addons. +if [ ${#addons[@]} -gt 1 ]; then + tmp=$(mktemp -d) + trap 'rm -rf "$tmp"' EXIT + git archive HEAD --format=tar -- "${addons[@]}" | tar -x -C "$tmp" + out="$dist/$repo_name-all.zip" + ( cd "$tmp" && zip -qr "$out" "${addons[@]}" ) + echo "built dist/$repo_name-all.zip" +fi diff --git a/tools/sweep.py b/tools/sweep.py new file mode 100755 index 0000000..4d01c93 --- /dev/null +++ b/tools/sweep.py @@ -0,0 +1,163 @@ +#!/usr/bin/env python3 +"""Sweep this coa-ace3 bundle into every Exiles fork that embeds Ace3 libs. + +Run from anywhere; the script locates itself and walks sibling repos at +$REPOS_ROOT (default /home/sub/repos/coa). For each fork that bundles +any AceXxx-3.0 library, the matching directory is rsynced from this +bundle with --delete so the fork stays byte-identical to canonical. + +USAGE + tools/sweep.py # apply sweep + tools/sweep.py --dry-run # show what would change without writing + +WHY THIS SCRIPT EXISTS + Previous sweeps were ad-hoc scripts living in /tmp during a session + and re-derived by hand each time. That made it easy to forget the + ElvUI exclusion (see EXCLUDED_FORKS below) and re-clobber ElvUI's + customized lib stack on every sync. Committing the canonical script + here keeps the exclusion list visible and reviewable. + +EXCLUDED_FORKS + coa-elvui ships its OWN bundled Ace3 with ElvUI-specific patches + inside otherwise-stock-named files (AceLocale, AceConfigDialog, the + AceGUI widgets) PLUS files that don't exist in canonical at all + (AceGUIWidget-Button-ElvUI.lua). rsync --delete obliterates the + latter; an in-place sync overwrites the former. Either failure + breaks /ec and floods locale errors. ElvUI maintains its own bundle + on its own cadence and must never be swept by this tool. +""" +import argparse +import os +import re +import subprocess +import sys +from pathlib import Path + +# --- configuration ----------------------------------------------------------- + +REPOS_ROOT = Path(os.environ.get("REPOS_ROOT", "/home/sub/repos/coa")) +BUNDLE = Path(__file__).resolve().parent.parent / "Ace3" # canonical Ace3 lives under /Ace3/ + +# Forks that this sweep MUST NOT touch. Document the reason inline. +EXCLUDED_FORKS = { + "coa-elvui", # ships its own ElvUI-patched Ace3 stack; sweep would clobber it +} + +# Lib names whose directories we sync from the bundle. +LIB_NAMES = re.compile(r"^(LibStub|CallbackHandler-1\.0|Ace\w*-3\.0)$") + +# rsync excludes — repo metadata never deployed, plus a belt-and-braces +# guard against deleting any -ElvUI file that might exist in destinations we +# didn't intend to touch (e.g. a future fork that pulls in some ElvUI widget). +RSYNC_EXCLUDES = [ + ".git", ".gitattributes", ".gitignore", ".github", ".idea", + ".editorconfig", ".luacheckrc", ".pkgmeta", + "*-ElvUI*", # never delete or overwrite ElvUI-namespaced files +] + + +# --- discovery --------------------------------------------------------------- + +def bundle_lib_sources(): + """Return {libname: absolute path inside bundle} for every shippable lib. + + Handles the nested AceConfig children (AceConfigCmd/Dialog/Registry). + """ + out = {} + for path in BUNDLE.rglob("*"): + if not path.is_dir(): + continue + if path.name in {".git", "tools"}: + continue + if LIB_NAMES.match(path.name): + out.setdefault(path.name, path) + return out + + +def fork_lib_targets(fork: Path, src_names): + """Return {libname: absolute path inside fork} for each lib the fork bundles. + + A lib is "bundled" when there's a top-level directory containing + /.lua. We don't add new libs to forks that didn't + already ship them. + """ + targets = {} + for path in fork.rglob("*.lua"): + if "/.git/" in str(path): + continue + if "-ElvUI" in path.name: + continue + name = path.stem + if name not in src_names: + continue + parent = path.parent + if parent.name != name: + continue + targets.setdefault(name, parent) + return targets + + +# --- sweep ------------------------------------------------------------------- + +def sweep(dry_run: bool) -> int: + src_map = bundle_lib_sources() + if not src_map: + print(f"no libs found inside {BUNDLE}; nothing to sweep", file=sys.stderr) + return 2 + + forks = sorted(p for p in REPOS_ROOT.iterdir() + if p.is_dir() and p.name.startswith("coa-") + and p.name != "coa-ace3" + and (p / ".git").exists()) + + print(f"bundle: {BUNDLE}") + print(f"forks scan: {REPOS_ROOT}") + print(f"excluded: {sorted(EXCLUDED_FORKS)}") + print(f"libs: {sorted(src_map)}") + print() + + total_synced = total_skipped = 0 + for fork in forks: + if fork.name in EXCLUDED_FORKS: + print(f" skip {fork.name} (excluded — ships its own customized Ace3)") + total_skipped += 1 + continue + + targets = fork_lib_targets(fork, src_map.keys()) + if not targets: + print(f" no-libs {fork.name}") + continue + + for libname in sorted(targets): + src = src_map[libname] + dst = targets[libname] + cmd = ["rsync", "-a", "--delete"] + if dry_run: + cmd += ["--dry-run", "--itemize-changes"] + for exc in RSYNC_EXCLUDES: + cmd += ["--exclude", exc] + cmd += [f"{src}/", f"{dst}/"] + res = subprocess.run(cmd, capture_output=True, text=True) + if res.returncode != 0: + print(f" ! rsync failed for {fork.name}/{libname}: {res.stderr.strip()}") + continue + tag = "would-sync" if dry_run else "synced" + print(f" {tag:<9} {fork.name}/{dst.relative_to(fork)}") + total_synced += 1 + + print() + print(f"summary: {total_synced} lib dirs {'would be synced' if dry_run else 'synced'}, " + f"{total_skipped} forks excluded") + return 0 + + +def main(): + ap = argparse.ArgumentParser(description=__doc__) + ap.add_argument("--dry-run", action="store_true", + help="show what would change without writing") + args = ap.parse_args() + sys.exit(sweep(args.dry_run)) + + +if __name__ == "__main__": + main()