Thread Tools Display Modes
09-20-09, 09:29 AM   #1
Dainton
A Flamescale Wyrmkin
 
Dainton's Avatar
AddOn Author - Click to view addons
Join Date: Jun 2008
Posts: 115
Intoxication level filtering

So since Brewfest is upon us I've realized how annoying the tipsy/drunk spam is (its always kind of irked me, but this event really made me want to do something about it). I'm wanting to filter out the DRUNK_MESSAGE_OTHER and DRUNK_MESSAGE_ITEM_OTHER system messages, but I don't really have all of the know how to piece everything together.

I'm pretty sure that there needs to be a ChatFrame_AddMessageEventFilter in there along with a gsub or two, but like I said my knowledge of LUA is amateur at best.

The messages that I'd like to filter from the GlobalStrings.lua are:
DRUNK_MESSAGE_ITEM_OTHER1 = "%s is looking sober from the %s.";
DRUNK_MESSAGE_ITEM_OTHER2 = "%s seems a little tipsy from the %s.";
DRUNK_MESSAGE_ITEM_OTHER3 = "%s is getting drunk off of %s.";
DRUNK_MESSAGE_ITEM_OTHER4 = "%s is completely smashed from the %s.";
DRUNK_MESSAGE_OTHER1 = "%s seems to be sobering up.";
DRUNK_MESSAGE_OTHER2 = "%s looks tipsy.";
DRUNK_MESSAGE_OTHER3 = "%s looks drunk.";
DRUNK_MESSAGE_OTHER4 = "%s looks completely smashed.";

I tried to guess and throw a little something together after looking at a couple of mods that do much more than I want, but it completely destroys the CHAT_MSG_SYSTEM
lua Code:
  1. local function intox(frame, event, msg, ...)
  2.     for i=1,4 do
  3.         if msg:match("DRUNK_MESSAGE_ITEM_OTHER"..i) then
  4.             msg:gsub("%%s", ".*")
  5.         elseif msg:match("DRUNK_MESSAGE_OTHER"..i) then
  6.             msg:gsub("%%s", ".*")
  7.         end
  8.     end
  9. end
  10. ChatFrame_AddMessageEventFilter("CHAT_MSG_SYSTEM", intox)
