1 -- Minetest: builtin/common/chatcommands.lua
3 -- For server-side translations (if INIT == "game")
4 -- Otherwise, use core.gettext
5 local S = core.get_translator("__builtin")
7 core.registered_chatcommands = {}
9 -- Interpret the parameters of a command, separating options and arguments.
10 -- Input: command, param
11 -- command: name of command
12 -- param: parameters of command
13 -- Returns: opts, args
14 -- opts is a string of option letters, or false on error
15 -- args is an array with the non-option arguments in order, or an error message
16 -- Example: for this command line:
17 -- /command a b -cd e f -g
18 -- the function would receive:
20 -- and it would return:
21 -- "cdg", {"a", "b", "e", "f"}
22 -- Negative numbers are taken as arguments. Long options (--option) are
23 -- currently rejected as reserved.
24 local function getopts(command, param)
27 for match in param:gmatch("%S+") do
28 if match:byte(1) == 45 then -- 45 = '-'
29 local second = match:byte(2)
31 return false, S("Invalid parameters (see /help @1).", command)
32 elseif second and (second < 48 or second > 57) then -- 48 = '0', 57 = '9'
33 opts = opts .. match:sub(2)
35 -- numeric, add it to args
36 args[#args + 1] = match
39 args[#args + 1] = match
45 function core.register_chatcommand(cmd, def)
47 def.params = def.params or ""
48 def.description = def.description or ""
49 def.privs = def.privs or {}
50 def.mod_origin = core.get_current_modname() or "??"
51 core.registered_chatcommands[cmd] = def
54 function core.unregister_chatcommand(name)
55 if core.registered_chatcommands[name] then
56 core.registered_chatcommands[name] = nil
58 core.log("warning", "Not unregistering chatcommand " ..name..
59 " because it doesn't exist.")
63 function core.override_chatcommand(name, redefinition)
64 local chatcommand = core.registered_chatcommands[name]
65 assert(chatcommand, "Attempt to override non-existent chatcommand "..name)
66 for k, v in pairs(redefinition) do
67 rawset(chatcommand, k, v)
69 core.registered_chatcommands[name] = chatcommand
72 if INIT == "client" then
73 function core.register_list_command(command, desc, setting)
75 def.description = desc
76 def.params = "del <item> | add <item> | list"
77 function def.func(param)
78 local list = (minetest.settings:get(setting) or ""):split(",")
79 if param == "list" then
80 return true, table.concat(list, ", ")
82 local sparam = param:split(" ")
84 local item = sparam[2]
87 return false, "Missing item."
89 local i = table.indexof(list, item)
91 return false, item .. " is not on the list."
94 core.settings:set(setting, table.concat(list, ","))
95 return true, "Removed " .. item .. " from the list."
97 elseif cmd == "add" then
99 return false, "Missing item."
101 local i = table.indexof(list, item)
103 return false, item .. " is already on the list."
105 table.insert(list, item)
106 core.settings:set(setting, table.concat(list, ","))
107 return true, "Added " .. item .. " to the list."
111 return false, "Invalid usage. (See .help " .. command .. ")"
113 core.register_chatcommand(command, def)
117 local function format_help_line(cmd, def)
118 local cmd_marker = INIT == "client" and "." or "/"
119 local msg = core.colorize("#00ffff", cmd_marker .. cmd)
120 if def.params and def.params ~= "" then
121 msg = msg .. " " .. def.params
123 if def.description and def.description ~= "" then
124 msg = msg .. ": " .. def.description
129 local function do_help_cmd(name, param)
130 local opts, args = getopts("help", param)
135 return false, S("Too many arguments, try using just /help <command>")
137 local use_gui = INIT ~= "client" and core.get_player_by_name(name)
138 use_gui = use_gui and not opts:find("t")
140 if #args == 0 and not use_gui then
142 for cmd, def in pairs(core.registered_chatcommands) do
143 if INIT == "client" or core.check_player_privs(name, def.privs) then
144 cmds[#cmds + 1] = cmd
149 if INIT == "game" then
150 msg = S("Available commands: @1",
151 table.concat(cmds, " ")) .. "\n"
152 .. S("Use '/help <cmd>' to get more "
153 .. "information, or '/help all' to list "
156 msg = core.gettext("Available commands: ")
157 .. table.concat(cmds, " ") .. "\n"
158 .. core.gettext("Use '.help <cmd>' to get more "
159 .. "information, or '.help all' to list "
163 elseif #args == 0 or (args[1] == "all" and use_gui) then
164 core.show_general_help_formspec(name)
166 elseif args[1] == "all" then
168 for cmd, def in pairs(core.registered_chatcommands) do
169 if INIT == "client" or core.check_player_privs(name, def.privs) then
170 cmds[#cmds + 1] = format_help_line(cmd, def)
175 if INIT == "game" then
176 msg = S("Available commands:")
178 msg = core.gettext("Available commands:")
180 return true, msg.."\n"..table.concat(cmds, "\n")
181 elseif INIT == "game" and args[1] == "privs" then
183 core.show_privs_help_formspec(name)
187 for priv, def in pairs(core.registered_privileges) do
188 privs[#privs + 1] = priv .. ": " .. def.description
191 return true, S("Available privileges:").."\n"..table.concat(privs, "\n")
194 local def = core.registered_chatcommands[cmd]
197 if INIT == "game" then
198 msg = S("Command not available: @1", cmd)
200 msg = core.gettext("Command not available: ") .. cmd
204 return true, format_help_line(cmd, def)
209 if INIT == "client" then
210 core.register_chatcommand("help", {
211 params = core.gettext("[all | <cmd>]"),
212 description = core.gettext("Get help for commands"),
213 func = function(param)
214 return do_help_cmd(nil, param)
218 core.register_chatcommand("help", {
219 params = S("[all | privs | <cmd>] [-t]"),
220 description = S("Get help for commands or list privileges (-t: output in chat)"),