]> git.lizzy.rs Git - dragonfireclient.git/blob - builtin/common/chatcommands.lua
DevTest: Fix broken PNG textures
[dragonfireclient.git] / builtin / common / chatcommands.lua
1 -- Minetest: builtin/common/chatcommands.lua
2
3 -- For server-side translations (if INIT == "game")
4 -- Otherwise, use core.gettext
5 local S = core.get_translator("__builtin")
6
7 core.registered_chatcommands = {}
8
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:
19 --      a b -cd e f -g
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)
25         local opts = ""
26         local args = {}
27         for match in param:gmatch("%S+") do
28                 if match:byte(1) == 45 then -- 45 = '-'
29                         local second = match:byte(2)
30                         if second == 45 then
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)
34                         else
35                                 -- numeric, add it to args
36                                 args[#args + 1] = match
37                         end
38                 else
39                         args[#args + 1] = match
40                 end
41         end
42         return opts, args
43 end
44
45 function core.register_chatcommand(cmd, def)
46         def = def or {}
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
52 end
53
54 function core.unregister_chatcommand(name)
55         if core.registered_chatcommands[name] then
56                 core.registered_chatcommands[name] = nil
57         else
58                 core.log("warning", "Not unregistering chatcommand " ..name..
59                         " because it doesn't exist.")
60         end
61 end
62
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)
68         end
69         core.registered_chatcommands[name] = chatcommand
70 end
71
72 local function format_help_line(cmd, def)
73         local cmd_marker = INIT == "client" and "." or "/"
74         local msg = core.colorize("#00ffff", cmd_marker .. cmd)
75         if def.params and def.params ~= "" then
76                 msg = msg .. " " .. def.params
77         end
78         if def.description and def.description ~= "" then
79                 msg = msg .. ": " .. def.description
80         end
81         return msg
82 end
83
84 local function do_help_cmd(name, param)
85         local opts, args = getopts("help", param)
86         if not opts then
87                 return false, args
88         end
89         if #args > 1 then
90                 return false, S("Too many arguments, try using just /help <command>")
91         end
92         local use_gui = INIT ~= "client" and core.get_player_by_name(name)
93         use_gui = use_gui and not opts:find("t")
94
95         if #args == 0 and not use_gui then
96                 local cmds = {}
97                 for cmd, def in pairs(core.registered_chatcommands) do
98                         if INIT == "client" or core.check_player_privs(name, def.privs) then
99                                 cmds[#cmds + 1] = cmd
100                         end
101                 end
102                 table.sort(cmds)
103                 local msg
104                 if INIT == "game" then
105                         msg = S("Available commands: @1",
106                                 table.concat(cmds, " ")) .. "\n"
107                                 .. S("Use '/help <cmd>' to get more "
108                                 .. "information, or '/help all' to list "
109                                 .. "everything.")
110                 else
111                         msg = core.gettext("Available commands: ")
112                                 .. table.concat(cmds, " ") .. "\n"
113                                 .. core.gettext("Use '.help <cmd>' to get more "
114                                 .. "information, or '.help all' to list "
115                                 .. "everything.")
116                 end
117                 return true, msg
118         elseif #args == 0 or (args[1] == "all" and use_gui) then
119                 core.show_general_help_formspec(name)
120                 return true
121         elseif args[1] == "all" then
122                 local cmds = {}
123                 for cmd, def in pairs(core.registered_chatcommands) do
124                         if INIT == "client" or core.check_player_privs(name, def.privs) then
125                                 cmds[#cmds + 1] = format_help_line(cmd, def)
126                         end
127                 end
128                 table.sort(cmds)
129                 local msg
130                 if INIT == "game" then
131                         msg = S("Available commands:")
132                 else
133                         msg = core.gettext("Available commands:")
134                 end
135                 return true, msg.."\n"..table.concat(cmds, "\n")
136         elseif INIT == "game" and args[1] == "privs" then
137                 if use_gui then
138                         core.show_privs_help_formspec(name)
139                         return true
140                 end
141                 local privs = {}
142                 for priv, def in pairs(core.registered_privileges) do
143                         privs[#privs + 1] = priv .. ": " .. def.description
144                 end
145                 table.sort(privs)
146                 return true, S("Available privileges:").."\n"..table.concat(privs, "\n")
147         else
148                 local cmd = args[1]
149                 local def = core.registered_chatcommands[cmd]
150                 if not def then
151                         local msg
152                         if INIT == "game" then
153                                 msg = S("Command not available: @1", cmd)
154                         else
155                                 msg = core.gettext("Command not available: ") .. cmd
156                         end
157                         return false, msg
158                 else
159                         return true, format_help_line(cmd, def)
160                 end
161         end
162 end
163
164 if INIT == "client" then
165         core.register_chatcommand("help", {
166                 params = core.gettext("[all | <cmd>]"),
167                 description = core.gettext("Get help for commands"),
168                 func = function(param)
169                         return do_help_cmd(nil, param)
170                 end,
171         })
172 else
173         core.register_chatcommand("help", {
174                 params = S("[all | privs | <cmd>] [-t]"),
175                 description = S("Get help for commands or list privileges (-t: output in chat)"),
176                 func = do_help_cmd,
177         })
178 end