diff core.lua @ 19:f560cf82e7d3

Smarter handling of missed item cache entries. Basic persistent logging of debug messages (options panel or /loot debug alsolog) and script to print same.
author Farmbuyer of US-Kilrogg <farmbuyer@gmail.com>
date Mon, 29 Aug 2011 01:29:13 +0000
parents ca797c0f32d4
children d89aeb6b9f9e
line wrap: on
line diff
--- a/core.lua	Fri Aug 26 02:52:33 2011 +0000
+++ b/core.lua	Mon Aug 29 01:29:13 2011 +0000
@@ -44,6 +44,7 @@
                          -- autoshard:  optional name of disenchanting player, default nil
                          -- threshold:  optional loot threshold, default nil
 OuroLootSV_hist  = nil
+OuroLootSV_log   = {}
 
 
 ------ Constants
@@ -103,14 +104,23 @@
 		flow = false,
 		notraid = false,
 		cache = false,
+		alsolog = false,
 	}
 	function dprint (t,...)
-		if DEBUG_PRINT and debug[t] then return _G.print("<"..t.."> ",...) end
+		if DEBUG_PRINT and debug[t] then
+			local text = flib.safeprint("<"..t.."> ",...)
+			if debug.alsolog then
+				addon:log_with_timestamp(text)
+			end
+		end
 	end
 
 	if author_debug then
 		function pprint(t,...)
-			return _G.print("<<"..t..">> ",...)
+			local text = flib.safeprint("<<"..t..">> ",...)
+			if debug.alsolog then
+				addon:log_with_timestamp(text)
+			end
 		end
 	else
 		pprint = flib.nullfunc
@@ -447,6 +457,7 @@
 		end
 	end end
 	OuroLootSV_hist = self.history_all
+	OuroLootSV_log = #OuroLootSV_log > 0 and OuroLootSV_log or nil
 end
 
 do
@@ -587,16 +598,16 @@
 	-- 'from' and onwards only present if this is triggered by a broadcast
 	function addon:_do_loot (local_override, recipient, itemid, count, from, extratext)
 		local itexture = GetItemIcon(itemid)
-		--local iname, ilink, iquality, _,_,_,_,_,_, itexture = GetItemInfo(itemid)
 		local iname, ilink, iquality = GetItemInfo(itemid)
+		local i
 		if (not iname) or (not itexture) then
+			i = true
 			iname, ilink, iquality, itexture = 
 				UNKNOWN..': '..itemid, 'item:6948', ITEM_QUALITY_COMMON, [[ICONS\INV_Misc_QuestionMark]]
 		end
-		self.dprint('loot',">>_do_loot, R:", recipient, "I:", itemid, "C:", count, "frm:", from, "ex:", extratext, "Q:", iquality)
+		self.dprint('loot',">>_do_loot, R:", recipient, "I:", itemid, "C:", count, "frm:", from, "ex:", extratext, "q:", iquality)
 
-		local i
-		itemid = tonumber(ilink:match("item:(%d+)"))
+		itemid = tonumber(ilink:match("item:(%d+)") or 0)
 		if local_override or ((iquality >= self.threshold) and not opts.itemfilter[itemid]) then
 			if (self.rebroadcast and (not from)) and not local_override then
 				self:broadcast('loot', recipient, itemid, count)
@@ -611,6 +622,7 @@
 						kind		= 'loot',
 						person		= recipient,
 						person_class= select(2,UnitClass(recipient)),
+						cache_miss	= i and true or nil,
 						quality		= iquality,
 						itemname	= iname,
 						id			= itemid,
@@ -622,8 +634,10 @@
 						extratext	= extratext,
 						is_heroic	= self:is_heroic_item(ilink),
 					}
