Thread Tools Display Modes
07-09-15, 09:48 PM   #1
alikim
A Fallenroot Satyr
Join Date: Jul 2015
Posts: 27
Question Why this addon action is blocked?

Hi,

I'm writing an addon that disables ExtraActionBarFrame and creates my own frame to use instead.

Code:
PLBARS[10*9+6] - stores a flag to switch between custom and default bars
xRef[9][1]  - my custom frame, "ExtraBarFrame"
xRef[9][2] - texture of xRef[9][1]
xRef[9][3] - secure template button, child of xRef[9][1], "ExtraBarFrameButton"
xRef[9][4] - texture of xRef[9][3]

This is the function that is called on UPDATE_EXTRA_ACTIONBAR:

local function setExtraBar()
	if PLBARS[10*9+6] == 1 then
		xRef[9][1]:Show()
		ExtraActionBarFrame.button:Hide()

		local EABF = ExtraActionBarFrame
		local tex = EABF.button.icon:GetTexture()
		if not HasExtraActionBar() then 
			xRef[9][3]:Hide()
			xRef[9][2]:SetTexture(unpack(PLBARS[10*9 + 5]))
		else
			if tex ~= nil then xRef[9][4]:SetTexture(tex) end
			xRef[9][3]:Show()
			xRef[9][2]:SetTexture(unpack(barColor["EXTRA"]))
		end
    
	else
		xRef[9][1]:Hide()
		ExtraActionBarFrame.button:Show()
	end
end
Everything works just fine except sometimes when I throw an extra bar item while in combat I have a message that interface action failed because of the addon and my custom secure button is not being hidden.

This is what taint.log says:

Code:
7/10 13:23:52.412  ActionButton_UpdateFlyout()
7/10 13:23:52.412  An action was blocked in combat because of taint from PlayerBars - ExtraBarFrame:Show()
7/10 13:23:52.412      Interface\AddOns\PlayerBars\main.lua:163 setExtraBar()
7/10 13:23:52.412      Interface\AddOns\PlayerBars\main.lua:421
7/10 13:23:52.412  ActionButton_UpdateFlyout()
7/10 13:23:52.412  An action was blocked in combat because of taint from PlayerBars - ExtraActionButton1:Hide()
7/10 13:23:52.412      Interface\AddOns\PlayerBars\main.lua:164 setExtraBar()
7/10 13:23:52.412      Interface\AddOns\PlayerBars\main.lua:421
7/10 13:23:52.412  ActionButton_UpdateFlyout()
7/10 13:23:52.412  An action was blocked in combat because of taint from PlayerBars - ExtraBarFrameButton:Hide()
7/10 13:23:52.412      Interface\AddOns\PlayerBars\main.lua:169 setExtraBar()
7/10 13:23:52.412      Interface\AddOns\PlayerBars\main.lua:421
Can anyone help me to figure out how to fix this?

Thanks,

Last edited by alikim : 07-09-15 at 09:53 PM.
  Reply With Quote
07-10-15, 04:33 AM   #2
rowaasr13
A Fallenroot Satyr
AddOn Author - Click to view addons
Join Date: Jun 2007
Posts: 27
That's obviously because you can't do anything with secure buttons in combat. It is the vary basis of their design: you get access to limited set of secure functions under scheme that prevents you to reprogram it on-the-fly in the combat and thus achieve automation.
__________________
Garrison Mission Manager
  Reply With Quote
07-10-15, 05:51 AM   #3
alikim
A Fallenroot Satyr
Join Date: Jul 2015
Posts: 27
Originally Posted by rowaasr13 View Post
That's obviously because you can't do anything with secure buttons in combat. It is the vary basis of their design: you get access to limited set of secure functions under scheme that prevents you to reprogram it on-the-fly in the combat and thus achieve automation.
I can make a secure button that casts a spell during combat, so why can't I make a secure button that throws a grenade during combat? I'm not reprogramming it, I just show or hide it.

Anyway, then how do I make my own version of the ExtraActionBar functionality?
  Reply With Quote
