Reply
Thread Tools Display Modes
Unread 09-30-13, 11:09 PM   #1
nefftd
A Murloc Raider
AddOn Author - Click to view addons
Join Date: Mar 2012
Posts: 4
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.
nefftd is offline   Reply With Quote
Unread 10-01-13, 10:33 AM   #2
Resike
A Molten Giant
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 618
You realize you can disable this in the game options.

Last edited by Resike : 10-01-13 at 10:47 AM.
Resike is offline   Reply With Quote
Unread 10-01-13, 04:10 PM   #3
nefftd
A Murloc Raider
AddOn Author - Click to view addons
Join Date: Mar 2012
Posts: 4
Originally Posted by Resike View Post
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.
nefftd is offline   Reply With Quote
Reply

Go BackWoWInterface » Developer Discussions » Tutorials & Other Helpful Info. » Prevent specific BNet toasts from showing up - taint free!

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