-					self.dprint('loot', "added entry", i)
-					self:_addHistoryEntry(i)
+					self.dprint('loot', "added loot entry", i)
+					if not self.history_suppress then
+						self:_addHistoryEntry(i)
+					end
 					if self.display then
 						self:redisplay()
 						--[[
@@ -747,6 +761,9 @@
 			return self:BuildMainDisplay()
 		end
 
+	elseif cmd == "fixcache" then
+		self:do_item_cache_fixup()
+
 	else
 		if self:OpenMainDisplayToTab(cmd) then
 			return
@@ -852,6 +869,15 @@
 
 
 ------ Behind the scenes routines
+-- Semi-experimental debugging aid.
+do
+	local date = _G.date
+	local log = OuroLootSV_log
+	function addon:log_with_timestamp (msg)
+		tinsert (log, date('%m:%d %H:%M:%S  ')..msg)
+	end
+end
+
 -- Adds indices to traverse the tables in a nice sorted order.
 do
 	local byindex, temp = {}, {}
@@ -996,7 +1022,7 @@
 		if #candidates == 1 then
 			-- (1) or (2)
 			boss.duration = boss.duration or 0
-			addon.dprint('loot', "only one candidate")
+			addon.dprint('loot', "only one boss candidate")
 		else
 			-- (3), should only be one 'cast entry and our local entry
 			if #candidates ~= 2 then
@@ -1011,16 +1037,16 @@
 			for i,c in ipairs(candidates) do
 				if c.duration then
 					boss = c
-					addon.dprint('loot', "fixup found candidate", i, "duration", c.duration)
+					addon.dprint('loot', "fixup found boss candidate", i, "duration", c.duration)
 					break
 				end
 			end
 		end
 		bossi = addon._addLootEntry(boss)
-		--
-		bossi = addon._adjustBossOrder (bossi, g_boss_signpost)
+		-- addon.
+		bossi = addon._adjustBossOrder (bossi, g_boss_signpost) or bossi
 		g_boss_signpost = nil
-		addon.dprint('loot', "added entry", bossi)
+		addon.dprint('loot', "added boss entry", bossi)
 		if boss.reason == 'kill' then
 			addon:_mark_boss_kill (bossi)
 			if opts.chatty_on_kill then
@@ -1049,6 +1075,7 @@
 			else
 				self.recent_boss:add(signature)
 				g_boss_signpost = #g_loot + 1
+				self.dprint('loot', "added boss signpost", g_boss_signpost)
 				-- Possible scenarios:  (1) we don't see a boss event at all (e.g., we're
 				-- outside the instance) and so this only happens once as a non-local event,
 				-- (2) we see a local event first and all non-local events are filtered
@@ -1263,7 +1290,7 @@
 			return
 		end
 		if (type(is)~='number') or (type(should_be)~='number') or (is < should_be) then
-			--pprint('loot', "...the hell? bailing")
+			pprint('loot', is, should_be, "...the hell? bailing")
 			return
 		end
 		if g_loot[should_be].kind == 'time' then
@@ -1282,6 +1309,38 @@
 	end
 end
 
+-- In the rare case of items getting put into the loot table without current
+-- item cache data (which will have arrived by now).
+function addon:do_item_cache_fixup()
+	self:Print("Fixing up missing item cache data...")
+
+	local numfound = 0
+	local borkedpat = '^'..UNKNOWN..': (%S+)'
+
+	for i,e in self:filtered_loot_iter('loot') do
+		if e.cache_miss then
+			local borked_id = e.itemname:match(borkedpat)
+			if borked_id then
+				numfound = numfound + 1
+				-- Best to use the safest and most flexible API here, which is GII and
+				-- its assload of return values.
+				local iname, ilink, iquality, _,_,_,_,_,_, itexture = GetItemInfo(borked_id)
+				if iname then
+					self:Print("    Entry %d patched up with %s.", i, ilink)
+					e.quality = iquality
+					e.itemname = iname
+					e.id = tonumber(ilink:match("item:(%d+)"))
+					e.itemlink = ilink
+					e.itexture = itexture
+					e.cache_miss = nil
+				end
+			end
+		end
+	end
+
+	self:Print("...finished.  Found %d |4entry:entries; with weird data.", numfound)
+end
+
 
 ------ Saved texts
 function addon:check_saved_table(silent_p)