(I'm not sure if this is the one that did nothing or broke everything.)

Any help with this is greatly appreciated.
  Reply With Quote
09-20-09, 09:41 AM   #2
Waverian
A Chromatic Dragonspawn
AddOn Author - Click to view addons
Join Date: Dec 2006
Posts: 188
lua Code:
  1. local function intox(frame, event, msg, ...)
  2.     for i=1,4 do
  3.         if msg:match("DRUNK_MESSAGE_ITEM_OTHER"..i) then
  4.             msg:gsub("%%s", ".*")
  5.         elseif msg:match("DRUNK_MESSAGE_OTHER"..i) then
  6.             msg:gsub("%%s", ".*")
  7.         end
  8.     end
  9. end
  10. ChatFrame_AddMessageEventFilter("CHAT_MSG_SYSTEM", intox)

Few problems:

* In a message event filter, you return true to filter the message completely, return false to let it pass unaltered, or return a modified string and the vararg to modify the message.

* The DRUNK_MESSAGE_ITEM_OTHERN and DRUNK_MESSAGE_OTHERN are global variables. You're just comparing your message to a direct string called DRUNK_MESSAGE_ITEM_OTHERN, etc. You want to access the variable.


Code:
local function intox(frame, event, msg, ...)
	for i=1,4 do
		-- access the global variable
		if msg:match(_G["DRUNK_MESSAGE_ITEM_OTHER"..i]) or msg:match(_G["DRUNK_MESSAGE_OTHER"..i]) then
			return true
		end
	end
	return false -- this is probably implied and not needed
end
ChatFrame_AddMessageEventFilter("CHAT_MSG_SYSTEM", intox)
Something like that, ish.

Last edited by Waverian : 09-20-09 at 09:44 AM.
  Reply With Quote
09-20-09, 09:54 AM   #3
xConStruct
A Chromatic Dragonspawn
 
xConStruct's Avatar
AddOn Author - Click to view addons
Join Date: May 2008
Posts: 199
In addition:
The gsub(), as you already said, is necessary to match the pattern correctly, because "%s" would only match one character, but we need to match multiple ones.

Code:
local function intox(frame, event, msg, ...)
	for i=1,4 do
		-- access the global variable
		local drunk1 = _G["DRUNK_MESSAGE_ITEM_OTHER"..i]:gsub("%%s", "%s-")
		local drunk2 = _G["DRUNK_MESSAGE_OTHER"..i]:gsub("%%s", "%s-")
		if msg:match(drunk1) or msg:match(drunk2) then
			return true
		end
	end
	return false -- this is probably implied and not needed
end
ChatFrame_AddMessageEventFilter("CHAT_MSG_SYSTEM", intox)
__________________
« Website | GitHub »

Oh hai!
  Reply With Quote
09-20-09, 10:17 AM   #4
Slakah
A Molten Giant
 
Slakah's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2007
Posts: 863
%s in a patterns matches a space so instead of replacing it with %s- you would instead probably need to replace it with a .+, I know cargor probably knows this and has just made a silly mistake :P
lua Code:
  1. local patterns = {}
  2. local limit = 4
  3. for i = 1, limit do
  4.     patterns[(i*2)-1] = _G["DRUNK_MESSAGE_ITEM_OTHER"..i]:gsub("%%s", "%s-")) -- odd
  5.     patterns[i*2] = _G["DRUNK_MESSAGE_OTHER"..i]:gsub("%%s", "%s-") -- even
  6. end
  7.  
  8. local function intox(f, e, msg)
  9.     for i = 1, limit * 2 do
  10.         if msg:find(pattern) then
  11.             return true
  12.         end
  13.     end
  14.     return false
  15. end
  16.  
  17. ChatFrame_AddMessageEventFilter("CHAT_MSG_SYSTEM", intox)
is what I would use.

edit: Grrrr why on earth can't [highlight] handle parenthesis .

Last edited by Slakah : 09-20-09 at 10:20 AM.
  Reply With Quote
09-20-09, 11:01 AM   #5
xConStruct
A Chromatic Dragonspawn
 
xConStruct's Avatar
AddOn Author - Click to view addons
Join Date: May 2008
Posts: 199
Ha, collective knowledge - we get further with every reply
You're right with %s ... that explain why my match() printed so strange results in my lua-environment :P

