changeset 129:2731702567c4

- Detect loot received in LFR when player isn't eligible (for the strange people out there who are tracking in LFR). - Followup for r116, make sure all entries in display table are properly updated. Add a force-refresh button to the Help tab for the worst case.
author Farmbuyer of US-Kilrogg <farmbuyer@gmail.com>
date Mon, 27 Aug 2012 02:53:42 -0400
parents dc39ce56a62d
children 08d3d2b7c31d
files core.lua gui.lua verbage.lua
diffstat 3 files changed, 84 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/core.lua	Wed Aug 22 23:37:24 2012 -0400
+++ b/core.lua	Mon Aug 27 02:53:42 2012 -0400
@@ -178,7 +178,8 @@
 local my_name				= UnitName('player')
 local comm_cleanup_ttl		= 4   -- seconds in the communications cache
 local version_large			= nil -- defaults to 1, possibly changed by version
-local g_LOOT_ITEM_ss, g_LOOT_ITEM_MULTIPLE_sss, g_LOOT_ITEM_SELF_s, g_LOOT_ITEM_SELF_MULTIPLE_ss
+local g_LOOT_ITEM_ss, g_LOOT_ITEM_MULTIPLE_sss, g_LOOT_ITEM_SELF_s
+local g_LOOT_ITEM_SELF_MULTIPLE_ss, g_LOOT_ITEM_WHILE_PLAYER_INELIGIBLE_ss
 
 
 ------ Addon member data
@@ -966,7 +967,7 @@
 	end
 
 	--[[
-	The four loot format patterns of interest, changed into relatively tight
+	The five loot format patterns of interest, changed into relatively tight
 	string match patterns.  Done at enable-time rather than load-time against
 	the slim chance that one of the non-US "delocalizers" needs to mess with
 	the global patterns before we transform them.
@@ -975,8 +976,6 @@
 	trigger on 'receive item' instead, which would detect extracting stuff
 	from mail, or s/PUSHED/CREATED/ for things like healthstones and guild
 	cauldron flasks.
-
-	??? do something with LOOT_ITEM_WHILE_PLAYER_INELIGIBLE for locked LFRs?
 	]]
 
 	-- LOOT_ITEM = "%s receives loot: %s." --> (.+) receives loot: (.+)%.
@@ -991,6 +990,13 @@
 	-- LOOT_ITEM_SELF_MULTIPLE = "You receive loot: %sx%d." --> You receive loot: (.+)(x%d+)%.
 	g_LOOT_ITEM_SELF_MULTIPLE_ss = LOOT_ITEM_SELF_MULTIPLE:gsub('%.$','%%.'):gsub('%%s','(.+)'):gsub('x%%d','(x%%d+)')
 
