Thread Tools Display Modes
09-10-17, 06:27 AM   #1
Sylen
A Wyrmkin Dreamwalker
AddOn Author - Click to view addons
Join Date: Jan 2011
Posts: 50
Filter Buffs/Debuffs on Default Nameplates

TL;TR:
Is there a clean way you can filter(whitelist) the buffs/debuffs shown on the default blizzard nameplates (including the new personal resource display)?


I tried to modify the default filter to show all harmful spells by a player but as far as i can tell it achieved nothing. This is the code i am using for it
Code:
hooksecurefunc(NamePlateDriverFrame, "OnUnitAuraUpdate", function(self, unit)
	local filter;
	if UnitIsUnit("player", unit) then
		filter = "HELPFUL|INCLUDE_NAME_PLATE_ONLY";
	else
		local reaction = UnitReaction("player", unit);
		if reaction and reaction <= 4 then
			-- Reaction 4 is neutral and less than 4 becomes increasingly more hostile
			filter = "HARMFUL|PLAYER";
		else
			filter = "NONE";
		end
	end
 
	local nameplate = C_NamePlate.GetNamePlateForUnit(unit);
	if (nameplate) then
		nameplate.UnitFrame.BuffFrame:UpdateBuffs(nameplate.namePlateUnitToken, filter);
	end
end)
After some research i stumbled upon this thread in which the same problem is identified by Ketho but it seems nobody found a solution.

I researched more and found this script/macro on the mmo-champion forums, which stated by the author does the following:
"I was also disappointed the nameplates weren't showing all buffs on me so this script makes it show ALL buffs except indefinite buffs or buffs that last more than about a minute. It also doesn't show buffs with the SpellID specified by b so you can add your own unwanted SpellIDs to b or just leave it as b={} if you don't care."
Source
Code:
/run local b={196608,126896};local gn=UnitAura;local function fn(...)local a={gn(...)};a[15]=a[6]~=nil and not tContains(b,a[11])and abs(a[6]-31)<31;return unpack(a);end UnitAura=fn;
This script does indeed work but it uses a blacklist-filtering and i felt like creating a blacklist for all buffs i don't want to see on myself is too much work.
I figured what i need is a whitelist filter so i changed the script to this:
Code:
--Filter buffs/debuffs on nameplates, personal resource display
local filter = CreateFrame("Frame")
filter:RegisterEvent("PLAYER_ENTERING_WORLD")

filter:SetScript("OnEvent", function()
	--This filters debuffs and buffs(personal resource display)
	local Whitelist = {}
	
	local gn = UnitAura
	local function Filter(...)
		local AllBuffs = {gn(...)}
		AllBuffs[15] = AllBuffs[6] ~= nil and tContains(Whitelist, AllBuffs[11]) and abs(AllBuffs[6]-31)<31 return unpack(AllBuffs) end
	UnitAura = Filter
end)
The whitelist filter works just fine but another problem now occured, the script eats tremendous amounts of memory while running for a longer time resulting in a performance loss and fps drop.
At this point it overextends my coding knowledge and i don't really know how to move on.
  Reply With Quote
09-13-17, 04:44 AM   #2
CC_WOW
A Deviate Faerie Dragon
 
CC_WOW's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2016
Posts: 19
I'm not an expert by any means, but some basic profiling tells me that each time the Filter function is called you use an additional 700-800 bytes of memory (sometimes more) which are never freed (that part is the problem). This is probably the result of you re-creating tables every time the code is execute with the { ... } constructor - see http://lua-users.org/wiki/OptimisingGarbageCollection

Running collectgarbage("collect") would help, but it is obviously not a practical solution unless you do it at a given threshold only. Normally, the garbage collector would mark the unused table and should collect ("sweep") it automatically, but in my tests it simply hasn't done that and I couldn't tell you why - I assume it runs when too much memory has been used, which should still be long before you are getting FPS drops.

PS: Is overwriting APIs like that really a good idea? UnitAura is used by at least Blizzard_NamePlates and also in the BuffFrame (I think). But someone else surely is more proficient than I am in these things :P
  Reply With Quote
09-13-17, 06:42 AM   #3
Sylen
A Wyrmkin Dreamwalker
AddOn Author - Click to view addons
Join Date: Jan 2011
Posts: 50
I will have a look into this.

