View Single Post
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