+	-- LOOT_ITEM_WHILE_PLAYER_INELIGIBLE is mostly the same as LOOT_ITEM with
+	-- an inline texture and no full stop.  The punctuation in the texture
+	-- path causes fits while matching, so just make that a wildcard rather
+	-- than trying to escape it all.
+	g_LOOT_ITEM_WHILE_PLAYER_INELIGIBLE_ss = LOOT_ITEM_WHILE_PLAYER_INELIGIBLE:
+		gsub('\124T%S*\124t','\124T%%S*\124t'):gsub('%%s','(.+)')
+
 	--[[
 	Throw in the default disposition types.  This could be called during load
 	were it not for the need to talk to the GUI data (not set up yet).
@@ -1743,6 +1749,7 @@
 
 	-- Returns the index of the resulting new loot entry, or nil after
 	-- displaying any errors.
+	local match = string.match
 	function addon:CHAT_MSG_LOOT (event, ...)
 		if (not self.rebroadcast) and (not self.enabled) and (event ~= "manual") then return end
 
@@ -1760,14 +1767,19 @@
 			--ChatFrame2:AddMessage("original string:  >"..(msg:gsub("\124","\124\124")).."<")
 
 			-- test in most likely order:  other people get more loot than "you" do
-			person, itemstring, count = msg:match(g_LOOT_ITEM_MULTIPLE_sss)
+			person, itemstring, count = match(msg,g_LOOT_ITEM_MULTIPLE_sss)
 			if not person then
-				person, itemstring = msg:match(g_LOOT_ITEM_ss)
+				person, itemstring = match(msg,g_LOOT_ITEM_ss)
 			end
 			if not person then
-				itemstring, count = msg:match(g_LOOT_ITEM_SELF_MULTIPLE_ss)
+				-- Could only do this text if in an LFR... but the restriction
+				-- might apply elsewhere soon enough.
+				person, itemstring = match(msg,g_LOOT_ITEM_WHILE_PLAYER_INELIGIBLE_ss)
+			end
+			if not person then
+				itemstring, count = match(msg,g_LOOT_ITEM_SELF_MULTIPLE_ss)
 				if not itemstring then
-					itemstring = msg:match(g_LOOT_ITEM_SELF_s)
+					itemstring = match(msg,g_LOOT_ITEM_SELF_s)
 				end
 			end
 
@@ -1777,7 +1789,7 @@
 
 			-- Name might be colorized, remove the highlighting
 			if person then
-				person = person:match("|c%x%x%x%x%x%x%x%x(%S+)") or person
+				person = match(person,"|c%x%x%x%x%x%x%x%x(%S+)") or person
 			else
 				person = my_name    -- UNIT_YOU / You
 			end
@@ -2327,7 +2339,7 @@
 	end
 
 	self.threshold = opts.threshold or self.threshold -- in the case of restoring but not tracking
-	local g_loot_wrapper = self:gui_init (g_loot, g_uniques)
+	local g_loot_wrapper = self:gui_init (true, g_loot, g_uniques)
 	opts.autoshard = nil
 	opts.threshold = nil
 
@@ -2491,7 +2503,7 @@
 			then
 				first = first or i
 				attempts = attempts + 1
-				assert(tremove(g_loot,i)==d,"_mark_boss_kill screwed up data badly")
+				assert(g_gui.g_dloot:remove(i)==d,"_mark_boss_kill screwed up data badly")
 			else
 				i = i + 1
 			end
@@ -2683,6 +2695,7 @@
 			addon:Fire ('NewLootEntry', e, index)
 		end
 		g_loot[index] = e
+		g_gui.g_dloot[index] = nil
 		addon:Fire ('NewEOIEntry', e, index)
 		return index
 	end
@@ -2724,8 +2737,8 @@
 		end
 
 		assert(g_loot[is].kind == 'boss')
-		local boss = tremove (g_loot, is)
-		tinsert (g_loot, should_be, boss)
+		local boss = g_gui.g_dloot:remove(is)
+		g_gui.g_dloot:insert (should_be, boss)
 		return should_be
 	end
 end
--- a/gui.lua	Wed Aug 22 23:37:24 2012 -0400
+++ b/gui.lua	Mon Aug 27 02:53:42 2012 -0400
@@ -65,6 +65,7 @@
 
 local pairs, ipairs, tinsert, tremove, tostring, tonumber =
 	pairs, ipairs, table.insert, table.remove, tostring, tonumber
+local math_min, math_huge = math.min, math.huge
 
 local pprint, tabledump = addon.pprint, flib.tabledump
 local GetItemInfo, ITEM_QUALITY_COLORS = GetItemInfo, ITEM_QUALITY_COLORS
@@ -138,17 +139,20 @@
 		["LEN"] = function()
 			return #g_loot
 		end,
-		-- returns the display's entry and the core entry
+		-- returns the core entry and the display's entry
 		["remove"] = function (dt, i)
-			local reale = tremove (g_loot, i)
-			return tremove (dt, i), reale
+			return tremove (g_loot, i), tremove (dt, i)
 		end,
-		-- counterpart
-		--[[
-		["insert"] = function (dt, i, displaye, reale)
+		-- counterpart; display entry is optional
+		["insert"] = function (dt, i, reale, displaye)
 			tinsert (g_loot, i, reale)
-			tinsert (dt, i, displaye)
-		end,]]
+			if displaye then
+				tinsert (dt, i, displaye)
+			else
+				tinsert (dt, i, 42)  -- grow it
+				dt[i] = nil          -- force the index metamethod to trigger
+			end
+		end,
 	}
 	local function wrap_e (t,index)
 		local real = g_loot[index]
@@ -371,8 +375,10 @@
 relevant" bits (icons, user-friendly labels, etc) in the g_dloot table,
 which inherits (so to speak) the corresponding row entries.
 
-Everything from the loot_clean index to the end of the table is filled out;
-loot_clean is updated.  Override this starting point with the function arg.
+This is called *often*, so we try to minimize waste by keeping track of the
+last known index known to have updated info.  Everything from the loot_clean
+index to the end of the table is filled out; loot_clean is updated.  Override
+this starting point with the function argument.
 ]]
 function addon:_fill_out_eoi_data (opt_starting_index)
 	if #g_loot < 1 then
@@ -385,7 +391,9 @@
 	local colcount = #eoi_st_cols
 
 	-- 'while true' so that we can use (inner) break as (outer) continue
