Add one-shot item API foundation cleanup

This commit is contained in:
Dusk-92
2026-08-24 13:50:36 +02:00
parent 22334b91eb
commit bba58b9215
+428
View File
@@ -0,0 +1,428 @@
name: One-shot Item API Foundation
on:
push:
branches: [classicapi-enhanced]
paths:
- '.github/workflows/item-api-foundation.yml'
permissions:
contents: write
jobs:
patch:
if: github.actor != 'github-actions[bot]'
runs-on: ubuntu-latest
steps:
- name: Checkout ShaguTweaks
uses: actions/checkout@v4
with:
ref: classicapi-enhanced
- name: Centralize ClassicAPI item helpers
shell: python
run: |
from pathlib import Path
# ------------------------------------------------------------------
# api.lua: add a small, reusable item compatibility layer.
# ------------------------------------------------------------------
api = Path('api.lua')
text = api.read_text(encoding='utf-8')
old = '''API.inventory = type(_G.C_Container) == "table"
and type(_G.C_Container.GetContainerNumFreeSlots) == "function"
API.merchant = type(_G.C_MerchantFrame) == "table"
'''
new = '''API.inventory = type(_G.C_Container) == "table"
and type(_G.C_Container.GetContainerNumFreeSlots) == "function"
API.containeritems = type(_G.C_Container) == "table"
and type(_G.C_Container.GetContainerItemID) == "function"
API.items = type(_G.C_Item) == "table"
API.iteminfo = API.items and type(_G.C_Item.GetItemInfo) == "function"
API.itemname = API.items and type(_G.C_Item.GetItemNameByID) == "function"
API.itemquality = API.items and type(_G.C_Item.GetItemQualityByID) == "function"
API.itemprice = API.items and type(_G.C_Item.GetItemSellPriceByID) == "function"
API.merchant = type(_G.C_MerchantFrame) == "table"
'''
if old not in text:
raise SystemExit('api.lua capability marker not found')
text = text.replace(old, new, 1)
old = '''API.GetContainerNumFreeSlots = function(bag)
if API.inventory then
return _G.C_Container.GetContainerNumFreeSlots(bag)
end
return 0, 0
end
API.GetNumJunkItems = function()
'''
new = '''API.GetContainerNumFreeSlots = function(bag)
if API.inventory then
return _G.C_Container.GetContainerNumFreeSlots(bag)
end
return 0, 0
end
-- Item helpers use direct ClassicAPI IDs whenever possible. Legacy links remain
-- as a fallback for compatibility with a stock 1.12-style call path.
local function GetItemIDFromLink(link)
if not link then return end
local _, _, itemID = string.find(link, "item:(%d+)")
return itemID and tonumber(itemID) or nil
end
API.GetItemIDFromLink = GetItemIDFromLink
API.GetContainerItemID = function(bag, slot)
if API.containeritems then
local itemID = _G.C_Container.GetContainerItemID(bag, slot)
if itemID then return itemID end
end
return GetItemIDFromLink(_G.GetContainerItemLink(bag, slot))
end
API.GetInventoryItemID = function(unit, slot)
if type(_G.GetInventoryItemID) == "function" then
local itemID = _G.GetInventoryItemID(unit, slot)
if itemID then return itemID end
end
return GetItemIDFromLink(_G.GetInventoryItemLink(unit, slot))
end
API.GetItemInfo = function(item)
if API.iteminfo then
return _G.C_Item.GetItemInfo(item)
end
return _G.GetItemInfo(item)
end
API.GetItemNameByID = function(itemID)
if not itemID then return end
if API.itemname then
return _G.C_Item.GetItemNameByID(itemID)
end
local name = _G.GetItemInfo(itemID)
return name
end
API.GetItemQualityByID = function(itemID)
if not itemID then return end
if API.itemquality then
return _G.C_Item.GetItemQualityByID(itemID)
end
local _, _, quality = _G.GetItemInfo(itemID)
return quality
end
API.GetItemSellPriceByID = function(itemID)
if not itemID then return end
if API.itemprice then
return _G.C_Item.GetItemSellPriceByID(itemID)
end
end
API.GetNumJunkItems = function()
'''
if old not in text:
raise SystemExit('api.lua function marker not found')
text = text.replace(old, new, 1)
api.write_text(text, encoding='utf-8', newline='\n')
# ------------------------------------------------------------------
# helpers.lua: make common item helpers custom-item aware without
# changing their old public semantics.
# ------------------------------------------------------------------
helpers = Path('helpers.lua')
text = helpers.read_text(encoding='utf-8')
marker = 'ShaguTweaks.GetItemIDFromLink = function(itemLink)\n'
head, sep, _ = text.partition(marker)
if not sep:
raise SystemExit('helpers.lua item-helper marker not found')
tail = r'''local function LegacyItemIDFromLink(itemLink)
if not itemLink then return end
local _, _, itemID = string.find(itemLink, "item:(%d+)")
return itemID and tonumber(itemID) or nil
end
ShaguTweaks.GetItemIDFromLink = function(itemLink)
local API = ShaguTweaks.API
if API and API.GetItemIDFromLink then
return API.GetItemIDFromLink(itemLink)
end
return LegacyItemIDFromLink(itemLink)
end
ShaguTweaks.GetItemCount = function(itemName)
if not itemName then return 0 end
local API = ShaguTweaks.API
local count = 0
for bag = 4, 0, -1 do
for slot = 1, GetContainerNumSlots(bag) do
local _, itemCount = GetContainerItemInfo(bag, slot)
if itemCount then
local itemID
if API and API.GetContainerItemID then
itemID = API.GetContainerItemID(bag, slot)
else
itemID = LegacyItemIDFromLink(GetContainerItemLink(bag, slot))
end
local queryName
if itemID and API and API.GetItemNameByID then
queryName = API.GetItemNameByID(itemID)
elseif itemID then
queryName = GetItemInfo(itemID)
end
if queryName == itemName then
count = count + itemCount
end
end
end
end
return count
end
local itemLinkByNameCache = {}
local function CacheItemLink(name, link)
if name and name ~= "" and link then
itemLinkByNameCache[name] = link
end
return link
end
local function FindOwnedItemLinkByName(name)
local API = ShaguTweaks.API
-- Bags first: this is both much cheaper than an ID sweep and works for Turtle
-- custom items whose IDs are far beyond vanilla's original range.
for bag = 0, 4 do
for slot = 1, GetContainerNumSlots(bag) do
local link = GetContainerItemLink(bag, slot)
if link then
local itemID = API and API.GetContainerItemID and API.GetContainerItemID(bag, slot)
or LegacyItemIDFromLink(link)
local itemName = itemID and API and API.GetItemNameByID and API.GetItemNameByID(itemID)
if not itemName then
local _, _, linkedName = string.find(link, "%[(.-)%]")
itemName = linkedName
end
if itemName == name then return link end
end
end
end
-- Equipped items are another cheap source of already-resolved links.
for slot = 0, 19 do
local link = GetInventoryItemLink("player", slot)
if link then
local itemID = API and API.GetInventoryItemID and API.GetInventoryItemID("player", slot)
or LegacyItemIDFromLink(link)
local itemName = itemID and API and API.GetItemNameByID and API.GetItemNameByID(itemID)
if not itemName then
local _, _, linkedName = string.find(link, "%[(.-)%]")
itemName = linkedName
end
if itemName == name then return link end
end
end
end
ShaguTweaks.GetItemLinkByName = function(name)
if not name or name == "" then return end
if itemLinkByNameCache[name] then
return itemLinkByNameCache[name]
end
local ownedLink = FindOwnedItemLinkByName(name)
if ownedLink then
return CacheItemLink(name, ownedLink)
end
-- Legacy compatibility fallback. Vanilla has no generic name -> itemID
-- resolver, so retain the original base-game sweep for non-owned items.
-- Crucially, custom items the player owns no longer depend on this limit.
for itemID = 1, 25818 do
local itemName, itemLink, itemQuality = GetItemInfo(itemID)
if itemName and itemName == name then
local _, _, _, hex = GetItemQualityColor(tonumber(itemQuality))
local hyperLink = hex .. "|H" .. itemLink .. "|h[" .. itemName .. "]|h" .. FONT_COLOR_CODE_CLOSE
return CacheItemLink(name, hyperLink)
end
end
end
'''
helpers.write_text(head + tail, encoding='utf-8', newline='\n')
# ------------------------------------------------------------------
# item-colors.lua: stop relying on parsed legacy links for bag/bank/
# inspect rarity. Direct IDs + ClassicAPI quality work for Turtle IDs.
# ------------------------------------------------------------------
colors = Path('mods/item-colors.lua')
text = colors.read_text(encoding='utf-8')
old = 'local T = ShaguTweaks.T\nlocal GetExpansion = ShaguTweaks.GetExpansion\n'
new = 'local T = ShaguTweaks.T\nlocal API = ShaguTweaks.API\nlocal GetExpansion = ShaguTweaks.GetExpansion\n'
if old not in text:
raise SystemExit('item-colors.lua header marker not found')
text = text.replace(old, new, 1)
old = 'local defcolor = {}\n\nlocal paperdoll_slots = {\n'
new = r'''local defcolor = {}
local function GetQualityFromLink(link)
if not link then return end
local itemID = API and API.GetItemIDFromLink and API.GetItemIDFromLink(link)
if itemID and API and API.GetItemQualityByID then
local quality = API.GetItemQualityByID(itemID)
if quality ~= nil then return quality end
end
local _, _, istring = string.find(link, "|H(.+)|h")
if istring then
local _, _, quality = GetItemInfo(istring)
return quality
end
end
local function GetBagItemQuality(bag, slot)
if API and API.GetContainerItemID and API.GetItemQualityByID then
local itemID = API.GetContainerItemID(bag, slot)
if itemID then
local quality = API.GetItemQualityByID(itemID)
if quality ~= nil then return quality end
end
end
return GetQualityFromLink(GetContainerItemLink(bag, slot))
end
local function GetUnitItemQuality(unit, slot)
if API and API.GetInventoryItemID and API.GetItemQualityByID then
local itemID = API.GetInventoryItemID(unit, slot)
if itemID then
local quality = API.GetItemQualityByID(itemID)
if quality ~= nil then return quality end
end
end
return GetQualityFromLink(GetInventoryItemLink(unit, slot))
end
local paperdoll_slots = {
'''
if old not in text:
raise SystemExit('item-colors.lua helper marker not found')
text = text.replace(old, new, 1)
old = ''' local link = GetInventoryItemLink("target", i)
local border = button.ShaguTweaks_border
'''
new = ''' local quality = GetUnitItemQuality("target", i)
local border = button.ShaguTweaks_border
'''
if old not in text:
raise SystemExit('item-colors.lua inspect link marker not found')
text = text.replace(old, new, 1)
old = ''' border:SetBackdropBorderColor(defcolor["inspect"][1], defcolor["inspect"][2], defcolor["inspect"][3], 1)
if link then
local _, _, istring = string.find(link, "|H(.+)|h")
local _, _, quality = GetItemInfo(istring)
if quality then
local r, g, b = GetItemQualityColor(quality)
border:SetBackdropBorderColor(r, g, b, 1)
end
end
'''
new = ''' border:SetBackdropBorderColor(defcolor["inspect"][1], defcolor["inspect"][2], defcolor["inspect"][3], 1)
if quality ~= nil then
local r, g, b = GetItemQualityColor(quality)
border:SetBackdropBorderColor(r, g, b, 1)
end
'''
if old not in text:
raise SystemExit('item-colors.lua inspect quality marker not found')
text = text.replace(old, new, 1)
old = ''' local link = GetContainerItemLink(id, button:GetID())
if button and button:IsShown() and link then
local _, _, istring = string.find(link, "|H(.+)|h")
local _, _, quality = GetItemInfo(istring)
if quality then
local r, g, b = GetItemQualityColor(quality)
button.ShaguTweaks_border:SetBackdropBorderColor(r,g,b)
end
end
'''
new = ''' local quality = GetBagItemQuality(id, button:GetID())
if button and button:IsShown() and quality ~= nil then
local r, g, b = GetItemQualityColor(quality)
button.ShaguTweaks_border:SetBackdropBorderColor(r,g,b)
end
'''
if old not in text:
raise SystemExit('item-colors.lua bag quality marker not found')
text = text.replace(old, new, 1)
old = ''' local button = _G["BankFrameItem"..i]
\t\t local link = GetContainerItemLink(-1, i)
if button then
'''
new = ''' local button = _G["BankFrameItem"..i]
local quality = GetBagItemQuality(-1, i)
if button then
'''
if old not in text:
raise SystemExit('item-colors.lua bank link marker not found')
text = text.replace(old, new, 1)
old = ''' if link then
local _, _, istring = string.find(link, "|H(.+)|h")
local _, _, q = GetItemInfo(istring)
if q and q > 1 then
local r, g, b = GetItemQualityColor(q)
button.ShaguTweaks_border:SetBackdropBorderColor(r,g,b)
end
end
'''
new = ''' if quality and quality > 1 then
local r, g, b = GetItemQualityColor(quality)
button.ShaguTweaks_border:SetBackdropBorderColor(r,g,b)
end
'''
if old not in text:
raise SystemExit('item-colors.lua bank quality marker not found')
text = text.replace(old, new, 1)
colors.write_text(text, encoding='utf-8', newline='\n')
# Sanity checks for the intended migration.
assert 'API.GetContainerItemID = function' in api.read_text(encoding='utf-8')
assert 'FindOwnedItemLinkByName' in helpers.read_text(encoding='utf-8')
assert 'GetBagItemQuality' in colors.read_text(encoding='utf-8')
print('ClassicAPI item foundation applied')
- name: Validate and commit
run: |
git diff --check
git diff --stat
git rm .github/workflows/item-api-foundation.yml
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add api.lua helpers.lua mods/item-colors.lua
git diff --cached --check
git commit -m "Centralize ClassicAPI item handling"
git push origin HEAD:classicapi-enhanced