This commit is contained in:
Cooldude2606
2019-08-09 18:12:00 +01:00
parent 129b39bbb9
commit 84a9c869a3
137 changed files with 24370 additions and 2547 deletions

View File

@@ -1,34 +1,37 @@
--- Factorio command making module that makes commands with better parse and more modularity
-- @author Cooldude2606
--[[
>>>>Example Authenticator:
The command system is most useful when you can control who can use commands; to do this would would need to
define an authenticator which is ran every time a command is run; in this example I will show a simple one
that requires some commands to require the user to be a game admin:
--[[-- Core Module - Commands
- Factorio command making module that makes commands with better parse and more modularity
@core Commands
@alias Commands
When the authenticator is called be the command handler it will be passed 4 vales:
1) the player who used the command
2) the name of the command that is being used
3) any flags which have been set for this command, this is a table of values set using :set_flag(name,value)
4) the reject function which is the preferred method to prevent execution of the command
@usage
---- Example Authenticator:
-- The command system is most useful when you can control who can use commands; to do this would would need to
-- define an authenticator which is ran every time a command is run; in this example I will show a simple one
-- that requires some commands to require the user to be a game admin:
For our admin only example we will set a flag to true when we want it do be admin only so when we define the
command will will use :set_flag('admin_only',true) and then inside the authenticator we will test if the flag
is present using: if flags.admin_only then
-- When the authenticator is called be the command handler it will be passed 4 vales:
-- 1) the player who used the command
-- 2) the name of the command that is being used
-- 3) any flags which have been set for this command, this is a table of values set using :set_flag(name,value)
-- 4) the reject function which is the preferred method to prevent execution of the command
Although no return is required to allow the command to execute it is best practice to return true; we do this in
two cases in our authenticator:
1) when the "admin_only" flag is not set, which we take to mean any one can use it
2) when the "admin_only" flag is set, and the player is admin
-- For our admin only example we will set a flag to true when we want it do be admin only so when we define the
-- command will will use :set_flag('admin_only',true) and then inside the authenticator we will test if the flag
-- is present using: if flags.admin_only then
Now when the user is not an admin and the command requires you to be an admin then we must reject the request:
1) return false -- this is the most basic block and should only be used while testing
2) return reject -- returning the reject function is only an option as a fail safe, same as returning false
3) reject() -- this will block execution without returning to allow further code to be ran in the authenticator
4) reject('This command is for admins only!') -- Using reject as a function allows a error message to be returned
5) return reject() -- using return on either case above is best practice as you should execute all code before rejecting
-- Although no return is required to allow the command to execute it is best practice to return true; we do this in
-- two cases in our authenticator:
-- 1) when the "admin_only" flag is not set, which we take to mean any one can use it
-- 2) when the "admin_only" flag is set, and the player is admin
Example Code:
-- Now when the user is not an admin and the command requires you to be an admin then we must reject the request:
-- 1) return false -- this is the most basic block and should only be used while testing
-- 2) return reject -- returning the reject function is only an option as a fail safe, same as returning false
-- 3) reject() -- this will block execution without returning to allow further code to be ran in the authenticator
-- 4) reject('This command is for admins only!') -- Using reject as a function allows a error message to be returned
-- 5) return reject() -- using return on either case above is best practice as you should execute all code before rejecting
-- Example Code:
Commands.add_authenticator(function(player,command,flags,reject)
if flags.admin_only then -- our test for the "admin_only" flag
if player.admin then
@@ -41,41 +44,42 @@
end
end)
>>>>Example Parse:
Before you go making commands it is important to understand the most powerful feature of this command handler,
when you define a command you are able to type the params and have then be parsed by an handler so before your
command is ever executed you can be sure that all the params are valid. This module should be paired with a general
command parse but you may want to create your own:
@usage
---- Example Parse:
-- Before you go making commands it is important to understand the most powerful feature of this command handler,
-- when you define a command you are able to type the params and have then be parsed by an handler so before your
-- command is ever executed you can be sure that all the params are valid. This module should be paired with a general
-- command parse but you may want to create your own:
For our example we will create a parse to accept only integer numbers in a given range:
1) we will give it the name "number-range-int" this is the "type" that the input is expected to be
2) when we define the type we will also define the min and max of the range so we can use the function more than once
Example parse usage:
-- For our example we will create a parse to accept only integer numbers in a given range:
-- 1) we will give it the name "number-range-int" this is the "type" that the input is expected to be
-- 2) when we define the type we will also define the min and max of the range so we can use the function more than once
-- Example parse usage:
:add_param('repeat_count',false,'number-range-int',5,10) -- range 5 to 10 inclusive
The command parse will be passed 3 params and any other you define, in our case:
1) the input that has been given by the user for this param, the role of this function is to transform this value
nb: the input is a string but can be nil if the param is marked as optional
2) the player who is using the command, this is always present
3) the reject function to throw an error to the user, this is always present
4) the range min, this is user defined and has the value given when the param is defined
5) the range max, this is user defined and has the value given when the param is defined
-- The command parse will be passed 3 params and any other you define, in our case:
-- 1) the input that has been given by the user for this param, the role of this function is to transform this value
-- nb: the input is a string but can be nil if the param is marked as optional
-- 2) the player who is using the command, this is always present
-- 3) the reject function to throw an error to the user, this is always present
-- 4) the range min, this is user defined and has the value given when the param is defined
-- 5) the range max, this is user defined and has the value given when the param is defined
When returning from the param parse you again have a few options with how to do this:
1) you return the new value for the param (any non nil value) this value is then passed to the command callback
2) not returning will cause a generic invalid error and the command callback is blocked, not recommenced
3) return reject -- this is just a failsafe in case the function is not called, same as no return
4) return reject() -- will give a shorter error message as you pass a nil custom error
5) return reject('Number entered is not in range: '..range_min..', '..range_max) -- returns a custom error the the user
nb: if you do not return reject after you call it then you are still returning nil so there will be a duplicate message
-- When returning from the param parse you again have a few options with how to do this:
-- 1) you return the new value for the param (any non nil value) this value is then passed to the command callback
-- 2) not returning will cause a generic invalid error and the command callback is blocked, not recommenced
-- 3) return reject -- this is just a failsafe in case the function is not called, same as no return
-- 4) return reject() -- will give a shorter error message as you pass a nil custom error
-- 5) return reject('Number entered is not in range: '..range_min..', '..range_max) -- returns a custom error the the user
-- nb: if you do not return reject after you call it then you are still returning nil so there will be a duplicate message
It should be noted that if you want to expand on an existing parse you can use Commands.parse(type,input,player,reject)
and this value will either return a new value for the input or nil, if it is nil you should return nil to prevent double
messages to the user:
-- It should be noted that if you want to expand on an existing parse you can use Commands.parse(type,input,player,reject)
-- and this value will either return a new value for the input or nil, if it is nil you should return nil to prevent double
-- messages to the user:
input = Commands.parse('number-int',input,player,reject)
if not input then return end -- nil check
Example Code:
-- Example Code:
Commands.add_parse('number-range-int',function(input,player,reject,range_min,range_max)
local rtn = tonumber(input) and math.floor(tonumber(input)) or nil -- converts input to number
if not rtn or rtn < range_min or rtn > range_max then
@@ -87,22 +91,23 @@
end
end)
>>>>Example Command:
How for the fun part making the commands, the commands can be set up with any number of params and flags that you want,
you can add aliases for the commands and set default values for optional params and of course register your command callback
in our example we will just have a command that will repeat the users name in chat X amount of times and only allow admins to use it.
@usage
---- Example Command:
-- How for the fun part making the commands, the commands can be set up with any number of params and flags that you want,
-- you can add aliases for the commands and set default values for optional params and of course register your command callback
-- in our example we will just have a command that will repeat the users name in chat X amount of times and only allow admins to use it.
First we create the new command, nb this will not register the command to the game this is done at the end, we will call
the command "repeat-name" and set the help message as follows:
-- First we create the new command, nb this will not register the command to the game this is done at the end, we will call
-- the command "repeat-name" and set the help message as follows:
Commands.new_command('repeat-name','Will repeat you name a number of times in chat.')
Now for our first param we will call "repeat-count" and it will be a required value between 1 and 5 inclusive:
-- Now for our first param we will call "repeat-count" and it will be a required value between 1 and 5 inclusive:
:add_param('repeat-count',false,'number-range-int',1,5)
Our second param we need a custom parse for but we have not defined it, this is an option for when it is unlikely for
any other command to use the same input type; however in our case it will just be a boolean which should be noted as being
included in the general command parse config. As for the param its self it will be called "smiley" and will be optional with
a default value of false:
-- Our second param we need a custom parse for but we have not defined it, this is an option for when it is unlikely for
-- any other command to use the same input type; however in our case it will just be a boolean which should be noted as being
-- included in the general command parse config. As for the param its self it will be called "smiley" and will be optional with
-- a default value of false:
:add_param('smiley',true,function(input,player,reject)
-- since it is optional the input can be nil, in which case we just return
if not input then return end
@@ -115,12 +120,12 @@
end
end)
Once all params are defined you can now define some default values if you have optional params, the default value will be used only
when no value is given as input, if an invalid value is given then the command will still fail and this value will not be used, the
default can also be a function which is passed the player using the command and returns a value. Here we set the default for "smiley" to false:
-- Once all params are defined you can now define some default values if you have optional params, the default value will be used only
-- when no value is given as input, if an invalid value is given then the command will still fail and this value will not be used, the
-- default can also be a function which is passed the player using the command and returns a value. Here we set the default for "smiley" to false:
:set_defaults{smiley=false}
Another example of defaults if we have: item, amount[opt], player[opt]
-- Another example of defaults if we have: item, amount[opt], player[opt]
:set_defaults{
amount = 50, -- more than one value can be set at a time
player = function(player)
@@ -128,18 +133,18 @@
end
}
Now the params are set up we can alter how the command works, we can set auth flags, add aliases to this command or enable "auto concat"
which is when you want all extra words to be concatenated onto the end of the last param, useful for reason or messages:
-- Now the params are set up we can alter how the command works, we can set auth flags, add aliases to this command or enable "auto concat"
-- which is when you want all extra words to be concatenated onto the end of the last param, useful for reason or messages:
:set_flag('admin_only',true) -- in our case we want "admin_only" to be set to true so only admins can use the command
:add_alias('name','rname') -- we also add two aliases here: "name" and "rname" which point to this command
-- :enable_auto_concat() we do not use this in our case but this can also be used to enable the "auto concat" feature
And finally we want to register a callback to this command, the callback is what defines what the command does, can be as complex as you
want it to be to as simple as our example; the command receives two params plus all that you have defines:
1) the player who used the command
2) in our case repeat_count which will be a number
3) in our case smiley which will be a boolean
4) the raw input; this param is always last as is always present as a catch all
-- And finally we want to register a callback to this command, the callback is what defines what the command does, can be as complex as you
-- want it to be to as simple as our example; the command receives two params plus all that you have defines:
-- 1) the player who used the command
-- 2) in our case repeat_count which will be a number
-- 3) in our case smiley which will be a boolean
-- 4) the raw input; this param is always last as is always present as a catch all
:register(function(player,repeat_count,smiley,raw)
-- this is to show the value for raw as this is an example command, the log file will also show this
game.print(player.name..' used a command with input: '..raw)
@@ -155,7 +160,7 @@
-- see below for what else can be used here
end)
Some other useful functions that can be used are:
-- Some other useful functions that can be used are:
Commands.print(any,colour[opt]) -- this will return any value value to the user including if it is ran through rcon console
Commands.error(message[opt]) -- this returns a warning to the user, aka an error that does not prevent execution of the command
return Commands.error(message[opt]) -- this returns an error to the user, and will halt the command execution, ie no success message is returned
@@ -163,7 +168,7 @@
return Commands.success(message[opt]) -- will return the success message to the user and your given message, halts execution
return <any> if any value is returned then it will be returned to the player via a Commands.success call
Example Code:
-- Example Code:
Commands.new_command('repeat-name','Will repeat you name a number of times in chat.')
:add_param('repeat-count',false,'number-range-int',1,5) -- required int in range 1 to 5 inclusive
:add_param('smiley',true,function(input,player,reject) -- optional boolean default false
@@ -188,32 +193,6 @@
end
end)
>>>>Functions List (see function for more detail):
Commands.add_authenticator(callback) --- Adds an authorization callback, function used to check if a player if allowed to use a command
Commands.remove_authenticator(callback) --- Removes an authorization callback, see add_authenticator for adding them
Commands.authorize(player,command_name) --- Mostly used internally, calls all authorization callbacks, returns if the player is authorized
Commands.get(player) --- Gets all commands that a player is allowed to use, game commands not included
Commands.search(keyword,allowed_player) --- Searches command names and help messages to find possible commands, game commands included
Commands.add_parse(name,callback) --- Adds a parse function which can be called by name rather than callback (used in add_param)
Commands.remove_parse(name) --- Removes a parse function, see add_parse for adding them
Commands.parse(name,input,player,reject,...) --- Intended to be used within other parse functions, runs a parse and returns success and new value
Commands.new_command(name,help) --- Creates a new command object to added details to, note this does not register the command to the game
Commands._prototype:add_param(name,optional,parse,...) --- Adds a new param to the command this will be displayed in the help and used to parse the input
Commands._prototype:set_defaults(defaults) --- Adds default values to params only matters if the param is optional
Commands._prototype:set_flag(name,value) --- Adds a tag to the command which is passed via the flags param to the authenticators, can be used to assign command roles or type
Commands._prototype:add_alias(...) --- Adds an alias or multiple that will also be registered with the same callback, eg /teleport can be /tp with both working
Commands._prototype:enable_auto_concat() --- Enables auto concatenation of any params on the end so quotes are not needed for last param
Commands._prototype:register(callback) --- Adds the callback to the command and registers all aliases, params and help message with the game
Commands.error(error_message,play_sound) --- Sends an error message to the player and returns a constant to return to command handler to exit execution
Commands.internal_error(success,command_name,error_message) --- Sends an error to the player and logs the error, used with pcall within command handler please avoid direct use
Commands.success(value) --- Sends a value to the player, followed by a command complete message
Commands.print(value) --- Short cut for player_return, will return any value given to it (not just strings) in a string format to the player/server
Commands.run_command(command_event) --- Main event function that is ran for all commands, used internally please avoid direct use
]]
local Game = require 'utils.game' --- @dep utils.game
@@ -233,6 +212,10 @@ local Commands = {
_prototype={}, -- used to store functions which gets added to new custom commands
}
--- Authenication.
-- Functions that control who can use commands
-- @section auth
--- Adds an authorization callback, function used to check if a player if allowed to use a command
-- @tparam function callback the callback you want to register as an authenticator
-- callback param - player: LuaPlayer - the player who is trying to use the command
@@ -317,6 +300,9 @@ function Commands.authorize(player,command_name)
return true, Commands.defines.success
end
end
--- Getters.
-- Functions that get commands
-- @section getters
--- Gets all commands that a player is allowed to use, game commands not included
-- @tparam[opt] LuaPlayer player the player that you want to get commands of, nil will return all commands
@@ -364,6 +350,10 @@ function Commands.search(keyword,allowed_player)
return matches
end
--- Parse.
-- Functions that help with parsing
-- @section parse
--- Adds a parse function which can be called by name rather than callback (used in add_param)
-- nb: this is not needed as you can use the callback directly this just allows it to be called by name
-- @tparam string name the name of the parse, should be the type like player or player_alive, must be unique
@@ -403,6 +393,10 @@ function Commands.parse(name,input,player,reject,...)
return rtn
end
--- Creation.
-- Functions that create a new command
-- @section creation
--- Creates a new command object to added details to, note this does not register the command to the game
-- @tparam string name the name of the command to be created
-- @tparam string help the help message for the command
@@ -540,6 +534,10 @@ function Commands._prototype:register(callback)
end
end
--- Status.
-- Functions that indicate status
-- @section status
--- Sends an error message to the player and returns a constant to return to command handler to exit execution
-- nb: this is for non fatal errors meaning there is no log of this event
-- nb: if reject is giving as a param to the callback use that instead

