Thread Tools Display Modes
07-26-18, 05:20 PM   #1
Chokobo
A Murloc Raider
Join Date: Jul 2018
Posts: 9
Understanding this codes behavior.

First post here. I need a little help understanding what is going on if someone is willing.

Foremost I maintain an addon for personal use which just handles small little things to help me in my daily business.

Secondly I have never really delved into the realm of having to deal with secure code, or protected function, or hardware events etc. I will admit I am a complete novice in this area.

So, here is my question. I have this addon, it has one button. If you press the button, it should do 1 of 2 things via a function.

1.)
If "the table" is not populated, it will populate it with group ID's (From group finder), and it will filter those which are on auto accept. Now "the table" is populated.

2.) IF the table is populated, it will attempt to join the first group ID in the list of "the table"


What seems to be happening (In order):

1.) I press the button, There is no data, so it searches and populates.
2.) I press the button, Data Exists and it attempts to join (Protected) and I get an error "Interface action failed because of an Addon". Table is cleared, The function continues and repopulates the table
3.) I press the button, Data Exists and it attempts to join a group (Protected), and it succeeds.


What I dont understand is why this thing is not joining a group on the second press, but will on all subsequent presses. I know I am not going to win any awards for stellar programming here, but I would appreciate anyone willing to help me understand these secure functions and hardware events.

You can find the code here https://pastebin.com/fKmsNHQT

OR alternately here is the code in forum

Code:
ChokoTools = {}
 
