Go to Page... |
Thread Tools | Display Modes |
03-16-19, 10:48 AM | #1 |
SecureHandlerAttributeTemplate optimization
Good afternoon,
I along with other users have noticed a recent change with BFA where certain quests utilize an attribute change on action buttons to show them. The best example of this is during the quest Righteous Retribution: https://www.wowhead.com/quest=49741/...ution#comments After mounting the gryphon Galeheart, you enter an Overridebar state. However, you initially don't have any buttons. The buttons are later added via an attribute change. Addons such as rActionBar, and I'm sure others, do not account for this, and assume the buttons will be there during their '_onstate-page' secure snippets. As such, I first came up with a solution to simply hooksecureframe a function that ran just as this occurred. While this code: Lua Code:
works wonderfully, it causes taint, as I'm changing the attributes of buttons outside of a secureframe. As such, and not knowing much about SecureHandler*Template coding, I embarked on this endeavor. I came up with the following code: Lua Code:
The basic idea is to hook into the OnAttributeChanged functions for both the normal actionbar button (ActionButton1-12) and the OverrideActionBarButton1-6. Here, I would execute secure code to change the attributes of the buttons to properly display the actionbutton when you "page" into an actionbar but the buttons come later. Just looking at this code, I feel like it is not great. I'm sure it can be better optimized, but I wanted to reach out to people who perhaps have better experience with SecureHandlers to determine my next steps. Any feedback is greatly appreciated. Please note, the bottom code functions precisely how I'd like it to. It is taint free, and handles every scenario I can think of without fail. All I'm asking is for optimization so it doesn't run 36 times instead of 6 for example. |
|
03-16-19, 04:12 PM | #2 |
You don't have to use table.insert in Execute snippets, you can just `button[i] = ...`.
I think you have a flaw in the inner for cycle: Lua Code:
|
|
03-16-19, 04:52 PM | #3 |
Thanks for the reply.
Changed the i's inside of the i loops to j's and k's. Removed table.insert and set to button[i] =. I wish there was a way to somehow access the i from outside of the secure execute snippet so I didn't have to change all 6 buttons every time any one of them changed. |
|
03-17-19, 11:22 PM | #4 |
As it turned out, there was a taint that was possible with the previous code.
I have completely rectified this and tested the hell out of it in several really weird edge cases and as far as I can tell, no taint. If anyone is interested in the code to alleviate the lack of button population in certain circumstances, you may find it here: Lua Code:
I've put in a bunch of documentation for why I did what I did. One thing I can't resolve, is why I need to RegisterStateDriver for visibility for the :SetAttribute('_onattributechanged', _onAttributeChanged) to actually fire. Without this RegisterStateDriver(...) line, this doesn't happen. Is there anyone who can explain that finding? Last edited by Terenna : 03-18-19 at 07:51 AM. |
|
03-22-19, 10:25 PM | #5 |
I am fine with button 7-12 showing on vehicle bar.
Would that work if I just keep the second part of the code? |
|
03-23-19, 06:21 AM | #6 | |
Code:
buttons[i]:SetAttribute('statehidden', true) Hopefully I explained that in a way that answered your question. |
||
03-23-19, 11:41 AM | #7 |
That does make sense and your explanation was both succinct and understandable. When I did try and hook each individual button with the 2nd block of code in the original post for this thread, I got tainting. Curious if it was from shitty secure frame code that wasn't actually secure, I did something as simple as this:
Lua Code:
and/or Lua Code:
that is, a blank function that simply hooked into the script, it caused tainting. So that's when I thought I couldn't hook into the individual buttons no matter what I did. To fairly easily recreate the taint, you can use the BfA "turtles" faction quests that involve you becoming the crab or defending the baby turtles. Allow yourself to get in combat by shooting something and then leave and then reenter and you'll taint with any sort of HookScript on the override or ActionButtons. That being said, is my solution using the secure code snippets and the registered state driver the "correct" way to go about my initial desire? Or is there a less verbose method that doesn't involve secureframes? Last edited by Terenna : 03-23-19 at 11:47 AM. |
|
03-23-19, 11:44 AM | #8 | |
Lua Code:
If not, please give me more detail so I can help you better |
||
03-23-19, 07:44 PM | #9 | |
Code:
local header = CreateFrame('Frame', nil, nil, 'SecureHandlerStateTemplate') for id = 1, NUM_ACTIONBAR_BUTTONS do local name = 'ActionButton' .. id header:SetFrameRef(name, _G[name]) end for id = 1, NUM_OVERRIDE_BUTTONS do local name = 'OverrideActionBarButton' .. id header:SetFrameRef(name, _G[name]) end header:Execute(([[ actionButton = table.new() for id = 1, NUM_ACTIONBAR_BUTTONS do actionButton[id] = self:GetFrameRef('ActionButton' .. id) end overrideButton = table.new() for id = 1, NUM_OVERRIDE_BUTTONS do overrideButton[id] = self:GetFrameRef('OverrideActionBarButton' .. id) end ]]):gsub('NUM_ACTIONBAR_BUTTONS', NUM_ACTIONBAR_BUTTONS):gsub('NUM_OVERRIDE_BUTTONS', NUM_OVERRIDE_BUTTONS)) header:SetAttribute("_onstate-override", ([[ if newstate then for id = 1, NUM_OVERRIDE_BUTTONS do local stateHidden = overrideButton[id]:GetAttribute('statehidden') actionButton[id]:SetAttribute('statehidden', stateHidden) actionButton[id][stateHidden and 'Hide' or 'Show'](actionButton[id]) end for id = NUM_OVERRIDE_BUTTONS + 1, NUM_ACTIONBAR_BUTTONS do actionButton[id]:SetAttribute('statehidden', true) actionButton[id]:Hide() end else for id = 1, NUM_ACTIONBAR_BUTTONS do actionButton[id]:SetAttribute('statehidden', false) actionButton[id]:Show() end end ]]):gsub('NUM_ACTIONBAR_BUTTONS', NUM_ACTIONBAR_BUTTONS):gsub('NUM_OVERRIDE_BUTTONS', NUM_OVERRIDE_BUTTONS)) RegisterStateDriver(header, "override", "[overridebar][vehicleui] true") Code:
[vehicleui] 12; [overridebar] 14; [possessbar] [@vehicle, exists] 12; [shapeshift] 13; [bar:2] 2; [bar:3] 3; [bar:4] 4; [bar:5] 5; [bar:6] 6; [bonusbar:1] 7; [bonusbar:2] 8; [bonusbar:3] 9; [bonusbar:4] 10; [bonusbar:5] 11; 1 Code:
local header = CreateFrame('Frame', nil, nil, 'SecureHandlerBaseTemplate') header:WrapScript(ActionButton1, 'OnAttributeChanged', [[ print(self:GetName(), 'OnAttributeChanged', name, value) -- Your secure snippet here ]]) |
||
03-23-19, 08:11 PM | #10 |
I am using rActionbar atm, and do meet the overridebar update problem as you mentioned. But I need the button grids stay shown.
It is so weired that these code below actually work properly on vehicle buttons for rActionbar. Maybe it just need an update. Lua Code:
Last edited by siweia : 03-24-19 at 03:07 AM. |
|
03-23-19, 08:15 PM | #11 | ||
eg https://www.wowhead.com/quest=47261/...-your-direhorn
Last edited by siweia : 03-24-19 at 03:12 AM. |
|||
03-24-19, 03:04 AM | #12 |
I just came up with an idea, the code below does fix the override buttons update as well. (for rActionbar)
Not sure whether it taints or not. Lua Code:
Last edited by siweia : 03-24-19 at 04:53 AM. |
|
04-04-19, 02:46 AM | #13 |
Keep in mind...
Keep in mind Blizzard will not let you f*ck with attribute values while in combat or out of control... Your use of SetAttribute().
Last edited by Nightness : 04-04-19 at 03:03 AM. |
|
04-08-19, 04:51 AM | #14 | |
I solved the issue by manually page swapping when on such a quest. The onpage event fires before the actual button attribute change takes effect. If I had such a problem I would switch bar1 to bar5 and back and the buttons would show. It works because you manually trigger the onpage event with that swap. By the time you do it the button attributes are the correct ones.
My guess is that certain quests show the overridebar (with or without ui) and progressively add buttons to that bar based on events. rActionbar uses only the actionbar1 and uses the visibility state driver to trigger the actionbar page swap. It might be possible to do what Vrul wrote. You try to track the attribute of the overridebar buttons and listen for the event change. It might be possible to apply the button attributes of the overridebar to the actionbar1 buttons or just trigger a pageswap (like the manual back and forth).
__________________
| Simple is beautiful. | WoWI AddOns | GitHub | Zork (WoW)
|
||
04-09-19, 08:35 PM | #15 | |
|
||
04-10-19, 08:33 PM | #16 |
Vrul's code should allow it to work as he helped me fix this for nUI, and it worked for a non nUI custom bar addon that I used for testing before applying the changes to nUI with Vruls help again and testing again. And that was for this specific quest chain.
Of course, if blizzard made changes to the bar since the expansion came out it may have effected it but no one has of yet reported an action bar problem with nUI.
__________________
Characters: Gwynedda - 70 - Demon Warlock Galaviel - 65 - Resto Druid Gamaliel - 61 - Disc Priest Gwynytha - 60 - Survival Hunter Lienae - 60 - Resto Shaman Plus several others below level 60 Info Panel IDs : http://www.wowinterface.com/forums/s...818#post136818 |
|
WoWInterface » Developer Discussions » General Authoring Discussion » SecureHandlerAttributeTemplate optimization |
«
Previous Thread
|
Next Thread
»
|
Display Modes |
Linear Mode |
Switch to Hybrid Mode |
Switch to Threaded Mode |
|
|