To hopefully make it ready for copy&paste (although [highlight]'s copying of line-numbers is bugging me):
With "pattern" slakah meant "patterns[i]" (:

lua Code:
  1. local patterns = {}
  2. local limit = 4
  3. for i = 1, limit do
  4.     patterns[(i*2)-1] = _G["DRUNK_MESSAGE_ITEM_OTHER"..i]:gsub("%%s", ".+")) -- odd
  5.     patterns[i*2] = _G["DRUNK_MESSAGE_OTHER"..i]:gsub("%%s", ".+") -- even
  6. end
  7.  
  8. local function intox(f, e, msg)
  9.     for i = 1, limit * 2 do
  10.         if msg:find(patterns[i]) then
  11.             return true
  12.         end
  13.     end
  14.     return false
  15. end
  16.  
  17. ChatFrame_AddMessageEventFilter("CHAT_MSG_SYSTEM", intox)
__________________
« Website | GitHub »

Oh hai!
  Reply With Quote
09-20-09, 12:23 PM   #6
Dainton
A Flamescale Wyrmkin
 
Dainton's Avatar
AddOn Author - Click to view addons
Join Date: Jun 2008
Posts: 115
You guys are amazing!

I'll try this out later in the day to see if it works. Would any of you mind explaining what all of the math that's going on means? The [(i*2)-1], [i*2], and i=1,limit*2. I understand the rest of the code except for this.

P.S. Someone needs the fix the square brackets not being able to display properly in highlight tags.
  Reply With Quote
09-20-09, 12:58 PM   #7
Waverian
A Chromatic Dragonspawn
AddOn Author - Click to view addons
Join Date: Dec 2006
Posts: 188
i*2-1 will always be an odd number, and i*2 will always be an even number. It's just an array where odd indexes are DRUNK_MESSAGE_ITEM_OTHERN and even are DRUNK_MESSAGE_OTHERN.

Since there's 2 types of message, and 4 of each type, there's a total of 8 possible messages, or 8 indexes in our patterns table. limit * 2 iterates all of them.


This seems like a really convoluted method though. What's the advantage? Readability seems worse. You're trading 8 :gsub calls for 4 more iterations and a table access. I guess efficiency?
  Reply With Quote
09-20-09, 01:13 PM   #8
xConStruct
A Chromatic Dragonspawn
 
xConStruct's Avatar
AddOn Author - Click to view addons
Join Date: May 2008
Posts: 199
I would have used tinsert() or patterns[#patterns+1] instead of messing around with odd and even indizes. And also #patterns instead of limit * 2

If I were to write this code, I would probably follow Slakah's approach, because in my opinion it makes the code a lot more readable - we've got a table for all checks and then iterate over it, instead of cluttering the function with the lenghty variable name and gsub(). That is also the reason why I used the two locals in my first code instead of writing it all in one line.

It can be more efficient: We are building the table with our gsub()-patterns on load and then just access the table, thus avoiding two gsub() calls in our function, concatenating a string ("DRUNK_MESSAGE_OTHER"..i) and accessing the global table - and just doing one table access to our local one. So, it can be more efficient CPU-wise, but the effects are barely noticable if at all.

Conclusion: It's just a matter of preference and what you prefer for readabilty
__________________
« Website | GitHub »

Oh hai!
  Reply With Quote
09-20-09, 06:47 PM   #9
Layrajha
A Frostmaul Preserver
 
Layrajha's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 275
I have a question that I should be ashamed of... but well, coding in a script language seems to make ugly code less unforgivable.

What happens if you just replace all the global strings by the empty string? Does it work properly, does it print empty lines, or does it output lua errors? In the first case, it would certainly be the most efficient way, even if I would certainly not write this in anything public
  Reply With Quote
09-21-09, 05:57 AM   #10
xConStruct
A Chromatic Dragonspawn
 
xConStruct's Avatar
AddOn Author - Click to view addons
Join Date: May 2008
Posts: 199
In this case, I would guess that it prints out the empty string (e.g. ""), since Blizz mostly doesn't check beforehand if the string is empty or not. If you set it nil, it would most likely result in an error.
Just try it

There are also examples where global strings are used in a secure environment and if you change them, they become tainted and can block code from functioning correctly.
A good example is the global string RANGE_INDICATOR (which is the small dot on action bars and the item-button of the quest tracker) - if you set it to "" to hide it, the item-button doesn't work anymore if you click it, because its environment is tainted.
__________________
« Website | GitHub »

Oh hai!
  Reply With Quote
09-21-09, 07:03 AM   #11
Layrajha
A Frostmaul Preserver
 
Layrajha's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 275
Originally Posted by Cargor View Post
In this case, I would guess that it prints out the empty string (e.g. ""), since Blizz mostly doesn't check beforehand if the string is empty or not. If you set it nil, it would most likely result in an error.
Just try it
Set it to nil and disable lua errors!


...

/runawayinshame

Originally Posted by Cargor View Post
There are also examples where global strings are used in a secure environment and if you change them, they become tainted and can block code from functioning correctly.
A good example is the global string RANGE_INDICATOR (which is the small dot on action bars and the item-button of the quest tracker) - if you set it to "" to hide it, the item-button doesn't work anymore if you click it, because its environment is tainted.
Nice to know. I wouldn't have guessed that global strings could be used in any secure environment. Not that there's any problem with not being able to change RANGE_INDICATOR though
  Reply With Quote

WoWInterface » Developer Discussions » General Authoring Discussion » Intoxication level filtering

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off