WoWInterface

WoWInterface (https://www.wowinterface.com/forums/index.php)
-   Lua/XML Help (https://www.wowinterface.com/forums/forumdisplay.php?f=16)
-   -   Understanding this codes behavior. (https://www.wowinterface.com/forums/showthread.php?t=56452)

Chokobo 07-26-18 05:20 PM

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


Xrystal 07-26-18 07:43 PM

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.

Chokobo 07-26-18 07:50 PM

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.

Xrystal 07-26-18 07:59 PM

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

Chokobo 07-26-18 08:27 PM

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.

Xrystal 07-27-18 10:09 AM

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


Quote:

Originally Posted by Chokobo (Post 329061)
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.


Chokobo 07-27-18 11:25 AM

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 :)

Prejudice182 07-27-18 04:45 PM

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.

Chokobo 07-27-18 11:29 PM

Ha, yeah, that would do the trick wouldn't it. Thanks for revealing that blatant oversight on my part.

PhoenixPower 07-28-18 01:37 AM

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.

Chokobo 07-28-18 01:32 PM

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.

Chokobo 07-28-18 02:21 PM

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.


All times are GMT -6. The time now is 07:49 AM.

vBulletin © 2024, Jelsoft Enterprises Ltd
© 2004 - 2022 MMOUI