--Standard Basic Button
ChokoTools.RandHop = CreateFrame("Button",nil,UIParent,"UIGoldBorderButtonTemplate")
ChokoTools.RandHop:SetSize(50,24)
ChokoTools.RandHop:SetPoint("BOTTOMLEFT",0,0)
ChokoTools.RandHop:SetText("HOP")
ChokoTools.RandHop:SetScript("OnClick", function(self, event, ...)
    ChokoTools:JoinRandomGroup()
end)
 
 
--Function: Search for groups with Auto Accept on. Join if we have data.
function ChokoTools:JoinRandomGroup()
    --Search already completed. (2nd Click)
    if (ChokoTools.FilteredIDs) and (#ChokoTools.FilteredIDs >= 1) then
        print("Joining...")
        C_LFGList.ApplyToGroup(ChokoTools.FilteredIDs[1], "", false, false, true)
        ChokoTools.FilteredIDs = {} --Reset table to empty
    end
   
    print("Searching...")
    ChokoTools.SearchResults = {}
    ChokoTools.FilteredIDs = {}
 
    --Search Groups (Taken and modified from "ServerHop" Addon)
    local lang = {}
    for k,v in pairs(C_LFGList.GetAvailableLanguageSearchFilter()) do lang[v]=true end
    C_LFGList.Search(6,LFGListSearchPanel_ParseSearchTerms(""),0,0,lang) --Search "Custom" groups
   
    --Get Search Results
    c, ChokoTools.SearchResults = C_LFGList.GetSearchResults()
   
    --Iterate through search results
    for i=1,#ChokoTools.SearchResults do
        local id, _, _, _, _, _, _, _, _, _, _, _, _, _, autoinv = C_LFGList.GetSearchResultInfo(ChokoTools.SearchResults[i])
        if autoinv == true then
            table.insert(ChokoTools.FilteredIDs,id)
        end
    end
end

Last edited by Chokobo : 07-26-18 at 05:24 PM.
  Reply With Quote
07-26-18, 07:43 PM   #2
Xrystal
nUI Maintainer
 
Xrystal's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Feb 2006
Posts: 5,892
I may have misheard, but I thought that they made changes to the group finder API so that addons can't auto invite/join using scripts/addons. If I am remembering right that could explain your problems.
__________________
  Reply With Quote
07-26-18, 07:50 PM   #3
Chokobo
A Murloc Raider
Join Date: Jul 2018
Posts: 9
That is correct. But it is protected with a hardware event. I just assumed my button I am clicking would be a hardware event? That's the area I am weak on and I am fishing for answers. The code I posted seems to work after 3-4 clicks. But I feel it should be prompting me for a group after the second click.
  Reply With Quote
07-26-18, 07:59 PM   #4
Xrystal
nUI Maintainer
 
Xrystal's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Feb 2006
Posts: 5,892
Hmm, I've never used buttons to carry out full function execution before so can't comment on how that would work .. I have only used secure buttons to execute a spell or ability specified in the creation code.

That said, unless the template your button inherits from inherits from SecureFrame/SecureActionButton etc that might be the problem you are having .. but it may entail looking at this page to see if the properties needed include something you can use.

https://wow.gamepedia.com/SecureActionButtonTemplate
__________________
  Reply With Quote
07-26-18, 08:27 PM   #5
Chokobo
A Murloc Raider
Join Date: Jul 2018
Posts: 9
Thanks for the link. I agree with you. That is most likely the answer. I looked at that page today, and I suppose the macro route would best suit my style.

However, when I attempt to use their example, I get a strange error. This is after placing a secure button in my Lua file. as shown (Almost Identical to theirs):

Code:
local macroBtn = CreateFrame("Button", "myMacroButton", UIParent, "SecureActionButtonTemplate")
macroBtn:SetAttribute("type1", "macro") -- left click causes macro
macroBtn:SetAttribute("macrotext1", "/s test") -- text for macro on left click
macroBtn:SetSize(50,24)
macroBtn:SetPoint("BOTTOMLEFT",50,0)
macroBtn:SetText("HOP")
No button appears on the screen, as I would expect it to. and it gives me this error, which I am researching now, but maybe you all know something about it.

Error:
Code:
Unknown: Couldn't find relative frame: $parentDetails
https://imgur.com/a/nxxqeSJ

I feel like I am missing something with the secure action template. I'm not sure what, it's probably simple, but is just going over my head currently.
  Reply With Quote
07-27-18, 10:09 AM   #6
Xrystal
nUI Maintainer
 
Xrystal's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Feb 2006
Posts: 5,892
That error usually points to an xml file trying to access a frame by name but the name is incorrect. You might have to do a global search of your addon folder to see if that $parentDetails text appears anywhere amongst your addons. And then start looking at Blizzard frames to see if it is an error there from one of the addons.

This is a bookmark worth keeping if you are intending more addon writing.
https://www.townlong-yak.com/framexml/live

Or use this guide to extract your own up to date version as and when you need it.
https://wow.gamepedia.com/Viewing_Bl...interface_code


Originally Posted by Chokobo View Post
Error:
Code:
Unknown: Couldn't find relative frame: $parentDetails
https://imgur.com/a/nxxqeSJ

I feel like I am missing something with the secure action template. I'm not sure what, it's probably simple, but is just going over my head currently.
__________________
  Reply With Quote
07-27-18, 11:25 AM   #7
Chokobo
A Murloc Raider
Join Date: Jul 2018
Posts: 9
Thanks for the links. I really do appreciate it.

I'll take deeper dive into all that this weekend and see if I can figure something out. Thanks for taking me down a different tunnel in this rabbit hole
  Reply With Quote
07-27-18, 04:45 PM   #8
Prejudice182
A Kobold Labourer
Join Date: Jul 2018
Posts: 1
I believe you have to initialize a new FontString to set a text value to it.

Code:
local macroBtn = CreateFrame("Button", "myMacroButton", UIParent, "SecureActionButtonTemplate")
macroBtn:SetAttribute("type1", "macro")
macroBtn:SetAttribute("macrotext1", "/s test")
macroBtn:SetSize(100,100)
macroBtn:SetPoint("TOPLEFT",50,0)
local macroBtnText =  macroBtn:CreateFontString()
macroBtnText:SetPoint("CENTER")
macroBtnText:SetSize(200,20)
macroBtnText:SetFont("Fonts\\FRIZQT__.TTF", 12, "OUTLINE")
macroBtnText:SetText("HOP")
This gives the following output, highlighted with framestack.
  Reply With Quote
07-27-18, 11:29 PM   #9
Chokobo
A Murloc Raider
Join Date: Jul 2018
Posts: 9
Ha, yeah, that would do the trick wouldn't it. Thanks for revealing that blatant oversight on my part.
  Reply With Quote
07-28-18, 01:37 AM   #10
PhoenixPower
A Defias Bandit
Join Date: Aug 2011
Posts: 3
I believe you call you call C_LFGList.GetSearchResults too early, returning in invalid values getting passed to ApplyToGroup on the second click. You shouldn't need a secure button to execute protected functions here though. The code execution of your snippet goes something like this.

First click, you start a search and get the search results before they are ready. The filtering code populates FilteredIDs with old invalid values.

Now the second time you click the ApplyToGroup function fails silentyly because FilteredIDs[1] is not a valid group to join. Then the function doesn't return but continue and starts another search, but at this point you already called a secure function for this hardware event, so this search call shows the "Interface action failed because of an Addon" error. But by now the search results from the first click have been received properly so your GetSearchResults/GetSearchResultInfo code populates the FilteredIDs table with valid values.

Then on the third click your ApplyToGroup call works and you join the first group, but again the code never seems to start a new search again. It just keeps repopulating FilteredIDs with valid values from GetSearchResults and calling ApplyToGroup on them every time. Internally it seems that after calling ApplyToGroup it removes that ID from the values that GetSearchResults will return, so you get a different group each time until the list is depleted.

How it's meant to be done is after a call to C_LFGList.Search, wait for the LFG_LIST_SEARCH_RESULTS_RECEIVED (or LFG_LIST_SEARCH_FAILED) event and in that OnEvent callback fill your SearchResults table. Then on the second click your function will enter the if statement and apply to a valid group. Also put a return at the end of the if statement so no new search gets started.

The parent error seems to come from using UIGoldBorderButtonTemplate, which tries to anchor itself to $parentDetails. Right now it's used nowhere in the Blizzard UI, but it was used in Mists of Pandaria and Warlords of Draenor for the challenge mode frame. If you use UIPanelButtonTemplate for example it shows no error.

Last edited by PhoenixPower : 07-28-18 at 01:39 AM.
  Reply With Quote
07-28-18, 01:32 PM   #11
Chokobo
A Murloc Raider
Join Date: Jul 2018
Posts: 9
That makes total sense. Let me tidy up the implementation and I'll repost it here. I'm 99% sure this will fix it.

I never really thought about the search data being incomplete.
  Reply With Quote
07-28-18, 02:21 PM   #12
Chokobo
A Murloc Raider
Join Date: Jul 2018
Posts: 9
Ok, PhoenixPower. You win. that did the trick.

So, the take aways from this lesson, for me, we're incomplete understanding of how and when data was being returned. A less than ideal mock up of the code for testing. And, chasing down the wrong issue to solve the problem.

Below, I have corrected the issues and all is working as intended. Thanks so much for all the help. I really appreciate it.

FWIW this button is what helps me escape long dungeons without running back to the entrance (Transmog Farmer Here). Not a new concept, but I like to be in control of my own tools.

Find the code here: https://pastebin.com/zr0WqzPP

Code:
ChokoTools.SearchResults = {}
ChokoTools.FilteredIDs = {}
ChokoTools.HopFSM = "Search"
 
--Standard Basic Button
ChokoTools.RandHop = CreateFrame("Button",nil,UIParent)
ChokoTools.RandHop:SetSize(50,18)
ChokoTools.RandHop:SetPoint("BOTTOMLEFT",0,0)
ChokoTools.RandHop:SetText("HOP")
ChokoTools.RandHop:RegisterEvent("LFG_LIST_SEARCH_RESULTS_RECEIVED")
ChokoTools.RandHop:RegisterEvent("LFG_LIST_SEARCH_FAILED")
ChokoTools.RandHop.bg = ChokoTools.RandHop:CreateTexture("ARTWORK")
ChokoTools.RandHop.bg:SetColorTexture(0.2,0.2,0.2,1)
ChokoTools.RandHop.bg:SetAllPoints(ChokoTools.RandHop)
ChokoTools.RandHop.txt = ChokoTools.RandHop:CreateFontString(nil,"ARTWORK")
ChokoTools.RandHop.txt:SetFont("Interface\\AddOns\\ChokoTools\\fonts\\Exo2.ttf", 12)
ChokoTools.RandHop.txt:SetTextColor(0.8,0.8,0.8)
ChokoTools.RandHop.txt:SetText("HOP")
ChokoTools.RandHop.txt:SetPoint("CENTER")
 
 
 
ChokoTools.RandHop:SetScript("OnClick", function(self, event, ...)
    if IsInGroup() or IsInRaid() then
        LeaveParty()
        ChokoTools.SearchResults = {}
        ChokoTools.FilteredIDs = {}
        ChokoTools.HopFSM = "Search"
        ChokoTools.RandHop.txt:SetText("HOP")
        return
    end
    ChokoTools:RandomGroup()
end)
 
ChokoTools.RandHop:SetScript("OnEvent", function(self, event, ...)
    if event == "LFG_LIST_SEARCH_RESULTS_RECEIVED" then
        --Get Search Results
        c, ChokoTools.SearchResults = C_LFGList.GetSearchResults()
       
        --Iterate through search results
        for i=1,#ChokoTools.SearchResults do
            local id, _, _, _, _, _, _, _, _, _, _, _, _, _, autoinv = C_LFGList.GetSearchResultInfo(ChokoTools.SearchResults[i])
           
            if autoinv == true then
                table.insert(ChokoTools.FilteredIDs,id)
            end
        end
        ChokoTools.HopFSM = "Join"
        ChokoTools.RandHop.txt:SetText("JOIN")
       
    elseif event == "LFG_LIST_SEARCH_FAILED" then
   
        ChokoTools.SearchResults = {}
        ChokoTools.FilteredIDs = {}
        ChokoTools.HopFSM = "Search"
    end
end)
 
--Function: Search for groups with Auto Accept on. Join if we have data.
function ChokoTools:RandomGroup()
   
    if ChokoTools.HopFSM == "Join" then
        if (ChokoTools.FilteredIDs) and (#ChokoTools.FilteredIDs >= 1) then
            print("Joining...")
            C_LFGList.ApplyToGroup(ChokoTools.FilteredIDs[1], "", false, false, true)
            ChokoTools.FilteredIDs = {} --Reset table to empty
        end
    end
   
    if ChokoTools.HopFSM == "Search" then
        print("Searching...")
        ChokoTools.SearchResults = {}
        ChokoTools.FilteredIDs = {}
 
        --Search Groups (Taken and modified from "ServerHop" Addon)
        local lang = {}
        for k,v in pairs(C_LFGList.GetAvailableLanguageSearchFilter()) do lang[v]=true end
        C_LFGList.Search(6,LFGListSearchPanel_ParseSearchTerms(""),0,0,lang) --Search "Custom" groups
       
    end
end





Thanks again for all the help, everyone. I sincerely do appreciate it.

Last edited by Chokobo : 07-28-18 at 02:46 PM.
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Understanding this codes behavior.

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