initial commit
This commit is contained in:
675
LibTSM/Service/AuctionScanClasses/Query.lua
Normal file
675
LibTSM/Service/AuctionScanClasses/Query.lua
Normal file
@@ -0,0 +1,675 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- https://tradeskillmaster.com --
|
||||
-- All Rights Reserved - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
--- AuctionQuery Class.
|
||||
-- A class which is used to build a query to scan the auciton house.
|
||||
-- @classmod AuctionQuery
|
||||
|
||||
local _, TSM = ...
|
||||
local Query = TSM.Init("Service.AuctionScanClasses.Query")
|
||||
local String = TSM.Include("Util.String")
|
||||
local ObjectPool = TSM.Include("Util.ObjectPool")
|
||||
local ItemString = TSM.Include("Util.ItemString")
|
||||
local TempTable = TSM.Include("Util.TempTable")
|
||||
local Table = TSM.Include("Util.Table")
|
||||
local ItemInfo = TSM.Include("Service.ItemInfo")
|
||||
local AuctionHouseWrapper = TSM.Include("Service.AuctionHouseWrapper")
|
||||
local Scanner = TSM.Include("Service.AuctionScanClasses.Scanner")
|
||||
local LibTSMClass = TSM.Include("LibTSMClass")
|
||||
local AuctionQuery = LibTSMClass.DefineClass("AuctionQuery")
|
||||
local private = {
|
||||
objectPool = ObjectPool.New("AUCTION_SCAN_QUERY", AuctionQuery),
|
||||
}
|
||||
local ITEM_SPECIFIC = newproxy()
|
||||
local ITEM_BASE = newproxy()
|
||||
local DEFAULT_SORTS = TSM.IsWowClassic() and
|
||||
{ -- classic
|
||||
"seller",
|
||||
"quantity",
|
||||
"unitprice",
|
||||
} or
|
||||
{ -- retail
|
||||
{ sortOrder = Enum.AuctionHouseSortOrder.Price, reverseSort = false },
|
||||
{ sortOrder = Enum.AuctionHouseSortOrder.Name, reverseSort = false },
|
||||
}
|
||||
local EMPTY_SORTS = {}
|
||||
local INV_TYPES = {
|
||||
CHEST = TSM.IsShadowlands() and Enum.InventoryType.IndexChestType or LE_INVENTORY_TYPE_CHEST_TYPE,
|
||||
ROBE = TSM.IsShadowlands() and Enum.InventoryType.IndexRobeType or LE_INVENTORY_TYPE_ROBE_TYPE,
|
||||
NECK = TSM.IsShadowlands() and Enum.InventoryType.IndexNeckType or LE_INVENTORY_TYPE_NECK_TYPE,
|
||||
FINGER = TSM.IsShadowlands() and Enum.InventoryType.IndexFingerType or LE_INVENTORY_TYPE_FINGER_TYPE,
|
||||
TRINKET = TSM.IsShadowlands() and Enum.InventoryType.IndexTrinketType or LE_INVENTORY_TYPE_TRINKET_TYPE,
|
||||
HOLDABLE = TSM.IsShadowlands() and Enum.InventoryType.IndexHoldableType or LE_INVENTORY_TYPE_HOLDABLE_TYPE,
|
||||
BODY = TSM.IsShadowlands() and Enum.InventoryType.IndexBodyType or LE_INVENTORY_TYPE_BODY_TYPE,
|
||||
CLOAK = TSM.IsShadowlands() and Enum.InventoryType.IndexCloakType or LE_INVENTORY_TYPE_CLOAK_TYPE,
|
||||
}
|
||||
assert(Table.Count(INV_TYPES) == 8)
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Module Functions
|
||||
-- ============================================================================
|
||||
|
||||
function Query.Get()
|
||||
return private.objectPool:Get()
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Class Meta Methods
|
||||
-- ============================================================================
|
||||
|
||||
function AuctionQuery.__init(self)
|
||||
self._str = ""
|
||||
self._strLower = ""
|
||||
self._strMatch = ""
|
||||
self._exact = false
|
||||
self._minQuality = -math.huge
|
||||
self._maxQuality = math.huge
|
||||
self._minLevel = -math.huge
|
||||
self._maxLevel = math.huge
|
||||
self._minItemLevel = -math.huge
|
||||
self._maxItemLevel = math.huge
|
||||
self._class = nil
|
||||
self._subClass = nil
|
||||
self._invType = nil
|
||||
self._classFilter1 = {}
|
||||
self._classFilter2 = {}
|
||||
self._usable = false
|
||||
self._uncollected = false
|
||||
self._upgrades = false
|
||||
self._unlearned = false
|
||||
self._canLearn = false
|
||||
self._minPrice = 0
|
||||
self._maxPrice = math.huge
|
||||
self._items = {}
|
||||
self._customFilters = {}
|
||||
self._isBrowseDoneFunc = nil
|
||||
self._specifiedPage = nil
|
||||
self._getAll = nil
|
||||
self._resolveSellers = false
|
||||
self._callback = nil
|
||||
self._queryTemp = {}
|
||||
self._filtersTemp = {}
|
||||
self._classFiltersTemp = {}
|
||||
self._browseResults = {}
|
||||
self._page = 0
|
||||
end
|
||||
|
||||
function AuctionQuery.Release(self)
|
||||
self._str = ""
|
||||
self._strLower = ""
|
||||
self._strMatch = ""
|
||||
self._exact = false
|
||||
self._minQuality = -math.huge
|
||||
self._maxQuality = math.huge
|
||||
self._minLevel = -math.huge
|
||||
self._maxLevel = math.huge
|
||||
self._minItemLevel = -math.huge
|
||||
self._maxItemLevel = math.huge
|
||||
self._class = nil
|
||||
self._subClass = nil
|
||||
self._invType = nil
|
||||
wipe(self._classFilter1)
|
||||
wipe(self._classFilter2)
|
||||
self._usable = false
|
||||
self._uncollected = false
|
||||
self._upgrades = false
|
||||
self._unlearned = false
|
||||
self._canLearn = false
|
||||
self._minPrice = 0
|
||||
self._maxPrice = math.huge
|
||||
wipe(self._items)
|
||||
wipe(self._customFilters)
|
||||
self._isBrowseDoneFunc = nil
|
||||
self._specifiedPage = nil
|
||||
self._getAll = nil
|
||||
self._resolveSellers = false
|
||||
self._callback = nil
|
||||
wipe(self._queryTemp)
|
||||
wipe(self._filtersTemp)
|
||||
wipe(self._classFiltersTemp)
|
||||
for _, row in pairs(self._browseResults) do
|
||||
row:Release()
|
||||
end
|
||||
wipe(self._browseResults)
|
||||
self._page = 0
|
||||
private.objectPool:Recycle(self)
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Public Class Methods
|
||||
-- ============================================================================
|
||||
|
||||
function AuctionQuery.SetStr(self, str, exact)
|
||||
self._str = str or ""
|
||||
self._strLower = strlower(self._str)
|
||||
self._strMatch = String.Escape(self._strLower)
|
||||
self._exact = exact or false
|
||||
return self
|
||||
end
|
||||
|
||||
function AuctionQuery.SetQualityRange(self, minQuality, maxQuality)
|
||||
self._minQuality = minQuality or -math.huge
|
||||
self._maxQuality = maxQuality or math.huge
|
||||
return self
|
||||
end
|
||||
|
||||
function AuctionQuery.SetLevelRange(self, minLevel, maxLevel)
|
||||
self._minLevel = minLevel or -math.huge
|
||||
self._maxLevel = maxLevel or math.huge
|
||||
return self
|
||||
end
|
||||
|
||||
function AuctionQuery.SetItemLevelRange(self, minItemLevel, maxItemLevel)
|
||||
self._minItemLevel = minItemLevel or -math.huge
|
||||
self._maxItemLevel = maxItemLevel or math.huge
|
||||
return self
|
||||
end
|
||||
|
||||
function AuctionQuery.SetClass(self, class, subClass, invType)
|
||||
self._class = class or nil
|
||||
self._subClass = subClass or nil
|
||||
self._invType = invType or nil
|
||||
return self
|
||||
end
|
||||
|
||||
function AuctionQuery.SetUsable(self, usable)
|
||||
self._usable = usable or false
|
||||
return self
|
||||
end
|
||||
|
||||
function AuctionQuery.SetUncollected(self, uncollected)
|
||||
self._uncollected = uncollected or false
|
||||
return self
|
||||
end
|
||||
|
||||
function AuctionQuery.SetUpgrades(self, upgrades)
|
||||
self._upgrades = upgrades or false
|
||||
return self
|
||||
end
|
||||
|
||||
function AuctionQuery.SetUnlearned(self, unlearned)
|
||||
self._unlearned = unlearned or false
|
||||
return self
|
||||
end
|
||||
|
||||
function AuctionQuery.SetCanLearn(self, canLearn)
|
||||
self._canLearn = canLearn or false
|
||||
return self
|
||||
end
|
||||
|
||||
function AuctionQuery.SetPriceRange(self, minPrice, maxPrice)
|
||||
self._minPrice = minPrice or 0
|
||||
self._maxPrice = maxPrice or math.huge
|
||||
return self
|
||||
end
|
||||
|
||||
function AuctionQuery.SetItems(self, items)
|
||||
wipe(self._items)
|
||||
if type(items) == "table" then
|
||||
for _, itemString in ipairs(items) do
|
||||
local baseItemString = ItemString.GetBaseFast(itemString)
|
||||
self._items[itemString] = ITEM_SPECIFIC
|
||||
if baseItemString ~= itemString then
|
||||
self._items[baseItemString] = self._items[baseItemString] or ITEM_BASE
|
||||
end
|
||||
end
|
||||
elseif type(items) == "string" then
|
||||
local itemString = items
|
||||
local baseItemString = ItemString.GetBaseFast(itemString)
|
||||
self._items[itemString] = ITEM_SPECIFIC
|
||||
if baseItemString ~= itemString then
|
||||
self._items[baseItemString] = self._items[baseItemString] or ITEM_BASE
|
||||
end
|
||||
elseif items ~= nil then
|
||||
error("Invalid items type: "..tostring(items))
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
function AuctionQuery.AddCustomFilter(self, func)
|
||||
self._customFilters[func] = true
|
||||
return self
|
||||
end
|
||||
|
||||
function AuctionQuery.SetIsBrowseDoneFunction(self, func)
|
||||
self._isBrowseDoneFunc = func
|
||||
return self
|
||||
end
|
||||
|
||||
function AuctionQuery.SetPage(self, page)
|
||||
if page == nil then
|
||||
self._specifiedPage = nil
|
||||
elseif type(page) == "number" or page == "FIRST" or page == "LAST" then
|
||||
assert(TSM.IsWowClassic())
|
||||
self._specifiedPage = page
|
||||
else
|
||||
error("Invalid page: "..tostring(page))
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
function AuctionQuery.SetGetAll(self, getAll)
|
||||
-- only currently support GetAll on classic
|
||||
assert(not getAll or TSM.IsWowClassic())
|
||||
self._getAll = getAll
|
||||
return self
|
||||
end
|
||||
|
||||
function AuctionQuery.SetResolveSellers(self, resolveSellers)
|
||||
self._resolveSellers = resolveSellers
|
||||
return self
|
||||
end
|
||||
|
||||
function AuctionQuery.SetCallback(self, callback)
|
||||
self._callback = callback
|
||||
return self
|
||||
end
|
||||
|
||||
function AuctionQuery.Browse(self, forceNoScan)
|
||||
assert(not TSM.IsWowClassic() or not forceNoScan)
|
||||
|
||||
local noScan = forceNoScan or false
|
||||
if not TSM.IsWowClassic() then
|
||||
local numItems = 0
|
||||
for _, itemType in pairs(self._items) do
|
||||
if itemType == ITEM_SPECIFIC then
|
||||
numItems = numItems + 1
|
||||
end
|
||||
end
|
||||
if numItems > 0 and numItems < 500 then
|
||||
-- it's faster to just issue individual item searches instead of a browse query
|
||||
noScan = true
|
||||
end
|
||||
end
|
||||
|
||||
if noScan then
|
||||
assert(not TSM.IsWowClassic())
|
||||
local itemKeys = TempTable.Acquire()
|
||||
for itemString in pairs(self._items) do
|
||||
if itemString == ItemString.GetBaseFast(itemString) then
|
||||
local itemId, battlePetSpeciesId = nil, nil
|
||||
if ItemString.IsPet(itemString) then
|
||||
itemId = ItemString.ToId(ItemString.GetPetCage())
|
||||
battlePetSpeciesId = ItemString.ToId(itemString)
|
||||
else
|
||||
itemId = ItemString.ToId(itemString)
|
||||
battlePetSpeciesId = 0
|
||||
end
|
||||
local itemKey = C_AuctionHouse.MakeItemKey(itemId, 0, 0, battlePetSpeciesId)
|
||||
-- FIX for 9.0.1 bug where MakeItemKey randomly adds an itemLevel which breaks scanning
|
||||
itemKey.itemLevel = 0
|
||||
tinsert(itemKeys, itemKey)
|
||||
end
|
||||
end
|
||||
local future = Scanner.BrowseNoScan(self, itemKeys, self._browseResults, self._callback)
|
||||
TempTable.Release(itemKeys)
|
||||
return future
|
||||
else
|
||||
self._page = 0
|
||||
return Scanner.Browse(self, self._resolveSellers, self._browseResults, self._callback)
|
||||
end
|
||||
end
|
||||
|
||||
function AuctionQuery.GetSearchProgress(self)
|
||||
if TSM.IsWowClassic() then
|
||||
return 1
|
||||
end
|
||||
local progress, totalNum = 0, 0
|
||||
for _, row in pairs(self._browseResults) do
|
||||
progress = progress + row:_GetSearchProgress()
|
||||
totalNum = totalNum + 1
|
||||
end
|
||||
if totalNum == 0 then
|
||||
return 0
|
||||
end
|
||||
return progress / totalNum
|
||||
end
|
||||
|
||||
function AuctionQuery.GetBrowseResults(self, baseItemString)
|
||||
return self._browseResults[baseItemString]
|
||||
end
|
||||
|
||||
function AuctionQuery.ItemSubRowIterator(self, itemString)
|
||||
local result = TempTable.Acquire()
|
||||
local baseItemString = ItemString.GetBaseFast(itemString)
|
||||
local isBaseItemString = itemString == baseItemString
|
||||
local row = self._browseResults[baseItemString]
|
||||
if row then
|
||||
for _, subRow in row:SubRowIterator() do
|
||||
local subRowBaseItemString = subRow:GetBaseItemString()
|
||||
local subRowItemString = subRow:GetItemString()
|
||||
if (isBaseItemString and subRowBaseItemString == itemString) or (not isBaseItemString and subRowItemString == itemString) then
|
||||
tinsert(result, subRow)
|
||||
end
|
||||
end
|
||||
end
|
||||
return TempTable.Iterator(result)
|
||||
end
|
||||
|
||||
function AuctionQuery.GetCheapestSubRow(self, itemString)
|
||||
assert(not TSM.IsWowClassic())
|
||||
local cheapest, cheapestItemBuyout = nil, nil
|
||||
for _, subRow in self:ItemSubRowIterator(itemString) do
|
||||
local quantity = subRow:GetQuantities()
|
||||
local _, numOwnerItems = subRow:GetOwnerInfo()
|
||||
local _, itemBuyout = subRow:GetBuyouts()
|
||||
if numOwnerItems ~= quantity and itemBuyout < (cheapestItemBuyout or math.huge) then
|
||||
cheapest = subRow
|
||||
cheapestItemBuyout = itemBuyout
|
||||
end
|
||||
end
|
||||
return cheapest
|
||||
end
|
||||
|
||||
function AuctionQuery.BrowseResultsIterator(self)
|
||||
return pairs(self._browseResults)
|
||||
end
|
||||
|
||||
function AuctionQuery.RemoveResultRow(self, row)
|
||||
local baseItemString = row:GetBaseItemString()
|
||||
assert(baseItemString and self._browseResults[baseItemString])
|
||||
self._browseResults[baseItemString] = nil
|
||||
row:Release()
|
||||
if self._callback then
|
||||
self._callback(self)
|
||||
end
|
||||
end
|
||||
|
||||
function AuctionQuery.Search(self, row, useCachedData)
|
||||
assert(not TSM.IsWowClassic())
|
||||
assert(self._browseResults)
|
||||
return Scanner.Search(self, self._resolveSellers, useCachedData, row, self._callback)
|
||||
end
|
||||
|
||||
function AuctionQuery.CancelBrowseOrSearch(self)
|
||||
Scanner.Cancel()
|
||||
end
|
||||
|
||||
function AuctionQuery.ItemIterator(self)
|
||||
return private.ItemIteratorHelper, self._items, nil
|
||||
end
|
||||
|
||||
function AuctionQuery.WipeBrowseResults(self)
|
||||
for _, row in pairs(self._browseResults) do
|
||||
row:Release()
|
||||
end
|
||||
wipe(self._browseResults)
|
||||
if self._callback then
|
||||
self._callback(self)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Private Class Methods
|
||||
-- ============================================================================
|
||||
|
||||
function AuctionQuery._SetSort(self)
|
||||
if not TSM.IsWowClassic() then
|
||||
return true
|
||||
end
|
||||
|
||||
local sorts = (type(self._specifiedPage) == "string" or self._getAll) and EMPTY_SORTS or DEFAULT_SORTS
|
||||
|
||||
if GetAuctionSort("list", #sorts + 1) == nil then
|
||||
local properlySorted = true
|
||||
for i, col in ipairs(sorts) do
|
||||
local sortCol, sortReversed = GetAuctionSort("list", #sorts - i + 1)
|
||||
-- we never care to reverse a sort so if it's reversed then it's not properly sorted
|
||||
if sortCol ~= col or sortReversed then
|
||||
properlySorted = false
|
||||
break
|
||||
end
|
||||
end
|
||||
if properlySorted then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
SortAuctionClearSort("list")
|
||||
for _, col in ipairs(sorts) do
|
||||
SortAuctionSetSort("list", col, false)
|
||||
end
|
||||
SortAuctionApplySort("list")
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function AuctionQuery._SendWowQuery(self)
|
||||
-- build the class filters
|
||||
wipe(self._classFiltersTemp)
|
||||
wipe(self._classFilter1)
|
||||
wipe(self._classFilter2)
|
||||
if self._invType == INV_TYPES.CHEST or self._invType == INV_TYPES.ROBE then
|
||||
-- default AH only sends in queries for robe chest type, we need to mimic this when using a chest filter
|
||||
self._classFilter1.classID = LE_ITEM_CLASS_ARMOR
|
||||
self._classFilter1.subClassID = self._subClass
|
||||
self._classFilter1.inventoryType = INV_TYPES.CHEST
|
||||
tinsert(self._classFiltersTemp, self._classFilter1)
|
||||
self._classFilter2.classID = LE_ITEM_CLASS_ARMOR
|
||||
self._classFilter2.subClassID = self._subClass
|
||||
self._classFilter2.inventoryType = INV_TYPES.ROBE
|
||||
tinsert(self._classFiltersTemp, self._classFilter2)
|
||||
elseif self._invType == INV_TYPES.NECK or self._invType == INV_TYPES.FINGER or self._invType == INV_TYPES.TRINKET or self._invType == INV_TYPES.HOLDABLE or self._invType == INV_TYPES.BODY then
|
||||
self._classFilter1.classID = LE_ITEM_CLASS_ARMOR
|
||||
self._classFilter1.subClassID = LE_ITEM_ARMOR_GENERIC
|
||||
self._classFilter1.inventoryType = self._invType
|
||||
tinsert(self._classFiltersTemp, self._classFilter1)
|
||||
elseif self._invType == INV_TYPES.CLOAK then
|
||||
self._classFilter1.classID = LE_ITEM_CLASS_ARMOR
|
||||
self._classFilter1.subClassID = LE_ITEM_ARMOR_CLOTH
|
||||
self._classFilter1.inventoryType = self._invType
|
||||
tinsert(self._classFiltersTemp, self._classFilter1)
|
||||
elseif self._class then
|
||||
self._classFilter1.classID = self._class
|
||||
self._classFilter1.subClassID = self._subClass
|
||||
self._classFilter1.inventoryType = self._invType
|
||||
tinsert(self._classFiltersTemp, self._classFilter1)
|
||||
end
|
||||
|
||||
-- build the query
|
||||
local minLevel = self._minLevel ~= -math.huge and self._minLevel or nil
|
||||
local maxLevel = self._maxLevel ~= math.huge and self._maxLevel or nil
|
||||
if TSM.IsWowClassic() then
|
||||
if self._specifiedPage == "LAST" then
|
||||
self._page = max(ceil(select(2, GetNumAuctionItems("list")) / NUM_AUCTION_ITEMS_PER_PAGE) - 1, 0)
|
||||
elseif self._specifiedPage == "FIRST" then
|
||||
self._page = 0
|
||||
elseif self._specifiedPage then
|
||||
self._page = self._specifiedPage
|
||||
end
|
||||
local minQuality = self._minQuality == -math.huge and 0 or self._minQuality
|
||||
return AuctionHouseWrapper.QueryAuctionItems(self._str, minLevel, maxLevel, self._page, self._usable, minQuality, self._getAll, self._exact, self._classFiltersTemp)
|
||||
else
|
||||
wipe(self._filtersTemp)
|
||||
if self._uncollected then
|
||||
tinsert(self._filtersTemp, Enum.AuctionHouseFilter.UncollectedOnly)
|
||||
end
|
||||
if self._usable then
|
||||
tinsert(self._filtersTemp, Enum.AuctionHouseFilter.UsableOnly)
|
||||
end
|
||||
if self._upgrades then
|
||||
tinsert(self._filtersTemp, Enum.AuctionHouseFilter.UpgradesOnly)
|
||||
end
|
||||
if self._exact then
|
||||
tinsert(self._filtersTemp, Enum.AuctionHouseFilter.ExactMatch)
|
||||
end
|
||||
local minQuality = self._minQuality == -math.huge and 0 or self._minQuality
|
||||
for i = minQuality + Enum.AuctionHouseFilter.PoorQuality, min(self._maxQuality + Enum.AuctionHouseFilter.PoorQuality, Enum.AuctionHouseFilter.ArtifactQuality) do
|
||||
tinsert(self._filtersTemp, i)
|
||||
end
|
||||
wipe(self._queryTemp)
|
||||
self._queryTemp.searchString = self._str
|
||||
self._queryTemp.minLevel = minLevel
|
||||
self._queryTemp.maxLevel = maxLevel
|
||||
self._queryTemp.sorts = DEFAULT_SORTS
|
||||
self._queryTemp.filters = self._filtersTemp
|
||||
self._queryTemp.itemClassFilters = self._classFiltersTemp
|
||||
return AuctionHouseWrapper.SendBrowseQuery(self._queryTemp)
|
||||
end
|
||||
end
|
||||
|
||||
function AuctionQuery._IsFiltered(self, row, isSubRow, itemKey)
|
||||
local baseItemString = row:GetBaseItemString()
|
||||
local itemString = row:GetItemString()
|
||||
assert(baseItemString)
|
||||
local name, quality, itemLevel, maxItemLevel = row:GetItemInfo(itemKey)
|
||||
local _, itemBuyout, minItemBuyout = row:GetBuyouts(itemKey)
|
||||
if row:IsSubRow() and itemBuyout == 0 then
|
||||
_, itemBuyout = row:GetBidInfo()
|
||||
end
|
||||
|
||||
if next(self._items) then
|
||||
if not self._items[baseItemString] then
|
||||
return true
|
||||
end
|
||||
if isSubRow and itemString and self._items[itemString] ~= ITEM_SPECIFIC and self._items[baseItemString] ~= ITEM_SPECIFIC then
|
||||
return true
|
||||
elseif not isSubRow and itemString and not self._items[itemString] then
|
||||
return true
|
||||
end
|
||||
end
|
||||
if self._str ~= "" and name then
|
||||
name = strlower(name)
|
||||
if not strmatch(name, self._strMatch) or (self._exact and name ~= self._strLower) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
if self._minLevel ~= -math.huge or self._maxLevel ~= math.huge then
|
||||
local minLevel = TSM.IsShadowlands() and ItemString.IsPet(baseItemString) and (itemLevel or maxItemLevel) or ItemInfo.GetMinLevel(baseItemString)
|
||||
if minLevel < self._minLevel or minLevel > self._maxLevel then
|
||||
return true
|
||||
end
|
||||
end
|
||||
if itemLevel and (itemLevel < self._minItemLevel or itemLevel > self._maxItemLevel) then
|
||||
return true
|
||||
end
|
||||
if maxItemLevel and maxItemLevel < self._minItemLevel then
|
||||
return true
|
||||
end
|
||||
if quality and (quality < self._minQuality or quality > self._maxQuality) then
|
||||
return true
|
||||
end
|
||||
if self._class and ItemInfo.GetClassId(baseItemString) ~= self._class then
|
||||
return true
|
||||
end
|
||||
if self._subClass and ItemInfo.GetSubClassId(baseItemString) ~= self._subClass then
|
||||
return true
|
||||
end
|
||||
if self._invType and ItemInfo.GetInvSlotId(baseItemString) ~= self._invType then
|
||||
return true
|
||||
end
|
||||
if self._unlearned and CanIMogIt:PlayerKnowsTransmog(ItemInfo.GetLink(baseItemString)) then
|
||||
return true
|
||||
end
|
||||
if self._canLearn and not CanIMogIt:CharacterCanLearnTransmog(ItemInfo.GetLink(baseItemString)) then
|
||||
return true
|
||||
end
|
||||
if itemBuyout and (itemBuyout < self._minPrice or itemBuyout > self._maxPrice) then
|
||||
return true
|
||||
end
|
||||
if minItemBuyout and minItemBuyout > self._maxPrice then
|
||||
return true
|
||||
end
|
||||
for func in pairs(self._customFilters) do
|
||||
if func(self, row, isSubRow, itemKey) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function AuctionQuery._BrowseIsDone(self, isRetry)
|
||||
if TSM.IsWowClassic() then
|
||||
local numAuctions, totalAuctions = GetNumAuctionItems("list")
|
||||
if totalAuctions <= NUM_AUCTION_ITEMS_PER_PAGE and numAuctions ~= totalAuctions then
|
||||
-- there are cases where we get (0, 1) from the API - no idea why so just assume we're not done
|
||||
return false
|
||||
end
|
||||
local numPages = ceil(totalAuctions / NUM_AUCTION_ITEMS_PER_PAGE)
|
||||
if self._getAll then
|
||||
return true
|
||||
end
|
||||
if self._specifiedPage then
|
||||
if isRetry then
|
||||
return false
|
||||
end
|
||||
-- check if we're on the right page
|
||||
local specifiedPage = (self._specifiedPage == "FIRST" and 0) or (self._specifiedPage == "LAST" and numPages - 1) or self._specifiedPage
|
||||
return self._page == specifiedPage
|
||||
elseif self._isBrowseDoneFunc and self._isBrowseDoneFunc(self) then
|
||||
return true
|
||||
else
|
||||
return self._page >= numPages
|
||||
end
|
||||
else
|
||||
if self._isBrowseDoneFunc and self._isBrowseDoneFunc(self) then
|
||||
return true
|
||||
end
|
||||
return C_AuctionHouse.HasFullBrowseResults()
|
||||
end
|
||||
end
|
||||
|
||||
function AuctionQuery._BrowseIsPageValid(self)
|
||||
if TSM.IsWowClassic() then
|
||||
if self._specifiedPage then
|
||||
return self:_BrowseIsDone()
|
||||
else
|
||||
return true
|
||||
end
|
||||
else
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
function AuctionQuery._BrowseRequestMore(self, isRetry)
|
||||
if TSM.IsWowClassic() then
|
||||
assert(not self._getAll)
|
||||
if self._specifiedPage then
|
||||
return self:_SendWowQuery()
|
||||
end
|
||||
if not isRetry then
|
||||
self._page = self._page + 1
|
||||
end
|
||||
return self:_SendWowQuery()
|
||||
else
|
||||
return AuctionHouseWrapper.RequestMoreBrowseResults()
|
||||
end
|
||||
end
|
||||
|
||||
function AuctionQuery._OnSubRowRemoved(self, row)
|
||||
local baseItemString = row:GetBaseItemString()
|
||||
assert(row == self._browseResults[baseItemString])
|
||||
if row:GetNumSubRows() == 0 then
|
||||
self._browseResults[baseItemString] = nil
|
||||
row:Release()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Private Helper Functions
|
||||
-- ============================================================================
|
||||
|
||||
function private.ItemIteratorHelper(items, index)
|
||||
while true do
|
||||
local itemString, itemType = next(items, index)
|
||||
if not itemString then
|
||||
return
|
||||
elseif itemType == ITEM_SPECIFIC then
|
||||
return itemString
|
||||
end
|
||||
index = itemString
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user