View File

@@ -1,39 +1,7 @@
--- Adds some commonly used functions used in many modules
-- @author cooldude2606
--[[
>>>>Functions List (see function for more detail):
Common.type_check(value,test_type) --- Compare types faster for faster validation of prams
Common.type_check_error(value,test_type,error_message,level) --- Raises an error if the value is of the incorrect type
Common.param_check(value,test_type,param_name,param_number) --- Raises an error when the value is the incorrect type, uses a consistent error message format
Common.player_return(value,colour,player) --- Will return a value of any type to the player/server console, allows colour for in-game players
Common.write_json(path,tbl) --- Writes a table object to a file in json format
Common.opt_require(path) --- Calls a require that will not error if the file is not found
Common.ext_require(path,...) --- Calls a require and returns only the keys given, file must return a table
Common.format_time(ticks,options) --- Formats tick into a clean format, denominations from highest to lowest
Common.move_items(items,surface,position,radius,chest_type) --- Moves items to the position and stores them in the closest entity of the type given
Common.print_grid_value(value, surface, position, scale, offset, immutable) --- Prints a colored value on a location.
Common.print_colored_grid_value(value, surface, position, offset, immutable,
color_value, base_color, delta_color, under_bound, over_bound) --- Prints a colored value on a location. with extra settings.
Common.clear_flying_text(surface) --- Clears all flying text entities on a surface
Common.string_contains(s, contains) --- Tests if a string contains a given substring.
Common.extract_keys(tbl,...) --- Extracts certain keys from a table
Common.enum(tbl) --- Converts a table to an enum
Common.auto_complete(options,input,use_key,rtn_key) --- Returns the closest match to the input
Common.table_keys(tbl) --- Returns all the keys of a table
Common.table_values(tbl) --- Returns all the values of a table
Common.table_alphanumsort(tbl) --- Returns the list is a sorted way that would be expected by people (this is by key)
Common.table_keysort(tbl) --- Returns the list is a sorted way that would be expected by people (this is by key) (faster alternative than above)
Common.format_chat_colour(message,color) --- Returns a message with valid chat tags to change its colour
Common.format_chat_colour_localized(message,color) --- Returns a message with valid chat tags to change its colour, using localization
Common.format_chat_player_name(player,raw_string) --- Returns the players name in the players color
--[[-- Core Module - Common Library
- Adds some commonly used functions used in many modules
@core Common-Library
@alias Common
]]
local Colours = require 'resources.color_presets' --- @dep resources.color_presets
@@ -532,7 +500,7 @@ local function sortFunc(x, y) --sorts tables with mixed index types.
end
--- Returns a copy of all of the values in the table.
-- @tparam table table tbl the to copy the keys from, or an empty table if tbl is nil
-- @tparam table tbl the to copy the keys from, or an empty table if tbl is nil
-- @tparam[opt] boolean sorted whether to sort the keys (slower) or keep the random order from pairs()
-- @tparam[opt] boolean as_string whether to try and parse the values as strings, or leave them as their existing type
-- @treturn array an array with a copy of all the values in the table
@@ -558,7 +526,7 @@ function Common.table_values(tbl, sorted, as_string)
end
--- Returns a copy of all of the keys in the table.
-- @tparam table table tbl the to copy the keys from, or an empty table if tbl is nil
-- @tparam table tbl the to copy the keys from, or an empty table if tbl is nil
-- @tparam[opt] boolean sorted whether to sort the keys (slower) or keep the random order from pairs()
-- @tparam[opt] boolean as_string whether to try and parse the keys as strings, or leave them as their existing type
-- @treturn array an array with a copy of all the keys in the table

View File

@@ -1,7 +1,14 @@
--- This file is used to require all the different elements of the gui module
-- each module has an outline here but for more details see their separate files in ./gui
--[[-- Core Module - Gui
- This file is used to require all the different elements of the gui module
- each module has an outline here but for more details see their separate files in ./gui
- please read the files for more documentation that cant be shown here
- please note there is a rework planned but not started
@core Gui
@alias Gui
]]
local Gui = require 'expcore.gui.core' --- @dep expcore.gui.core
--[[
Core

View File

@@ -1,4 +1,12 @@
--- Gui structure define for center gui frames
--[[-- Core Module - Gui
@module Gui
@alias Prototype
]]
--- Center Guis.
-- Gui structure define for center gui frames
-- @section center
--[[
>>>> Functions
CenterFrames.get_flow(player) --- Gets the center flow for a player

View File

@@ -1,4 +1,12 @@
--- Gui structure define for left frames
--[[-- Core Module - Gui
@module Gui
@alias Prototype
]]
--- Left Guis.
-- Gui structure define for left frames
-- @section left
--[[
>>>> Example formating

View File

@@ -1,4 +1,12 @@
--- Gui structure define for popup gui
--[[-- Core Module - Gui
@module Gui
@alias Prototype
]]
--- Popups.
-- Gui structure define for popup gui
-- @section popups
--[[
>>>> Functions
PopupFrames.get_flow(player) --- Gets the left flow that contains the popup frames

View File

@@ -1,4 +1,12 @@
--- Gui structure for the toolbar (top left)
--[[-- Core Module - Gui
@module Gui
@alias Prototype
]]
--- Toolbar.
-- Gui structure for the toolbar (top left)
-- @section toolbar
--[[
>>>> Example format
-- this is the same as any other button define, this just automatically draws it

View File

@@ -1,6 +1,14 @@
--- Core gui file for making element defines and element classes (use require 'expcore.gui')
--[[-- Core Module - Gui
@module Gui
@alias Prototype
]]
--- Core.
-- Core gui file for making element defines and element classes (use require 'expcore.gui')
-- see utils.gui for event handlering
-- see expcore.gui.test for examples for element defines
-- @section core
--[[
>>>> Basic useage with no defines
This module can be igroned if you are only wanting only event handlers as utils.gui adds the following:
@@ -138,6 +146,7 @@ Gui.names = {} -- Stores debug names to link to gui uids
--- Used to create new element defines from a class prototype, please use the own given by the class
-- @tparam table prototype the class prototype that will be used for the element define
-- @tparam[opt] string debug_name the name that you want to see while debuging
-- @treturn table the new element define with all functions accessed via __index metamethod
function Gui.new_define(prototype,debug_name)
local name = Gui.uid_name()
@@ -159,7 +168,7 @@ function Gui.new_define(prototype,debug_name)
end
--- Gets an element define give the uid, debug name or a copy of the element define
-- @tparam name ?string|table the uid, debug name or define for the element define to get
-- @tparam ?string|table name the uid, debug name or define for the element define to get
-- @tparam[opt] boolean internal when true the error trace is one level higher (used internally)
-- @treturn table the element define that was found or an error
function Gui.get_define(name,internal)
@@ -207,8 +216,8 @@ function Gui.categorize_by_surface(element)
end
--- Draws a copy of the element define to the parent element, see draw_to
-- @tparam name ?string|table the uid, debug name or define for the element define to draw
-- @tparam element LuaGuiEelement the parent element that it the define will be drawn to
-- @tparam ?string|table name the uid, debug name or define for the element define to draw
-- @tparam LuaGuiEelement element the parent element that it the define will be drawn to
-- @treturn LuaGuiElement the new element that was created
function Gui.draw(name,element,...)
local define = Gui.get_define(name,true)
@@ -256,7 +265,7 @@ function Gui.set_padding(element,up,down,left,right)
end
--- Sets the padding for a gui style
-- @tparam element LuaStyle the element to set the padding for
-- @tparam LuaStyle style the element to set the padding for
-- @tparam[opt=0] number up the amount of padding on the top
-- @tparam[opt=0] number down the amount of padding on the bottom
-- @tparam[opt=0] number left the amount of padding on the left

View File

@@ -1,4 +1,12 @@
--- Gui class define for buttons and sprite buttons
--[[-- Core Module - Gui
@module Gui
@alias Prototype
]]
--- Buttons.
-- Gui class define for buttons and sprite buttons
-- @section Buttons
--[[
>>>> Functions
Button.new_button(name) --- Creates a new button element define

View File

@@ -1,4 +1,12 @@
--- Gui class define for checkbox and radiobuttons
--[[-- Core Module - Gui
@module Gui
@alias Prototype
]]
--- Checkboxs.
-- Gui class define for checkbox and radiobuttons
-- @section checkboxs
--[[
>>>> Using an option set
An option set is a set of radio buttons where only one of them can be active at a time, this means that when one

View File

@@ -1,4 +1,12 @@
--- Gui class define for dropdowns and list box
--[[-- Core Module - Gui
@module Gui
@alias Prototype
]]
--- Dropdowns.
-- Gui class define for dropdowns and list box
-- @section dropdowns
--[[
>>>> Functions
Dropdown.new_dropdown(name) --- Creates a new dropdown element define

View File

@@ -1,4 +1,12 @@
--- Gui class defines for elem buttons
--[[-- Core Module - Gui
@module Gui
@alias Prototype
]]
--- Elem Buttons.
-- Gui class defines for elem buttons
-- @section elem-buttons
--[[
>>>> Functions
ElemButton.new_elem_button(name) --- Creates a new elem button element define

View File

@@ -1,4 +1,12 @@
--- Gui element define for progress bars
--[[-- Core Module - Gui
@module Gui
@alias Prototype
]]
--- Progress Bars.
-- Gui element define for progress bars
-- @section progress-bars
--[[
>>>> Functions
ProgressBar.set_maximum(element,amount,count_down) --- Sets the maximum value that represents the end value of the progress bar

View File

@@ -1,4 +1,12 @@
--- Gui class define for sliders
--[[-- Core Module - Gui
@module Gui
@alias Prototype
]]
--- Sliders.
-- Gui class define for sliders
-- @section sliders
--[[
>>>> Functions
Slider.new_slider(name) --- Creates a new slider element define

View File

@@ -1,4 +1,12 @@
--- Gui class define for text fields and text boxes
--[[-- Core Module - Gui
@module Gui
@alias Prototype
]]
--- Text.
-- Gui class define for text fields and text boxes
-- @section text
--[[
>>>> Functions
Text.new_text_field(name) --- Creates a new text field element define

View File

@@ -1,4 +1,12 @@
--- This file is a breakout from core which forcues on instance management of defines
--[[-- Core Module - Gui
@module Gui
@alias Prototype
]]
--- Instances.
-- This file is a breakout from core which forcues on instance management of defines
-- @section instances
--[[
>>>> Using registered instance groups
The main use of this module is to register a group of elements referred here as "instances of an element define" in which
@@ -158,7 +166,7 @@ end
--- Gets all valid element instances and has the option of running a callback on those that are valid
-- @tparam string name the name of the instance group to get the instances of
-- @tparam[opt] string category the category to get the instances of, not needed when no categorise function
-- @tparam[opt] callback function when given the callback will be ran on all valid elements
-- @tparam[opt] function callback when given the callback will be ran on all valid elements
-- callback param - element LuaGuiElement - the current valid element
-- @treturn table the table of element instances with all invalid ones removed
function Instances.get_valid_elements(name,category,callback)
@@ -186,7 +194,7 @@ Instances.apply_to_elements = Instances.get_valid_elements
--- A version of add_element that does not require the group to be registered
-- @tparam string name the name of the instance group to add the element to
-- @tparam category ?string|nil the category to add the element to, can be nil but must still be given
-- @tparam ?string|nil category the category to add the element to, can be nil but must still be given
-- @tparam LuaGuiElement element the element to add to the instance group
function Instances.unregistered_add_element(name,category,element)
if not Instances.data[name] then Instances.data[name] = {} end
@@ -200,7 +208,7 @@ end
--- A version of get_elements that does not require the group to be registered
-- @tparam string name the name of the instance group to get the instances of
-- @tparam category ?string|nil the category to get the instances of, can be nil but must still be given
-- @tparam ?string|nil category the category to get the instances of, can be nil but must still be given
-- @tparam[opt] function callback when given will be called on all valid instances
-- callback param - element LuaGuiElement - the current valid element
-- @treturn table the table of element instances with all invalid ones removed

View File

@@ -1,4 +1,12 @@
--- Used to create new gui prototypes see elements and concepts
--[[-- Core Module - Gui
@module Gui
@alias Prototype
]]
--- Prototype.
-- Used to create new gui prototypes see elements and concepts
-- @section prototype
--[[
>>>> Functions
Constructor.event(event_name) --- Creates a new function to add functions to an event handler
@@ -200,7 +208,7 @@ Prototype.on_style_update = Constructor.event('on_style_update')
--- Sets the style for the element define
-- @tparam string style the style that will be used for this element when drawn
-- @tparam[opt] callback function function is called when element is drawn to alter its style
-- @tparam[opt] function callback function is called when element is drawn to alter its style
-- @treturn self the element define to allow chaining
function Prototype:set_style(style,callback)
self.draw_data.style = style
@@ -211,7 +219,7 @@ function Prototype:set_style(style,callback)
end
--- Sets the element to be drawn inside a nameless flow, can be given a name using a function
-- @tparam state ?boolean|function when true a padless flow is created to contain the element
-- @tparam ?boolean|function state when true a padless flow is created to contain the element
-- @treturn self the element define to allow chaining
function Prototype:set_embedded_flow(state)
if state == false or type(state) == 'function' then

View File

@@ -1,6 +1,14 @@
--- This file creates a test gui that is used to test every input method
--[[-- Core Module - Gui
@module Gui
@alias tests
]]
--- Test.
-- This file creates a test gui that is used to test every input method
-- note that this does not cover every permutation only features in independence
-- for example store in most cases is just by player name, but other store methods are tested with checkbox
-- @section test
local Gui = require 'expcore.gui' --- @dep expcore.gui
local format_chat_colour,table_keys = ext_require('expcore.common','format_chat_colour','table_keys') --- @dep expcore.common
local Colors = require 'resources.color_presets' --- @dep resources.color_presets

View File

@@ -1,7 +1,10 @@
--- Permission group making for factorio so you never have to make one by hand again
-- @author Cooldude2606
--[[
>>>>Example Group (Allow All)
--[[-- Core Module - Permission Groups
- Permission group making for factorio so you never have to make one by hand again
@core Permissions-Groups
@alias Permissions_Groups
@usage
---- Example Group (Allow All)
-- here we will create an admin group however we do not want them to use the map editor or mess with the permission groups
Permission_Groups.new_group('Admin') -- this defines a new group called "Admin"
@@ -14,38 +17,14 @@
'toggle_map_editor'
}
>>>>Example Group (Disallow All)
@usage
---- Example Group (Disallow All)
-- here we will create a group that cant do anything but talk in chat
Permission_Groups.new_group('Restricted') -- this defines a new group called "Restricted"
:disallow_all() -- this makes the default to disallow any input action unless set other wise
:allow('write_to_console') -- here we allow them to chat, {} can be used here if we had more than one action
>>>>Functions List (see function for more detail):
Permissions_Groups.new_group(name) --- Defines a new permission group that can have it actions set in the config
Permissions_Groups.get_group_by_name(name) --- Returns the group with the given name, case sensitive
Permissions_Groups.get_group_from_player(player) --- Returns the group that a player is in
Permissions_Groups.reload_permissions() --- Reloads/creates all permission groups and sets them to they configured state
Permissions_Groups.lockdown_permissions(exempt) --- Removes all permissions from every permission group except for "Default" and any passed as exempt
Permissions_Groups.set_player_group(player,group) --- Sets a player's group to the one given, a player can only have one group at a time
Permissions_Groups._prototype:set_action(action,state) --- Sets the allow state of an action for this group, used internally but is safe to use else where
Permissions_Groups._prototype:allow(actions) --- Sets an action or actions to be allowed for this group even with disallow_all triggered, Do not use in runtime
Permissions_Groups._prototype:disallow(actions) --- Sets an action or actions to be disallowed for this group even with allow_all triggered, Do not use in runtime
Permissions_Groups._prototype:allow_all() --- Sets the default state for any actions not given to be allowed, useful with :disallow
Permissions_Groups._prototype:disallow_all() --- Sets the default state for any action not given to be disallowed, useful with :allow
Permissions_Groups._prototype:is_allowed(action) --- Returns if an input action is allowed for this group
Permissions_Groups._prototype:get_raw() --- Returns the LuaPermissionGroup that was created with this group object, used internally
Permissions_Groups._prototype:create() --- Creates or updates the permission group with the configured actions, used internally
Permissions_Groups._prototype:add_player(player) --- Adds a player to this group
Permissions_Groups._prototype:remove_player(player) --- Removes a player from this group
Permissions_Groups._prototype:get_players(online) --- Returns all player that are in this group with the option to filter to online/offline only
Permissions_Groups._prototype:print(message) --- Prints a message to every player in this group
]]
@@ -58,6 +37,10 @@ local Permissions_Groups = {
_prototype={} -- stores functions that are used on group instances
}
--- Getters.
-- Functions that get permission groups
-- @section getters
--- Defines a new permission group that can have it actions set in the config
-- @tparam string name the name of the new group
-- @treturn Permissions_Groups._prototype the new group made with function to allow and disallow actions
@@ -92,6 +75,10 @@ function Permissions_Groups.get_group_from_player(player)
end
end
--- Setters.
-- Functions that control all groups
-- @section players
--- Reloads/creates all permission groups and sets them to they configured state
function Permissions_Groups.reload_permissions()
for _,group in pairs(Permissions_Groups.groups) do
@@ -137,6 +124,10 @@ function Permissions_Groups.set_player_group(player,group)
return true
end
--- Actions.
-- Functions that control group actions
-- @section actions
--- Sets the allow state of an action for this group, used internally but is safe to use else where
-- @tparam ?string|defines.input_action action the action that you want to set the state of
-- @tparam boolean state the state that you want to set it to, true = allow, false = disallow
@@ -203,6 +194,10 @@ function Permissions_Groups._prototype:is_allowed(action)
return state
end
--- Players.
-- Functions that control group players
-- @section players
--- Returns the LuaPermissionGroup that was created with this group object, used internally
-- @treturn LuaPermissionGroup the raw lua permission group
function Permissions_Groups._prototype:get_raw()

View File

@@ -1,7 +1,10 @@
--- Factorio role system to manage custom permissions
-- @author Cooldude2606
--[[
>>>>Using Role System (Frontend):
--[[-- Core Module - Roles
- Factorio role system to manage custom permissions.
@core Roles
@alias Roles
@usage
---- Using Role System (Frontend):
When a map first starts you will want to define on mass all the players you expect to join and the roles to give them:
Roles.override_player_roles{
Cooldude2606 = {'Owner','Admin','Member'},
@@ -12,7 +15,8 @@
Roles.assign_player(player,'Admin',by_player_name) -- this will give the "Admin" role to the player
Roles.unassign_player(player,{'Admin','Moderator'},by_player_name) -- this will remove "Admin" and "Moderator" role in one go
>>>>Using Role System (Backend):
@usage
---- Using Role System (Backend):
To comparer two players you can comparer the index of they highest roles, can be used when you want to allow a "write" down type system:
Roles.get_player_highest_role(playerOne).index < Roles.get_player_highest_role(playerTwo).index -- remember that less means a higher role
@@ -24,7 +28,8 @@
Roles.player_has_flag(player,'is_donator') -- your roles can be grouped together with flags such as is_donator
Roles.player_allowed(player,'game modifiers') -- or you can have an action based system where each action is something the player can do
>>>>Example Flag Define:
@usage
---- Example Flag Define:
Flags can be used to group multiple roles and actions under one catch all, for example if you want a piece of code to only
be active for your donators then you would add a "is_donator" flag to all your donator roles and then in the code test if
a player has that tag present:
@@ -47,7 +52,8 @@
-- some donator only code
end
>>>>Example Role Define:
@usage
---- Example Role Define:
You can't use a role system without any roles so first you must define your roles; each role has a minimum of a name with
the option for a shorthand:
Roles.new_role('Administrator','Admin')
@@ -86,7 +92,8 @@
'gui/game settings'
}
>>>>Example System Define:
@usage
---- Example System Define:
Once all roles are defined these steps must be done to ensure the system is ready to use, this includes setting a default
role, assigning a root (all permission) role that the server/system will use and the linear order that the roles fall into:
@@ -103,55 +110,6 @@
Just remember that in this example all these roles have not been defined; so make sure all your roles that are used are defined
before hand; a config file on load is useful for this to ensure that its loaded before the first player even joins.
>>>>Functions List (see function for more detail):
Roles.debug() --- Returns a string which contains all roles in index order displaying all data for them
Roles.print_to_roles(roles,message) --- Prints a message to all players in the given roles, may send duplicate message however factorio blocks spam
Roles.print_to_roles_higher(role,message) --- Prints a message to all players who have the given role or one which is higher (excluding default)
Roles.print_to_roles_lower(role,message) --- Prints a message to all players who have the given role or one which is lower (excluding default)
Roles.get_role_by_name(name) --- Get a role for the given name
Roles.get_role_by_order(index) --- Get a role with the given order index
Roles.get_role_from_any(any) --- Gets a role from a name,index or role object (where it is just returned)
Roles.get_player_roles(player) --- Gets all the roles of the given player, this will always contain the default role
Roles.get_player_highest_role(player) --- Gets the highest role which the player has, can be used to compeer one player to another
Roles.assign_player(player,roles,by_player_name,silent) --- Gives a player the given role(s) with an option to pass a by player name used in the log
Roles.unassign_player(player,roles,by_player_name,silent) --- Removes a player from the given role(s) with an option to pass a by player name used in the log
Roles.override_player_roles(roles) --- Overrides all player roles with the given table of roles, useful to mass set roles on game start
Roles.player_has_role(player,search_role) --- A test for weather a player has the given role
Roles.player_has_flag(player,flag_name) --- A test for weather a player has the given flag true for at least one of they roles
Roles.player_allowed(player,action) --- A test for weather a player has at least one role which is allowed the given action
Roles.define_role_order(order) --- Used to set the role order, higher in the list is better, must be called at least once in config
Roles.define_flag_trigger(name,callback) --- Defines a new trigger for when a tag is added or removed from a player
Roles.set_default(name) --- Sets the default role which every player will have, this needs to be called at least once
Roles.set_root(name) --- Sets the root role which will always have all permissions, any server actions act from this role
Roles.new_role(name,short_hand) --- Defines a new role and returns the prototype to allow configuration
Roles._prototype:set_allow_all(state) --- Sets the default allow state of the role, true will allow all actions
Roles._prototype:allow(actions) --- Sets the allow actions for this role, actions in this list will be allowed for this role
Roles._prototype:disallow(actions) --- Sets the disallow actions for this role, will prevent actions from being allowed regardless of inheritance
Roles._prototype:is_allowed(action) --- Test for if a role is allowed the given action, mostly internal see Roles.player_allowed
Roles._prototype:set_flag(name,value) --- Sets the state of a flag for a role, flags can be used to apply effects to players
Roles._prototype:clear_flags() --- Clears all flags from this role, individual flags can be removed with set_flag(name,false)
Roles._prototype:has_flag(name) --- A test for if the role has a flag set
Roles._prototype:set_custom_tag(tag) --- Sets a custom player tag for the role, can be accessed by other code
Roles._prototype:set_custom_color(color) --- Sets a custom colour for the role, can be accessed by other code
Roles._prototype:set_permission_group(name,use_factorio_api) --- Sets the permission group for this role, players will be moved to the group of they highest role
Roles._prototype:set_parent(role) --- Sets the parent for a role, any action not in allow or disallow will be looked for in its parents
Roles._prototype:set_auto_promote_condition(callback) --- Sets an auto promote condition that is checked every 5 seconds, if true is returned then the player will receive the role
Roles._prototype:set_block_auto_promote(state) --- Sets the role to not allow players to have auto promote effect them, useful to keep people locked to a punishment
Roles._prototype:add_player(player,skip_check,skip_event) --- Adds a player to this role, players can have more than one role at a time, used internally see Roles.assign
Roles._prototype:remove_player(player,skip_check,skip_event) --- Removes a player from this role, players can have more than one role at a time, used internally see Roles.unassign
Roles._prototype:get_players(online) --- Returns an array of all the players who have this role, can be filtered by online status
Roles._prototype:print(message) --- Will print a message to all players with this role
]]
local Game = require 'utils.game' --- @dep utils.game
@@ -189,6 +147,10 @@ Global.register(Roles.config,function(tbl)
end
end)
--- Getter.
-- Functions which get roles
-- @section get
--- Internal function used to trigger a few different things when roles are changed
-- this is the raw internal trigger as the other function is called at other times
-- there is a second half called role_update which triggers after the event call, it also is called when a player joins
@@ -348,6 +310,10 @@ function Roles.get_player_highest_role(player)
return highest
end
--- Assinment.
-- Functions for changing player's roles
-- @section assinment
--- Gives a player the given role(s) with an option to pass a by player name used in the log
-- @tparam LuaPlayer player the player that will be assigned the roles
-- @tparam table roles table a of roles that the player will be given, can be one role and can be role names
@@ -394,6 +360,10 @@ function Roles.override_player_roles(roles)
Roles.config.players = roles
end
--- Checks.
-- Functions for checking player's roles
-- @section checks
--- A test for weather a player has the given role
-- @tparam LuaPlayer player the player to test the roles of
-- @tparam ?string|number|table search_role a pointer to the role that is being searched for
@@ -439,6 +409,10 @@ function Roles.player_allowed(player,action)
return false
end
--- Definations.
-- Functions which are used to define roles
-- @section checks
--- Used to set the role order, higher in the list is better, must be called at least once in config
-- nb: function also re links parents due to expected position in the config file
-- @tparam table order table a which is keyed only by numbers (start 1) and values are roles in order with highest first
@@ -508,6 +482,10 @@ function Roles.new_role(name,short_hand)
return role
end
--- Role Actions.
-- Functions for using the role action system
-- @section actions
--- Sets the default allow state of the role, true will allow all actions
-- @tparam[opt=true] boolean state true will allow all actions
-- @treturn Roles._prototype allows chaining
@@ -551,6 +529,10 @@ function Roles._prototype:is_allowed(action)
return self.allowed_actions[action] or self.allow_all_actions or is_root
end
--- Role Flags.
-- Functions for using the role flag system
-- @section flags
--- Sets the state of a flag for a role, flags can be used to apply effects to players
-- @tparam string name the name of the flag to set the value of
-- @tparam[opt=true] boolean value the state to set the flag to
@@ -575,6 +557,10 @@ function Roles._prototype:has_flag(name)
return self.flags[name] or false
end
--- Role Properties.
-- Functions for chaning other proerties
-- @section properties
--- Sets a custom player tag for the role, can be accessed by other code
-- @tparam string tag the value that the tag will be
-- @treturn Roles._prototype allows chaining
@@ -639,6 +625,10 @@ function Roles._prototype:set_block_auto_promote(state)
return self
end
--- Role Players.
-- Functions that control players in a role
-- @section players
--- Adds a player to this role, players can have more than one role at a time, used internally see Roles.assign
-- @tparam LuaPlayer player the player that will be given this role
-- @tparam boolean skip_check when true player will be taken as the player name (use when player has not yet joined)

View File

@@ -1,66 +1,73 @@
--- Adds an easy way to store and watch for updates to a value
--[[
>>>> Basic Use
At the most basic level this allows for the naming of locations to store in the global table, the second feature is that you are
able to listen for updates of this value, which means that when ever the set function is called it will trigger the update callback.
--[[-- Core Module - Store
- Adds an easy way to store and watch for updates to a value
@core Store
@alias Store
This may be useful when storing config values and when they get set you want to make sure it is taken care of, or maybe you want
to have a value that you can trigger an update of from different places.
@usage
---- Basic Use
-- At the most basic level this allows for the naming of locations to store in the global table, the second feature is that you are
-- able to listen for updates of this value, which means that when ever the set function is called it will trigger the update callback.
-- this will register a new location called 'scenario.difficulty'
-- This may be useful when storing config values and when they get set you want to make sure it is taken care of, or maybe you want
-- to have a value that you can trigger an update of from different places.
-- This will register a new location called 'scenario.difficulty'
-- note that setting a start value is optional and we could take nil to mean normal
Store.register('scenario.difficulty',function(value)
game.print('The scenario difficulty has be set to: '..value)
end)
-- this will set the value in the store to 'hard' and will trigger the update callback which will print a message to the game
-- This will set the value in the store to 'hard' and will trigger the update callback which will print a message to the game
Store.set('scenario.difficulty','hard')
-- this will return 'hard'
-- This will return 'hard'
Store.get('scenario.difficulty')
>>>> Using Children
One limitation of store is that all locations must be registered to avoid desyncs, to get round this issue "children" can be used.
When you set the value of a child it does not have its own update callback so rather the "parent" location which has been registered
will have its update value called with a second param of the name of that child.
@usage
---- Using Children
-- One limitation of store is that all locations must be registered to avoid desyncs, to get round this issue "children" can be used.
-- When you set the value of a child it does not have its own update callback so rather the "parent" location which has been registered
-- will have its update value called with a second param of the name of that child.
This may be useful when you want a value of each player or force and since you cant register every player at the start you must use
the players name as the child name.
-- This may be useful when you want a value of each player or force and since you cant register every player at the start you must use
-- the players name as the child name.
-- this will register the location 'scenario.score' where we plan to use force names as the child
-- This will register the location 'scenario.score' where we plan to use force names as the child
Store.register('scenario.score',function(value,child)
game.print(child..' now has a score of '..value)
end)
-- this will return nil, but will not error as children don't need to be registered
-- This will return nil, but will not error as children don't need to be registered
Store.get('scenario.score','player')
-- this will set 'player' to have a value of 10 for 'scenario.score' and trigger the game message print
-- This will set 'player' to have a value of 10 for 'scenario.score' and trigger the game message print
Store.set('scenario.score','player',10)
-- this would be the similar to Store.get however this will return the names of all the children
-- This would be the similar to Store.get however this will return the names of all the children
Store.get_children('scenario.score')
>>>> Using Sync
There is the option to use synced values which is the same as a normal value however you can combine this with an external script
which can read the output from 'script-output/log/store.log' and have it send rcon commands back to the game allowing for cross instance
syncing of values.
@usage
---- Using Sync
-- There is the option to use synced values which is the same as a normal value however you can combine this with an external script
-- which can read the output from 'script-output/log/store.log' and have it send rcon commands back to the game allowing for cross instance
-- syncing of values.
This may be useful when you want to have a value change effect multiple instances or even if you just want a database to store values so
you can sync data between map resets.
-- This may be useful when you want to have a value change effect multiple instances or even if you just want a database to store values so
-- you can sync data between map resets.
-- this example will register the location 'statistics.total-play-time' where we plan to use plan names as the child
-- This example will register the location 'statistics.total-play-time' where we plan to use plan names as the child
-- note that the location must be the same across instances
Store.register('statistics.total-play-time',true,function(value,child)
game.print(child..' now has now played for '..value)
end)
-- use of set and are all the same as non synced but you should include from_sync as true
-- Use of set and are all the same as non synced but you should include from_sync as true
>>>> Alternative method
Some people may prefer to use a variable rather than a string for formating reasons here is an example. Also for any times when
there will be little external input Store.uid_location() can be used to generate non conflicting locations, uid_location will also
be used if you give a nil location.
@usage
---- Alternative method
-- Some people may prefer to use a variable rather than a string for formating reasons here is an example. Also for any times when
-- there will be little external input Store.uid_location() can be used to generate non conflicting locations, uid_location will also
-- be used if you give a nil location.
local store_game_speed =
Store.register(function(value)

View File

@@ -1,24 +1,22 @@
--- An extention of task and token to allow a single require to register and run functions bypassing all permissions
--[[
>>>> Usage
To use sudo you must register the allowed functions when the files are loaded, often this will just be giving access to
some functions within a module if you expect that some parts may be blocked by in game permissions or a custom system you have made
--[[-- Core Module - Sudo
- An extention of task and token to allow a single require to register and run functions bypassing all permissions.
@core Sudo
@alias Sudo
-- this will be blocked if the current player (from a command or gui) is not admin
@usage
-- To use sudo you must register the allowed functions when the files are loaded, often this will just be giving access to
-- some functions within a module if you expect that some parts may be blocked by in game permissions or a custom system you have made
-- This will be blocked if the current player (from a command or gui) is not admin
local function make_admin(player)
player.admin = true
player.admin = true
end
-- here we give sudo access to the function under the name "make-admin"
-- Here we give sudo access to the function under the name "make-admin"
Sudo.register('make-admin',make_admin)
-- this will allow us to bypass this by running one tick later outside of any player scope
-- This will allow us to bypass this by running one tick later outside of any player scope
Sudo.run('make-admin',game.player)
>>>> Functions
Sudo.register(name,callback) --- Registers a new callback under the given name, used to avoid desyncs
Sudo.get(name) --- Gets the function that is registered under the given name
Sudo.run(name,...) --- Runs the function that is registered under the given name, you may supply any number of params as needed
]]
local Task = require 'utils.task' --- @dep utils.task
local Token = require 'utils.token' --- @dep utils.token
@@ -56,7 +54,7 @@ function Sudo.get(name)
end
--- Runs the function that is registered under the given name, you may supply any number of params as needed
-- @tparam name string the name of the function you want to run
-- @tparam string name the name of the function you want to run
-- @tparam[opt] any ... the other params that you want to pass to your function
function Sudo.run(name,...)
local token = Sudo.tokens[name]