Mercurial > wow > ouroloot
comparison core.lua @ 151:42dd3076baaf
Initial attempt at tracking bonus rolls and non-loot items.
Add more loot-catching patterns, and generalize them a little more. Bonus
rolls are tracked by default, non-loot stuff is not. Bonus rolls don't seem
to be working, but non-loot definitely is. (It may be that the patterns for
bonus rolls are not actually used by the game client, or rather, that the
game client does not issue those events for bonus rolls which are not your
own. I have yet to win a bonus roll since implementing the code, but one
person in LFR claimed to win a bonus item which simply wasn't visible to me
at all. More data needed.)
author | Farmbuyer of US-Kilrogg <farmbuyer@gmail.com> |
---|---|
date | Fri, 09 Jan 2015 19:14:56 -0500 |
parents | 63bda09d88fe |
children |
comparison
equal
deleted
inserted
replaced
150:63bda09d88fe | 151:42dd3076baaf |
---|---|
146 ['chatty_on_remote_changes'] = false, | 146 ['chatty_on_remote_changes'] = false, |
147 ['chatty_on_local_changes'] = false, | 147 ['chatty_on_local_changes'] = false, |
148 ['chatty_on_changes_frame'] = 1, | 148 ['chatty_on_changes_frame'] = 1, |
149 ['itemfilter'] = {}, | 149 ['itemfilter'] = {}, |
150 ['itemvault'] = {}, | 150 ['itemvault'] = {}, |
151 ['track_bonusrolls'] = true, | |
152 ['track_nonloot'] = false, | |
151 } } | 153 } } |
152 local virgin = "First time loaded? Hi! Use the /ouroloot command" | 154 local virgin = "First time loaded? Hi! Use the /ouroloot command" |
153 .." to show the main display. You should probably browse the instructions" | 155 .." to show the main display. You should probably browse the instructions" |
154 .." if you've never used this before; %s to display the help window. This" | 156 .." if you've never used this before; %s to display the help window. This" |
155 .." welcome message will not intrude again." | 157 .." welcome message will not intrude again." |
180 local my_name = UnitName('player') | 182 local my_name = UnitName('player') |
181 local comm_cleanup_ttl = 4 -- seconds in the communications cache | 183 local comm_cleanup_ttl = 4 -- seconds in the communications cache |
182 local version_large = nil -- defaults to 1, possibly changed by version | 184 local version_large = nil -- defaults to 1, possibly changed by version |
183 local timestamp_fmt_unique = '%Y/%m/%dT%H:%M:%S' | 185 local timestamp_fmt_unique = '%Y/%m/%dT%H:%M:%S' |
184 local timestamp_fmt_history = '%Y/%m/%d %H:%M:%S' | 186 local timestamp_fmt_history = '%Y/%m/%d %H:%M:%S' |
185 local g_LOOT_ITEM_ss, g_LOOT_ITEM_MULTIPLE_sss, g_LOOT_ITEM_SELF_s | |
186 local g_LOOT_ITEM_SELF_MULTIPLE_ss, g_LOOT_ITEM_WHILE_PLAYER_INELIGIBLE_ss | |
187 | 187 |
188 | 188 |
189 ------ Addon member data | 189 ------ Addon member data |
190 local flib = LibStub("LibFarmbuyer") | 190 local flib = LibStub("LibFarmbuyer") |
191 addon.author_debug = flib.author_debug | 191 addon.author_debug = flib.author_debug |
399 local GetNumGroupMembers = GetNumGroupMembers | 399 local GetNumGroupMembers = GetNumGroupMembers |
400 local IsInRaid = IsInRaid | 400 local IsInRaid = IsInRaid |
401 -- En masse forward decls of symbols defined inside local blocks | 401 -- En masse forward decls of symbols defined inside local blocks |
402 local _register_bossmod, makedate, create_new_cache, _init, _log, _do_loot_metas | 402 local _register_bossmod, makedate, create_new_cache, _init, _log, _do_loot_metas |
403 local _history_by_loot_id, _setup_unique_replace, _unavoidable_collision | 403 local _history_by_loot_id, _setup_unique_replace, _unavoidable_collision |
404 local _notify_about_change, _LFR_suppressing, _add_loot_disposition | 404 local _notify_about_change, _LFR_suppressing, _add_loot_disposition, _grok |
405 | 405 |
406 -- Try to extract numbers from the .toc "Version" and munge them into an | 406 -- Try to extract numbers from the .toc "Version" and munge them into an |
407 -- integral form for comparison. The result doesn't need to be meaningful as | 407 -- integral form for comparison. The result doesn't need to be meaningful as |
408 -- long as we can reliably feed two of them to "<" and get useful answers. | 408 -- long as we can reliably feed two of them to "<" and get useful answers. |
409 -- | 409 -- |
867 _init(self) | 867 _init(self) |
868 self.dprint('flow', "version strings:", version_large, self.revision, self.status_text) | 868 self.dprint('flow', "version strings:", version_large, self.revision, self.status_text) |
869 g_gui = self.gui_state_pointer | 869 g_gui = self.gui_state_pointer |
870 self.gui_state_pointer = nil | 870 self.gui_state_pointer = nil |
871 self.load_assert = nil | 871 self.load_assert = nil |
872 | |
873 --[[ | |
874 The loot format patterns of interest, changed into relatively tight string | |
875 match patterns. Done during initialization rather than at load-time | |
876 against the slim chance that one of the non-US "delocalizers" needs to | |
877 adjust the global patterns before we transform them. | |
878 ]] | |
879 local function ss (m) return m:gsub('%.$','%%.'):gsub('%%s','(.+)') end | |
880 local function ssd (m) return m:gsub('%.$','%%.'):gsub('%%s','(.+)'):gsub('x%%d','(x%%d+)') end | |
881 local function s (m) return m:gsub('%.$','%%.'):gsub('%%s','(.+)') end | |
882 local function sd (m) return m:gsub('%.$','%%.'):gsub('%%s','(.+)'):gsub('x%%d','(x%%d+)') end | |
883 | |
884 local loot_patterns = { | |
885 -- LOOT_ITEM = "%s receives loot: %s." --> (.+) receives loot: (.+)%. | |
886 -- LOOT_ITEM_BONUS_ROLL = "%s receives bonus loot: %s." --> (.+) receives bonus loot: (.+)%. | |
887 -- LOOT_ITEM_PUSHED = "%s receives item: %s." --> (.+) receives item: (.+)%. | |
888 ['LOOT_ss'] = ss(_G.LOOT_ITEM), | |
889 ['BONUS_ss'] = ss(_G.LOOT_ITEM_BONUS_ROLL), | |
890 ['ITEM_ss'] = ss(_G.LOOT_ITEM_PUSHED), | |
891 | |
892 -- LOOT_ITEM_MULTIPLE = "%s receives loot: %sx%d." --> (.+) receives loot: (.+)(x%d+)%. | |
893 -- LOOT_ITEM_BONUS_ROLL_MULTIPLE = "%s receives bonus loot: %sx%d." --> (.+) receives bonus loot: (.+)(x%d+)%. | |
894 -- LOOT_ITEM_PUSHED_MULTIPLE = "%s receives item: %sx%d." --> (.+) receives item: (.+)(x%d+)%. | |
895 ['LOOT_MULTIPLE_ssd'] = ssd(_G.LOOT_ITEM_MULTIPLE), | |
896 ['BONUS_MULTIPLE_ssd'] = ssd(_G.LOOT_ITEM_BONUS_ROLL_MULTIPLE), | |
897 ['ITEM_MULTIPLE_ssd'] = ssd(_G.LOOT_ITEM_PUSHED_MULTIPLE), | |
898 | |
899 -- LOOT_ITEM_SELF = "You receive loot: %s." --> You receive loot: (.+)%. | |
900 -- LOOT_ITEM_BONUS_ROLL_SELF = "You receive bonus loot: %s." --> You receive bonus loot: (.+)%. | |
901 -- LOOT_ITEM_PUSHED_SELF = "You receive item: %s." --> You receive item: (.+)%. | |
902 ['LOOT_SELF_s'] = s(_G.LOOT_ITEM_SELF), | |
903 ['BONUS_SELF_s'] = s(_G.LOOT_ITEM_BONUS_ROLL_SELF), | |
904 ['ITEM_SELF_s'] = s(_G.LOOT_ITEM_PUSHED_SELF), | |
905 | |
906 -- LOOT_ITEM_SELF_MULTIPLE = "You receive loot: %sx%d." --> You receive loot: (.+)(x%d+)%. | |
907 -- LOOT_ITEM_BONUS_ROLL_SELF_MULTIPLE = "You receive bonus loot: %sx%d." --> You receive bonus loot: (.+)(x%d+)%. | |
908 -- LOOT_ITEM_PUSHED_SELF_MULTIPLE = "You receive item: %sx%d." --> You receive item: (.+)(x%d+)%. | |
909 ['LOOT_SELF_MULTIPLE_sd'] = sd(_G.LOOT_ITEM_SELF_MULTIPLE), | |
910 ['BONUS_SELF_MULTIPLE_sd'] = sd(_G.LOOT_ITEM_BONUS_ROLL_SELF_MULTIPLE), | |
911 ['ITEM_SELF_MULTIPLE_sd'] = sd(_G.LOOT_ITEM_PUSHED_SELF_MULTIPLE), | |
912 | |
913 -- LOOT_ITEM_WHILE_PLAYER_INELIGIBLE is mostly the same as LOOT_ITEM with | |
914 -- an inline texture and no full stop. The punctuation in the texture | |
915 -- path causes fits while matching, so just make that a wildcard rather | |
916 -- than trying to escape it all. | |
917 ['LOOT_WHILE_PLAYER_INELIGIBLE_ss'] = | |
918 _G.LOOT_ITEM_WHILE_PLAYER_INELIGIBLE:gsub('\124T%S*\124t','\124T%%S*\124t'):gsub('%%s','(.+)'), | |
919 } | |
920 _grok = setfenv (_grok, loot_patterns) | |
921 for k,v in pairs(loot_patterns) do | |
922 self.dprint('loot', "Loot pattern", k, "set to", v) | |
923 end | |
924 | |
872 self.OnInitialize = nil -- free up ALL the things! | 925 self.OnInitialize = nil -- free up ALL the things! |
873 end | 926 end |
874 | 927 |
875 function addon:OnEnable() | 928 function addon:OnEnable() |
876 self:RegisterEvent("PLAYER_LOGOUT") | 929 self:RegisterEvent("PLAYER_LOGOUT") |
962 self:Print("Error registering '%s' as a keybinding, check spelling!", | 1015 self:Print("Error registering '%s' as a keybinding, check spelling!", |
963 opts.keybinding_text) | 1016 opts.keybinding_text) |
964 end | 1017 end |
965 break | 1018 break |
966 end | 1019 end |
967 | |
968 --[[ | |
969 The five loot format patterns of interest, changed into relatively tight | |
970 string match patterns. Done at enable-time rather than load-time against | |
971 the slim chance that one of the non-US "delocalizers" needs to mess with | |
972 the global patterns before we transform them. | |
973 | |
974 The SELF patterns can be replaced with LOOT_ITEM_PUSHED_SELF[_MULTIPLE] to | |
975 trigger on 'receive item' instead, which would detect extracting stuff | |
976 from mail, or s/PUSHED/CREATED/ for things like healthstones and guild | |
977 cauldron flasks. | |
978 ]] | |
979 | |
980 -- LOOT_ITEM = "%s receives loot: %s." --> (.+) receives loot: (.+)%. | |
981 g_LOOT_ITEM_ss = LOOT_ITEM:gsub('%.$','%%.'):gsub('%%s','(.+)') | |
982 | |
983 -- LOOT_ITEM_MULTIPLE = "%s receives loot: %sx%d." --> (.+) receives loot: (.+)(x%d+)%. | |
984 g_LOOT_ITEM_MULTIPLE_sss = LOOT_ITEM_MULTIPLE:gsub('%.$','%%.'):gsub('%%s','(.+)'):gsub('x%%d','(x%%d+)') | |
985 | |
986 -- LOOT_ITEM_SELF = "You receive loot: %s." --> You receive loot: (.+)%. | |
987 g_LOOT_ITEM_SELF_s = LOOT_ITEM_SELF:gsub('%.$','%%.'):gsub('%%s','(.+)') | |
988 | |
989 -- LOOT_ITEM_SELF_MULTIPLE = "You receive loot: %sx%d." --> You receive loot: (.+)(x%d+)%. | |
990 g_LOOT_ITEM_SELF_MULTIPLE_ss = LOOT_ITEM_SELF_MULTIPLE:gsub('%.$','%%.'):gsub('%%s','(.+)'):gsub('x%%d','(x%%d+)') | |
991 | |
992 -- LOOT_ITEM_WHILE_PLAYER_INELIGIBLE is mostly the same as LOOT_ITEM with | |
993 -- an inline texture and no full stop. The punctuation in the texture | |
994 -- path causes fits while matching, so just make that a wildcard rather | |
995 -- than trying to escape it all. | |
996 g_LOOT_ITEM_WHILE_PLAYER_INELIGIBLE_ss = LOOT_ITEM_WHILE_PLAYER_INELIGIBLE: | |
997 gsub('\124T%S*\124t','\124T%%S*\124t'):gsub('%%s','(.+)') | |
998 | 1020 |
999 --[[ | 1021 --[[ |
1000 Throw in the default disposition types. This could be called during load | 1022 Throw in the default disposition types. This could be called during load |
1001 were it not for the need to talk to the GUI data (not set up yet). | 1023 were it not for the need to talk to the GUI data (not set up yet). |
1002 | 1024 |
1690 break | 1712 break |
1691 end | 1713 end |
1692 end | 1714 end |
1693 | 1715 |
1694 if (self.rebroadcast and (not from)) and not local_override then | 1716 if (self.rebroadcast and (not from)) and not local_override then |
1695 self:vbroadcast('loot', recipient, unique, itemstring, count) | 1717 self:vbroadcast('loot', recipient, unique, itemstring, count, extratext) |
1696 end | 1718 end |
1697 if (not self.enabled) and (not local_override) then break end | 1719 if (not self.enabled) and (not local_override) then break end |
1698 | 1720 |
1699 local oldersig = recipient .. iname .. (count or "") | 1721 local oldersig = recipient .. iname .. (count or "") |
1700 local signature, seenit | 1722 local signature, seenit |
1782 "> added to cache as candidate", #candidates) | 1804 "> added to cache as candidate", #candidates) |
1783 end | 1805 end |
1784 break | 1806 break |
1785 end | 1807 end |
1786 self.dprint('loot',"<<"..prefix, "out") | 1808 self.dprint('loot',"<<"..prefix, "out") |
1787 return ret1, ret2 | 1809 return ret1, ret2 -- FIXME mostly garbage |
1810 end | |
1811 | |
1812 local match = string.match | |
1813 _grok = function (msg, bonus_p, item_p) | |
1814 local person, itemlink, count, extra | |
1815 while true do | |
1816 extra = "loot" | |
1817 -- test in most likely order: other people get more loot than you do | |
1818 person, itemlink, count = match (msg, LOOT_MULTIPLE_ssd); if person then break end | |
1819 person, itemlink = match (msg, LOOT_ss); if person then break end | |
1820 -- Could only do this if in an LFR... but the restriction | |
1821 -- might apply elsewhere soon enough. | |
1822 person, itemlink = match (msg, LOOT_WHILE_PLAYER_INELIGIBLE_ss); if person then break end | |
1823 | |
1824 -- other people get more bonus loot than you do, too | |
1825 if bonus_p then | |
1826 extra = "bonus" | |
1827 person, itemlink, count = match (msg, BONUS_MULTIPLE_ssd); if person then break end | |
1828 person, itemlink = match (msg, BONUS_ss); if person then break end | |
1829 end | |
1830 | |
1831 -- i can haz cheezburgr? | |
1832 extra = "loot" | |
1833 itemlink, count = match (msg, LOOT_SELF_MULTIPLE_sd); if itemlink then break end | |
1834 itemlink = match (msg, LOOT_SELF_s); if itemlink then break end | |
1835 | |
1836 -- getting stuff out of the mailbox, the salvage boxes, etc | |
1837 if item_p then | |
1838 extra = "item" | |
1839 person, itemlink, count = match (msg, ITEM_MULTIPLE_ssd); if person then break end | |
1840 person, itemlink = match (msg, ITEM_ss); if person then break end | |
1841 itemlink, count = match (msg, ITEM_SELF_MULTIPLE_sd); if itemlink then break end | |
1842 itemlink = match (msg, ITEM_SELF_s); if itemlink then break end | |
1843 end | |
1844 break | |
1845 end | |
1846 return person, itemlink, count, extra | |
1788 end | 1847 end |
1789 | 1848 |
1790 -- Returns the index of the resulting new loot entry, or nil after | 1849 -- Returns the index of the resulting new loot entry, or nil after |
1791 -- displaying any errors. | 1850 -- displaying any errors. |
1792 local match = string.match | |
1793 function addon:CHAT_MSG_LOOT (event, ...) | 1851 function addon:CHAT_MSG_LOOT (event, ...) |
1794 if (not self.rebroadcast) and (not self.enabled) and (event ~= "manual") then return end | 1852 if (not self.rebroadcast) and (not self.enabled) and (event ~= "manual") then return end |
1795 | 1853 |
1796 if event == "CHAT_MSG_LOOT" then | 1854 if event == "CHAT_MSG_LOOT" then |
1797 local msg = ... | 1855 local msg = ... |
1798 local person, itemlink, count | |
1799 --ChatFrame2:AddMessage("original string: >"..(msg:gsub("\124","\124\124")).."<") | 1856 --ChatFrame2:AddMessage("original string: >"..(msg:gsub("\124","\124\124")).."<") |
1800 | 1857 self.dprint('loot', "CHAT_MSG_LOOT, message is >"..(msg:gsub("\124","\124\124")).."<") |
1801 -- test in most likely order: other people get more loot than "you" do | 1858 |
1802 person, itemlink, count = match(msg,g_LOOT_ITEM_MULTIPLE_sss) | 1859 local person, itemlink, count, extra = _grok (msg, opts.track_bonusrolls, opts.track_nonloot) |
1803 if not person then | |
1804 person, itemlink = match(msg,g_LOOT_ITEM_ss) | |
1805 end | |
1806 if not person then | |
1807 -- Could only do this text if in an LFR... but the restriction | |
1808 -- might apply elsewhere soon enough. | |
1809 person, itemlink = match(msg,g_LOOT_ITEM_WHILE_PLAYER_INELIGIBLE_ss) | |
1810 end | |
1811 if not person then | |
1812 itemlink, count = match(msg,g_LOOT_ITEM_SELF_MULTIPLE_ss) | |
1813 if not itemlink then | |
1814 itemlink = match(msg,g_LOOT_ITEM_SELF_s) | |
1815 end | |
1816 end | |
1817 | 1860 |
1818 if not itemlink then return end -- "PlayerX selected Greed", etc, not looting | 1861 if not itemlink then return end -- "PlayerX selected Greed", etc, not looting |
1819 self.dprint('loot', "CHAT_MSG_LOOT, person is", person, | 1862 self.dprint('loot', "CHAT_MSG_LOOT, person is", person, |
1820 ", itemlink is", itemlink, ", count is", count) | 1863 ", itemlink is", itemlink, ", count is", count, "extra is", extra) |
1864 extra = (extra == "bonus") and [[Bonus roll!]] or | |
1865 ((extra == "item") and [[Non-loot]] or nil) or | |
1866 nil | |
1821 | 1867 |
1822 -- Name might be colorized, remove the highlighting | 1868 -- Name might be colorized, remove the highlighting |
1823 if person then | 1869 if person then |
1824 person = match(person,"|c%x%x%x%x%x%x%x%x(%S+)") or person | 1870 person = match(person,"|c%x%x%x%x%x%x%x%x(%S+)") or person |
1825 else | 1871 else |
1826 person = my_name -- UNIT_YOU / You | 1872 person = my_name -- UNIT_YOU / You |
1827 end | 1873 end |
1828 | 1874 |
1829 return _do_loot (self, --[[override=]]false, person, --[[unique=]]nil, | 1875 return _do_loot (self, --[[override=]]false, person, --[[unique=]]nil, |
1830 match(itemlink,"item[%-?%d:]+"), count) | 1876 match(itemlink,"item[%-?%d:]+"), count, --[[from=]]nil, extra) |
1831 | 1877 |
1832 elseif event == "broadcast" then | 1878 elseif event == "broadcast" then |
1833 return _do_loot (self, --[[override=]]false, ...) | 1879 return _do_loot (self, --[[override=]]false, ...) |
1834 | 1880 |
1835 elseif event == "manual" then | 1881 elseif event == "manual" then |