diff --git a/ItemScanner.lua b/ItemScanner.lua
index 969fa74..c83bde0 100644
--- a/ItemScanner.lua
+++ b/ItemScanner.lua
@@ -165,168 +165,97 @@ local function OnUpdate(self)
end
end
-local startTime, roundStartTime, numProcessed, roundNumProcessed, valid, roundValid, chunkStart, chunkEnd
-local function itemParseCoroutine(start, tooltip, threadNumber)
- if threadNumber == 1 then
- chunkStart, chunkEnd = chunkSize * math.floor(start / chunkSize), chunkSize * math.floor((start + chunkSize) / chunkSize) - 1
- IS_status.items.scan_active = true
- IS_status.items.finished = false
+local startTime, roundStartTime, numProcessed, roundNumProcessed, valid, roundValid
+local function genericCoroutine(start, min, max, name, linkTemplate, delay, statusVars, tooltip, threadNumber)
+ if not threadNumber or threadNumber == 1 then
+ statusVars.scan_active = true
+ statusVars.finished = false
coroutine.yield()
startTime = GetTime()
roundStartTime = startTime
- IS_status.items.last_scanned = start - 1
+ statusVars.last_scanned = start - 1
numProcessed, roundNumProcessed, valid, roundValid = 0, 0, 0, 0
- print(string.format("ItemScanner: starting scan at item %d", start))
+ print(string.format("ItemScanner: starting scan at %s %d", name, start))
else
coroutine.yield()
end
local function scan(i, scanningAll)
- IS_status.items.last_scanned = i
+ statusVars.last_scanned = i
local itemStartTime = GetTime()
- if scanItemLink("item:" .. i .. ":0:0:0:0:0:0:0:85", tooltip, threadNumber) then
+ if scanItemLink(string.format(linkTemplate, i), tooltip, threadNumber) then
if scanningAll then
- if IS_status.items.invalid[i] ~= false then
+ if statusVars.invalid[i] ~= false then
valid, roundValid = valid + 1, roundValid + 1
end
else
- if IS_status.items.scan_active then
- IS_status.items.last_valid = i
+ if statusVars.scan_active then
+ statusVars.last_valid = i
end
valid, roundValid = valid + 1, roundValid + 1
end
-- Reset invalid count
- IS_status.items.invalid[i] = false
+ statusVars.invalid[i] = false
else
-- start with 3 if no previous value
- IS_status.items.invalid[i] = (IS_status.items.invalid[i] or 2) + 1
+ statusVars.invalid[i] = (statusVars.invalid[i] or 2) + 1
end
numProcessed = numProcessed + 1
roundNumProcessed = roundNumProcessed + 1
- while GetTime() - itemStartTime < VALID_DELAY do
+ while GetTime() - itemStartTime < delay do
coroutine.yield()
end
local currentTime = GetTime()
if currentTime - roundStartTime >= 120 then
local elapsedTime = currentTime - startTime
- print(string.format("ItemScanner: at item %d, %d in %.1f sec. (%.2f/min.) (%d valid), %d this round (%d valid)", i, numProcessed, elapsedTime, numProcessed / elapsedTime * 60, valid, roundNumProcessed, roundValid))
+ print(string.format("ItemScanner: at %s %d, %d in %.1f sec. (%.2f/min.) (%d valid), %d this round (%d valid)", name, i, numProcessed, elapsedTime, numProcessed / elapsedTime * 60, valid, roundNumProcessed, roundValid))
roundStartTime = roundStartTime + 120
roundNumProcessed, roundValid = 0, 0
end
end
- while IS_status.items.scan_active and not IS_status.items.finished do
- local i = IS_status.items.last_scanned
+ while statusVars.scan_active and not statusVars.finished do
+ local i = statusVars.last_scanned
if i == nil then
break
end
repeat
i = i + 1
- if i > chunkEnd or i > maxItem then
- IS_status.items.finished = true
+ if i > max then
+ statusVars.finished = true
break
end
- until not IS_status.items.invalid[i] or (type(IS_status.items.invalid[i]) == "number" and IS_status.items.invalid[i] < CONSECUTIVE_INVALID_TO_IGNORE)
- if IS_status.items.finished then
+ until not statusVars.invalid[i] or (type(statusVars.invalid[i]) == "number" and statusVars.invalid[i] < CONSECUTIVE_INVALID_TO_IGNORE)
+ if statusVars.finished then
break
end
scan(i, false)
end
- local chunkName = chunkStart .. "-" .. chunkEnd
- while IS_status.items.scan_active do
- local i = (IS_status.items.last_invalid[chunkName] or chunkStart - 1)
+ while statusVars.scan_active do
+ local i = (statusVars.last_invalid or min - 1)
repeat
i = i + 1
- if i > chunkEnd or i > maxItem then
- i = chunkStart
+ if i > max then
+ i = min
end
- until IS_status.items.invalid[i] ~= true
- IS_status.items.last_invalid[chunkName] = i
+ until statusVars.invalid[i] ~= true
+ statusVars.last_invalid = i
scan(i, true)
end
- if threadNumber == 1 then
+ if not threadNumber or threadNumber == 1 then
local elapsedTime = GetTime() - startTime
if elapsedTime == 0 then
elapsedTime = 0.001
end
- print(string.format("ItemScanner: scan stopped at item %d, %d in %.1f sec. (%.2f/min.) (%d valid)", IS_status.items.last_scanned, numProcessed, elapsedTime, numProcessed / elapsedTime * 60, valid))
+ print(string.format("ItemScanner: scan stopped at %s %d, %d in %.1f sec. (%.2f/min.) (%d valid)", name, statusVars.last_scanned, numProcessed, elapsedTime, numProcessed / elapsedTime * 60, valid))
end
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, "^all") then
commandHandler(string.gsub(msg, "all", "items"))
@@ -339,9 +268,6 @@ local function commandHandler(msg)
print("Scanning known valid items with " .. #(frame.itemco) .. " threads")
end
print("Last item: " .. tostring(IS_status.items.last_scanned or "none"))
- 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")
@@ -353,6 +279,9 @@ local function commandHandler(msg)
print("Scanning not active")
return
end
+ local currentTime = GetTime()
+ print("roundTime = " .. tostring(currentTime - roundStartTime))
+ print("elapsedTime = " .. tostring(currentTime - startTime))
elseif string.match(msg, "^items") then
local start
@@ -395,14 +324,19 @@ local function commandHandler(msg)
return
end
+ local chunkStart, chunkEnd = chunkSize * math.floor(start / chunkSize), chunkSize * math.floor((start + chunkSize) / chunkSize) - 1
+ if chunkEnd > maxItem then
+ chunkEnd = maxItem
+ end
+
frame.itemco = {}
for i = 1, NUM_THREADS do
local tooltip = _G["ItemScannerHiddenTooltip" .. i]
if not tooltip then
tooltip = CreateFrame("GameTooltip", "ItemScannerHiddenTooltip" .. i, nil, "ItemScannerHiddenTooltip")
end
- table.insert(frame.itemco, coroutine.wrap(itemParseCoroutine))
- frame.itemco[i](start + i - 1, tooltip, i)
+ table.insert(frame.itemco, coroutine.wrap(genericCoroutine))
+ frame.itemco[i](start + i - 1, chunkStart, chunkEnd, "item", "item:%d:0:0:0:0:0:0:0:85", VALID_DELAY * NUM_THREADS, IS_status.items[chunkStart .. "-" .. chunkEnd], tooltip, i)
end
frame:SetScript("OnUpdate", OnUpdate)
elseif string.match(msg, "^suffixes") then
@@ -433,12 +367,14 @@ local function commandHandler(msg)
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.suffco = coroutine.wrap(genericCoroutine)
+ frame.suffco(start, minSuffix, maxSuffix, "suffix", "item:11993:0:0:0:0:0:%d:100:85", VALID_DELAY, IS_status.suffixes, tooltip)
frame:SetScript("OnUpdate", OnUpdate)
else
print("Usage: /is <arg> (or /itemscanner <arg>")
@@ -483,10 +419,29 @@ SlashCmdList["ITEMSCANNER"] = commandHandler
-- Autoresumes on login
local function resume()
- if not IS_status.items.last_invalid then
- IS_status.items.last_invalid = {}
+ if not IS_status.items then
+ IS_status.items = {}
end
+ local metatable = {
+ __index = IS_status.items,
+ __newindex = function(tbl, key, val)
+ if key == "last_invalid" then
+ rawset(tbl, key, val)
+ else
+ IS_status.items[key] = val
+ end
+ end,
+ }
+ local t = IS_status.items
+ for i = 0, maxItem, chunkSize do
+ local chunkStart, chunkEnd = chunkSize * math.floor(i / chunkSize), chunkSize * math.floor((i + chunkSize) / chunkSize) - 1
+ local chunkName = chunkStart .. "-" .. chunkEnd
+ t[chunkName] = setmetatable(t[chunkName] or { last_invalid = (IS_status.items.last_invalid or {})[chunkName] }, metatable)
+ end
+
+ IS_status.items.last_invalid = nil
+
if IS_status.items.scan_active then
if IS_status.items.finished then
commandHandler("items next-chunk")