diff --git a/ItemScanner.lua b/ItemScanner.lua index c83bde0..048259d 100644 --- a/ItemScanner.lua +++ b/ItemScanner.lua @@ -1,4 +1,4 @@ -local minItem, maxItem, chunkSize, minSuffix, maxSuffix = 1, 99999, 20000, -500, 3000 +local minItem, maxItem, chunkSize, minSuffix, maxSuffix, minGem, maxGem = 1, 99999, 20000, -500, 3000, 1, 6000 local CONSECUTIVE_INVALID_TO_IGNORE = 5 local VALID_DELAY = 0.025 local INVALID_DELAY = 10 @@ -119,6 +119,15 @@ local function scanItemLink(link, tooltip, threadNumber) return true end +local function scanGem(gemId) + local results = {GetItemGem("item:25:0:" .. gemId .. ":0:0:0:0:0:0:0", 1)} + for _ in pairs(results) do + IS_gem_info[gemId] = results + return true + end + return false +end + local frame = CreateFrame("Frame") local nextSlot = 1 local function OnUpdate(self) @@ -160,6 +169,17 @@ local function OnUpdate(self) elseif err == true then self.suffco = nil end + elseif self.gemco then + status, err = pcall(self.gemco) + if status == false then + print("ItemScanner: gem scan error, aborting.") + self.gemco = nil + IS_status.gems.scan_active = false + error(err) + return + elseif err == true then + self.gemco = nil + end else frame:SetScript("OnUpdate", nil) end @@ -256,10 +276,83 @@ local function genericCoroutine(start, min, max, name, linkTemplate, delay, stat return true end +local function gemParseCoroutine(start) + IS_status.gems.scan_active = true + IS_status.gems.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 gem %d", start)) + + local function scan(i, scanningAll) + IS_status.gems.last_scanned = i + local itemStartTime = GetTime() + if scanGem(i) then + if scanningAll then + if IS_status.gems.invalid[i] ~= false then + valid, roundValid = valid + 1, roundValid + 1 + end + else + IS_status.gems.last_valid = i + valid, roundValid = valid + 1, roundValid + 1 + end + -- Reset invalid count + IS_status.gems.invalid[i] = false + else + -- start with 3 if no previous value + IS_status.gems.invalid[i] = (IS_status.gems.invalid[i] or 2) + 1 + end + while GetTime() - itemStartTime < VALID_DELAY do + coroutine.yield() + end + numProcessed = numProcessed + 1 + roundNumProcessed = roundNumProcessed + 1 + + local currentTime = GetTime() + if currentTime - roundStartTime >= 120 then + local elapsedTime = currentTime - startTime + print(string.format("ItemScanner: at gem %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, maxGem do + if not IS_status.gems.invalid[i] or (type(IS_status.gems.invalid[i]) == "number" and IS_status.gems.invalid[i] < CONSECUTIVE_INVALID_TO_IGNORE) then + if not IS_status.gems.scan_active then + break + end + scan(i, false) + end + end + IS_status.gems.finished = true + while IS_status.gems.scan_active do + local i = (IS_status.gems.last_invalid or minGem - 1) + repeat + i = i + 1 + if i > maxGem then + i = minGem + end + until IS_status.gems.invalid[i] ~= true + IS_status.gems.last_invalid = i + scan(i, true) + end + + local elapsedTime = GetTime() - startTime + if elapsedTime == 0 then + elapsedTime = 0.001 + end + print(string.format("ItemScanner: scan stopped at gem %d, %d in %.1f sec. (%.2f/min.) (%d valid)", IS_status.gems.last_scanned, numProcessed, elapsedTime, numProcessed / elapsedTime * 60, valid)) + + return true +end + local function commandHandler(msg) if string.match(msg, "^all") then commandHandler(string.gsub(msg, "all", "items")) commandHandler(string.gsub(msg, "all", "suffixes")) + commandHandler(string.gsub(msg, "all", "gems")) elseif string.match(msg, "^debug") then if IS_status.items.scan_active then if IS_status.items.finished then @@ -275,6 +368,13 @@ local function commandHandler(msg) print("Scanning known valid random suffixes") end print("Last suffix: " .. tostring(IS_status.suffixes.last_scanned or "none")) + elseif IS_status.gems.scan_active then + if IS_status.gems.finished then + print("Scanning all gems") + else + print("Scanning known valid gems") + end + print("Last gem: " .. tostring(IS_status.gems.last_scanned or "none")) else print("Scanning not active") return @@ -282,6 +382,39 @@ local function commandHandler(msg) local currentTime = GetTime() print("roundTime = " .. tostring(currentTime - roundStartTime)) print("elapsedTime = " .. tostring(currentTime - startTime)) + elseif string.match(msg, "^gems") then + local start + + if msg == "gems" or msg == "gems start" then + start = IS_status.gems.last_valid or IS_status.gems.last_scanned or minGem + elseif msg == "gems clear" then + IS_status.gems.last_scanned = nil + IS_status.gems.last_valid = nil + IS_gem_info = {} + return + elseif msg == "gems reset" then + commandHandler("gems clear") + commandHandler("gems restart") + return + elseif msg == "gems restart" then + start = minGem + IS_status.gems.last_scanned = nil + IS_status.gems.last_valid = nil + elseif msg == "gems stop" then + IS_status.gems.scan_active = false + return + else + print("Usage: /is gems <arg> (or /itemscanner gems <arg>") + print(" clear clears gem data but does not stop a running scan") + print(" reset clears gem 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") + return + end + frame.gemco = coroutine.wrap(gemParseCoroutine) + frame.gemco(start) + frame:SetScript("OnUpdate", OnUpdate) elseif string.match(msg, "^items") then local start @@ -380,6 +513,7 @@ local function commandHandler(msg) print("Usage: /is <arg> (or /itemscanner <arg>") print(" all scans all scannable objects") print(" debug prints scanning status") + print(" gems scans all gem ids") print(" items scans all items") print(" suffixes scans all random suffixes") end @@ -389,6 +523,10 @@ if not IS_item_info then IS_item_info = {} end +if not IS_gem_info then + IS_gem_info = {} +end + if not IS_status then IS_status = {} end @@ -413,6 +551,14 @@ if not IS_status.suffixes.invalid then IS_status.suffixes.invalid = {} end +if not IS_status.gems then + IS_status.gems = {} +end + +if not IS_status.gems.invalid then + IS_status.gems.invalid = {} +end + SLASH_ITEMSCANNER1="/is" SLASH_ITEMSCANNER2="/itemscanner" SlashCmdList["ITEMSCANNER"] = commandHandler @@ -457,7 +603,15 @@ local function resume() commandHandler("suffixes") end end - if not frame.itemco and not frame.suffco then + if IS_status.gems.scan_active then + if IS_status.gems.finished then + IS_status.gems.scan_active = false + IS_status.gems.finished = false + else + commandHandler("gems") + end + end + if not frame.itemco and not frame.suffco and not frame.gemco then print("Nothing seems to be active, restarting all") commandHandler("all reset") end diff --git a/ItemScanner.toc b/ItemScanner.toc index 33d4f34..f069ab0 100644 --- a/ItemScanner.toc +++ b/ItemScanner.toc @@ -2,6 +2,6 @@ ## Title: Item Scanner ## Notes: Collects and stores data about items ## Author: The Flying Squirrels -## SavedVariables: IS_item_info, IS_status +## SavedVariables: IS_gem_info, IS_item_info, IS_status ItemScanner.xml diff --git a/get-live-data.lua b/get-live-data.lua index 531efa4..c4c8458 100644 --- a/get-live-data.lua +++ b/get-live-data.lua @@ -15,7 +15,9 @@ end IS_invalid_items = IS_status.items.invalid IS_invalid_suffixes = IS_status.suffixes.invalid +IS_invalid_gems = IS_status.gems.invalid +--TODO: handle IS_gem_info too? for k, v in pairs(item_info) do if IS_item_info[k] then if #(v) > #(IS_item_info[k]) then @@ -78,6 +80,8 @@ 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", + ["IS_invalid_gems"] = "scanned/invalid-gems.lua", + ["IS_gem_info"] = {"scanned/gem-info%s.lua", {[""] = ""}}, ["ItemsThatNeedManualIntervention"] = "scanned/ItemsThatNeedManualIntervention.lua", }