07-10-15, 06:12 AM   #4
rowaasr13
A Fallenroot Satyr
AddOn Author - Click to view addons
Join Date: Jun 2007
Posts: 27
Originally Posted by alikim View Post
I can make a secure button that casts a spell during combat, so why can't I make a secure button that throws a grenade during combat? I'm not reprogramming it, I just show or hide it.
Anyway, then how do I make my own version of the ExtraActionBar functionality?
No, you're reprogramming it - you're altering its state by and how mouse would interract with it by hiding. Just imagine having buttons for ALL your spells stacked in one position spell and you dynamically hide all of them except one with best combat spell for current situation and here you'd have your mini-combat bot based on clicking the same spot on screen. You cannot alter SECURE frame from insecure code in combat, period. That's the point of entire system.

I can't remember from top of my head, but you might have some success with doing that from inside secure environment itself where you don't have functions that'd let you check combat status - i.e. your button can have secure script to always hide itself right after click.

You can have secure button to throw item in combat - it's pretty much same as spell button, but you won't be able to react to environment changes - e.g. leaving zone that gave you extra action - while in combat. The most you can do is to note relevant changes from events, save them somewhere and do actual modification after PLAYER_REGEN_ENABLED is fired.

You can't duplicate EAB functionality completely because it can change action or appear/disappear in middle in combat. This can only be done from secure Blizzard's code.
__________________
Garrison Mission Manager

Last edited by rowaasr13 : 07-10-15 at 06:17 AM.
  Reply With Quote
07-10-15, 06:23 AM   #5
alikim
A Fallenroot Satyr
Join Date: Jul 2015
Posts: 27
Originally Posted by rowaasr13 View Post
No, you're reprogramming it - you're altering its state by and how mouse would interract with it by hiding. Just imagine having buttons for ALL your spells stacked in one position spell and you dynamically hide all of them except one with best combat spell for current situation and here you'd have your mini-combat bot based on clicking the same spot on screen. You cannot alter SECURE frame from insecure code in combat, period. That's the point of entire system.

I can't remember from top of my head, but you might have some success with doing that from inside secure environment itself where you don't have functions that'd let you check combat status - i.e. your button can have secure script to always hide itself right after click.

You can have secure button to throw item in combat - it's pretty much same as spell button, but you won't be able to react to environment changes - e.g. leaving zone that gave you extra action - while in combat. The most you can do is to note relevant changes from events, save them somewhere and do actual modification after PLAYER_REGEN_ENABLED is fired.

You can't duplicate EAB functionality completely because it can change action or appear/disappear in middle in combat. This can only be done from secure Blizzard's code.
mmm... do you mean to create a hooksecurefunc on some original button call to turn off my button?
  Reply With Quote
07-10-15, 10:46 AM   #6
alikim
A Fallenroot Satyr
Join Date: Jul 2015
Posts: 27
Originally Posted by rowaasr13 View Post
...your button can have secure script to always hide itself right after click...
I mean how do you do this?
  Reply With Quote
07-11-15, 12:59 PM   #7
Lombra
A Molten Giant
 
Lombra's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2006
Posts: 554
I actually started to make this some time ago. I think it should work, but I never really bothered finishing it. Not sure if it's of any use to you. I never implemented hiding the default frame it seems. Most of it is copied from the UI source.

Code:
local items = {
	[19183] = true, -- Hourglass Sand
	[24494] = true, -- Tears of the Goddess
	[46029] = true, -- Magnetic Core
}

local bar = ExtraActionBarFrame

local button = CreateFrame("CheckButton", "ExtraExtraActionButton", ExtraActionBarFrame, "ExtraActionButtonTemplate")
button:SetPoint("CENTER")
button:SetAttribute("type", "item")
button.style:SetTexture("Interface\\ExtraButton\\Default")

function button:SetItem(itemID)
	bar:Show()
	bar.outro:Stop()
	bar.intro:Play()
	
	self:SetAttribute("item", "item:"..itemID)
	self.item = itemID
	self.icon:SetTexture(GetItemIcon(itemID))
end

button:RegisterEvent("BAG_UPDATE_COOLDOWN")
button:RegisterEvent("BAG_UPDATE")
button:RegisterEvent("SPELL_UPDATE_USABLE")
button:RegisterEvent("SPELL_UPDATE_COOLDOWN")
button:RegisterEvent("CURRENT_SPELL_CAST_CHANGED")

button:SetScript("OnAttributeChanged", function(self, name, value)
	-- if name == "item" then
		-- self.item = value
	-- end
end)

