From 4e424518652b3bc34f9a8ebfbea0a93390b98134 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Sat, 2 Mar 2019 15:50:03 +0000 Subject: [PATCH] Added add_defaults to Commands --- expcore/commands.lua | 62 ++++++++++++++++++++------------- modules/test.lua | 83 +++++++++++++------------------------------- 2 files changed, 63 insertions(+), 82 deletions(-) diff --git a/expcore/commands.lua b/expcore/commands.lua index 35383e1d..9c209dbe 100644 --- a/expcore/commands.lua +++ b/expcore/commands.lua @@ -30,8 +30,7 @@ -- input, player and reject are common to all parse functions -- range_min and range_max are passed to the function from add_param Commands.add_parse('number_range_int',function(input,player,reject,range_min,range_max) - local rtn = tonumber(input) or nil -- converts input to number - rtn = type(rtn) == 'number' and math.floor(rtn) or nil -- floor the number + 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 -- check if it is nil or out of the range -- invalid input for we will reject the input, they are a few ways to do this: -- dont return anything -- will print generic input error @@ -52,7 +51,7 @@ Commands.add_command('repeat-name','Will repeat you name a number of times in chat.') -- creates the new command with the name "repeat-name" and a help message :add_param('repeat-count',false,'number_range_int',1,5) -- adds a new param called "repeat-count" that is required and is type "number_range_int" the name can be used here as add_parse was used :add_param('smiley',true,function(input,player,reject) -- this param is optional and has a custom parse function where add_parse was not used before hand - if not input then return false end -- here you can see the default check + if not input then return end -- when they is an optional param input may be nil, you can return a default value here, but using nil will allow add_defaults to pick a default if input:lower() == 'true' or input:lower() == 'yes' then return true -- the value is truthy so true is returned else @@ -61,6 +60,7 @@ return false -- false is returned other wise end end) + :add_defaults{smiley=false} -- adds false as the default for smiley :add_tag('admin_only',true) -- adds the tag admin_only: true which because of the above authenticator means you must be added to use this command :add_alias('name','rname') -- adds two aliases "name" and "rname" for this command which will work as if the ordinal name was used --:auto_concat() -- cant be used due to optional param here, but this will make all user input params after the last expected one be added to the last expected one @@ -101,8 +101,7 @@ end) Commands.add_parse('number_range_int',function(input,player,reject,range_min,range_max) - local rtn = tonumber(input) or nil - rtn = type(rtn) == 'number' and math.floor(rtn) or nil + local rtn = tonumber(input) and math.floor(tonumber(input)) or nil if not rtn or rtn < range_min or rtn > range_max then return reject('Number entered is not in range: '..range_min..', '..range_max) else @@ -113,13 +112,14 @@ Commands.add_command('repeat-name','Will repeat you name a number of times in chat.') :add_param('repeat-count',false,'number_range_int',1,5) :add_param('smiley',true,function(input,player,reject) - if not input then return false end + if not input then return end if input:lower() == 'true' or input:lower() == 'yes' then return true else return false end end) + :add_defaults{smiley=false} :add_tag('admin_only',true) :add_alias('name','rname') :register(function(player,repeat_count,smiley,raw) @@ -146,6 +146,7 @@ Commands.add_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:add_defaults(defaults) --- Adds default values to params only matters if the param is optional Commands._prototype:add_tag(name,value) --- Adds a tag to the command which is passed via the tags 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:auto_concat() --- Enables auto concatenation of any params on the end so quotes are not needed for last param @@ -311,7 +312,7 @@ end --- 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 name string the name of the parse, should be the type like player or player_alive, must be unique --- @tparam callback function the callback that is ran to prase the input +-- @tparam callback function the callback that is ran to parse the input -- parse param - input: string - the input given by the user for this param -- parse param - player: LuaPlayer - the player who is using the command -- parse param - reject: function(error_message) - use this function to send a error to the user and fail running @@ -344,15 +345,9 @@ function Commands.add_command(name,help) auto_concat=false, min_param_count=0, max_param_count=0, - tags={ - -- stores tags that can be used by auth - }, - aliases={ - -- n = name: string - }, - params={ - -- [param_name] = {optional: boolean, parse: function} - } + tags={}, -- stores tags that can be used by auth + aliases={}, -- n = name: string + params={}, -- [param_name] = {optional: boolean, default: any, parse: function, parse_args: table} }, { __index= Commands._prototype }) @@ -385,6 +380,19 @@ function Commands._prototype:add_param(name,optional,parse,...) return self end +--- Adds default values to params only matters if the param is optional, if default value is a function it is called with param player +-- @tparam defaults table a table keyed by the name of the param with the value as the default value {paramName=defaultValue} +-- callback param - player: LuaPlayer - the player using the command, default value does not need to be a function callback +-- @treturn Commands._prototype pass through to allow more functions to be called +function Commands._prototype:add_defaults(defaults) + for name,value in pairs(defaults) do + if self.params[name] then + self.params[name].default = value + end + end + return self +end + --- Adds a tag to the command which is passed via the tags param to the authenticators, can be used to assign command roles or type -- @tparam name string the name of the tag to be added; used to keep tags separate -- @tparam value any the tag that you want can be anything that the authenticators are expecting @@ -431,7 +439,6 @@ end function Commands._prototype:register(callback) -- generates a description to be used self.callback = callback - local params = self.params local description = '' for param_name,param_details in pairs(self.params) do if param_details.optional then @@ -523,9 +530,9 @@ function Commands.run_command(command_event) local quote_params = {} -- stores any " " params input_string = input_string:gsub('"[^"]-"',function(w) -- finds all " " params are removes spaces for the next part - local no_qoutes = w:sub(2,-2) - local no_spaces = no_qoutes:gsub('%s','_') - quote_params[no_spaces]=no_qoutes + local no_quotes = w:sub(2,-2) + local no_spaces = no_quotes:gsub('%s','_') + quote_params[no_spaces]=no_quotes if command_data.auto_concat then -- if auto concat then dont remove quotes as it should be included later quote_params[w:gsub('%s','_')]=w @@ -583,7 +590,7 @@ function Commands.run_command(command_event) end if not type(parse_callback) == 'function' then -- if its not a function throw and error - Commands.internal_error(success,command_data.name,'Invalid param parse '..tostring(param_data.parse)) + Commands.internal_error(false,command_data.name,'Invalid param parse '..tostring(param_data.parse)) return end -- used below as the reject function @@ -595,9 +602,16 @@ function Commands.run_command(command_event) -- input: string, player: LuaPlayer, reject: function, ... extra args local success,param_parsed = pcall(parse_callback,raw_params[index],player,parse_fail,unpack(param_data.parse_args)) if Commands.internal_error(success,command_data.name,param_parsed) then return end - -- param_data.optional == false is so that optional parses are still ran even when not present - if (param_data.optional == false and param_parsed == nil) or param_parsed == Commands.defines.error or param_parsed == parse_fail then - -- no value was returned or error was returned, if nil then give error + if param_data.optional == true and param_parsed == nil then + -- if it is optional and param is nil then it is set to default + param_parsed = param_data.default + if type(param_parsed) == 'function' then + -- player: LuaPlayer + success,param_parsed = pcall(param_parsed,player) + if Commands.internal_error(success,command_data.name,param_parsed) then return end + end + elseif param_parsed == nil or param_parsed == Commands.defines.error or param_parsed == parse_fail then + -- no value was returned or error was returned, if nil then give generic error if not param_parsed == Commands.defines.error then Commands.error('Invalid Param "'..param_name..'"; please make sure it is the correct type') end return end diff --git a/modules/test.lua b/modules/test.lua index 0834d962..f9607b7a 100644 --- a/modules/test.lua +++ b/modules/test.lua @@ -12,80 +12,47 @@ end) local Commands = require 'expcore.commands' -- require the Commands module --- adds an admin only authenticator where if a command has the tag admin_only: true --- then will only allow admins to use this command Commands.add_authenticator(function(player,command,tags,reject) - if tags.admin_only then -- the command has the tag admin_only set to true - if player.admin then -- the player is an admin - return true -- no return is needed for success but is useful to include - else -- the player is not admin - -- you must return to block a command, they are a few ways to do this: - -- return false -- most basic and has no custom error message - -- return reject -- sill no error message and is here in case people dont know its a function - -- reject() -- rejects the player, return not needed but please return if possible - -- return reject() -- rejects the player and has a failsafe return to block command - -- reject('This command is for admins only!') -- reject but with custom error message, return not needed but please return if possible - return reject('This command is for admins only!') -- reject but with custom error message and has return failsafe + if tags.admin_only then + if player.admin then + return true + else + return reject('This command is for admins only!') end - else -- command does not require admin - return true -- no return is needed for success but is useful to include + else + return true end end) --- adds a parse that will cover numbers within the given range --- input, player and reject are common to all parse functions --- range_min and range_max are passed to the function from add_param Commands.add_parse('number_range_int',function(input,player,reject,range_min,range_max) - local rtn = tonumber(input) or nil -- converts input to number - rtn = type(rtn) == 'number' and math.floor(rtn) or nil -- floor the number - if not rtn or rtn < range_min or rtn > range_max then -- check if it is nil or out of the range - -- invalid input for we will reject the input, they are a few ways to do this: - -- dont return anything -- will print generic input error - -- return false -- this WILL NOT reject the input as false can be a valid output - -- return reject -- will print generic input error - -- return reject() -- will print generic input error with no please check type message - -- reject() -- if you do not return the value then they will be a duplicate message - return reject('Number entered is not in range: '..range_min..', '..range_max) -- reject with custom error + local rtn = tonumber(input) and math.floor(tonumber(input)) or nil + if not rtn or rtn < range_min or rtn > range_max then + return reject('Number entered is not in range: '..range_min..', '..range_max) else - return rtn -- returns the number value this will be passed to the command callback + return rtn end end) --- adds a command that will print the players name a given number of times --- and can only be used by admin to show how auth works -Commands.add_command('repeat-name','Will repeat you name a number of times in chat.') -- creates the new command with the name "repeat-name" and a help message -:add_param('repeat-count',false,'number_range_int',1,5) -- adds a new param called "repeat-count" that is required and is type "number_range_int" the name can be used here as add_parse was used -:add_param('smiley',true,function(input,player,reject) -- this param is optional and has a custom parse function where add_parse was not used before hand - if not input then return false end -- here you can see the default check +Commands.add_command('repeat-name','Will repeat you name a number of times in chat.') + :add_param('repeat-count',false,'number_range_int',1,5) + :add_param('smiley',true,function(input,player,reject) + if not input then return end if input:lower() == 'true' or input:lower() == 'yes' then - return true -- the value is truthy so true is returned + return true else - -- it should be noted that this function will be ran even when the param is not present - -- in this case input is nil and so a default can be returned, see above - return false -- false is returned other wise + return false end end) -:add_tag('admin_only',true) -- adds the tag admin_only: true which because of the above authenticator means you must be added to use this command -:add_alias('name','rname') -- adds two aliases "name" and "rname" for this command which will work as if the ordinal name was used ---:auto_concat() -- cant be used due to optional param here, but this will make all user input params after the last expected one be added to the last expected one -:register(function(player,repeat_count,smiley,raw) -- this registers the command to the game, notice the params are what were defined above - -- prints the raw input to show that it can be used +:add_defaults{smiley=false} +:add_tag('admin_only',true) +:add_alias('name','rname') +:register(function(player,repeat_count,smiley,raw) game.print(player.name..' used a command with input: '..raw) - -- some smiley logic - local msg + local msg = ') '..player.name if smiley then - msg = ':) '..player.name - else - msg = ') '..player.name + msg = ':'..msg end - -- prints your name alot for i = 1,repeat_count do - Commands.print(i..msg) -- this command is an alias for ("expcore.common").player_return it will print any value to the player/server not just strings - end - -- if you wanted to you can return some values here - -- no return -- only success message is printed - -- Commands.error('optional message here') -- prints an error message - -- return Commands.error('optional message here') -- prints an error message, and stops success message being printed - -- Commands.success('optional message here') -- same as below but success message is printed twice DONT DO this - -- return Commands.success('optional message here') -- prints your message and then the success message + Commands.print(i..msg) +end end) \ No newline at end of file