-- ------------------------------------------------------------------------------ -- -- TradeSkillMaster -- -- https://tradeskillmaster.com -- -- All Rights Reserved - Detailed license information included with addon. -- -- ------------------------------------------------------------------------------ -- local _, TSM = ... local QueryUtil = TSM.Init("Service.AuctionScanClasses.QueryUtil") local TempTable = TSM.Include("Util.TempTable") local Log = TSM.Include("Util.Log") local ItemString = TSM.Include("Util.ItemString") local Threading = TSM.Include("Service.Threading") local ItemInfo = TSM.Include("Service.ItemInfo") local Query = TSM.Include("Service.AuctionScanClasses.Query") local private = { itemListSortValue = {}, } local MAX_ITEM_INFO_RETRIES = 30 -- ============================================================================ -- Module Functions -- ============================================================================ function QueryUtil.GenerateThreaded(itemList, callback, context) -- get all the item info into the game's cache for _ = 1, MAX_ITEM_INFO_RETRIES do local isMissingItemInfo = false for _, itemString in ipairs(itemList) do if not private.HasInfo(itemString) then isMissingItemInfo = true end Threading.Yield() end if not isMissingItemInfo then break end Threading.Sleep(0.1) end -- remove items we're missing info for for i = #itemList, 1, -1 do if not private.HasInfo(itemList[i]) then Log.Err("Missing item info for %s", itemList[i]) tremove(itemList, i) end Threading.Yield() end if #itemList == 0 then return end -- add all the items if TSM.IsWowClassic() then for _, itemString in ipairs(itemList) do private.GenerateQuery(callback, context, itemString, private.GetItemQueryInfo(itemString)) end else -- sort the item list so all base items are grouped together but keep relative ordering between base items the same wipe(private.itemListSortValue) for i, itemString in ipairs(itemList) do local baseItemString = ItemString.GetBaseFast(itemString) private.itemListSortValue[baseItemString] = private.itemListSortValue[baseItemString] or i private.itemListSortValue[itemString] = private.itemListSortValue[baseItemString] end sort(itemList, private.ItemListSortHelper) local currentBaseItemString = nil local currentItems = TempTable.Acquire() for _, itemString in ipairs(itemList) do local baseItemString = ItemString.GetBaseFast(itemString) assert(baseItemString) if baseItemString == currentBaseItemString then -- same base item tinsert(currentItems, itemString) else -- new base item if currentBaseItemString then private.GenerateQuery(callback, context, currentItems, ItemInfo.GetName(currentBaseItemString)) wipe(currentItems) end currentBaseItemString = baseItemString tinsert(currentItems, itemString) end end if currentBaseItemString then private.GenerateQuery(callback, context, currentItems, ItemInfo.GetName(currentBaseItemString)) wipe(currentItems) end TempTable.Release(currentItems) end end -- ============================================================================ -- Private Helper Functions -- ============================================================================ function private.GetItemQueryInfo(itemString) local name = ItemInfo.GetName(itemString) local level = ItemInfo.GetMinLevel(itemString) or 0 local quality = ItemInfo.GetQuality(itemString) local classId = ItemInfo.GetClassId(itemString) or 0 local subClassId = ItemInfo.GetSubClassId(itemString) or 0 -- Ignoring level because level can now vary if itemString == ItemString.GetBase(itemString) and (classId == LE_ITEM_CLASS_WEAPON or classId == LE_ITEM_CLASS_ARMOR or (classId == LE_ITEM_CLASS_GEM and subClassId == LE_ITEM_GEM_ARTIFACTRELIC)) then level = nil end return name, level, level, quality, classId, subClassId end function private.HasInfo(itemString) return ItemInfo.GetName(itemString) and ItemInfo.GetQuality(itemString) and ItemInfo.GetMinLevel(itemString) end function private.GenerateQuery(callback, context, items, name, minLevel, maxLevel, quality, class, subClass) local query = Query.Get() :SetStr(name, false) :SetQualityRange(quality, quality) :SetLevelRange(minLevel, maxLevel) :SetClass(class, subClass) :SetItems(items) callback(query, context) end function private.ItemListSortHelper(a, b) local aSortValue = private.itemListSortValue[a] local bSortValue = private.itemListSortValue[b] if aSortValue ~= bSortValue then return aSortValue < bSortValue end return a < b end