1 /***********************************************************************
2  Freeciv - Copyright (C) 1996-2004 - The Freeciv Project
3    This program is free software; you can redistribute it and/or modify
4    it under the terms of the GNU General Public License as published by
5    the Free Software Foundation; either version 2, or (at your option)
6    any later version.
7 
8    This program is distributed in the hope that it will be useful,
9    but WITHOUT ANY WARRANTY; without even the implied warranty of
10    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11    GNU General Public License for more details.
12 ***********************************************************************/
13 
14 #ifdef HAVE_CONFIG_H
15 #include <fc_config.h>
16 #endif
17 
18 /* utility */
19 #include "fcintl.h"
20 
21 /* common */
22 #include "connection.h"
23 #include "mapimg.h"
24 
25 /* server */
26 #include "commands.h"
27 #include "voting.h"
28 
29 /* ai */
30 #include "difficulty.h"
31 
32 /* Set the synopsis text to don't be translated. */
33 #define SYN_ORIG_(String) "*" String
34 /* Test if the synopsis should be translated or not. */
35 #define SYN_TRANS_(String) ('*' == String[0] ? String + 1 : _(String))
36 
37 struct command {
38   const char *name;       /* name - will be matched by unique prefix   */
39   enum cmdlevel level;    /* access level required to use the command  */
40   const char *synopsis;   /* one or few-line summary of usage */
41   const char *short_help; /* one line (about 70 chars) description */
42   const char *extra_help; /* extra help information; will be line-wrapped */
43   char *(*extra_help_func)(const char *cmdname);
44                           /* dynamically generated help; if non-NULL,
45                            * extra_help is ignored. Must be pre-translated. */
46   enum cmd_echo echo;     /* Who will be notified when used. */
47   int vote_flags;         /* how to handle votes */
48   int vote_percent;       /* percent required, meaning depends on flags */
49 };
50 
51 /* Commands must match the values in enum command_id. */
52 static struct command commands[] = {
53   {"start",	ALLOW_BASIC,
54    /* no translatable parameters */
55    SYN_ORIG_("start"),
56    N_("Start the game, or restart after loading a savegame."),
57    N_("This command starts the game. When starting a new game, "
58       "it should be used after all human players have connected, and "
59       "AI players have been created (if required), and any desired "
60       "changes to initial server options have been made. "
61       "After 'start', each human player will be able to "
62       "choose their nation, and then the game will begin. "
63       "This command is also required after loading a savegame "
64       "for the game to recommence. Once the game is running this command "
65       "is no longer available, since it would have no effect."), NULL,
66    CMD_ECHO_NONE, VCF_NONE, 0
67   },
68 
69   {"help",	ALLOW_INFO,
70    /* TRANS: translate text between <> only */
71    N_("help\n"
72       "help commands\n"
73       "help options\n"
74       "help <command-name>\n"
75       "help <option-name>"),
76    N_("Show help about server commands and server options."),
77    N_("With no arguments gives some introductory help. "
78       "With argument \"commands\" or \"options\" gives respectively "
79       "a list of all commands or all options. "
80       "Otherwise the argument is taken as a command name or option name, "
81       "and help is given for that command or option. For options, the help "
82       "information includes the current and default values for that option. "
83       "The argument may be abbreviated where unambiguous."), NULL,
84    CMD_ECHO_NONE, VCF_NONE, 0
85   },
86 
87   {"list",	ALLOW_INFO,
88    /* no translatable parameters */
89    SYN_ORIG_("list\n"
90              "list colors\n"
91              "list connections\n"
92              "list delegations\n"
93              "list ignored users\n"
94              "list map image definitions\n"
95              "list players\n"
96              "list rulesets\n"
97              "list scenarios\n"
98              "list nationsets\n"
99              "list teams\n"
100              "list votes\n"),
101    N_("Show a list of various things."),
102    /* TRANS: don't translate text in '' */
103    N_("Show a list of:\n"
104       " - the player colors,\n"
105       " - connections to the server,\n"
106       " - all player delegations,\n"
107       " - your ignore list,\n"
108       " - the list of defined map images,\n"
109       " - the list of the players in the game,\n"
110       " - the available rulesets (for 'read' command),\n"
111       " - the available scenarios,\n"
112       " - the available nation sets in this ruleset,\n"
113       " - the teams of players or\n"
114       " - the running votes.\n"
115       "The argument may be abbreviated, and defaults to 'players' if "
116       "absent."), NULL,
117    CMD_ECHO_NONE, VCF_NONE, 0
118   },
119   {"quit",	ALLOW_HACK,
120    /* no translatable parameters */
121    SYN_ORIG_("quit"),
122    N_("Quit the game and shutdown the server."), NULL, NULL,
123    CMD_ECHO_ALL, VCF_NONE, 0
124   },
125   {"cut",	ALLOW_CTRL,
126    /* TRANS: translate text between <> only */
127    N_("cut <connection-name>"),
128    N_("Cut a client's connection to server."),
129    N_("Cut specified client's connection to the server, removing that client "
130       "from the game. If the game has not yet started that client's player "
131       "is removed from the game, otherwise there is no effect on the player. "
132       "Note that this command now takes connection names, not player names."),
133    NULL,
134    CMD_ECHO_ALL, VCF_NONE, 50
135   },
136   {"explain",	ALLOW_INFO,
137    /* TRANS: translate text between <> only */
138    N_("explain\n"
139       "explain <option-name>"),
140    N_("Explain server options."),
141    N_("The 'explain' command gives a subset of the functionality of 'help', "
142       "and is included for backward compatibility. With no arguments it "
143       "gives a list of options (like 'help options'), and with an argument "
144       "it gives help for a particular option (like 'help <option-name>')."),
145    NULL,
146    CMD_ECHO_NONE, VCF_NONE, 0
147   },
148   {"show",	ALLOW_INFO,
149    /* TRANS: translate text between <> only */
150    N_("show\n"
151       "show <option-name>\n"
152       "show <option-prefix>\n"
153       "show all\n"
154       "show vital\n"
155       "show situational\n"
156       "show rare\n"
157       "show changed\n"
158       "show locked\n"
159       "show rulesetdir"),
160    N_("Show server options."),
161    N_("With no arguments, shows vital server options (or available options, "
162       "when used by clients). With an option name argument, show only the "
163       "named option, or options with that prefix. With \"all\", it shows "
164       "all options. With \"vital\", \"situational\" or \"rare\", a set of "
165       "options with this level. With \"changed\", it shows only the options "
166       "which have been modified, while with \"locked\" all settings locked "
167       "by the ruleset will be listed. With \"ruleset\", it will show the "
168       "current ruleset directory name."), NULL,
169     CMD_ECHO_NONE, VCF_NONE, 0
170   },
171   {"wall",	ALLOW_ADMIN,
172    /* TRANS: translate text between <> only */
173    N_("wall <message>"),
174    N_("Send message to all connections."),
175    N_("For each connected client, pops up a window showing the message "
176       "entered."), NULL,
177    CMD_ECHO_ADMINS, VCF_NONE, 0
178   },
179   {"connectmsg", ALLOW_ADMIN,
180    /* TRANS: translate text between <> only */
181    N_("connectmsg <message>"),
182    N_("Set message to show to connecting players."),
183    N_("Set message to send to clients when they connect.\n"
184       "Empty message means that no message is sent."), NULL,
185    CMD_ECHO_ADMINS, VCF_NONE, 0
186   },
187   {"vote",	ALLOW_BASIC,
188    /* TRANS: translate text between [] only; "vote" is as a process */
189    N_("vote yes|no|abstain [vote number]"),
190    /* TRANS: "vote" as an instance of voting */
191    N_("Cast a vote."),
192       /* xgettext:no-c-format */
193    N_("A player with basic level access issuing a control level command "
194       "starts a new vote for the command. The /vote command followed by "
195       "\"yes\", \"no\", or \"abstain\", and optionally a vote number, "
196       "gives your vote. If you do not add a vote number, your vote applies "
197       "to the latest vote. You can only suggest one vote at a time. "
198       "The vote will pass immediately if more than half of the voters "
199       "who have not abstained vote for it, or fail immediately if at "
200       "least half of the voters who have not abstained vote against it."),
201    NULL,
202    CMD_ECHO_NONE, VCF_NONE, 0
203   },
204   {"debug",	ALLOW_CTRL,
205    /* TRANS: translate text between <> only */
206    N_("debug diplomacy <player>\n"
207       "debug ferries\n"
208       "debug tech <player>\n"
209       "debug city <x> <y>\n"
210       "debug units <x> <y>\n"
211       "debug unit <id>\n"
212       "debug timing\n"
213       "debug info"),
214    N_("Turn on or off AI debugging of given entity."),
215    N_("Print AI debug information about given entity and turn continuous "
216       "debugging output for this entity on or off."), NULL,
217    CMD_ECHO_ADMINS, VCF_NONE, 0
218   },
219   {"set",	ALLOW_CTRL,
220    /* TRANS: translate text between <> only */
221    N_("set <option-name> <value>"),
222    N_("Set server option."),
223    /* TRANS: don't translate text in '' */
224    N_("Set an option on the server. The syntax and legal values depend "
225       "on the option; see the help for each option. Some options are "
226       "\"bitwise\", in that they consist of a choice from a set of values; "
227       "separate these with |, for instance, '/set topology wrapx|iso'. For "
228       "these options, use syntax like '/set topology \"\"' to set no "
229       "values."), NULL,
230    CMD_ECHO_ALL, VCF_NONE, 50
231   },
232   {"team",	ALLOW_CTRL,
233    /* TRANS: translate text between <> only */
234    N_("team <player> <team>"),
235    N_("Change a player's team affiliation."),
236    N_("A team is a group of players that start out allied, with shared "
237       "vision and embassies, and fight together to achieve team victory "
238       "with averaged individual scores. Each player is always a member "
239       "of a team (possibly the only member). This command changes which "
240       "team a player is a member of. Use \"\" if names contain whitespace."),
241    NULL,
242    CMD_ECHO_ALL, VCF_NONE, 50
243   },
244   {"rulesetdir", ALLOW_CTRL,
245    /* TRANS: translate text between <> only */
246    N_("rulesetdir <directory>"),
247    N_("Choose new ruleset directory or modpack."),
248    NULL, NULL,
249    CMD_ECHO_ALL, VCF_NONE, 50
250   },
251   {"metamessage", ALLOW_CTRL,
252    /* TRANS: translate text between <> only */
253    N_("metamessage <meta-line>"),
254    N_("Set metaserver info line."),
255    N_("Set user defined metaserver info line. If parameter is omitted, "
256       "previously set metamessage will be removed. For most of the time "
257       "user defined metamessage will be used instead of automatically "
258       "generated messages, if it is available."), NULL,
259    CMD_ECHO_ADMINS, VCF_NONE, 50
260   },
261   {"metapatches", ALLOW_HACK,
262    /* TRANS: translate text between <> only */
263    N_("metapatches <meta-line>"),
264    N_("Set metaserver patches line."), NULL, NULL,
265    CMD_ECHO_ADMINS, VCF_NONE, 0
266   },
267   {"metaconnection",	ALLOW_ADMIN,
268    /* no translatable parameters */
269    SYN_ORIG_("metaconnection u|up\n"
270              "metaconnection d|down\n"
271              "metaconnection ?"),
272    N_("Control metaserver connection."),
273    N_("'metaconnection ?' reports on the status of the connection to metaserver. "
274       "'metaconnection down' or 'metac d' brings the metaserver connection down. "
275       "'metaconnection up' or 'metac u' brings the metaserver connection up. "
276       "'metaconnection persistent' or 'metac p' is like 'up', but keeps trying after failures. "),
277    NULL,
278    CMD_ECHO_ADMINS, VCF_NONE, 0
279   },
280   {"metaserver",	ALLOW_ADMIN,
281    /* TRANS: translate text between <> only */
282    N_("metaserver <address>"),
283    N_("Set address (URL) for metaserver to report to."), NULL, NULL,
284    CMD_ECHO_ADMINS, VCF_NONE, 0
285   },
286   {"aitoggle",	ALLOW_CTRL,
287    /* TRANS: translate text between <> only */
288    N_("aitoggle <player-name>"),
289    N_("Toggle AI status of player."), NULL, NULL,
290    CMD_ECHO_ADMINS, VCF_NONE, 50
291   },
292   {"take",    ALLOW_INFO,
293    /* TRANS: translate text between [] and <> only */
294    N_("take [connection-name] <player-name>"),
295    N_("Take over a player's place in the game."),
296    /* TRANS: Don't translate text between '' */
297    N_("Only the console and connections with cmdlevel 'hack' can force "
298       "other connections to take over a player. If you're not one of these, "
299       "only the <player-name> argument is allowed. If '-' is given for the "
300       "player name and the connection does not already control a player, one "
301       "is created and assigned to the connection. The 'allowtake' option "
302       "controls which players may be taken and in what circumstances."),
303    NULL,
304    CMD_ECHO_ADMINS, VCF_NONE, 0
305   },
306   {"observe",    ALLOW_INFO,
307    /* TRANS: translate text between [] only */
308    N_("observe [connection-name] [player-name]"),
309    N_("Observe a player or the whole game."),
310    /* TRANS: Don't translate text between '' */
311    N_("Only the console and connections with cmdlevel 'hack' can force "
312       "other connections to observe a player. If you're not one of these, "
313       "only the [player-name] argument is allowed. If the console gives no "
314       "player-name or the connection uses no arguments, then the connection "
315       "is attached to a global observer. The 'allowtake' option controls "
316       "which players may be observed and in what circumstances."), NULL,
317    CMD_ECHO_ADMINS, VCF_NONE, 0
318   },
319   {"detach",    ALLOW_INFO,
320    /* TRANS: translate text between <> only */
321    N_("detach <connection-name>"),
322    N_("Detach from a player."),
323    N_("Only the console and connections with cmdlevel 'hack' can force "
324       "other connections to detach from a player."), NULL,
325    CMD_ECHO_ADMINS, VCF_NONE, 0
326   },
327   {"create",	ALLOW_CTRL,
328    /* TRANS: translate text between <> and [] only */
329    N_("create <player-name> [ai type]"),
330    N_("Create an AI player with a given name."),
331    /* TRANS: don't translate text between single quotes */
332    N_("With the 'create' command a new player with the given name is "
333       "created.\n"
334       "If 'player-name' is empty, a random name will be assigned when the "
335       "game begins. Until then the player will be known by a name derived "
336       "from its type.\n"
337       "The 'ai type' parameter can be used to select which AI module will be "
338       "used for the created player. This requires that the respective module "
339       "has been loaded or built in to the server.\n"
340       "If the game has already started, the new player will have no units or "
341       "cities; also, if no free player slots are available, the slot of a "
342       "dead player can be reused (removing all record of that player from the "
343       "running game)."), NULL,
344    CMD_ECHO_ALL, VCF_NONE, 50
345   },
346   {"away",	ALLOW_BASIC,
347    /* no translatable parameters */
348    SYN_ORIG_("away"),
349    N_("Set yourself in away mode. The AI will watch your back."),
350    NULL, ai_level_help,
351    CMD_ECHO_NONE, VCF_NONE, 50
352   },
353   {"handicapped",	ALLOW_CTRL,
354    /* TRANS: translate text between <> only */
355    N_("handicapped\n"
356       "handicapped <player-name>"),
357    /* TRANS: translate 'Handicapped' as AI skill level */
358    N_("Set one or all AI players to 'Handicapped'."), NULL, ai_level_help,
359    CMD_ECHO_ALL, VCF_NONE, 50
360   },
361   {"novice",	ALLOW_CTRL,
362    /* TRANS: translate text between <> only */
363    N_("novice\n"
364       "novice <player-name>"),
365    /* TRANS: translate 'Novice' as AI skill level */
366    N_("Set one or all AI players to 'Novice'."), NULL, ai_level_help,
367    CMD_ECHO_ALL, VCF_NONE, 50
368   },
369   {"easy",	ALLOW_CTRL,
370    /* TRANS: translate text between <> only */
371    N_("easy\n"
372       "easy <player-name>"),
373    /* TRANS: translate 'Easy' as AI skill level */
374    N_("Set one or all AI players to 'Easy'."), NULL, ai_level_help,
375    CMD_ECHO_ALL, VCF_NONE, 50
376   },
377   {"normal",	ALLOW_CTRL,
378    /* TRANS: translate text between <> only */
379    N_("normal\n"
380       "normal <player-name>"),
381    /* TRANS: translate 'Normal' as AI skill level */
382    N_("Set one or all AI players to 'Normal'."), NULL, ai_level_help,
383    CMD_ECHO_ALL, VCF_NONE, 50
384   },
385   {"hard",	ALLOW_CTRL,
386    /* TRANS: translate text between <> only */
387    N_("hard\n"
388       "hard <player-name>"),
389    /* TRANS: translate 'Hard' as AI skill level */
390    N_("Set one or all AI players to 'Hard'."), NULL, ai_level_help,
391    CMD_ECHO_ALL, VCF_NONE, 50
392   },
393   {"cheating",  ALLOW_CTRL,
394    /* TRANS: translate text between <> only */
395    N_("cheating\n"
396       "cheating <player-name>"),
397    /* TRANS: translate 'Cheating' as AI skill level */
398    N_("Set one or all AI players to 'Cheating'."), NULL, ai_level_help,
399    CMD_ECHO_ALL, VCF_NONE, 50
400   },
401 #ifdef DEBUG
402   {"experimental",	ALLOW_CTRL,
403    /* TRANS: translate text between <> only */
404    N_("experimental\n"
405       "experimental <player-name>"),
406    /* TRANS: translate 'Experimental' as AI skill level */
407    N_("Set one or all AI players to 'Experimental'."), NULL, ai_level_help,
408    CMD_ECHO_ALL, VCF_NONE, 50
409   },
410 #endif /* DEBUG */
411   {"cmdlevel",	ALLOW_ADMIN,
412    /* TRANS: translate text between <> only */
413    N_("cmdlevel\n"
414       "cmdlevel <level>\n"
415       "cmdlevel <level> new\n"
416       "cmdlevel <level> first\n"
417       "cmdlevel <level> <connection-name>"),
418    N_("Query or set command access level access."),
419    N_("The command access level controls which server commands are available "
420       "to users via the client chatline. The available levels are:\n"
421       "    none  -  no commands\n"
422       "    info  -  informational or observer commands only\n"
423       "    basic -  commands available to players in the game\n"
424       "    ctrl  -  commands that affect the game and users\n"
425       "    admin -  commands that affect server operation\n"
426       "    hack  -  *all* commands - dangerous!\n"
427       "With no arguments, the current command access levels are reported. "
428       "With a single argument, the level is set for all existing "
429       "connections, and the default is set for future connections. "
430       "If 'new' is specified, the level is set for newly connecting clients. "
431       "If 'first come' is specified, the 'first come' level is set; it will be "
432       "granted to the first client to connect, or if there are connections "
433       "already, the first client to issue the 'first' command. "
434       "If a connection name is specified, the level is set for that "
435       "connection only.\n"
436       "Command access levels do not persist if a client disconnects, "
437       "because some untrusted person could reconnect with the same name. "
438       "Note that this command now takes connection names, not player names."
439       ), NULL,
440    CMD_ECHO_ADMINS, VCF_NONE, 50
441   },
442   {"first", ALLOW_BASIC,
443    /* no translatable parameters */
444    SYN_ORIG_("first"),
445    N_("If there is none, become the game organizer with increased permissions."),
446    NULL, NULL,
447    CMD_ECHO_ADMINS, VCF_NONE, 50
448   },
449   {"timeoutincrease", ALLOW_CTRL,
450    /* TRANS: translate text between <> only */
451    N_("timeoutincrease <turn> <turninc> <value> <valuemult>"),
452    N_("See \"/help timeoutincrease\"."),
453    N_("Every <turn> turns, add <value> to timeout timer, then add <turninc> "
454       "to <turn> and multiply <value> by <valuemult>. Use this command in "
455       "concert with the option \"timeout\". Defaults are 0 0 0 1"), NULL,
456    CMD_ECHO_ALL, VCF_NONE, 50
457   },
458   {"cancelvote", ALLOW_BASIC,
459    /* TRANS: translate text between <> only; "vote" is as a process */
460    N_("cancelvote\n"
461       "cancelvote <vote number>\n"
462       "cancelvote all\n"),
463    /* TRANS: "vote" as a process */
464    N_("Cancel a running vote."),
465    /* TRANS: "vote" as a process */
466    N_("With no arguments this command removes your own vote. If you have "
467       "an admin access level, you can cancel any vote by vote number, or "
468       "all votes with the \'all\' argument."), NULL,
469    CMD_ECHO_ADMINS, VCF_NONE, 0
470   },
471   {"ignore", ALLOW_INFO,
472    /* TRANS: translate text between <> and [] only */
473    N_("ignore [type=]<pattern>"),
474    N_("Block all messages from users matching the pattern."),
475    N_("The given pattern will be added to your ignore list; you will not "
476       "receive any messages from users matching this pattern. The type "
477       "may be either \"user\", \"host\", or \"ip\". The default type "
478       "(if omitted) is to match against the username. The pattern supports "
479       "unix glob style wildcards, i.e., * matches zero or more character, ? "
480       "exactly one character, [abc] exactly one of 'a' 'b' or 'c', etc. "
481       "To access your current ignore list, issue \"/list ignore\"."), NULL,
482    CMD_ECHO_NONE, VCF_NONE, 0
483   },
484   {"unignore", ALLOW_INFO,
485    /* TRANS: translate text between <> */
486    N_("unignore <range>"),
487    N_("Remove ignore list entries."),
488    N_("The ignore list entries in the given range will be removed; "
489       "you will be able to receive messages from the respective users. "
490       "The range argument may be a single number or a pair of numbers "
491       "separated by a dash '-'. If the first number is omitted, it is "
492       "assumed to be 1; if the last is omitted, it is assumed to be "
493       "the last valid ignore list index. To access your current ignore "
494       "list, issue \"/list ignore\"."), NULL,
495    CMD_ECHO_NONE, VCF_NONE, 0
496   },
497   {"playercolor", ALLOW_ADMIN,
498    /* TRANS: translate text between <> */
499    N_("playercolor <player-name> <color>\n"
500       "playercolor <player-name> reset"),
501    N_("Define the color of a player."),
502    N_("This command sets the color of a specific player, overriding any color "
503       "assigned according to the 'plrcolormode' setting.\n"
504       "The color is defined using hexadecimal notation (hex) for the "
505       "combination of Red, Green, and Blue color components (RGB), similarly "
506       "to HTML. For each component, the lowest (darkest) value is 0 (in "
507       "hex: 00), and the highest value is 255 (in hex: FF). The color "
508       "definition is simply the three hex values concatenated together "
509       "(RRGGBB). For example, the following command sets Caesar to pure red:\n"
510       "  playercolor Caesar ff0000\n"
511       "Before the game starts, this command can only be used if the "
512       "'plrcolormode' setting is set to 'PLR_SET'; a player's color can be "
513       "unset again by specifying 'reset'.\n"
514       "Once the game has started and colors have been assigned, this command "
515       "changes the player color in any mode; 'reset' cannot be used.\n"
516       "To list the player colors, use 'list colors'."), NULL,
517    CMD_ECHO_NONE, VCF_NONE, 0
518   },
519   {"endgame",	ALLOW_ADMIN,
520    /* no translatable parameters */
521    SYN_ORIG_("endgame"),
522    N_("End the game immediately in a draw."), NULL, NULL,
523    CMD_ECHO_ALL, VCF_NONE, 0
524   },
525   {"surrender",	ALLOW_BASIC,
526    /* no translatable parameters */
527    SYN_ORIG_("surrender"),
528    N_("Concede the game."),
529    N_("This tells everyone else that you concede the game, and if all "
530       "but one player (or one team) have conceded the game in this way "
531       "then the game ends."), NULL,
532    CMD_ECHO_NONE, VCF_NONE, 0
533   },
534   {"remove",	ALLOW_CTRL,
535    /* TRANS: translate text between <> only */
536    N_("remove <player-name>"),
537    N_("Fully remove player from game."),
538    N_("This *completely* removes a player from the game, including "
539       "all cities and units etc. Use with care!"), NULL,
540    CMD_ECHO_ALL, VCF_NONE, 50
541   },
542   {"save",	ALLOW_ADMIN,
543    /* TRANS: translate text between <> only */
544    N_("save\n"
545       "save <file-name>"),
546    N_("Save game to file."),
547    N_("Save the current game to file <file-name>. If no file-name "
548       "argument is given saves to \"<auto-save name prefix><year>m.sav[.gz]\". "
549       "To reload a savegame created by 'save', start the server with "
550       "the command-line argument:\n"
551       "    '--file <filename>' or '-f <filename>'\n"
552       "and use the 'start' command once players have reconnected."), NULL,
553    CMD_ECHO_ADMINS, VCF_NONE, 0
554   },
555   {"scensave",	ALLOW_ADMIN,
556    /* TRANS: translate text between <> only */
557    N_("scensave\n"
558       "scensave <file-name>"),
559    N_("Save game to file as scenario."),
560    N_("Save the current game to file <file-name> as scenario. If no file-name "
561       "argument is given saves to \"<auto-save name prefix><year>m.sav[.gz]\". "
562       "To reload a savegame created by 'scensave', start the server with "
563       "the command-line argument:\n"
564       "    '--file <filename>' or '-f <filename>'\n"
565       "and use the 'start' command once players have reconnected."), NULL,
566    CMD_ECHO_ADMINS, VCF_NONE, 0
567   },
568   {"load",      ALLOW_CTRL,
569    /* TRANS: translate text between <> only */
570    N_("load\n"
571       "load <file-name>"),
572    N_("Load game from file."),
573    N_("Load a game from <file-name>. Any current data including players, "
574       "rulesets and server options are lost."), NULL,
575    CMD_ECHO_ADMINS, VCF_NONE, 50
576   },
577   {"read",	ALLOW_CTRL,
578    /* TRANS: translate text between <> only */
579    N_("read <file-name>"),
580    N_("Process server commands from file."), NULL, NULL,
581    CMD_ECHO_ADMINS, VCF_NONE, 50
582   },
583   {"write",	ALLOW_HACK,
584    /* TRANS: translate text between <> only */
585    N_("write <file-name>"),
586    N_("Write current settings as server commands to file."), NULL, NULL,
587    CMD_ECHO_ADMINS, VCF_NONE, 0
588   },
589   {"reset",	ALLOW_CTRL,
590    /* no translatable parameters */
591    SYN_ORIG_("reset [game|ruleset|script|default]"),
592    N_("Reset all server settings."),
593    N_("Reset all settings if it is possible. The following levels are "
594       "supported:\n"
595       "  game     - using the values defined at the game start\n"
596       "  ruleset  - using the values defined in the ruleset\n"
597       "  script   - using default values and rereading the start script\n"
598       "  default  - using default values\n"), NULL,
599    CMD_ECHO_ALL, VCF_NONE, 50
600   },
601   {"default",	ALLOW_CTRL,
602    /* TRANS: translate text between <> only */
603    N_("default <option name>"),
604    N_("Set option to its default value"),
605    N_("Reset the option to its default value. If the default ever changes "
606       "in a future version, the option's value will follow that change."),
607       NULL,
608    CMD_ECHO_ALL, VCF_NONE, 50
609   },
610   {"lua", ALLOW_ADMIN,
611    /* TRANS: translate text between <> only */
612    N_("lua cmd <script line>\n"
613       "lua file <script file>\n"
614       "lua <script line> (deprecated)"),
615    N_("Evaluate a line of Freeciv script or a Freeciv script file in the "
616       "current game."), NULL, NULL,
617    CMD_ECHO_ADMINS, VCF_NONE, 0
618   },
619   {"kick", ALLOW_CTRL,
620    /* TRANS: translate text between <> */
621     N_("kick <user>"),
622     N_("Cut a connection and disallow reconnect."),
623     N_("The connection given by the 'user' argument will be cut from the "
624        "server and not allowed to reconnect. The time the user wouldn't be "
625        "able to reconnect is controlled by the 'kicktime' setting."), NULL,
626    CMD_ECHO_ADMINS, VCF_NOPASSALONE, 50
627   },
628   {"delegate", ALLOW_BASIC,
629    /* TRANS: translate only text between [] and <> */
630    N_("delegate to <username> [player-name]\n"
631       "delegate cancel [player-name]\n"
632       "delegate take <player-name>\n"
633       "delegate restore\n"
634       "delegate show <player-name>"),
635    N_("Delegate control to another user."),
636    N_("Delegation allows a user to nominate another user who can temporarily "
637       "take over control of their player while they are away.\n"
638       "'delegate to <username>': allow <username> to 'delegate take' your "
639       "player.\n"
640       "'delegate cancel': nominated user can no longer take your player.\n"
641       "'delegate take <player-name>': take control of a player who has been "
642       "delegated to you. (Behaves like 'take', except that the 'allowtake' "
643       "restrictions are not enforced.)\n"
644       "'delegate restore': relinquish control of a delegated player (opposite "
645       "of 'delegate take') and restore your previous view, if any. (This also "
646       "happens automatically if the player's owner reconnects.)\n"
647       "'delegate show': show who control of your player is currently "
648       "delegated to, if anyone.\n"
649       "The [player-name] argument can only be used by connections with "
650       "cmdlevel 'admin' or above to force the corresponding change of the "
651       "delegation status."), NULL,
652    CMD_ECHO_NONE, VCF_NONE, 0
653   },
654   {"fcdb", ALLOW_ADMIN,
655    /* TRANS: translate text between <> only */
656    N_("fcdb reload\n"
657       "fcdb lua <script>"),
658    N_("Manage the authentication database."),
659    N_("The argument 'reload' causes the database script file to be re-read "
660       "after a change, while the argument 'lua' evaluates a line of Lua "
661       "script in the context of the Lua instance for the database."), NULL,
662    CMD_ECHO_ADMINS, VCF_NONE, 0
663   },
664   {"mapimg",   ALLOW_ADMIN,
665    /* TRANS: translate text between <> only */
666    N_("mapimg define <mapdef>\n"
667       "mapimg show <id>|all\n"
668       "mapimg create <id>|all\n"
669       "mapimg delete <id>|all\n"
670       "mapimg colortest"),
671    N_("Create image files of the world/player map."),
672    NULL, mapimg_help,
673    CMD_ECHO_ADMINS, VCF_NONE, 50
674   },
675   {"rfcstyle",	ALLOW_HACK,
676    /* no translatable parameters */
677    SYN_ORIG_("rfcstyle"),
678    N_("Switch server output between 'RFC-style' and normal style."), NULL, NULL,
679    CMD_ECHO_ADMINS, VCF_NONE, 0
680   },
681   {"serverid",	ALLOW_INFO,
682    /* no translatable parameters */
683    SYN_ORIG_("serverid"),
684    N_("Simply returns the id of the server."), NULL, NULL,
685    CMD_ECHO_NONE, VCF_NONE, 0
686   }
687 };
688 
689 
690 /**************************************************************************
691   Return command by its number.
692 **************************************************************************/
command_by_number(int i)693 const struct command *command_by_number(int i)
694 {
695   fc_assert_ret_val(i >= 0 && i < CMD_NUM, NULL);
696   return &commands[i];
697 }
698 
699 /**************************************************************************
700   Return name of the command
701 **************************************************************************/
command_name(const struct command * pcommand)702 const char *command_name(const struct command *pcommand)
703 {
704   return pcommand->name;
705 }
706 
707 /**************************************************************************
708   Return name of the command by commands number.
709 **************************************************************************/
command_name_by_number(int i)710 const char *command_name_by_number(int i)
711 {
712   return command_by_number(i)->name;
713 }
714 
715 /**************************************************************************
716   Returns the synopsis text of the command (translated).
717 **************************************************************************/
command_synopsis(const struct command * pcommand)718 const char *command_synopsis(const struct command *pcommand)
719 {
720   return SYN_TRANS_(pcommand->synopsis);
721 }
722 
723 /**************************************************************************
724   Returns the short help text of the command (translated).
725 **************************************************************************/
command_short_help(const struct command * pcommand)726 const char *command_short_help(const struct command *pcommand)
727 {
728   return _(pcommand->short_help);
729 }
730 
731 /**************************************************************************
732   Returns the extra help text of the command (translated).
733   The caller must free this string.
734 **************************************************************************/
command_extra_help(const struct command * pcommand)735 char *command_extra_help(const struct command *pcommand)
736 {
737   if (pcommand->extra_help_func) {
738     fc_assert(pcommand->extra_help == NULL);
739     return pcommand->extra_help_func(pcommand->name);
740   } else if (pcommand->extra_help) {
741     return fc_strdup(_(pcommand->extra_help));
742   } else {
743     return NULL;
744   }
745 }
746 
747 /**************************************************************************
748   ...
749 **************************************************************************/
command_level(const struct command * pcommand)750 enum cmdlevel command_level(const struct command *pcommand)
751 {
752   return pcommand->level;
753 }
754 
755 /****************************************************************************
756   Retrurns the flag of the command to notify the users about its usage.
757 ****************************************************************************/
command_echo(const struct command * pcommand)758 enum cmd_echo command_echo(const struct command *pcommand)
759 {
760   return pcommand->echo;
761 }
762 
763 /**************************************************************************
764   Returns a bit-wise combination of all vote flags set for this command.
765 **************************************************************************/
command_vote_flags(const struct command * pcommand)766 int command_vote_flags(const struct command *pcommand)
767 {
768   return pcommand ? pcommand->vote_flags : 0;
769 }
770 
771 /**************************************************************************
772   Returns the vote percent required for this command to pass in a vote.
773 **************************************************************************/
command_vote_percent(const struct command * pcommand)774 int command_vote_percent(const struct command *pcommand)
775 {
776   return pcommand ? pcommand->vote_percent : 0;
777 }
778