=====MinionLib Lua===== This minionlib library is holding the core functionality on which all our bots are running. You can freely use the available functions for your Addon, in order to do that, you just need to open your **module.def** and set the dependency of your Addon to the minionlib: [Module] Name=YourAddon Dependencies=minionlib Version=1 Files=myluacode.lua Enabled=1 ===Minion Menu=== The Minion Menu is the main menu used by minion to access all settings and addons. 3rd-party developers may add custom options to the menu in several different ways. ==Structure== The minion is layered into 3 distinct parts, components, members, and submembers. All components must have a header and (optionally) members, which are displayed when the header is clicked (and the menu is open).\\ All component headers require the following properties: **//bool// ''expanded'', //string// ''name'', //string// ''id''** \\ All component headers optionally contain the following properties: **//string// ''texture''**\\ Members are displayed below their component containers, and they represent the rows that appear directly below the header.\\ Members may optionally contain submembers.\\ All members require the following properties: **//string// ''name'', //string// ''id''**\\ All members optionally contain the following properties: **//string// ''texture'', //string// ''tooltip'', //function// ''onClick'', //bool// ''sort''**\\ Submembers are displayed to the right and grow vertically downward. They are useful if you wish to section off a large amount of events.\\ Submembers will be sorted in alphabetical order by name if the **''sort''** tag is specified on the parent member.\\ All submembers require the following properties: **//string// ''name'', //string// ''id''**\\ All submembers optionally contain the following properties: **//string// ''texture'', //string// ''tooltip'', //function// ''onClick''**\\ ==API== ***''ml_gui.ui_mgr:AddComponent( //table// component)''** ***''ml_gui.ui_mgr:AddMember( //table// member, //string// componentid)''** ***''ml_gui.ui_mgr:AddComponent( //table// submember, //string// componentid, //string// memberid)''** ==Example== local ffxiv_mainmenu = { header = { id = "FFXIVMINION##MENU_HEADER", expanded = false, name = "FFXIVMinion", texture = GetStartupPath().."\\GUI\\UI_Textures\\ffxiv_shiny.png"}, members = { } } ml_gui.ui_mgr:AddComponent(ffxiv_mainmenu) ml_gui.ui_mgr:AddMember({ id = "FFXIVMINION##MENU_DEV1", name = "Dev1", onClick = function() Dev.GUI.open = not Dev.GUI.open end, tooltip = "Open the Dev monitor."},"FFXIVMINION##MENU_HEADER") ml_gui.ui_mgr:AddMember({ id = "FFXIVMINION##MENU_DEV2", name = "Dev2", onClick = function() Dev.GUI.open = not Dev.GUI.open end, tooltip = "Open the Dev monitor."},"FFXIVMINION##MENU_HEADER") ml_gui.ui_mgr:AddMember({ id = "FFXIVMINION##MENU_DEV3", name = "Dev3", onClick = function() Dev.GUI.open = not Dev.GUI.open end, tooltip = "Open the Dev monitor."},"FFXIVMINION##MENU_HEADER") ml_gui.ui_mgr:AddMember({ id = "FFXIVMINION##MENU_DEV4", name = "Dev4", onClick = function() Dev.GUI.open = not Dev.GUI.open end, tooltip = "Open the Dev monitor."},"FFXIVMINION##MENU_HEADER") ml_gui.ui_mgr:AddMember({ id = "FFXIVMINION##MENU_DEV5", name = "Dev5", onClick = function() Dev.GUI.open = not Dev.GUI.open end, sort = true},"FFXIVMINION##MENU_HEADER") ml_gui.ui_mgr:AddSubMember({ id = "FFXIVMINION##DEV_1", name = "DevA", onClick = function() Dev.GUI.open = not Dev.GUI.open end, tooltip = "Open the Dev monitor."},"FFXIVMINION##MENU_HEADER","FFXIVMINION##MENU_DEV5") ml_gui.ui_mgr:AddSubMember({ id = "FFXIVMINION##DEV_2", name = "DevE", onClick = function() Dev.GUI.open = not Dev.GUI.open end, tooltip = "Open the Dev monitor."},"FFXIVMINION##MENU_HEADER","FFXIVMINION##MENU_DEV5") ml_gui.ui_mgr:AddSubMember({ id = "FFXIVMINION##DEV_3", name = "DevM", onClick = function() Dev.GUI.open = not Dev.GUI.open end, tooltip = "Open the Dev monitor."},"FFXIVMINION##MENU_HEADER","FFXIVMINION##MENU_DEV5") ml_gui.ui_mgr:AddSubMember({ id = "FFXIVMINION##DEV_4", name = "DevC", onClick = function() Dev.GUI.open = not Dev.GUI.open end, tooltip = "Open the Dev monitor."},"FFXIVMINION##MENU_HEADER","FFXIVMINION##MENU_DEV5") ===Utility Functions=== ==General== ***''d(...)''** *Prints out the passed variable or the result of a function into the console. ***''stacktrace()''** *Prints out the current call stack into the console. ***''Exit()''** *Closes the current game instance ***''ml_debug( //string// str )''** *Prints our the passed variable or the result of a function into the console when gEnableLog == "1". ***''ml_error( //string// str )''** *Prints our the passed variable or the result of a function into the console. ***''ml_log( //string// str )''** *Adds the string to the statusbar-line which gets shown on each pulse. ***''Now()''** *Returns tickcount from ml_global_information.Now ***''RegisterEventHandler(//string// eventtoregisterfor,//function// handler, //string// customNameHereToIdentifyYourCode)''** *Registers a local handler to an event ***''Reload()''** *Returns //bool// , reloads all lua modules ***''TimeSince(//integer// previousTime)''** *Returns //integer// ml_global_information.Now - previousTime ***''Unload()''** *Returns //bool// , tries to unload the bot ***''QueueEvent( //string// eventname, //string// args, ...)''** *Queues and Fires the Event with 1-n arguments. Eventname and arguments need to be strings. *Use RegisterEventHandler("eventname", handlerfunc) , to register a lua function which will handle the fired event. *Requires at least 1 argument, even if it's a blank string. (ex. QueueEvent("some event","")) ==File I/O== For every I/O function, you need to use double dashes! Example: FolderExists("c:\\minionapp\\ILikeBeer\\Folder") ***''GetStartupPath()''** *Returns //string//, filepath to the root bot folder ***''GetLuaModsPath()''** *Returns //string//, filepath to the ..MinionApp/Bots/xxxx/LuaMods folder, where all Lua addon folders are ***''FileExists(//string// fullpathtofile)''** *Returns //bool// ***''FileLoad(//string// fullpathtofile)''** *Returns //variant// , loads a file which was saved before with FileSave ***''FileSave(//string// fullpathtofile, //variant// data)''** *Returns //bool// , can take in a luatable, will save the whole table structure in a "human readable file" ***''FileWrite(//string// fullpathtofile, //string// data)''** *Returns //bool// , writes the string into the file. ***''FileWrite(//string// fullpathtofile, //string// data, //bool// arg)''** *Returns //bool// , writes the string into the file. If 3rd arg is true, it will add the data to the end of the file. ***''FileDelete(//string// fullpathtofile)''** *Returns //bool// ***''FileIsValidImage(//string// fullpathtofile)''** *Returns //bool// ***''FileSize(//string// fullpathtofile)''** *Returns //number// ***''FolderExists(//string// fullpathtofolder)''** *Returns //bool// ***''FolderCreate(//string// fullpathtofolder)''** *Returns //bool// ***''FolderDelete(//string// fullpathtofolder)''** *Returns //bool// ***''FolderList(//string// fullpathtofolder, __//string// pattern=""__, __//bool// includeFolders=false__)''** *Where pattern is normal regex and should be put in double brackets in lua. Eg. %%[[(.*)lua$]]%% *Returns //table// with all files in that directory. ==String== The following functions extend the default //string// from the lua library. Usage: //string.contains(..)// ***''contains(//string// arg, //string// arg2)''** *Returns //bool//, if arg2 was found in arg ***''empty(//string// arg)''** *Returns //bool//, if arg is type(string) and length is 0 ***''ends(//string// arg, //string// arg2)''** *Returns //bool//, if arg ends with arg2 ***''split(//string// arg, //string// seperator)''** *Returns //iterator//, seperates arg, Usage: for moochable in string.split(moochables, ",") do ... end ***''starts(//string// arg, //string// arg2)''** *Returns //bool//, if arg starts with arg2 ***''toboolean(//string// arg)''** *Returns //bool// ***''totable(//string// arg, //string// seperator)''** *Returns //table//, seperates arg ***''trim(//string// arg, //int// num)''** *Returns //bool//, trims arg by num characters ***''valid(//string// arg)''** *Returns //bool//, if arg is type(string) ***''starts(//string// str, //string// starts)''** *Returns //bool//, if the str begins with "starts" ***''ends(//string// str, //string// ends)''** *Returns //bool//, if the str ends with "ends" ***''hash(//string// arg)''** *Returns //number//, a md5 encoded number for the passed string ==Table== The following functions extend the default //table// from the lua library. Usage: //table.valid(..)// ***''clear(//table// arg )''** *Sets all values in the table to nil. ***''contains(//table// table, value)''** *Returns //bool// if the value exists in the table ***''deepcopy(//table// arg, __//bool// skipMetaTable __)''** *Returns //table//, makes a deepcopy of the passed table. Pass "true" as 2nd arg to not duplicate the metatable. ***''deepcompare(//table// table1, //table// table2, //bool// ignore_metatable)''** *Returns //bool//, compares two tables if they are equal. ***''delete(//table// table, //variant// object)''** *Returns //bool// if the object was removed from the table ***''find(//table// table, value)''** *Returns //number// if the value exists in the table, it returns the key position, else nil ***''invert(//table// arg )''** *Returns //table//, flips a table so keys become values ***''merge(//table// table1, //table// table2, //bool// keepexistingentries)''** *Returns //table1//, merged with table 2. If keepexistingentries is not passed, all existing keys&values in table1 will be overwritten with the ones from table2, else the values of table2 are just inserted into table1. ***''pairsbykeys(//table// table1, __//function// sort__)''** *Returns //iterator// over the table which is default sorted by its keys. Optionally pass your custom sort function as 2nd arg. Usage: "for key,value in table.pairsbykeys(table) do.." ***''pairsbyvalue(//table// table1, __//function// sort__)''** *Returns //iterator// over the table which is default sorted by its values. Optionally pass your custom sort function as 2nd arg. Usage: "for key,value in table.pairsbyvalue(table) do.." ***''print(//table// arg )''** *Prints the table content line by line into the minion console. ***''randomvalue(//table// arg )''** *Returns a random value from the table. ***''shallowcopy(//table// arg )''** *Returns //table// ***''size(//table// arg )''** *Returns //number//, of elements the table contains. Returns 0 if the arg is no table. ***''valid(//table// arg )''** *Returns //bool//, if the passed arg is a valid table with at least 1 entry ==Math== The following functions extend the default //math// from the lua library. Usage: //math.distance3d(..)// ***''angle(//table// heading1, //table// heading2)''** *Returns //number//, calculates the shortest angle between two headings ( 2x table with x,y,z ) Result is angle between 0 - 180 degree ***''approxequal(//number// num1, //number// num2)''** *Returns //bool// ***''crossproduct(//table// pos1, //table// pos2)''** *Returns //table// ***''distance2d(//number// x, //number// y, //number// x1, //number// y1)''** *Returns //number// ***''distance3d(//table// pos1, //table// pos2)''** *Returns //number// ***''distance3d(//number// x, //number// y, //number// z, //number// x1, //number// y1, //number// z1)''** *Returns //number// ***''distancepointline(//table// p1, //table// p2, //table// p3)''** *Returns //number//, takes in 3 points, first two are the "line" defining points, last one is the point we want to get the distance to that line from ***''magnitude(//table// pos)''** *Returns //number// ***''round(//number// num, //integer// decimals)''** *Returns //number// ***''randomize(//integer// int)''** *Returns //integer// , takes in a percentage from 0-100 and gives back a random number "near" that value ==Navigation== ***''PathDistance(//table// posTable)''** *Returns //number// distance, usage: PathDistance(NavigationManager:GetPath(myPos.x,myPos.y,myPos.z,p.x,p.y,p.z)) ==Structure== The minion is layered into 3 distinct parts, components, members, and submembers. All components must have a header and (optionally) members, which are displayed when the header is clicked (and the menu is open).\\ All component headers require the following properties: **//bool// ''expanded'', //string// ''name'', //string// ''id''** \\ All component headers optionally contain the following properties: **//string// ''texture''**\\ Members are displayed below their component containers, and they represent the rows that appear directly below the header.\\ Members may optionally contain submembers.\\ All members require the following properties: **//string// ''name'', //string// ''id''**\\ All members optionally contain the following properties: **//string// ''texture'', //string// ''tooltip'', //function// ''onClick'', //bool// ''sort''**\\ Submembers are displayed to the right and grow vertically downward. They are useful if you wish to section off a large amount of events.\\ Submembers will be sorted in alphabetical order by name if the **''sort''** tag is specified on the parent member.\\ All submembers require the following properties: **//string// ''name'', //string// ''id''**\\ All submembers optionally contain the following properties: **//string// ''texture'', //string// ''tooltip'', //function// ''onClick''**\\ ==API== ***''ml_gui.ui_mgr:AddComponent( //table// component)''** ***''ml_gui.ui_mgr:AddMember( //table// member, //string// componentid)''** ***''ml_gui.ui_mgr:AddComponent( //table// submember, //string// componentid, //string// memberid)''** ===HTTPRequest=== Use this function to do any kind of asynchronous http calls. Example: function SendHttpRequest() local function success(str, header, statuscode) d("HTTP Request: success.") d("HTTP Result Header: " .. tostring(header)) d("HTTP Result StatusCode: " .. tostring(statuscode)) local data = json.decode(str) if data then d("HTTP Request: data valid. Currency Coin info:") d(data) end local function HeadersTable(header) if type(header) == "string" and #header > 0 then header = string.match(header,".?%c(.*)") -- Removing the first entry local tbl = {} for w in header:gmatch("[^%c]+") do local k,v = string.match(w,"(.*): (.*)") tbl[k] = v end table.print(tbl) return tbl end end header = HeadersTable(header) -- if you want to convert the header string to a table end local function failed(error, header, statuscode) d("HTTP Failed Error: " .. error) d("HTTP Failed Header: " .. header) d("HTTP Failed StatusCode: " .. tostring(statuscode)) end local params = { host = "api.guildwars2.com", path = "/v2/currencies?ids=1", port = 443, method = "GET", -- "GET","POST","PUT","DELETE" https = true, onsuccess = success, onfailure = failed, getheaders = true, --true will return the headers, if you dont need it you can leave this at nil body = "", --optional, if not required for your call can be nil or "" headers = {}, --optional, if not required for your call can be nil or "" } HttpRequest(params) end