local MAJOR, MINOR = "LibItemUpgradeInfo-1.0", 30 local type,tonumber,select,strsplit,GetItemInfoFromHyperlink=type,tonumber,select,strsplit,GetItemInfoFromHyperlink local unpack,GetDetailedItemLevelInfo=unpack,GetDetailedItemLevelInfo local library,previous = _G.LibStub:NewLibrary(MAJOR, MINOR) local lib=library --#lib Needed to keep Eclipse LDT happy if not lib then return end local pp=print --[===[@debug@ LoadAddOn("Blizzard_DebugTools") LoadAddOn("LibDebug") if LibDebug then LibDebug() end --@end-debug@]===] --@non-debug@ local print=function() end --@end-non-debug@ --[[ Caching system 1 itemName String The name of the item. 2 itemLink String The item link of the item. 3 itemRarity Number The quality of the item. The value is 0 to 7, which represents Poor to Heirloom. This appears to include gains from upgrades/bonuses. 4 itemLevel Number The item level of this item, not including item levels gained from upgrades. There is currently no API to get the item level including upgrades/bonuses. 5 itemMinLevel Number The minimum level required to use the item, 0 meaning no level requirement. 6 itemType String The type of the item: Armor, Weapon, Quest, Key, etc. 7 itemSubType String The sub-type of the item: Enchanting, Cloth, Sword, etc. See itemType. 8 itemStackCount Number How many of the item per stack: 20 for Runecloth, 1 for weapon, 100 for Alterac Ram Hide, etc. 9 itemEquipLoc String The type of inventory equipment location in which the item may be equipped, or "" if it can't be equippable. The string returned is also the name of a global string variable e.g. if "INVTYPE_WEAPONMAINHAND" is returned, _G["INVTYPE_WEAPONMAINHAND"] will be the localized, displayable name of the location. 10 iconFileDataID Number The FileDataID for the icon texture for the item. 11 itemSellPrice Number The price, in copper, a vendor is willing to pay for this item, 0 for items that cannot be sold. 12 itemClassID Number This is the numerical value that determines the string to display for 'itemType'. 13 itemSubClassID Number This is the numerical value that determines the string to display for 'itemSubType' 14 bindType Number Item binding type: 0 - none; 1 - on pickup; 2 - on equip; 3 - on use; 4 - quest. 15 expacID Number 16 itemSetID Number 17 isCraftingReagent bool --]] -- ItemLink Constants local i_Name=1 local i_Link=2 local i_Rarity=3 local i_Quality=3 local i_Level=4 local i_MinLevel =5 local i_ClassName=6 local i_SubClassName=7 local i_StackCount=8 local i_EquipLoc=9 local i_TextureId=10 local i_SellPrice=11 local i_ClassID=12 local i_SubClass_ID=13 local i_unk1=14 local i_unk2=15 local i_unk3=16 local i_unk4=17 do local oGetItemInfo=GetItemInfo lib.itemcache=lib.itemcache or setmetatable({miss=0,tot=0},{ __index=function(table,key) if (not key) then return "" end if (key=="miss") then return 0 end if (key=="tot") then return 0 end local cached={oGetItemInfo(key)} if #cached==0 then return nil end local itemLink=cached[2] if not itemLink then return nil end local itemID=lib:GetItemID(itemLink) local quality=cached[3] local cacheIt=true if quality==LE_ITEM_QUALITY_ARTIFACT then local relic1, relic2, relic3 = select(4,strsplit(':', itemLink)) if relic1 and relic1 ~= '' and not oGetItemInfo(relic1) then cacheIt = false end if relic2 and relic2 ~= '' and not oGetItemInfo(relic2) then cacheIt = false end if relic3 and relic3 ~= '' and not oGetItemInfo(relic3) then cacheIt = false end end cached.englishClass=GetItemClassInfo(cached[12]) cached.englishSubClass=GetItemSubClassInfo(cached[12],cached[13]) if cacheIt then rawset(table,key,cached) end table.miss=table.miss+1 return cached end }) end local cache=lib.itemcache local function CachedGetItemInfo(key,index) if not key then return nil end index=index or 1 cache.tot=cache.tot+1 local cached=cache[key] if cached and type(cached)=='table' then return select(index,unpack(cached)) else rawset(cache,key,nil) -- voiding broken cache entry end end local upgradeTable = { [ 1] = { upgrade = 1, max = 1, ilevel = 8 }, [373] = { upgrade = 1, max = 3, ilevel = 4 }, [374] = { upgrade = 2, max = 3, ilevel = 8 }, [375] = { upgrade = 1, max = 3, ilevel = 4 }, [376] = { upgrade = 2, max = 3, ilevel = 4 }, [377] = { upgrade = 3, max = 3, ilevel = 4 }, [378] = { ilevel = 7 }, [379] = { upgrade = 1, max = 2, ilevel = 4 }, [380] = { upgrade = 2, max = 2, ilevel = 4 }, [445] = { upgrade = 0, max = 2, ilevel = 0 }, [446] = { upgrade = 1, max = 2, ilevel = 4 }, [447] = { upgrade = 2, max = 2, ilevel = 8 }, [451] = { upgrade = 0, max = 1, ilevel = 0 }, [452] = { upgrade = 1, max = 1, ilevel = 8 }, [453] = { upgrade = 0, max = 2, ilevel = 0 }, [454] = { upgrade = 1, max = 2, ilevel = 4 }, [455] = { upgrade = 2, max = 2, ilevel = 8 }, [456] = { upgrade = 0, max = 1, ilevel = 0 }, [457] = { upgrade = 1, max = 1, ilevel = 8 }, [458] = { upgrade = 0, max = 4, ilevel = 0 }, [459] = { upgrade = 1, max = 4, ilevel = 4 }, [460] = { upgrade = 2, max = 4, ilevel = 8 }, [461] = { upgrade = 3, max = 4, ilevel = 12 }, [462] = { upgrade = 4, max = 4, ilevel = 16 }, [465] = { upgrade = 0, max = 2, ilevel = 0 }, [466] = { upgrade = 1, max = 2, ilevel = 4 }, [467] = { upgrade = 2, max = 2, ilevel = 8 }, [468] = { upgrade = 0, max = 4, ilevel = 0 }, [469] = { upgrade = 1, max = 4, ilevel = 4 }, [470] = { upgrade = 2, max = 4, ilevel = 8 }, [471] = { upgrade = 3, max = 4, ilevel = 12 }, [472] = { upgrade = 4, max = 4, ilevel = 16 }, [491] = { upgrade = 0, max = 4, ilevel = 0 }, [492] = { upgrade = 1, max = 4, ilevel = 4 }, [493] = { upgrade = 2, max = 4, ilevel = 8 }, [494] = { upgrade = 0, max = 6, ilevel = 0 }, [495] = { upgrade = 1, max = 6, ilevel = 4 }, [496] = { upgrade = 2, max = 6, ilevel = 8 }, [497] = { upgrade = 3, max = 6, ilevel = 12 }, [498] = { upgrade = 4, max = 6, ilevel = 16 }, [503] = { upgrade = 3, max = 3, ilevel = 1 }, [504] = { upgrade = 3, max = 4, ilevel = 12 }, [505] = { upgrade = 4, max = 4, ilevel = 16 }, [506] = { upgrade = 5, max = 6, ilevel = 20 }, [507] = { upgrade = 6, max = 6, ilevel = 24 }, [529] = { upgrade = 0, max = 2, ilevel = 0 }, [530] = { upgrade = 1, max = 2, ilevel = 5 }, [531] = { upgrade = 2, max = 2, ilevel = 10 }, [535] = { upgrade = 1, max = 3, ilevel = 15 }, [536] = { upgrade = 2, max = 3, ilevel = 30 }, [537] = { upgrade = 3, max = 3, ilevel = 45 }, [538] = { upgrade = 0, max = 3, ilevel = 0 }, } do local stub = { ilevel = 0 } setmetatable(upgradeTable, { __index = function(t, key) return stub end}) end -- Tooltip Scanning stuff local itemLevelPattern = _G.ITEM_LEVEL:gsub("%%d", "(%%d+)") local soulboundPattern = _G.ITEM_SOULBOUND local boePattern=_G.ITEM_BIND_ON_EQUIP local bopPattern=_G.ITEM_BIND_ON_PICKUP local boaPattern1=_G.ITEM_BIND_TO_BNETACCOUNT local boaPattern2=_G.ITEM_BNETACCOUNTBOUND local patterns={ [soulboundPattern]="soulbound", [boePattern]="boe", [bopPattern]="bop", [boaPattern1]="boa", [boaPattern2]="boa", } local scanningTooltip local anchor lib.tipCache = lib.tipCache or setmetatable({},{__index=function(table,key) return {} end}) local tipCache = lib.tipCache local emptytable={} local function ScanTip(itemLink,itemLevel,show) if type(itemLink)=="number" then itemLink=CachedGetItemInfo(itemLink,2) if not itemLink then return emptytable end end if type(tipCache[itemLink].ilevel)=="nil"then -- or not tipCache[itemLink].cached then local cacheIt=true if not scanningTooltip then anchor=CreateFrame("Frame") anchor:Hide() scanningTooltip = _G.CreateFrame("GameTooltip", "LibItemUpgradeInfoTooltip", nil, "GameTooltipTemplate") end --scanningTooltip:ClearLines() GameTooltip_SetDefaultAnchor(scanningTooltip,anchor) local itemString=itemLink:match("|H(.-)|h") local rc,message=pcall(scanningTooltip.SetHyperlink,scanningTooltip,itemString) if (not rc) then return emptytable end scanningTooltip:Show() local quality,_,_,class,subclass,_,_,_,_,classIndex,subclassIndex=CachedGetItemInfo(itemLink,3) -- line 1 is the item name -- line 2 may be the item level, or it may be a modifier like "Heroic" -- check up to line 6 just in case local ilevel,soulbound,bop,boe,boa,heirloom if quality==LE_ITEM_QUALITY_ARTIFACT and itemLevel then local relic1, relic2, relic3 = select(4,strsplit(':', itemLink)) if relic1 and relic1 ~= '' and not CachedGetItemInfo(relic1) then cacheIt = false end if relic2 and relic2 ~= '' and not CachedGetItemInfo(relic2) then cacheIt = false end if relic3 and relic3 ~= '' and not CachedGetItemInfo(relic3) then cacheIt = false end ilevel=itemLevel end if show then for i=1,12 do local l, ltext = _G["LibItemUpgradeInfoTooltipTextLeft"..i], nil local r, rtext = _G["LibItemUpgradeInfoTooltipTextRight"..i], nil if l then ltext=l:GetText() rtext=r:GetText() _G.print(i,ltext,' - ',rtext) end end end tipCache[itemLink]={ ilevel=nil, soulbound=nil, bop=nil, boe=nil, boa=nil, cached=cacheIt } local c=tipCache[itemLink] for i = 2, 6 do local label, text = _G["LibItemUpgradeInfoTooltipTextLeft"..i], nil if label then text=label:GetText() end if text then if show then _G.print("|cFFFFFF00".. text .. "|r") end if c.ilevel==nil then c.ilevel = tonumber(text:match(itemLevelPattern)) end for pattern,key in pairs(patterns) do if type(c[key])=="nil" then if text:find(pattern) then if show then _G.print(text , "matched",pattern) end c[key]=true end end end end end c.ilevel=c.ilevel or itemLevel itemLevel=GetDetailedItemLevelInfo(itemLink) if type(c.ilevel)=="number" then c.ilevel=math.max(c.ilevel,itemLevel) else c.ilevel=itemLevel end scanningTooltip:Hide() end return tipCache[itemLink] end -- GetUpgradeID(itemString) -- -- Arguments: -- itemString - String - An itemLink or itemString denoting the item -- -- Returns: -- Number - The upgrade ID (possibly 0), or nil if the input is invalid or -- does not contain upgrade info function lib:GetUpgradeID(itemString) if type(itemString)~="string" then return end local itemString = itemString:match("item[%-?%d:]+") or ""-- Standardize itemlink to itemstring local instaid, _, numBonuses, affixes = select(12, strsplit(":", itemString, 15)) instaid=tonumber(instaid) or 7 numBonuses=tonumber(numBonuses) or 0 if instaid >0 and (instaid-4)%8==0 then return tonumber((select(numBonuses + 1, strsplit(":", affixes)))) end end -- GetCurrentUpgrade(id) -- -- Returns the current upgrade level of the item, e.g. 1 for a 1/2 item. -- -- Arguments: -- id - Number - The upgrade ID of the item (obtained via GetUpgradeID()) -- -- Returns: -- Number - The current upgrade level of the item. Returns nil if the item -- cannot be upgraded function lib:GetCurrentUpgrade(id) return upgradeTable[id].upgrade end -- GetMaximumUpgrade(id) -- -- Returns the maximum upgrade level of the item, e.g. 2 for a 1/2 item. -- -- Arguments: -- id - Number - The upgrade ID of the item (obtained via GetUpgradeID()) -- -- Returns: -- Number - The maximum upgrade level of the item. Returns nil if the item -- cannot be upgraded function lib:GetMaximumUpgrade(id) return upgradeTable[id].max end -- GetItemLevelUpgrade(id) -- -- Returns the item level increase that this upgrade is worth, e.g. 4 for a -- 1/2 item or 8 for a 2/2 item. -- -- Arguments: -- id - Number - The upgrade ID of the item (obtained via GetUpgradeID()) -- -- Returns: -- Number - The item level increase of the item. Returns 0 if the item -- cannot be or has not been upgraded function lib:GetItemLevelUpgrade(id) return upgradeTable[id].ilevel end -- GetItemUpgradeInfo(itemString) -- -- Returns the current upgrade level, maximum upgrade level, and item level -- increase for an item. -- -- Arguments: -- itemString - String - An itemLink or itemString denoting the item -- -- Returns if the item can be upgraded: -- Number - The current upgrade level of the item -- Number - The maximum upgrade level of the item -- Number - The item level increase of the item -- or if the item cannot be upgraded: -- nil -- nil -- 0 -- or if the item is invalid or does not contain upgrade info: -- nil function lib:GetItemUpgradeInfo(itemString) local id = self:GetUpgradeID(itemString) if id then local cur = self:GetCurrentUpgrade(id) local max = self:GetMaximumUpgrade(id) local delta = self:GetItemLevelUpgrade(id) return cur, max, delta end return nil end -- GetHeirloomTrueLevel(itemString) -- -- Returns the true item level for an heirloom (actually, returns the true level for any adapting item) -- -- Arguments: -- itemString - String - An itemLink or itemString denoting the item -- -- Returns: -- Number, Boolean - The true item level of the item. If the item is not -- an heirloom, or an error occurs when trying to scan the -- item tooltip, the second return value is false. Otherwise -- the second return value is true. If the input is invalid, -- (nil, false) is returned. -- Convert the ITEM_LEVEL constant into a pattern for our use function lib:GetHeirloomTrueLevel(itemString) if type(itemString) ~= "string" then return nil,false end local _, itemLink, rarity, itemLevel = CachedGetItemInfo(itemString) if (not itemLink) then return nil,false end local rc=ScanTip(itemLink,itemLevel) if rc.ilevel then return rc.ilevel,true end return itemLevel, false end -- GetUpgradedItemLevel(itemString) -- -- Returns the true item level of the item, including upgrades and heirlooms. -- -- Arguments: -- itemString - String - An itemLink or itemString denoting the item -- -- Returns: -- Number - The true item level of the item, or nil if the input is invalid function lib:GetUpgradedItemLevel(itemString) -- check for heirlooms first local ilvl, isTrue = self:GetHeirloomTrueLevel(itemString) if isTrue then return ilvl end -- not an heirloom? fall back to the regular item logic local id = self:GetUpgradeID(itemString) if ilvl and id then ilvl = ilvl + self:GetItemLevelUpgrade(id) end return ilvl end -- IsBop(itemString) -- -- Check an item for Bind On Pickup. -- -- Arguments: -- itemString - String - An itemLink or itemString denoting the item -- -- Returns: -- Boolean - True if Bind On Pickup function lib:IsBop(itemString) local rc=ScanTip(itemString) return rc.bop end -- IsBoe(itemString) -- -- Check an item for Bind On Equip. -- -- Arguments: -- itemString - String - An itemLink or itemString denoting the item -- -- Returns: -- Boolean - True if Bind On Equip function lib:IsBoe(itemString) local rc=ScanTip(itemString) return rc.boe end -- IsBoa(itemString) -- -- Check an item for Bind On Aaccount -- -- Arguments: -- itemString - String - An itemLink or itemString denoting the item -- -- Returns: -- Boolean - True if Bind On Equip function lib:IsBoa(itemString) local rc=ScanTip(itemString) return rc.boa end -- IsArtifact(itemString) -- -- Check an item for Heirloom -- -- Arguments: -- itemString - String - An itemLink or itemString denoting the item -- -- Returns: -- Boolean - True if Artifact function lib:IsArtifact(itemString) return CachedGetItemInfo(itemString,i_Quality)==LE_ITEM_QUALITY_ARTIFACT end -- GetClassInfoIsHeirloom(itemString) -- -- Retrieve class and subclass -- -- Arguments: -- itemString - String - An itemLink or itemString denoting the item -- -- Returns: -- class,subclass function lib:GetClassInfo(itemString) local rc=ScantTip(itemString) return rc.class,rc.subclass end -- IsHeirloom(itemString) -- -- Check an item for Heirloom -- -- Arguments: -- itemString - String - An itemLink or itemString denoting the item -- -- Returns: -- Boolean - True if Heirloom function lib:IsHeirloom(itemString) return CachedGetItemInfo(itemString,i_Quality) ==LE_ITEM_QUALITY_HEIRLOOM end --- -- Parses an itemlink and returns itemId without calling API again -- @param #lib self -- @param #string itemlink -- @return #number itemId or 0 function lib:GetItemID(itemlink) if (type(itemlink)=="string") then local itemid,context=GetItemInfoFromHyperlink(itemlink) return tonumber(itemid) or 0 --return tonumber(itemlink:match("Hitem:(%d+):")) or 0 else return 0 end end --- -- -- Returns a caching version of GetItemInfo. Can be used to override the original one. -- Adds a second parameter to directly retrieving a specific value -- (Note: internally uses select so it's actually like calling select(n,GetItemInfo(itemID)) -- -- Arguments: -- self #lib self -- -- Returns: -- #function The new function --@do-not-package-- local slots={ INVSLOT_AMMO = INVSLOT_AMMO, INVSLOT_HEAD = INVSLOT_HEAD, INVSLOT_NECK = INVSLOT_NECK, INVSLOT_SHOULDER = INVSLOT_SHOULDER, INVSLOT_BODY = INVSLOT_BODY, INVSLOT_CHEST = INVSLOT_CHEST, INVSLOT_WAIST = INVSLOT_WAIST, INVSLOT_LEGS = INVSLOT_LEGS, INVSLOT_FEET = INVSLOT_FEET, INVSLOT_WRIST = INVSLOT_WRIST, INVSLOT_HAND = INVSLOT_HAND, INVSLOT_FINGER1 = INVSLOT_FINGER1, INVSLOT_FINGER2 = INVSLOT_FINGER2, INVSLOT_TRINKET1 = INVSLOT_TRINKET1, INVSLOT_TRINKET2 = INVSLOT_TRINKET2, INVSLOT_BACK = INVSLOT_BACK, INVSLOT_MAINHAND = INVSLOT_MAINHAND, INVSLOT_OFFHAND = INVSLOT_OFFHAND, INVSLOT_RANGED = INVSLOT_RANGED, INVSLOT_TABARD = INVSLOT_TABARD, } local INVSLOT_FIRST_EQUIPPED = INVSLOT_FIRST_EQUIPPED; local INVSLOT_LAST_EQUIPPED = INVSLOT_LAST_EQUIPPED _G.SLASH_CHECKSLOT1="/checkslot" SlashCmdList['CHECKSLOT'] = function(args,chatframe) _G.print(args) local slot=strsplit(' ',args) if not slot or slot=="" then DevTools_Dump(slots) return end slot=tonumber(slot) local itemlink=GetInventoryItemLink("player",slot) if itemlink then for k,v in pairs(slots) do if slot==v then _G.print("Item in " , k) break end end _G.print(itemlink) DevTools_Dump({GetDetailedItemLevelInfo(itemlink)}) print(itemlink) _G.print(lib:ScanTip(itemlink)) end end function lib:ScanTip(itemLink) --self.itemcache[itemLink]=nil self.tipCache[itemLink]=nil local GameTooltip=_G.LibItemUpgradeInfoTooltip if GameTooltip then GameTooltip_SetDefaultAnchor(GameTooltip, UIParent) GameTooltip:SetHyperlink(itemLink) GameTooltip:Show() end return ScanTip(itemLink,100,true) end function lib:GetCachingGetItemInfo() return CachedGetItemInfo end function lib:GetCacheStats() local c=lib.itemcache local h=c.tot-c.miss local perc=( h>0) and h/c.tot*100 or 0 return c.miss,h,perc end function lib:GetCache() return lib.itemcache end function lib:CleanCache() return wipe(lib.itemcache) end --[===========[ ]===========] --[===[ Debug utilities ]===] --[===========[ ]===========] local function compareTables(t1, t2) local seen = {} for k, v1 in pairs(t1) do seen[k] = true local v2 = rawget(t2, k) if not v2 then return false end if type(v1) ~= type(v2) then return false end if type(v1) == "table" then if not compareTables(v1, v2) then return false end elseif v1 ~= v2 then return false end end for k in pairs(t2) do if not seen[k] then return false end end return true end -- prints the table rows in red and green -- omits the lead { and the trailing } local function printDiffTable(t1, t2) local keys, seen = {}, {} for k in pairs(t1) do keys[#keys+1] = k seen[k] = true end for k in pairs(t2) do if not seen[k] then keys[#keys+1] = k end end table.sort(keys) local function formatTable(t) local comps = {} for k, v in pairs(t) do comps[#comps+1] = ("%s = %d"):format(k, v) end return "{ " .. table.concat(comps, ", ") .. " }" end for _, k in ipairs(keys) do local v1, v2 = rawget(t1, k), rawget(t2, k) local equal if type(v1) == "table" and type(v2) == "table" then equal = compareTables(v1, v2) else equal = v1 == v2 end if not equal then if v1 then pp(("|cffff0000 [%d] = %s,|r"):format(k, formatTable(v1))) end if v2 then pp(("|cff00ff00 [%d] = %s,|r"):format(k, formatTable(v2))) end end end end -- Scans the first 10000 upgrade IDs -- Run this with /run LibStub:GetLibrary("LibItemUpgradeInfo-1.0"):_CheckUpgradeTable() -- If you don't have Aspirant's Staff of Harmony cached it may error out, just try again. do local debugFrame local worker local newTable local debugTooltip function lib:_CheckUpgradeTable(itemLink) if worker then pp("|cffff0000LibItemUpgradeInfo-1.0: upgrade check already in progress") return end if not debugFrame then debugFrame = _G.CreateFrame("frame") debugFrame:Hide() debugFrame:SetScript("OnUpdate", function() local ok, result, count, max = pcall(worker) if not ok or result then debugFrame:Hide() worker = nil end if not ok then pp("|cffff0000LibItemUpgradeInfo-1.0 error: " .. result .. "|r") elseif result then pp("LibItemUpgradeInfo-1.0: scan complete") if compareTables(upgradeTable, newTable) then pp("LibItemUpgradeInfo-1.0: |cff00ff00No changes|r") else pp("LibItemUpgradeInfo-1.0: |cffff0000New table:|r {") printDiffTable(upgradeTable, newTable) pp("}") end else pp("LibItemUpgradeInfo-1.0: scanning " .. count .. "/" .. max) end end) end if not debugTooltip then debugTooltip = _G.CreateFrame("GameTooltip", "LibItemUpgradeInfoDebugTooltip", nil, "GameTooltipTemplate") debugTooltip:SetOwner(_G.WorldFrame, "ANCHOR_NONE") end newTable = {} --local itemLink = "|cff0070dd|Hitem:89551:0:0:0:0:0:0:0:90:253:0:0:1:0|h[Aspirant's Staff of Harmony]|h|r" local itemLink = itemLink or "|cff0070dd|Hitem:89551:0:0:0:0:0:0:0:100:253:4:0:0:0|h[Aspirant's Staff of Harmony]|h|r" -- Livello รจ il 9,upgradeid il 14. Al decimo posto, un valore che deve essere 4 o 4+n *8) per far scattare l'uso dell'upgradeid local itemLevel = select(4, _G.GetItemInfo(itemLink)) assert(itemLevel, "Can't find item level for itemLink") local count, max, batchsize = 0, 10000, 200 worker = function() for i = count, math.min(max, count+batchsize) do local link = itemLink:gsub("%d+|h", i.."|h") debugTooltip:ClearLines() debugTooltip:SetHyperlink(link) local upgrade, max local curLevel, maxLevel = _G.LibItemUpgradeInfoDebugTooltipTextLeft3:GetText():match("^Upgrade Level: (%d+)/(%d+)") local ilvl = tonumber(_G.LibItemUpgradeInfoDebugTooltipTextLeft2:GetText():match("Item Level (%d+)")) if not ilvl then ilvl = tonumber(_G.LibItemUpgradeInfoDebugTooltipTextLeft3:GetText():match("Item Level (%d+)")) end assert(ilvl ~= nil, "Can't find ItemLevel in tooltip: " .. _G.LibItemUpgradeInfoDebugTooltipTextLeft2:GetText()) if curLevel or maxLevel or ilvl ~= itemLevel then newTable[i] = { upgrade = tonumber(curLevel), max = tonumber(maxLevel), ilevel = ilvl - itemLevel } end end count = count + batchsize return (count > max), count, max end debugFrame:Show() end end --@end-do-not-package-- -- vim: set noet sw=4 ts=4: