comparison 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
comparison
equal deleted inserted replaced
18:ca797c0f32d4 19:f560cf82e7d3
42 -- are name/forum/attend/date 42 -- are name/forum/attend/date
43 OuroLootSV_opts = nil -- same as option_defaults until changed 43 OuroLootSV_opts = nil -- same as option_defaults until changed
44 -- autoshard: optional name of disenchanting player, default nil 44 -- autoshard: optional name of disenchanting player, default nil
45 -- threshold: optional loot threshold, default nil 45 -- threshold: optional loot threshold, default nil
46 OuroLootSV_hist = nil 46 OuroLootSV_hist = nil
47 OuroLootSV_log = {}
47 48
48 49
49 ------ Constants 50 ------ Constants
50 local option_defaults = { 51 local option_defaults = {
51 ['popup_on_join'] = true, 52 ['popup_on_join'] = true,
101 comm = false, 102 comm = false,
102 loot = false, 103 loot = false,
103 flow = false, 104 flow = false,
104 notraid = false, 105 notraid = false,
105 cache = false, 106 cache = false,
107 alsolog = false,
106 } 108 }
107 function dprint (t,...) 109 function dprint (t,...)
108 if DEBUG_PRINT and debug[t] then return _G.print("<"..t.."> ",...) end 110 if DEBUG_PRINT and debug[t] then
111 local text = flib.safeprint("<"..t.."> ",...)
112 if debug.alsolog then
113 addon:log_with_timestamp(text)
114 end
115 end
109 end 116 end
110 117
111 if author_debug then 118 if author_debug then
112 function pprint(t,...) 119 function pprint(t,...)
113 return _G.print("<<"..t..">> ",...) 120 local text = flib.safeprint("<<"..t..">> ",...)
121 if debug.alsolog then
122 addon:log_with_timestamp(text)
123 end
114 end 124 end
115 else 125 else
116 pprint = flib.nullfunc 126 pprint = flib.nullfunc
117 end 127 end
118 128
445 t.st = nil 455 t.st = nil
446 t.byname = nil 456 t.byname = nil
447 end 457 end
448 end end 458 end end
449 OuroLootSV_hist = self.history_all 459 OuroLootSV_hist = self.history_all
460 OuroLootSV_log = #OuroLootSV_log > 0 and OuroLootSV_log or nil
450 end 461 end
451 462
452 do 463 do
453 local IsInInstance, UnitName, UnitIsConnected, UnitClass, UnitRace, UnitSex, 464 local IsInInstance, UnitName, UnitIsConnected, UnitClass, UnitRace, UnitSex,
454 UnitLevel, UnitInRaid, UnitIsVisible, GetGuildInfo = 465 UnitLevel, UnitInRaid, UnitIsVisible, GetGuildInfo =
585 local GetItemInfo, GetItemIcon = GetItemInfo, GetItemIcon 596 local GetItemInfo, GetItemIcon = GetItemInfo, GetItemIcon
586 597
587 -- 'from' and onwards only present if this is triggered by a broadcast 598 -- 'from' and onwards only present if this is triggered by a broadcast
588 function addon:_do_loot (local_override, recipient, itemid, count, from, extratext) 599 function addon:_do_loot (local_override, recipient, itemid, count, from, extratext)
589 local itexture = GetItemIcon(itemid) 600 local itexture = GetItemIcon(itemid)
590 --local iname, ilink, iquality, _,_,_,_,_,_, itexture = GetItemInfo(itemid)
591 local iname, ilink, iquality = GetItemInfo(itemid) 601 local iname, ilink, iquality = GetItemInfo(itemid)
602 local i
592 if (not iname) or (not itexture) then 603 if (not iname) or (not itexture) then
604 i = true
593 iname, ilink, iquality, itexture = 605 iname, ilink, iquality, itexture =
594 UNKNOWN..': '..itemid, 'item:6948', ITEM_QUALITY_COMMON, [[ICONS\INV_Misc_QuestionMark]] 606 UNKNOWN..': '..itemid, 'item:6948', ITEM_QUALITY_COMMON, [[ICONS\INV_Misc_QuestionMark]]
595 end 607 end
596 self.dprint('loot',">>_do_loot, R:", recipient, "I:", itemid, "C:", count, "frm:", from, "ex:", extratext, "Q:", iquality) 608 self.dprint('loot',">>_do_loot, R:", recipient, "I:", itemid, "C:", count, "frm:", from, "ex:", extratext, "q:", iquality)
597 609
598 local i 610 itemid = tonumber(ilink:match("item:(%d+)") or 0)
599 itemid = tonumber(ilink:match("item:(%d+)"))
600 if local_override or ((iquality >= self.threshold) and not opts.itemfilter[itemid]) then 611 if local_override or ((iquality >= self.threshold) and not opts.itemfilter[itemid]) then
601 if (self.rebroadcast and (not from)) and not local_override then 612 if (self.rebroadcast and (not from)) and not local_override then
602 self:broadcast('loot', recipient, itemid, count) 613 self:broadcast('loot', recipient, itemid, count)
603 end 614 end
604 if self.enabled or local_override then 615 if self.enabled or local_override then
609 self.recent_loot:add(signature) 620 self.recent_loot:add(signature)
610 i = self._addLootEntry{ -- There is some redundancy here... 621 i = self._addLootEntry{ -- There is some redundancy here...
611 kind = 'loot', 622 kind = 'loot',
612 person = recipient, 623 person = recipient,
613 person_class= select(2,UnitClass(recipient)), 624 person_class= select(2,UnitClass(recipient)),
625 cache_miss = i and true or nil,
614 quality = iquality, 626 quality = iquality,
615 itemname = iname, 627 itemname = iname,
616 id = itemid, 628 id = itemid,
617 itemlink = ilink, 629 itemlink = ilink,
618 itexture = itexture, 630 itexture = itexture,
620 count = count, 632 count = count,
621 bcast_from = from, 633 bcast_from = from,
622 extratext = extratext, 634 extratext = extratext,
623 is_heroic = self:is_heroic_item(ilink), 635 is_heroic = self:is_heroic_item(ilink),
624 } 636 }
625 self.dprint('loot', "added entry", i) 637 self.dprint('loot', "added loot entry", i)
626 self:_addHistoryEntry(i) 638 if not self.history_suppress then
639 self:_addHistoryEntry(i)
640 end
627 if self.display then 641 if self.display then
628 self:redisplay() 642 self:redisplay()
629 --[[ 643 --[[
630 local st = self.display:GetUserData("eoiST") 644 local st = self.display:GetUserData("eoiST")
631 if st and st.frame:IsVisible() then 645 if st and st.frame:IsVisible() then
744 if self.display then 758 if self.display then
745 self.display:Hide() 759 self.display:Hide()
746 else 760 else
747 return self:BuildMainDisplay() 761 return self:BuildMainDisplay()
748 end 762 end
763
764 elseif cmd == "fixcache" then
765 self:do_item_cache_fixup()
749 766
750 else 767 else
751 if self:OpenMainDisplayToTab(cmd) then 768 if self:OpenMainDisplayToTab(cmd) then
752 return 769 return
753 end 770 end
850 end 867 end
851 end 868 end
852 869
853 870
854 ------ Behind the scenes routines 871 ------ Behind the scenes routines
872 -- Semi-experimental debugging aid.
873 do
874 local date = _G.date
875 local log = OuroLootSV_log
876 function addon:log_with_timestamp (msg)
877 tinsert (log, date('%m:%d %H:%M:%S ')..msg)
878 end
879 end
880
855 -- Adds indices to traverse the tables in a nice sorted order. 881 -- Adds indices to traverse the tables in a nice sorted order.
856 do 882 do
857 local byindex, temp = {}, {} 883 local byindex, temp = {}, {}
858 local function sort (src, dest) 884 local function sort (src, dest)
859 for k in pairs(src) do 885 for k in pairs(src) do
994 local boss, bossi 1020 local boss, bossi
995 boss = candidates[1] 1021 boss = candidates[1]
996 if #candidates == 1 then 1022 if #candidates == 1 then
997 -- (1) or (2) 1023 -- (1) or (2)
998 boss.duration = boss.duration or 0 1024 boss.duration = boss.duration or 0
999 addon.dprint('loot', "only one candidate") 1025 addon.dprint('loot', "only one boss candidate")
1000 else 1026 else
1001 -- (3), should only be one 'cast entry and our local entry 1027 -- (3), should only be one 'cast entry and our local entry
1002 if #candidates ~= 2 then 1028 if #candidates ~= 2 then
1003 -- could get a bunch of 'cast entries on the heels of one another 1029 -- could get a bunch of 'cast entries on the heels of one another
1004 -- before the local one ever fires, apparently... sigh 1030 -- before the local one ever fires, apparently... sigh
1009 end 1035 end
1010 -- try and be generic anyhow 1036 -- try and be generic anyhow
1011 for i,c in ipairs(candidates) do 1037 for i,c in ipairs(candidates) do
1012 if c.duration then 1038 if c.duration then
1013 boss = c 1039 boss = c
1014 addon.dprint('loot', "fixup found candidate", i, "duration", c.duration) 1040 addon.dprint('loot', "fixup found boss candidate", i, "duration", c.duration)
1015 break 1041 break
1016 end 1042 end
1017 end 1043 end
1018 end 1044 end
1019 bossi = addon._addLootEntry(boss) 1045 bossi = addon._addLootEntry(boss)
1020 -- 1046 -- addon.
1021 bossi = addon._adjustBossOrder (bossi, g_boss_signpost) 1047 bossi = addon._adjustBossOrder (bossi, g_boss_signpost) or bossi
1022 g_boss_signpost = nil 1048 g_boss_signpost = nil
1023 addon.dprint('loot', "added entry", bossi) 1049 addon.dprint('loot', "added boss entry", bossi)
1024 if boss.reason == 'kill' then 1050 if boss.reason == 'kill' then
1025 addon:_mark_boss_kill (bossi) 1051 addon:_mark_boss_kill (bossi)
1026 if opts.chatty_on_kill then 1052 if opts.chatty_on_kill then
1027 addon:Print("Registered kill for '%s' in %s!", boss.bosskill, boss.instance) 1053 addon:Print("Registered kill for '%s' in %s!", boss.bosskill, boss.instance)
1028 end 1054 end
1047 if not_from_local and self.recent_boss:test(signature) then 1073 if not_from_local and self.recent_boss:test(signature) then
1048 self.dprint('cache', "boss <",signature,"> already in cache, skipping") 1074 self.dprint('cache', "boss <",signature,"> already in cache, skipping")
1049 else 1075 else
1050 self.recent_boss:add(signature) 1076 self.recent_boss:add(signature)
1051 g_boss_signpost = #g_loot + 1 1077 g_boss_signpost = #g_loot + 1
1078 self.dprint('loot', "added boss signpost", g_boss_signpost)
1052 -- Possible scenarios: (1) we don't see a boss event at all (e.g., we're 1079 -- Possible scenarios: (1) we don't see a boss event at all (e.g., we're
1053 -- outside the instance) and so this only happens once as a non-local event, 1080 -- outside the instance) and so this only happens once as a non-local event,
1054 -- (2) we see a local event first and all non-local events are filtered 1081 -- (2) we see a local event first and all non-local events are filtered
1055 -- by the cache, (3) we happen to get some non-local events before doing 1082 -- by the cache, (3) we happen to get some non-local events before doing
1056 -- our local event (not because of network weirdness but because our local 1083 -- our local event (not because of network weirdness but because our local
1261 --pprint('loot', is, should_be) 1288 --pprint('loot', is, should_be)
1262 if is == should_be then --pprint('loot', "equal, yay") 1289 if is == should_be then --pprint('loot', "equal, yay")
1263 return 1290 return
1264 end 1291 end
1265 if (type(is)~='number') or (type(should_be)~='number') or (is < should_be) then 1292 if (type(is)~='number') or (type(should_be)~='number') or (is < should_be) then
1266 --pprint('loot', "...the hell? bailing") 1293 pprint('loot', is, should_be, "...the hell? bailing")
1267 return 1294 return
1268 end 1295 end
1269 if g_loot[should_be].kind == 'time' then 1296 if g_loot[should_be].kind == 'time' then
1270 should_be = should_be + 1 1297 should_be = should_be + 1
1271 if is == should_be then 1298 if is == should_be then
1278 local boss = tremove (g_loot, is) 1305 local boss = tremove (g_loot, is)
1279 --pprint('loot', "MOVING", boss.bosskill) 1306 --pprint('loot', "MOVING", boss.bosskill)
1280 tinsert (g_loot, should_be, boss) 1307 tinsert (g_loot, should_be, boss)
1281 return should_be 1308 return should_be
1282 end 1309 end
1310 end
1311
1312 -- In the rare case of items getting put into the loot table without current
1313 -- item cache data (which will have arrived by now).
1314 function addon:do_item_cache_fixup()
1315 self:Print("Fixing up missing item cache data...")
1316
1317 local numfound = 0
1318 local borkedpat = '^'..UNKNOWN..': (%S+)'
1319
1320 for i,e in self:filtered_loot_iter('loot') do
1321 if e.cache_miss then
1322 local borked_id = e.itemname:match(borkedpat)
1323 if borked_id then
1324 numfound = numfound + 1
1325 -- Best to use the safest and most flexible API here, which is GII and
1326 -- its assload of return values.
1327 local iname, ilink, iquality, _,_,_,_,_,_, itexture = GetItemInfo(borked_id)
1328 if iname then
1329 self:Print(" Entry %d patched up with %s.", i, ilink)
1330 e.quality = iquality
1331 e.itemname = iname
1332 e.id = tonumber(ilink:match("item:(%d+)"))
1333 e.itemlink = ilink
1334 e.itexture = itexture
1335 e.cache_miss = nil
1336 end
1337 end
1338 end
1339 end
1340
1341 self:Print("...finished. Found %d |4entry:entries; with weird data.", numfound)
1283 end 1342 end
1284 1343
1285 1344
1286 ------ Saved texts 1345 ------ Saved texts
1287 function addon:check_saved_table(silent_p) 1346 function addon:check_saved_table(silent_p)