button:SetScript("OnEvent", function(self)
	local item = self.item
	if not item then return end
	local start, duration, enable = GetItemCooldown(item)
	CooldownFrame_SetTimer(self.cooldown, start, duration, enable)
	if (not item or duration > 0 and enable == 0) then
		self.icon:SetVertexColor(0.4, 0.4, 0.4)
	else
		self.icon:SetVertexColor(1, 1, 1)
	end
	
	self.icon:SetDesaturated(false)
	
	if (GameTooltip:GetOwner() == self) then
		GameTooltip:SetInventoryItemByID(self.item)
	end
end)

button:SetScript("OnEnter", function(self)
	if GetCVar("UberTooltips") == "1" then
		GameTooltip_SetDefaultAnchor(GameTooltip, self)
	else
		local parent = self:GetParent()
		if parent == MultiBarBottomRight or parent == MultiBarRight or parent == MultiBarLeft then
			GameTooltip:SetOwner(self, "ANCHOR_LEFT")
		else
			GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
		end
	end
	if GameTooltip:SetInventoryItemByID(self.item) then
		-- self.UpdateTooltip = ActionButton_SetTooltip
	-- else
		-- self.UpdateTooltip = nil
	end
end)

button:SetScript("OnUpdate", function(self, elapsed)
	if ( ActionButton_IsFlashing(self) ) then
		local flashtime = self.flashtime;
		flashtime = flashtime - elapsed;
		
		if ( flashtime <= 0 ) then
			local overtime = -flashtime;
			if ( overtime >= ATTACK_BUTTON_FLASH_TIME ) then
				overtime = 0;
			end
			flashtime = ATTACK_BUTTON_FLASH_TIME - overtime;

			local flashTexture = _G[self:GetName().."Flash"];
			if ( flashTexture:IsShown() ) then
				flashTexture:Hide();
			else
				flashTexture:Show();
			end
		end
		
		self.flashtime = flashtime;
	end
	
	-- Handle range indicator
	local rangeTimer = self.rangeTimer
	if rangeTimer then
		rangeTimer = rangeTimer - elapsed

		if rangeTimer <= 0 then
			local count = _G[self:GetName().."HotKey"]
			local valid = IsItemInRange(self.item)
			if count:GetText() == RANGE_INDICATOR then
				if valid == 0 then
					count:Show()
					count:SetVertexColor(1.0, 0.1, 0.1)
				elseif valid == 1 then
					count:Show()
					count:SetVertexColor(0.6, 0.6, 0.6)
				else
					count:Hide()
				end
			else
				if valid == 0 then
					count:SetVertexColor(1.0, 0.1, 0.1)
				else
					count:SetVertexColor(0.6, 0.6, 0.6)
				end
			end
			rangeTimer = TOOLTIP_UPDATE_TIME
		end
		
		self.rangeTimer = rangeTimer
	end
end)
__________________
Grab your sword and fight the Horde!
  Reply With Quote
07-13-15, 04:51 AM   #8
rowaasr13
A Fallenroot Satyr
AddOn Author - Click to view addons
Join Date: Jun 2007
Posts: 27
Originally Posted by alikim View Post
I mean how do you do this?
Check docs for SecureHandlerWrapScript.
__________________
Garrison Mission Manager
  Reply With Quote
07-16-15, 09:56 AM   #9
sezz
A Chromatic Dragonspawn
AddOn Author - Click to view addons
Join Date: Apr 2008
Posts: 158
Originally Posted by alikim View Post
I mean how do you do this?
this is what I'm using for my profession cds, not sure if it's the right way but it works and doesn't taint

Code:
		button:WrapScript(button, "PreClick", [[
			if (button == "RightButton") then
				-- Hide
				self:SetID(0);
				self:SetAttribute("userhidden", true);
				self:SetAttribute("macrotext", nil);
				self:Hide();

				-- Update Anchors
				self:GetParent():RunAttribute("UpdateChildAnchors");
			elseif (button == "MiddleButton") then
				-- Toggle Profession
				self:SetAttribute("macrotext", self:GetAttribute("macrotext-profession"));
			else
				-- Create Profession Cooldown Item
				self:SetAttribute("macrotext", self:GetAttribute("macrotext-tradeskill"));
			end
		]]);

btw, why don't you just reskin the original button instead?
  Reply With Quote

WoWInterface » Developer Discussions » General Authoring Discussion » Why this addon action is blocked?

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