WoWInterface

WoWInterface (https://www.wowinterface.com/forums/index.php)
-   AddOn Search/Requests (https://www.wowinterface.com/forums/forumdisplay.php?f=6)
-   -   Redirect System Messages (https://www.wowinterface.com/forums/showthread.php?t=54779)

txamethyst 11-02-16 07:28 AM

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 ;)

Kanegasi 11-02-16 04:51 PM

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.

Phanx 11-02-16 09:09 PM

Quote:

Originally Posted by Kanegasi (Post 320617)
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.

Kanegasi 11-02-16 09:33 PM

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.


All times are GMT -6. The time now is 12:50 PM.

vBulletin © 2024, Jelsoft Enterprises Ltd
© 2004 - 2022 MMOUI