Improvements for ExpCommands

This commit is contained in:
Cooldude2606
2024-11-08 12:59:12 +00:00
parent c61c931b58
commit c9bf85835f
9 changed files with 142 additions and 137 deletions

View File

@@ -9,13 +9,14 @@ The default permission authorities controlled by the flags: admin_only, system_o
]]
local Storage = require("modules/exp_util/storage")
local Commands = require("modules/exp_commands")
local Commands = require("modules/exp_commands") --- @class Commands
local add, allow, deny = Commands.add_permission_authority, Commands.status.success, Commands.status.unauthorised
local authorities = {}
local system_players = {}
local disabled_commands = {}
local system_players = {} --- @type table<string, boolean>
local disabled_commands = {} --- @type table<string, boolean>
Storage.register({
system_players,
disabled_commands,
@@ -100,7 +101,7 @@ authorities.system_only =
--- If Commands.disable was called then no one can use the command
authorities.disabled =
add(function(_player, command)
add(function(player, command)
if disabled_commands[command.name] then
return deny{ "exp-commands-authorities.disabled" }
else

View File

@@ -1,6 +1,5 @@
--[[-- Command Module - Help
--[[-- Commands - Help
Game command to list and search all registered commands in a nice format
@commands _system-ipc
--- Get all messages related to banning a player
/commands ban
@@ -13,13 +12,16 @@ local Commands = require("modules/exp_commands")
local PAGE_SIZE = 5
local search_cache = {}
--- @alias ResultsPage LocalisedString[]
--- @class HelpCacheEntry: { keyword: string, pages: ResultsPage[], found: number }
local search_cache = {} --- @type table<number, HelpCacheEntry>
Storage.register(search_cache, function(tbl)
search_cache = tbl
end)
--- Format commands into a strings across multiple pages
--- @param commands { [string]: Commands.Command } The commands to split into pages
--- @param commands table<string, Commands.Command> The commands to split into pages
--- @param page_size number The number of requests to show per page
--- @return LocalisedString[][], number
local function format_as_pages(commands, page_size)

View File

@@ -1,6 +1,5 @@
--[[-- Command Module - IPC
--[[-- Commands - IPC
System command which sends an object to the clustorio api, should be used for debugging / echo commands
@commands _system-ipc
--- Send a message on your custom channel, message is a json string
/_ipc myChannel { "myProperty": "foo", "playerName": "Cooldude2606" }

View File

@@ -1,6 +1,5 @@
--[[-- Command Module - Rcon
--[[-- Commands - Rcon
System command which runs arbitrary code within a custom (not sandboxed) environment
@commands _system-rcon
--- Get the names of all online players, using rcon
/_system-rcon local names = {}; for index, player in pairs(game.connected_player) do names[index] = player.name end; return names;
@@ -12,53 +11,60 @@ System command which runs arbitrary code within a custom (not sandboxed) environ
local ExpUtil = require("modules/exp_util")
local Async = require("modules/exp_util/async")
local Storage = require("modules/exp_util/storage")
local Commands = require("modules/exp_commands")
local Clustorio = require("modules/clusterio/api")
local rcon_env = {}
local rcon_statics = {}
local rcon_callbacks = {}
setmetatable(rcon_statics, { __index = _G })
setmetatable(rcon_env, { __index = rcon_statics })
local Commands = require("modules/exp_commands") --- @class Commands
local rcon_env = {} --- @type table<string, any>
local rcon_static = {} --- @type table<string, any>
local rcon_dynamic = {} --- @type table<string, ExpCommand.RconDynamic>
setmetatable(rcon_static, { __index = _G })
setmetatable(rcon_env, { __index = rcon_static })
--- Some common static values which can be added now
--- @diagnostic disable: name-style-check
rcon_statics.Async = Async
rcon_statics.ExpUtil = ExpUtil
rcon_statics.Commands = Commands
rcon_statics.Clustorio = Clustorio
rcon_statics.print = Commands.print
rcon_statics.ipc = Clustorio.send_json
rcon_static.Async = Async
rcon_static.ExpUtil = ExpUtil
rcon_static.Commands = Commands
rcon_static.Clustorio = Clustorio
rcon_static.print = Commands.print
rcon_static.ipc = Clustorio.send_json
--- @diagnostic enable: name-style-check
--- Some common callback values which are useful when a player uses the command
function rcon_callbacks.player(player) return player end
--- @alias ExpCommand.RconDynamic fun(player: LuaPlayer?): any
function rcon_callbacks.surface(player) return player and player.surface end
function rcon_dynamic.player(player) return player end
function rcon_callbacks.force(player) return player and player.force end
function rcon_dynamic.surface(player) return player and player.surface end
function rcon_callbacks.position(player) return player and player.position end
function rcon_dynamic.force(player) return player and player.force end
function rcon_callbacks.entity(player) return player and player.selected end
function rcon_dynamic.position(player) return player and player.position end
function rcon_callbacks.tile(player) return player and player.surface.get_tile(player.position) end
function rcon_dynamic.entity(player) return player and player.selected end
function rcon_dynamic.tile(player) return player and player.surface.get_tile(player.position.x, player.position.y) end
--- The rcon env is saved between command runs to prevent desyncs
Storage.register(rcon_env, function(tbl)
rcon_env = setmetatable(tbl, { __index = rcon_statics })
rcon_env = setmetatable(tbl, { __index = rcon_static })
end)
--- Static values can be added to the rcon env which are not stored in global such as modules
--- @param name string Name of the value as it will appear in the rcon environment
--- @param value any Value it is have
function Commands.add_rcon_static(name, value)
ExpUtil.assert_not_runtime()
rcon_statics[name] = value
rcon_static[name] = value
end
--- Callback values can be added to the rcon env, these are called on each invocation and should return one value
function Commands.add_rcon_callback(name, callback)
--- @param name string Name of the value as it will appear in the rcon environment
--- @param callback ExpCommand.RconDynamic Callback called to get the current value
function Commands.add_rcon_dynamic(name, callback)
ExpUtil.assert_not_runtime()
rcon_callbacks[name] = callback
rcon_dynamic[name] = callback
end
Commands.new("_rcon", { "exp-commands_rcon.description" })
@@ -70,7 +76,7 @@ Commands.new("_rcon", { "exp-commands_rcon.description" })
-- 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
for name, callback in pairs(rcon_dynamic) do
local _, rtn = pcall(callback, player.index > 0 and player or nil)
rawset(env, name, rtn)
end

View File

@@ -1,6 +1,5 @@
--[[-- Command Module - Sudo
--[[-- Commands - Sudo
System command to execute a command as another player using their permissions (except for permissions group actions)
@commands _system-sudo
--- Run the example command as another player
-- As Cooldude2606: /repeat 5

View File

@@ -25,10 +25,9 @@ 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 = {}
local types = {} --- @class Commands._types
--- A boolean value where true is one of: yes, y, true, 1
--- @type Commands.InputParser
types.boolean =
add("boolean", function(input)
input = input:lower()
@@ -43,14 +42,12 @@ types.boolean =
end)
--- A string, validation does nothing but it is a requirement
--- @type Commands.InputParser
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
--- @type Commands.InputParserFactory
types.enum =
add("enum", function(options)
--- @cast options string[]
@@ -65,10 +62,9 @@ types.enum =
end)
--- A string which is the key of a table, takes one argument which is an map of string keys to values
--- @type Commands.InputParserFactory
types.key_of =
add("key_of", function(map)
--- @cast map { [string]: any }
--- @cast map table<string, any>
return function(input)
local option = auto_complete(map, input, true)
if option == nil then
@@ -80,7 +76,6 @@ types.key_of =
end)
--- A string with a maximum length, takes one argument which is the maximum length of a string
--- @type Commands.InputParserFactory
types.string_max_length =
add("string_max_length", function(maximum)
--- @cast maximum number
@@ -94,7 +89,6 @@ types.string_max_length =
end)
--- A number
--- @type Commands.InputParser
types.number =
add("number", function(input)
local number = tonumber(input)
@@ -106,7 +100,6 @@ types.number =
end)
--- An integer, number which has been floored
--- @type Commands.InputParser
types.integer =
add("integer", function(input)
local number = tonumber(input)
@@ -118,7 +111,6 @@ types.integer =
end)
--- A number in a given inclusive range
--- @type Commands.InputParserFactory
types.number_range =
add("number_range", function(minimum, maximum)
--- @cast minimum number
@@ -137,7 +129,6 @@ types.number_range =
end)
--- An integer in a given inclusive range
--- @type Commands.InputParserFactory
types.integer_range =
add("integer_range", function(minimum, maximum)
--- @cast minimum number
@@ -156,7 +147,6 @@ types.integer_range =
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)
@@ -168,7 +158,6 @@ types.player =
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)
@@ -183,8 +172,7 @@ types.player_online =
end)
--- A player who is online and alive
--- @type Commands.InputParser
types.player_online =
types.player_alive =
add("player_alive", function(input, player)
local success, status, result = parse(input, player, Commands.types.player_online)
--- @cast result LuaPlayer
@@ -198,7 +186,6 @@ types.player_online =
end)
--- A force within the game
--- @type Commands.InputParser
types.force =
add("force", function(input)
local force = game.forces[input]
@@ -210,7 +197,6 @@ types.force =
end)
--- A surface within the game
--- @type Commands.InputParser
types.surface =
add("surface", function(input)
local surface = game.surfaces[input]
@@ -222,7 +208,6 @@ types.surface =
end)
--- A planet within the game
--- @type Commands.InputParser
types.planet =
add("planet", function(input)
local surface = game.planets[input]
@@ -234,7 +219,6 @@ types.planet =
end)
--- A name of a color from the predefined list, too many colours to use string-key
--- @type Commands.InputParser
types.color =
add("color", function(input)
local color = auto_complete(Commands.color, input, true)