Setup exp_scenario for commands

This commit is contained in:
Cooldude2606
2024-10-20 02:42:14 +01:00
parent 34a7879761
commit e78234898e
31 changed files with 2412 additions and 199 deletions

View File

@@ -62,7 +62,7 @@ end
authorities.character_only =
add(function(player, command)
if command.flags.character_only and player.controller_type ~= defines.controllers.character then
return deny{ "exp-commands-permissions.character-only" }
return deny{ "exp-commands-authorities.character-only" }
else
return allow()
end
@@ -72,7 +72,7 @@ authorities.character_only =
authorities.remote_only =
add(function(player, command)
if command.flags.character_only and player.controller_type ~= defines.controllers.remote then
return deny{ "exp-commands-permissions.remote-only" }
return deny{ "exp-commands-authorities.remote-only" }
else
return allow()
end
@@ -82,7 +82,7 @@ authorities.remote_only =
authorities.admin_only =
add(function(player, command)
if command.flags.admin_only and not player.admin then
return deny{ "exp-commands-permissions.admin-only" }
return deny{ "exp-commands-authorities.admin-only" }
else
return allow()
end
@@ -92,7 +92,7 @@ authorities.admin_only =
authorities.system_only =
add(function(player, command)
if command.flags.system_only and not system_players[player.name] then
return deny{ "exp-commands-permissions.system-only" }
return deny{ "exp-commands-authorities.system-only" }
else
return allow()
end
@@ -102,7 +102,7 @@ authorities.system_only =
authorities.disabled =
add(function(_player, command)
if disabled_commands[command.name] then
return deny{ "exp-commands-permissions.disabled" }
return deny{ "exp-commands-authorities.disabled" }
else
return allow()
end

View File

@@ -45,19 +45,22 @@ local function format_as_pages(commands, page_size)
description = command.description
end
local aliases = #command.aliases > 0 and { "exp-commands-help.aliases", table.concat(command.aliases, ", ") } or ""
pages[current_page][page_length] = { "exp-commands-help.format", command.name, description, aliases }
local aliases = #command.aliases > 0 and { "exp-commands_help.aliases", table.concat(command.aliases, ", ") } or ""
pages[current_page][page_length] = { "exp-commands_help.format", command.name, description, aliases }
end
return pages, total
end
Commands.new("commands", { "exp-commands-help.description" })
:add_aliases{ "chelp", "helpp" }
:optional("keyword", { "exp-commands-help.arg-keyword" }, Commands.types.string)
:optional("page", { "exp-commands-help.arg-page" }, Commands.types.integer)
Commands.new("commands", { "exp-commands_help.description" })
:optional("keyword", { "exp-commands_help.arg-keyword" }, Commands.types.string)
:optional("page", { "exp-commands_help.arg-page" }, Commands.types.integer)
:defaults{ keyword = "", page = 1 }
:add_aliases{ "chelp", "helpp" }
:register(function(player, keyword, page)
--- @cast keyword string | number
--- @cast page number
-- Allow listing of all commands
local as_number = tonumber(keyword)
local cache = search_cache[player.index]
@@ -81,20 +84,20 @@ Commands.new("commands", { "exp-commands-help.description" })
-- Error if no pages found
if found == 0 then
return Commands.status.success{ "exp-commands-help.no-results" }
return Commands.status.success{ "exp-commands_help.no-results" }
end
local page_data = pages[page]
if page_data == nil then
-- Page number was out of range for this search
return Commands.status.invalid_input{ "exp-commands-help.out-of-range", page, #pages }
return Commands.status.invalid_input{ "exp-commands_help.out-of-range", page, #pages }
end
-- Print selected page to the player
Commands.print{ "exp-commands-help.header", keyword == "" and "<all>" or keyword }
Commands.print{ "exp-commands_help.header", keyword == "" and "<all>" or keyword }
for _, command in pairs(page_data) do
Commands.print(command)
end
return Commands.status.success{ "exp-commands-help.footer", found, page, #pages }
return Commands.status.success{ "exp-commands_help.footer", found, page, #pages }
end)

View File

@@ -11,12 +11,15 @@ local Clustorio = require("modules/clusterio/api")
local json_to_table = helpers.json_to_table
Commands.new("_ipc", { "exp-commands-ipc.description" })
:add_flags{ "system_only" }
Commands.new("_ipc", { "exp-commands_ipc.description" })
:argument("channel", { "exp-commands_ipc.arg-channel" }, Commands.types.string)
:argument("message", { "exp-commands_ipc.arg-message" }, Commands.types.string)
:enable_auto_concatenation()
:argument("channel", { "exp-commands-ipc.arg-channel" }, Commands.types.string)
:argument("message", { "exp-commands-ipc.arg-message" }, Commands.types.string)
:add_flags{ "system_only" }
:register(function(_player, channel, message)
--- @cast channel string
--- @cast message string
local tbl = json_to_table(message)
if tbl == nil then
return Commands.status.invalid_input("Invalid json string")

View File

@@ -61,11 +61,13 @@ function Commands.add_rcon_callback(name, callback)
rcon_callbacks[name] = callback
end
Commands.new("_rcon", { "exp-commands-rcon.description" })
:add_flags{ "system_only" }
Commands.new("_rcon", { "exp-commands_rcon.description" })
:argument("invocation", { "exp-commands_rcon.arg-invocation" }, Commands.types.string)
:enable_auto_concatenation()
:argument("invocation", { "exp-commands-rcon.arg-invocation" }, Commands.types.string)
:add_flags{ "system_only" }
:register(function(player, invocation_string)
--- @cast invocation_string string
-- Construct the environment the command will run within
local env = setmetatable({}, { __index = rcon_env, __newindex = rcon_env })
for name, callback in pairs(rcon_callbacks) do

View File

@@ -9,13 +9,17 @@ System command to execute a command as another player using their permissions (e
local Commands = require("modules/exp_commands")
Commands.new("_sudo", { "exp-commands-sudo.description" })
:add_flags{ "system_only" }
Commands.new("_sudo", { "exp-commands_sudo.description" })
:argument("player", { "exp-commands_sudo.arg-player" }, Commands.types.player)
:argument("command", { "exp-commands_sudo.arg-command" }, Commands.types.key_of(Commands.registered_commands))
:argument("arguments", { "exp-commands_sudo.arg-arguments" }, Commands.types.string)
:enable_auto_concatenation()
:argument("player", { "exp-commands-sudo.arg-player" }, Commands.types.player)
:argument("command", { "exp-commands-sudo.arg-command" }, Commands.types.string_key(Commands.registered_commands))
:argument("arguments", { "exp-commands-sudo.arg-arguments" }, Commands.types.string)
:add_flags{ "system_only" }
:register(function(_player, player, command, parameter)
--- @cast player LuaPlayer
--- @cast command Commands.ExpCommand
--- @cast parameter string
--- @diagnostic disable-next-line: invisible
return Commands._event_handler{
name = command.name,

View File

@@ -4,7 +4,7 @@ The default data types that are available to all commands
Adds parsers for:
boolean
string_options - options: array of strings
string_key - map: table of string keys and any values
key_of - map: table of string keys and any values
string_max_length - maximum: number
number
integer
@@ -19,188 +19,230 @@ Adds parsers for:
]]
local ExpUtil = require("modules/exp_util")
local auto_complete = ExpUtil.auto_complete
local Commands = require("modules/exp_commands")
local add, parse = Commands.add_data_type, Commands.parse_input
local valid, invalid = Commands.status.success, Commands.status.invalid_input
local types = {}
--- A boolean value where true is one of: yes, y, true, 1
add("boolean", function(input)
input = input:lower()
if input == "yes"
or input == "y"
or input == "true"
or input == "1" then
return valid(true)
else
return valid(false)
end
end)
--- @type Commands.InputParser
types.boolean =
add("boolean", function(input)
input = input:lower()
if input == "yes"
or input == "y"
or input == "true"
or input == "1" then
return valid(true)
else
return valid(false)
end
end)
--- A string, validation does nothing but it is a requirement
--- @type Commands.InputParser
add("string", function(input)
return valid(input)
end)
types.string =
add("string", function(input)
return valid(input)
end)
--- A string from a set of options, takes one argument which is an array of options
--- @param options string[] The options which can be selected
--- @return Commands.InputParser
add("string_array", function(options)
return function(input)
local option = ExpUtil.auto_complete(options, input)
if option == nil then
return invalid{ "exp-commands-parse.string-options", table.concat(options, ", ") }
else
return valid(option)
--- @type Commands.InputParserFactory
types.enum =
add("enum", function(options)
--- @cast options string[]
return function(input)
local option = auto_complete(options, input)
if option == nil then
return invalid{ "exp-commands-parse.string-options", table.concat(options, ", ") }
else
return valid(option)
end
end
end
end)
end)
--- A string which is the key of a table, takes one argument which is an map of string keys to values
--- @param map { [string]: any } The options which can be selected
--- @return Commands.InputParser
add("string_key", function(map)
return function(input)
local option = ExpUtil.auto_complete(map, input, true)
if option == nil then
return invalid{ "exp-commands-parse.string-options", table.concat(table.get_keys(map), ", ") }
else
return valid(option)
--- @type Commands.InputParserFactory
types.key_of =
add("key_of", function(map)
--- @cast map { [string]: any }
return function(input)
local option = auto_complete(map, input, true)
if option == nil then
return invalid{ "exp-commands-parse.string-options", table.concat(table.get_keys(map), ", ") }
else
return valid(option)
end
end
end
end)
end)
--- A string with a maximum length, takes one argument which is the maximum length of a string
--- @param maximum number The maximum length of the input
--- @return Commands.InputParser
add("string_max_length", function(maximum)
return function(input)
if input:len() > maximum then
return invalid{ "exp-commands-parse.string-max-length", maximum }
else
return valid(input)
--- @type Commands.InputParserFactory
types.string_max_length =
add("string_max_length", function(maximum)
--- @cast maximum number
return function(input)
if input:len() > maximum then
return invalid{ "exp-commands-parse.string-max-length", maximum }
else
return valid(input)
end
end
end
end)
end)
--- A number
add("number", function(input)
local number = tonumber(input)
if number == nil then
return invalid{ "exp-commands-parse.number" }
else
return valid(number)
end
end)
--- @type Commands.InputParser
types.number =
add("number", function(input)
local number = tonumber(input)
if number == nil then
return invalid{ "exp-commands-parse.number" }
else
return valid(number)
end
end)
--- An integer, number which has been floored
add("integer", function(input)
local number = tonumber(input)
if number == nil then
return invalid{ "exp-commands-parse.number" }
else
return valid(math.floor(number))
end
end)
--- @type Commands.InputParser
types.integer =
add("integer", function(input)
local number = tonumber(input)
if number == nil then
return invalid{ "exp-commands-parse.number" }
else
return valid(math.floor(number))
end
end)
--- A number in a given inclusive range
--- @param minimum number The minimum of the allowed range, inclusive
--- @param maximum number The maximum of the allowed range, inclusive
--- @return Commands.InputParser
add("number_range", function(minimum, maximum)
local parser_number = Commands.types.number
return function(input, player)
local success, status, result = parse(input, player, parser_number)
if not success then
return status, result
elseif result < minimum or result > maximum then
return invalid{ "exp-commands-parse.number-range", minimum, maximum }
else
return valid(result)
--- @type Commands.InputParserFactory
types.number_range =
add("number_range", function(minimum, maximum)
--- @cast minimum number
--- @cast maximum number
local parser_number = Commands.types.number
return function(input, player)
local success, status, result = parse(input, player, parser_number)
if not success then
return status, result
elseif result < minimum or result > maximum then
return invalid{ "exp-commands-parse.number-range", minimum, maximum }
else
return valid(result)
end
end
end
end)
end)
--- An integer in a given inclusive range
--- @param minimum number The minimum of the allowed range, inclusive
--- @param maximum number The maximum of the allowed range, inclusive
--- @return Commands.InputParser
add("integer_range", function(minimum, maximum)
local parser_integer = Commands.types.integer
return function(input, player)
local success, status, result = parse(input, player, parser_integer)
--- @type Commands.InputParserFactory
types.integer_range =
add("integer_range", function(minimum, maximum)
--- @cast minimum number
--- @cast maximum number
local parser_integer = Commands.types.integer
return function(input, player)
local success, status, result = parse(input, player, parser_integer)
if not success then
return status, result
elseif result < minimum or result > maximum then
return invalid{ "exp-commands-parse.number-range", minimum, maximum }
else
return valid(result)
end
end
end)
--- A player who has joined the game at least once
--- @type Commands.InputParser
types.player =
add("player", function(input)
local player = game.get_player(input)
if player == nil then
return invalid{ "exp-commands-parse.player", input }
else
return valid(player)
end
end)
--- A player who is online
--- @type Commands.InputParser
types.player_online =
add("player_online", function(input, player)
local success, status, result = parse(input, player, Commands.types.player)
--- @cast result LuaPlayer
if not success then
return status, result
elseif result < minimum or result > maximum then
return invalid{ "exp-commands-parse.number-range", minimum, maximum }
elseif result.connected == false then
return invalid{ "exp-commands-parse.player-online" }
else
return valid(result)
end
end
end)
--- A player who has joined the game at least once
add("player", function(input)
local player = game.get_player(input)
if player == nil then
return invalid{ "exp-commands-parse.player", input }
else
return valid(player)
end
end)
--- A player who is online
add("player_online", function(input, player)
local success, status, result = parse(input, player, Commands.types.player)
--- @cast result LuaPlayer
if not success then
return status, result
elseif result.connected == false then
return invalid{ "exp-commands-parse.player-online" }
else
return valid(result)
end
end)
end)
--- A player who is online and alive
add("player_alive", function(input, player)
local success, status, result = parse(input, player, Commands.types.player_online)
--- @cast result LuaPlayer
if not success then
return status, result
elseif result.character == nil or result.character.health <= 0 then
return invalid{ "exp-commands-parse.player-alive" }
else
return valid(result)
end
end)
--- @type Commands.InputParser
types.player_online =
add("player_alive", function(input, player)
local success, status, result = parse(input, player, Commands.types.player_online)
--- @cast result LuaPlayer
if not success then
return status, result
elseif result.character == nil or result.character.health <= 0 then
return invalid{ "exp-commands-parse.player-alive" }
else
return valid(result)
end
end)
--- A force within the game
add("force", function(input)
local force = game.forces[input]
if force == nil then
return invalid{ "exp-commands-parse.force" }
else
return valid(force)
end
end)
--- @type Commands.InputParser
types.force =
add("force", function(input)
local force = game.forces[input]
if force == nil then
return invalid{ "exp-commands-parse.force" }
else
return valid(force)
end
end)
--- A surface within the game
add("surface", function(input)
local surface = game.surfaces[input]
if surface == nil then
return invalid{ "exp-commands-parse.surface" }
else
return valid(surface)
end
end)
--- @type Commands.InputParser
types.surface =
add("surface", function(input)
local surface = game.surfaces[input]
if surface == nil then
return invalid{ "exp-commands-parse.surface" }
else
return valid(surface)
end
end)
--- A planet within the game
--- @type Commands.InputParser
types.planet =
add("planet", function(input)
local surface = game.planets[input]
if surface == nil then
return invalid{ "exp-commands-parse.planet" }
else
return valid(surface)
end
end)
--- A name of a color from the predefined list, too many colours to use string-key
add("color", function(input)
local color = ExpUtil.auto_complete(Commands.color, input, true)
if color == nil then
return invalid{ "exp-commands-parse.color" }
else
return valid(color)
end
end)
--- @type Commands.InputParser
types.color =
add("color", function(input)
local color = auto_complete(Commands.color, input, true)
if color == nil then
return invalid{ "exp-commands-parse.color" }
else
return valid(color)
end
end)
return types