-	for i = (opt_starting_index or self.loot_clean or 1), #g_loot do while true do
+	local start = opt_starting_index or
+		math_min (#g_dloot, self.loot_clean or math_huge, #g_loot)
+	for i = start, #g_loot do while true do
 		local e = g_dloot[i]
 		if e == nil then
 			self.loot_clean = nil
@@ -832,11 +840,19 @@
 	end
 end
 
--- Done at startup, and whenever we've changed the population of tabs.
-function addon:gui_init (loot_pointer, uniques_pointer)
-	g_loot = assert(loot_pointer, "something went wrong at startup")
-	g_uniques = assert(uniques_pointer, "something went wrong at startup")
+-- Done at startup, and whenever we've changed the population of tabs.  Can
+-- be triggered by player.  In the first case only, the arguments are passed.
+function addon:gui_init (at_init_p, loot_pointer, uniques_pointer)
+	if at_init_p then
+		g_loot = assert(loot_pointer, "something went wrong at startup")
+		g_uniques = assert(uniques_pointer, "something went wrong at startup")
+	end
 	g_dloot = do_g_loot_wrap(g_loot)
+	gui.g_dloot = g_dloot   -- primarily for clean deletion
+	if gui.eoiST then       -- re-init
+		self:_fill_out_eoi_data(1)
+		gui.eoiST:SetData(g_dloot)
+	end
 	g_generated = nil
 	tabgroup_tabs = {}
 	window_title = "Ouro Loot " .. self.version
@@ -924,7 +940,7 @@
 	end,
 
 	df_DELETE = function(rowi)
-		local dgone, gone = g_dloot:remove(rowi)
+		local gone, dgone = g_dloot:remove(rowi)
 		addon:Fire ('DelEOIEntry', gone)
 		addon:Print("Removed %s.",
 			gone.itemlink or gone.bossname or gone.startday.text)
@@ -1310,6 +1326,16 @@
 
 	local e = data[realrow]
 	local cell = e.cols[column]
+	if not cell then
+		pprint('default_cellupdate', "row", realrow, "had no cell in col",
+			column, "retrying from first row")
+		addon:_fill_out_eoi_data(1)
+		cell = e.cols[column]
+		if not cell then
+			pprint('default_cellupdate', "FAILED, bailing")
+			return
+		end
+	end
 
 	cellFrame.text:SetText(cell.value)
 	-- subset of what the default ST's docellupdate looks for
@@ -2101,8 +2127,8 @@
 	UIDROPDOWNMENU_SHOW_TIME = 4
 
 	if dirty_tabs then
-		-- pointers known to be good by now, pass them back in
-		self:gui_init (g_loot, g_uniques)
+		self.dprint('flow', "dirty flag set in BuildMainDisplay, recreating!")
+		self:gui_init()
 		self:zero_printed_fenceposts()
 	end
 	gui.opts = self.db.profile
@@ -2573,7 +2599,7 @@
 			raidersnap	= data.yes_snap or {},
 		}
 		local entry = tremove(g_loot,boss_index)
-		tinsert(g_loot,data.rowindex,entry)
+		g_dloot:insert (data.rowindex, entry)
 		addon:_mark_boss_kill(data.rowindex)
 		gui.eoiST:OuroLoot_Refresh(data.rowindex)
 		local jumpprefix = addon.chatprefix ("GoToLootLine", data.rowindex)
@@ -2627,7 +2653,7 @@
 		data.display:Hide()
 		local loot_index = assert(addon:CHAT_MSG_LOOT ("manual", data.recipient, data.name, data.notes))
 		local entry = tremove(g_loot,loot_index)
-		tinsert(g_loot,data.rowindex,entry)
+		g_dloot:insert (data.rowindex, entry)
 		addon:_fill_out_eoi_data(data.rowindex)
 		addon:BuildMainDisplay()
 		local clicky = _new_rebroadcast_hyperlink (entry.unique)
--- a/verbage.lua	Wed Aug 22 23:37:24 2012 -0400
+++ b/verbage.lua	Mon Aug 27 02:53:42 2012 -0400
@@ -617,6 +617,8 @@
 
 -- Tab 5:  Help
 do
+	local mkbutton = addon.gui_state_pointer.mkbutton
+	local gui = addon.gui_state_pointer
 	local AceGUI = LibStub("AceGUI-3.0")
 	-- widget container status tables (will have things magically appear
 	-- inside them that we wish to preserve)
@@ -668,6 +670,16 @@
 		else
 			left:SelectByValue("basic")
 		end
+
+		local b = mkbutton("Force Loot Refresh",
+			[[Force the Loot tab display to update from stored data.  Shouldn't be needed.]])
+		b:SetFullWidth(true)
+		b:SetCallback("OnClick", function ()
+			addon.loot_clean = nil
+			addon:gui_init()
+			addon:Print[[Loot tab display re-initialized.]]
+		end)
+		specials:AddChild(b)
 	end
 
 	addon:register_tab_control_AT_END ("help", [[Help]],