WoWInterface

WoWInterface (https://www.wowinterface.com/forums/index.php)
-   Tutorials & Other Helpful Info. (https://www.wowinterface.com/forums/forumdisplay.php?f=12)
-   -   Prevent specific BNet toasts from showing up - taint free! (https://www.wowinterface.com/forums/showthread.php?t=48283)

nefftd 09-30-13 11:09 PM

Prevent specific BNet toasts from showing up - taint free!
 
In writing a little addon called OQSpam, I needed a reliable way to prevent BNet toasts from showing up. I'd seen other people in #wowuidev ask how to do this, to no avail. It seemed impossible until I traced through the FrameXML BNet.lua.

It's possible to reliably filter which toasts show in a taint-free manner by leveraging one simple fact: the BNet toast frame displays toasts using a queue, which is looped through in an OnUpdate function. Because of this, when a new toast is added it isn't actually displayed until the next OnUpdate cycle, so the toast can be removed using publicly-exposed API before that happens. It's extremely simple to do with very little code.

We need to borrow a couple constants from BNet.lua, which are hidden behind locals. So you'll need to copy them into your code, and may need to update them with each new patch. Then, we need to POST-hook the function BNToastFrame_AddToast:

Code:

-- Pull in constants from FrameXML -> BNet.lua
local BN_TOAST_TYPE_ONLINE = 1;
local BN_TOAST_TYPE_OFFLINE = 2;
local BN_TOAST_TYPE_BROADCAST = 3;
local BN_TOAST_TYPE_PENDING_INVITES = 4;
local BN_TOAST_TYPE_NEW_INVITE = 5;
local BN_TOAST_TYPE_CONVERSATION = 6;

-- Hook BNToastFrame_AddToast
hooksecurefunc('BNToastFrame_AddToast', function(toastType, toastData)
       
end)

Compare the first argument, toastType, to one of the constants we pulled in to check if it's what we're interested in. For instance, if you want to block a BNet broadcast from showing up:

Code:

-- Pull in constants from FrameXML -> BNet.lua
local BN_TOAST_TYPE_ONLINE = 1;
local BN_TOAST_TYPE_OFFLINE = 2;
local BN_TOAST_TYPE_BROADCAST = 3;
local BN_TOAST_TYPE_PENDING_INVITES = 4;
local BN_TOAST_TYPE_NEW_INVITE = 5;
local BN_TOAST_TYPE_CONVERSATION = 6;

-- Hook BNToastFrame_AddToast
hooksecurefunc('BNToastFrame_AddToast', function(toastType, toastData)
        if toastType == BN_TOAST_TYPE_BROADCAST then
                -- do the magic
        end
end)

Next, we have to use the toastData argument to do our filtering. Check the toastData argument against the API function BNetGetFriendInfoByID, and compare the returns according to how you want to filter them. For instance, if we want to block only BNet broadcasts which contain the word "BLOCK":

Code:

-- Pull in constants from FrameXML -> BNet.lua
local BN_TOAST_TYPE_ONLINE = 1;
local BN_TOAST_TYPE_OFFLINE = 2;
local BN_TOAST_TYPE_BROADCAST = 3;
local BN_TOAST_TYPE_PENDING_INVITES = 4;
local BN_TOAST_TYPE_NEW_INVITE = 5;
local BN_TOAST_TYPE_CONVERSATION = 6;

-- Hook BNToastFrame_AddToast
hooksecurefunc('BNToastFrame_AddToast', function(toastType, toastData)
        if toastType == BN_TOAST_TYPE_BROADCAST then
                local presenceID, givenName, surname, toonName, toonID, client, isOnline, lastOnline, isAFK, isDND, messageText, noteText, isRIDFriend, broadcastTime, canSoR = BNGetFriendInfoByID(toastData)
               
                if messageText:match('BLOCK') then  -- check if the message contains 'BLOCK'
                        BNToastFrame_RemoveToast(toastType, toastData)  -- VOILA!
                end
        end
end)

We use the public function BNToastFrame_RemoveToast to remove the toast. Because toasts don't get displayed until the next OnUpdate (screen frame), this removes the toast from the queue before it gets displayed at all -- the annoying sound doesn't even play. And as you can see, we've done this in a taint-free fashion.

Resike 10-01-13 10:33 AM

You realize you can disable this in the game options.

nefftd 10-01-13 04:10 PM

Quote:

Originally Posted by Resike (Post 285381)
You realize you can disable this in the game options.

Yes, you can disable all toasts. But more than one developer has expressed in interest in only hiding certain toasts. Take a look at my addon OQSpam for example. '

oQueue uses BNet broadcasts to communicate that oQueue is enabled. This causes broadcast toasts to appear often that just say "(OQ)" (in addition to chat frame spam). It's irritating, and some people want to be able to see normal toasts without seeing those. That's why I researched this method in the first place.


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

vBulletin © 2020, Jelsoft Enterprises Ltd
© 2004 - 2020 MMOUI