Thread Tools Display Modes
11-02-16, 07:28 AM   #1
txamethyst
An Aku'mai Servant
 
txamethyst's Avatar
Join Date: Feb 2005
Posts: 36
Redirect System Messages

A long time ago there was this mod:

http://www.wowinterface.com/download...ntrolTool.html

I would like to know if there is a way to resurrect some portion of it.

To be specific I want to make a new window for all system messages and then redirect a few things to the main chat window (guild member logon/off as an example). New window is the easy part but I don't have the knowledge to do any more than that.

Thanks in advance
  Reply With Quote
11-02-16, 04:51 PM   #2
Kanegasi
A Molten Giant
 
Kanegasi's Avatar
AddOn Author - Click to view addons
Join Date: Apr 2007
Posts: 666
I do something similar in my personal addon where I hide and redirect LocalDefense spam to print() so that it doesn't trigger the channel sound I have set in Prat. With some minor tweaks, this should work for your usage.

What I have:

lua Code:
  1. local frame=CreateFrame('frame')
  2.  
  3. function frame:PLAYER_LOGIN()
  4.     ChatFrame_AddMessageEventFilter('CHAT_MSG_CHANNEL',function(_,_,_,sender,_,chan,_,_,_,_,_,_,_,guid)
  5.         if strmatch(chan,'LocalDefense') and sender=='' and not guid then return true end
  6.     end) -- hides local defense system spam
  7. end
  8.  
  9. function frame:CHAT_MSG_CHANNEL(msg,sender,_,chan,_,_,_,_,_,_,_,guid)
  10.     if strmatch(chan,'LocalDefense') and sender=='' and not guid then print(msg) end
  11. end -- prints local defense system spam to ChatFrame1
  12.  
  13. frame:RegisterEvent('PLAYER_LOGIN')
  14. frame:RegisterEvent('CHAT_MSG_CHANNEL')
  15. frame:SetScript('OnEvent',function(self,event,...)self[event](self,...)end)


What should work for you:

lua Code:
  1. local frame=CreateFrame("frame")
  2.  
  3. function frame:PLAYER_LOGIN()
  4.     ChatFrame_AddMessageEventFilter("CHAT_MSG_SYSTEM",function(_,_,msg)
  5.         if strmatch(msg,FRIENDS_LIST_ONLINE)
  6.         or strmatch(msg,FRIENDS_LIST_OFFLINE)
  7. --      or strmatch(msg,VARIABLE_CONTAINING_STRING)
  8. --      or strmatch(msg,"manually entered string")
  9.         then return true end
  10.     end)
  11. end
  12.  
  13. function frame:CHAT_MSG_SYSTEM(msg)
  14.     if strmatch(msg,FRIENDS_LIST_ONLINE)
  15.     or strmatch(msg,FRIENDS_LIST_OFFLINE)
  16. --  or strmatch(msg,VARIABLE_CONTAINING_STRING)
  17. --  or strmatch(msg,"manually entered string")
  18.     then print(msg) end
  19. end
  20.  
  21. frame:RegisterEvent("PLAYER_LOGIN")
  22. frame:RegisterEvent("CHAT_MSG_SYSTEM")
  23. frame:SetScript("OnEvent",function(self,event,...)self[event](self,...)end)


To reroute more system messages, just add another strmatch line to both blocks as shown above. Make sure to remove the -- at the beginning of the line for things you add. If you are not familiar with making an addon, paste the above into http://addon.bool.no and it'll give you a zip file you can install like any other addon.
  Reply With Quote
11-02-16, 09:09 PM   #3
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Originally Posted by Kanegasi View Post
What should work for you
Close, but FRIENDS_LIST_ONLINE = "Online" and the system message you see when a friend logs in is "Kanegasi has come online." Lua is case-sensitive, so "Online" won't match the "online" in the system message. Also, the adjective "online" (as in FRIENDS_LIST_ONLINE) might not be the same word (or the same form of the word) as the present-perfect-tense verb "has come online" in languages other than English. To fix both of those issues, you should look for the actual string that's used for the system message. In this case, it's ERR_FRIEND_OFFLINE_S = "%s has gone offline."

Then you run into another problem, which is that simply passing ERR_FRIEND_OFFLINE_S to string.match won't match "Kanegasi has come online." because the ERR_FRIEND_OFFLINE_S contains a formatting token -- "%s" means "insert string here" and is used to mark where the player name goes. However, in string matching, "%s" means "look for one whitespace character".

If you want to use Blizzard's global strings for string matching, you have to "translate" the formatting tokens into pattern-matching tokens first:

Code:
local function topattern(str)
	if not str then return "" end
	str = gsub(str, "%%%d?$?c", ".+")
	str = gsub(str, "%%%d?$?d", "%%d+")
	str = gsub(str, "%%%d?$?s", ".+")
	str = gsub(str, "([%(%)])", "%%%1")
	return str
end
I'd also suggest using a table to hold all the strings you want to look for, rather than writing a long if-elseif chain:

Code:
local patterns = {
	topattern(ERR_FRIEND_OFFLINE_S),
	topattern(ERR_FRIEND_ONLINE_SS),
}
Then, in your event handler, just loop over the table:

Code:
for i = 1, #patterns do
	if msg:match(pattern) then
		return print(msg)
	end
end
Also, you don't need both a message filter and an event handler. The filter function can call print before returning true for the filter system. (And you don't need to wait for PLAYER_LOGIN to register the filter function.)

Code:
ChatFrame_AddMessageEventFilter("CHAT_MSG_SYSTEM",function(_,_,msg)
	for i = 1, #patterns do
		if msg:match(pattern) then
			print(msg)
			return true
		end
	end
end)
Finally, print just shows the message in white. If you want those messages to be shown in the system message color, you have to add the color yourself:

Code:
local color = ChatTypeColor.SYSTEM
print(string.format("|cff%x%x%x%x%x%x%s|r", color.r * 255, color.g * 255, color.b * 255, msg))
So the final version combining all of the above would be:

Code:
local function topattern(str)
	if not str then return "" end
	str = gsub(str, "%%%d?$?c", ".+")
	str = gsub(str, "%%%d?$?d", "%%d+")
	str = gsub(str, "%%%d?$?s", ".+")
	str = gsub(str, "([%(%)])", "%%%1")
	return str
end

local patterns = {
	topattern(ERR_FRIEND_OFFLINE_S),
	topattern(ERR_FRIEND_ONLINE_SS),
	-- Add more global strings here.
}

ChatFrame_AddMessageEventFilter("CHAT_MSG_SYSTEM",function(_,_,msg)
	for i = 1, #patterns do
		if msg:match(pattern) then
			local color = ChatTypeColor.SYSTEM
			print(string.format("|cff%x%x%x%x%x%x%s|r", color.r * 255, color.g * 255, color.b * 255, msg))
			return true
		end
	end
end)
And, if you wanted to be more explicit, you could use ChatFrame1:AddMessage instead of print. You'd also need to make this change if you wanted to send the messages anywhere other than ChatFrame1.
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.

Last edited by Phanx : 11-02-16 at 09:11 PM.
  Reply With Quote
11-02-16, 09:33 PM   #4
Kanegasi
A Molten Giant
 
Kanegasi's Avatar
AddOn Author - Click to view addons
Join Date: Apr 2007
Posts: 666
I didn't think about just using the actual strings. I even use your method of filtering %s in my Decliner addon. Also, the localdefense filter I have carries the yellow color over through print(), but probably because the |c code is in the message itself.
  Reply With Quote

WoWInterface » AddOns, Compilations, Macros » AddOn Search/Requests » Redirect System Messages

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