diff --git a/ItemScanner.lua b/ItemScanner.lua index 00ee536..969fa74 100644 --- a/ItemScanner.lua +++ b/ItemScanner.lua @@ -1,4 +1,4 @@ -local minItem, maxItem, chunkSize = 1, 99999, 20000 +local minItem, maxItem, chunkSize, minSuffix, maxSuffix = 1, 99999, 20000, -500, 3000 local CONSECUTIVE_INVALID_TO_IGNORE = 5 local VALID_DELAY = 0.025 local INVALID_DELAY = 10 @@ -79,6 +79,12 @@ local function scanItemLink(link, tooltip, threadNumber) if IS_item_info[link] and #(IS_item_info[link]) >= tooltip:NumLines() then return true end + -- Avoids recording blank random suffixes + if link:find("^item:11993:") and not link:find("^item:11993:0:0:0:0:0:0:") then + if _G[tooltipName .. "TextLeft1"]:GetText():find("^Clay Ring ?$") and tooltip:NumLines() == 5 then + return false + end + end IS_item_info[link] = { itemInfo = {GetItemInfo(link)}, @@ -143,6 +149,17 @@ local function OnUpdate(self) else self.itemco = nil end + elseif self.suffco then + status, err = pcall(self.suffco) + if status == false then + print("ItemScanner: suffix scan error, aborting.") + self.suffco = nil + IS_status.suffixes.scan_active = false + error(err) + return + elseif err == true then + self.suffco = nil + end else frame:SetScript("OnUpdate", nil) end @@ -241,8 +258,80 @@ local function itemParseCoroutine(start, tooltip, threadNumber) return true end +local function suffixParseCoroutine(start, tooltip) + IS_status.suffixes.scan_active = true + IS_status.suffixes.finished = false + coroutine.yield() + local startTime = GetTime() + local roundStartTime = startTime + local numProcessed, roundNumProcessed, valid, roundValid = 0, 0, 0, 0 + print(string.format("ItemScanner: starting scan at suffix %d", start)) + + local function scan(i, scanningAll) + IS_status.suffixes.last_scanned = i + local itemStartTime = GetTime() + if scanItemLink("item:11993:0:0:0:0:0:" .. i .. ":100:85", tooltip) then + if scanningAll then + if IS_status.suffixes.invalid[i] ~= false then + valid, roundValid = valid + 1, roundValid + 1 + end + else + IS_status.suffixes.last_valid = i + valid, roundValid = valid + 1, roundValid + 1 + end + -- Reset invalid count + IS_status.suffixes.invalid[i] = false + else + -- start with 3 if no previous value + IS_status.suffixes.invalid[i] = (IS_status.suffixes.invalid[i] or 2) + 1 + end + numProcessed = numProcessed + 1 + roundNumProcessed = roundNumProcessed + 1 + while GetTime() - itemStartTime < VALID_DELAY do + coroutine.yield() + end + + local currentTime = GetTime() + if currentTime - roundStartTime >= 120 then + local elapsedTime = currentTime - startTime + print(string.format("ItemScanner: at suffix %d, %d in %.1f sec. (%.2f/min.) (%d valid), %d this round (%d valid)", i, numProcessed, elapsedTime, numProcessed / elapsedTime * 60, valid, roundNumProcessed, roundValid)) + roundStartTime = roundStartTime + 120 + roundNumProcessed, roundValid = 0, 0 + end + end + + for i = start, maxSuffix do + if not IS_status.suffixes.invalid[i] or (type(IS_status.suffixes.invalid[i]) == "number" and IS_status.suffixes.invalid[i] < CONSECUTIVE_INVALID_TO_IGNORE) then + if not IS_status.suffixes.scan_active then + break + end + scan(i, false) + end + end + IS_status.suffixes.finished = true + while IS_status.suffixes.scan_active do + local i = (IS_status.suffixes.last_invalid or minSuffix - 1) + repeat + i = i + 1 + if i > maxSuffix then + i = minSuffix + end + until IS_status.suffixes.invalid[i] ~= true + IS_status.suffixes.last_invalid = i + scan(i, true) + end + + local elapsedTime = GetTime() - startTime + print(string.format("ItemScanner: scan stopped at suffix %d, %d in %.1f sec. (%.2f/min.) (%d valid)", IS_status.suffixes.last_scanned, numProcessed, elapsedTime, numProcessed / elapsedTime * 60, valid)) + + return true +end + local function commandHandler(msg) - if string.match(msg, "^debug") then + if string.match(msg, "^all") then + commandHandler(string.gsub(msg, "all", "items")) + commandHandler(string.gsub(msg, "all", "suffixes")) + elseif string.match(msg, "^debug") then if IS_status.items.scan_active then if IS_status.items.finished then print("Scanning all items with " .. #(frame.itemco) .. " threads") @@ -253,6 +342,13 @@ local function commandHandler(msg) local currentTime = GetTime() print("roundTime = " .. tostring(currentTime - roundStartTime)) print("elapsedTime = " .. tostring(currentTime - startTime)) + elseif IS_status.suffixes.scan_active then + if IS_status.suffixes.finished then + print("Scanning all random suffixes") + else + print("Scanning known valid random suffixes") + end + print("Last suffix: " .. tostring(IS_status.suffixes.last_scanned or "none")) else print("Scanning not active") return @@ -291,8 +387,8 @@ local function commandHandler(msg) return else print("Usage: /is items <arg> (or /itemscanner items <arg>") - print(" clear clears item data but does not stop a running scan") - print(" reset clears item data and starts over") + print(" clear clears item and suffix data but does not stop a running scan") + print(" reset clears item and suffix data and starts over") print(" restart restarts the current scan but leaves existing data intact") print(" start (default) starts where you last left off") print(" stop stops scanning but leaves existing data intact") @@ -309,10 +405,47 @@ local function commandHandler(msg) frame.itemco[i](start + i - 1, tooltip, i) end frame:SetScript("OnUpdate", OnUpdate) + elseif string.match(msg, "^suffixes") then + local start + + if msg == "suffixes" or msg == "suffixes start" then + start = IS_status.suffixes.last_valid or IS_status.suffixes.last_scanned or minSuffix + elseif msg == "suffixes clear" then + IS_status.suffixes.last_scanned = nil + IS_status.suffixes.last_valid = nil + return + elseif msg == "suffixes reset" then + commandHandler("suffixes restart") + return + elseif msg == "suffixes restart" then + start = minSuffix + IS_status.suffixes.last_scanned = nil + IS_status.suffixes.last_valid = nil + elseif msg == "suffixes stop" then + IS_status.suffixes.scan_active = false + return + else + print("Usage: /is suffixes <arg> (or /itemscanner suffixes <arg>") + print(" clear clears suffix progress but does not stop a running scan") + print(" reset clears suffix progress and starts over") + print(" restart restarts the current scan but leaves existing data intact") + print(" start (default) starts where you last left off") + print(" stop stops scanning but leaves existing data intact") + return + end + frame.suffco = coroutine.wrap(suffixParseCoroutine) + local tooltip = _G["ItemScannerHiddenTooltip1"] + if not tooltip then + tooltip = CreateFrame("GameTooltip", "ItemScannerHiddenTooltip1", nil, "ItemScannerHiddenTooltip") + end + frame.suffco(start, tooltip) + frame:SetScript("OnUpdate", OnUpdate) else print("Usage: /is <arg> (or /itemscanner <arg>") + print(" all scans all scannable objects") print(" debug prints scanning status") print(" items scans all items") + print(" suffixes scans all random suffixes") end end @@ -336,6 +469,14 @@ if not IS_status.items.last_invalid then IS_status.items.last_invalid = {} end +if not IS_status.suffixes then + IS_status.suffixes = {} +end + +if not IS_status.suffixes.invalid then + IS_status.suffixes.invalid = {} +end + SLASH_ITEMSCANNER1="/is" SLASH_ITEMSCANNER2="/itemscanner" SlashCmdList["ITEMSCANNER"] = commandHandler @@ -353,9 +494,17 @@ local function resume() commandHandler("items") end end - if not frame.itemco then - print("Nothing seems to be active, restarting") - commandHandler("items reset") + if IS_status.suffixes.scan_active then + if IS_status.suffixes.finished then + IS_status.suffixes.scan_active = false + IS_status.suffixes.finished = false + else + commandHandler("suffixes") + end + end + if not frame.itemco and not frame.suffco then + print("Nothing seems to be active, restarting all") + commandHandler("all reset") end end diff --git a/get-live-data.lua b/get-live-data.lua index 12996ef..531efa4 100644 --- a/get-live-data.lua +++ b/get-live-data.lua @@ -14,6 +14,7 @@ if not ItemsThatNeedManualIntervention then end IS_invalid_items = IS_status.items.invalid +IS_invalid_suffixes = IS_status.suffixes.invalid for k, v in pairs(item_info) do if IS_item_info[k] then @@ -41,7 +42,23 @@ for k, v in pairs(item_info) do end IS_item_info[k] = v else - ItemsThatNeedManualIntervention[k] = string.format("Unknown item link format: %q", k) + local start, _, suffNum = k:find("^item:11993:0:0:0:0:0:(%-?%d+):100:") + if start then + suffNum = tonumber(suffNum) + if type(IS_invalid_suffixes[suffNum]) == "number" then + if IS_invalid_suffixes[suffNum] > 10 then + v = nil + ItemsThatNeedManualIntervention[k] = nil + end + elseif IS_invalid_suffixes[suffNum] == true then + ItemsThatNeedManualIntervention[k] = "Exists in old data, but marked definitely invalid" + elseif IS_invalid_suffixes[suffNum] ~= false and IS_invalid_suffixes[suffNum] ~= nil then + ItemsThatNeedManualIntervention[k] = string.format("Unhandled invalid suffix type: %s (tostring = %q)", type(IS_invalid_suffixes[suffNum]), tostring(IS_invalid_suffixes[suffNum])) + end + IS_item_info[k] = v + else + ItemsThatNeedManualIntervention[k] = string.format("Unknown item link format: %q", k) + end end end end @@ -50,6 +67,7 @@ loadfile("sort.lua")() local tbl = { ["^item:%d%d?%d?:0:0:0:0:0:0:0:"] = "00000_00999", + ["^item:11993:0:0:0:0:0:%-?%d+:100:"] = "suffixes", } for i = 1, 99 do local padded = string.sub("00" .. i, -2) @@ -59,6 +77,7 @@ end local savedVars = { ["IS_item_info"] = {"scanned/item-info-%s.lua", tbl}, ["IS_invalid_items"] = "scanned/invalid-items.lua", + ["IS_invalid_suffixes"] = "scanned/invalid-suffixes.lua", ["ItemsThatNeedManualIntervention"] = "scanned/ItemsThatNeedManualIntervention.lua", } diff --git a/load-all-item-info.lua b/load-all-item-info.lua index 41706dd..7517e9a 100644 --- a/load-all-item-info.lua +++ b/load-all-item-info.lua @@ -24,3 +24,11 @@ while func do finish = padInteger(i + INCREMENT - 1) func = loadfile(string.format("scanned/item-info-%s_%s.lua", start, finish)) end + +func = loadfile("scanned/item-info-suffixes.lua") +if func then + func() + for k, v in pairs(_G["IS_item_info_suffixes"] or {}) do + item_info[k] = v + end +end