As far as overwriting Blizzard functions goes, i'm not really a fan of doing it but i haven't found a clean solution to filter the buffs.

I also still don't really understand how Blizzard itself filters the buffs. When I am playing on my Feral Druid and spec into Savage Roar, it is displayed above the PersonalResourceDisplay. The question is, how does the game know that it has to show this buff in particular. So there must be some kind of filtering already in place. The only important thing is, can you access it by Lua or is it somewhere in the C code. I couldn't find a pre-set whitelist in the interface code so I'm guessing you can not access it.
  Reply With Quote
09-13-17, 11:20 AM   #4
Ammako
A Frostmaul Preserver
AddOn Author - Click to view addons
Join Date: Jun 2016
Posts: 256
Google brought me to this thread on MMOC, with a script which seems to work:

Code:
local whitelist = {
	["Goremaw's Bite"] = "player",
	["Night Terrors"] = "player",
	["Nightblade"] = "player",
	["Symbols of Death"] = "player"
}

local function newShouldShowBuff(_,name,caster)
	return name and (whitelist[name] == caster or whitelist[name] == "all")
end

local function Mixin(baseFrame)
	baseFrame.UnitFrame.BuffFrame.ShouldShowBuff = newShouldShowBuff
end

local f = CreateFrame("Frame")
f:RegisterEvent("NAME_PLATE_UNIT_ADDED")
f:SetScript("OnEvent", function(_,_,unitId)
	Mixin(C_NamePlate.GetNamePlateForUnit(unitId))
end)

for _,baseFrame in pairs(C_NamePlate.GetNamePlates()) do
	Mixin(baseFrame)
end
Keep in mind this is a strict whitelist filter; buffs that normally show on nameplates as per default UI will be hidden unless they are added to the whitelist (I think that was already what you wanted, either way.)

https://gfycat.com/violetoldfashionedgraywolf

Haven't tested this for too long so I can't tell you if it runs into memory issues, but at least it doesn't make me puke inside my mouth by overwriting a global function.


Edit: Playing a bit more with this code enabled, it doesn't look like this works well at all. I had a few debuffs that weren't whitelisted that appeared on nameplates anyway.
Maybe somebody can figure out why it happens and fix the script, or come up with a different solution altogether :/

Last edited by Ammako : 09-13-17 at 02:52 PM.
  Reply With Quote
09-18-17, 08:26 AM   #5
Sylen
A Wyrmkin Dreamwalker
AddOn Author - Click to view addons
Join Date: Jan 2011
Posts: 50
Hey, thanks for your input Ammako. I'm gonna try this new code out for a while and will report my results back here.

Can you by any chance remember some of the buffs/debuffs that were not whitelisted, but showed up anyway?
  Reply With Quote
09-18-17, 11:38 AM   #6
Ammako
A Frostmaul Preserver
AddOn Author - Click to view addons
Join Date: Jun 2016
Posts: 256
I was in Suramar fishing for the daily, and the Paladin Judgement debuff was showing on the mini-boss' nameplate. I think there may have been another one but I can't remember.

All I had in the whitelist were those four sub rogue buffs/debuffs; I didn't even mean to keep this code running and had simply forgotten to comment it out, but that's probably a good thing because I wouldn't have caught the issue otherwise.
  Reply With Quote
09-18-17, 03:02 PM   #7
Sylen
A Wyrmkin Dreamwalker
AddOn Author - Click to view addons
Join Date: Jan 2011
Posts: 50
I was able to reproduce this issue. There are several buffs / debuffs shown that are not in the whitelist.

I queued some random battlegrounds and noticed that the collectable buffs (berserk, heal, sprint) show up aswell as the indefinite buffs you get for defending a flag.
  Reply With Quote
09-20-17, 04:03 AM   #8
Sylen
A Wyrmkin Dreamwalker
AddOn Author - Click to view addons
Join Date: Jan 2011
Posts: 50
Running this code the past days in different environments leads me to the conclusion that there is no logic behind which buffs/debuffs show up in spite of that they are not whitelisted.
I will add an additional blacklist filter for now. Let's see if this gets out of hand fairly quickly or if the list is clearly arranged.
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Filter Buffs/Debuffs on Default Nameplates

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