41 #include "table/strings.h"
81 #define DEF_CONSOLE_CMD(function) static bool function(byte argc, char *argv[])
82 #define DEF_CONSOLE_HOOK(function) static ConsoleHookResult function(bool echo)
98 if (echo)
IConsoleError(
"You cannot use this command because there is no network available.");
108 DEF_CONSOLE_HOOK(ConHookServerOnly)
113 if (echo)
IConsoleError(
"This command is only available to a network server.");
123 DEF_CONSOLE_HOOK(ConHookClientOnly)
128 if (echo)
IConsoleError(
"This command is not available to a network server.");
138 DEF_CONSOLE_HOOK(ConHookNeedNetwork)
143 if (echo)
IConsoleError(
"Not connected. This command is only available in multiplayer.");
153 DEF_CONSOLE_HOOK(ConHookNoNetwork)
156 if (echo)
IConsoleError(
"This command is forbidden in multiplayer.");
163 # define ConHookNoNetwork NULL
166 DEF_CONSOLE_HOOK(ConHookNewGRFDeveloperTool)
169 if (_game_mode == GM_MENU) {
170 if (echo)
IConsoleError(
"This command is only available in game and editor.");
173 #ifdef ENABLE_NETWORK
174 return ConHookNoNetwork(echo);
195 DEF_CONSOLE_CMD(ConResetEngines)
198 IConsoleHelp(
"Reset status data of all engines. This might solve some issues with 'lost' engines. Usage: 'resetengines'");
211 DEF_CONSOLE_CMD(ConResetEnginePool)
214 IConsoleHelp(
"Reset NewGRF allocations of engine slots. This will remove invalid engine definitions, and might make default engines available again.");
218 if (_game_mode == GM_MENU) {
219 IConsoleError(
"This command is only available in game and editor.");
224 IConsoleError(
"This can only be done when there are no vehicles in the game.");
237 DEF_CONSOLE_CMD(ConResetTile)
240 IConsoleHelp(
"Reset a tile to bare land. Usage: 'resettile <tile>'");
241 IConsoleHelp(
"Tile can be either decimal (34161) or hexadecimal (0x4a5B)");
266 DEF_CONSOLE_CMD(ConScrollToTile)
271 IConsoleHelp(
"Usage: 'scrollto <tile>' or 'scrollto <x> <y>'");
272 IConsoleHelp(
"Numbers can be either decimal (34161) or hexadecimal (0x4a5B).");
310 DEF_CONSOLE_CMD(ConSave)
313 IConsoleHelp(
"Save the current game. Usage: 'save <filename>'");
318 char *filename =
str_fmt(
"%s.sav", argv[1]);
337 DEF_CONSOLE_CMD(ConSaveConfig)
340 IConsoleHelp(
"Saves the configuration for new games to the configuration file, typically 'openttd.cfg'.");
341 IConsoleHelp(
"It does not save the configuration of the current game to the configuration file.");
350 DEF_CONSOLE_CMD(ConLoad)
353 IConsoleHelp(
"Load a game by name or index. Usage: 'load <file | number>'");
357 if (argc != 2)
return false;
359 const char *file = argv[1];
379 DEF_CONSOLE_CMD(ConRemove)
382 IConsoleHelp(
"Remove a savegame by name or index. Usage: 'rm <file | number>'");
386 if (argc != 2)
return false;
388 const char *file = argv[1];
405 DEF_CONSOLE_CMD(ConListFiles)
408 IConsoleHelp(
"List all loadable savegames and directories in the current dir via console. Usage: 'ls | dir'");
413 for (uint i = 0; i < _console_file_list.
Length(); i++) {
421 DEF_CONSOLE_CMD(ConChangeDirectory)
424 IConsoleHelp(
"Change the dir via console. Usage: 'cd <directory | number>'");
428 if (argc != 2)
return false;
430 const char *file = argv[1];
434 switch (item->type) {
435 case FIOS_TYPE_DIR:
case FIOS_TYPE_DRIVE:
case FIOS_TYPE_PARENT:
448 DEF_CONSOLE_CMD(ConPrintWorkingDirectory)
453 IConsoleHelp(
"Print out the current working directory. Usage: 'pwd'");
466 DEF_CONSOLE_CMD(ConClearBuffer)
469 IConsoleHelp(
"Clear the console buffer. Usage: 'clear'");
473 IConsoleClearBuffer();
482 #ifdef ENABLE_NETWORK
484 static bool ConKickOrBan(
const char *argv,
bool ban)
488 if (strchr(argv,
'.') == NULL && strchr(argv,
':') == NULL) {
527 DEF_CONSOLE_CMD(ConKick)
530 IConsoleHelp(
"Kick a client from a network game. Usage: 'kick <ip | client-id>'");
531 IConsoleHelp(
"For client-id's, see the command 'clients'");
535 if (argc != 2)
return false;
537 return ConKickOrBan(argv[1],
false);
540 DEF_CONSOLE_CMD(ConBan)
543 IConsoleHelp(
"Ban a client from a network game. Usage: 'ban <ip | client-id>'");
544 IConsoleHelp(
"For client-id's, see the command 'clients'");
545 IConsoleHelp(
"If the client is no longer online, you can still ban his/her IP");
549 if (argc != 2)
return false;
551 return ConKickOrBan(argv[1],
true);
554 DEF_CONSOLE_CMD(ConUnBan)
558 IConsoleHelp(
"Unban a client from a network game. Usage: 'unban <ip | client-id>'");
559 IConsoleHelp(
"For a list of banned IP's, see the command 'banlist'");
563 if (argc != 2)
return false;
565 uint index = (strchr(argv[1],
'.') == NULL) ? atoi(argv[1]) : 0;
582 DEF_CONSOLE_CMD(ConBanList)
585 IConsoleHelp(
"List the IP's of banned clients: Usage 'banlist'");
599 DEF_CONSOLE_CMD(ConPauseGame)
616 DEF_CONSOLE_CMD(ConUnpauseGame)
619 IConsoleHelp(
"Unpause a network game. Usage: 'unpause'");
637 DEF_CONSOLE_CMD(ConRcon)
640 IConsoleHelp(
"Remote control the server from another client. Usage: 'rcon <password> <command>'");
641 IConsoleHelp(
"Remember to enclose the command in quotes, otherwise only the first parameter is sent");
645 if (argc < 3)
return false;
655 DEF_CONSOLE_CMD(ConStatus)
658 IConsoleHelp(
"List the status of all clients connected to the server. Usage 'status'");
666 DEF_CONSOLE_CMD(ConServerInfo)
669 IConsoleHelp(
"List current and maximum client/company limits. Usage 'server_info'");
670 IConsoleHelp(
"You can change these values by modifying settings 'network.max_clients', 'network.max_companies' and 'network.max_spectators'");
681 DEF_CONSOLE_CMD(ConClientNickChange)
684 IConsoleHelp(
"Change the nickname of a connected client. Usage: 'client_name <client-id> <new-name>'");
685 IConsoleHelp(
"For client-id's, see the command 'clients'");
692 IConsoleError(
"Please use the command 'name' to change your own name!");
708 DEF_CONSOLE_CMD(ConJoinCompany)
711 IConsoleHelp(
"Request joining another company. Usage: join <company-id> [<password>]");
712 IConsoleHelp(
"For valid company-id see company list, use 255 for spectator");
730 IConsoleError(
"Cannot join spectators, maximum number of spectators reached.");
755 DEF_CONSOLE_CMD(ConMoveClient)
758 IConsoleHelp(
"Move a client to another company. Usage: move <client-id> <company-id>");
759 IConsoleHelp(
"For valid client-id see 'clients', for valid company-id see 'companies', use 255 for moving to spectators");
768 IConsoleError(
"Invalid client-id, check the command 'clients' for valid client-id's.");
788 IConsoleError(
"You cannot move someone to where he/she already is!");
798 DEF_CONSOLE_CMD(ConResetCompany)
801 IConsoleHelp(
"Remove an idle company from the game. Usage: 'reset_company <company-id>'");
802 IConsoleHelp(
"For company-id's, see the list of companies from the dropdown menu. Company 1 is 1, etc.");
806 if (argc != 2)
return false;
822 IConsoleError(
"Cannot remove company: a client is connected to that company.");
827 IConsoleError(
"Cannot remove company: the server is connected to that company.");
838 DEF_CONSOLE_CMD(ConNetworkClients)
841 IConsoleHelp(
"Get a list of connected clients including their ID, name, company-id, and IP. Usage: 'clients'");
850 DEF_CONSOLE_CMD(ConNetworkReconnect)
853 IConsoleHelp(
"Reconnect to server to which you were connected last time. Usage: 'reconnect [<company>]'");
854 IConsoleHelp(
"Company 255 is spectator (default, if not specified), 0 means creating new company.");
855 IConsoleHelp(
"All others are a certain company with Company 1 being #1");
867 if (playas < COMPANY_FIRST || playas >=
MAX_COMPANIES)
return false;
883 DEF_CONSOLE_CMD(ConNetworkConnect)
886 IConsoleHelp(
"Connect to a remote OTTD server and join the game. Usage: 'connect <ip>'");
887 IConsoleHelp(
"IP can contain port and company: 'IP[:Port][#Company]', eg: 'server.ottd.org:443#2'");
888 IConsoleHelp(
"Company #255 is spectator all others are a certain company with Company 1 being #1");
892 if (argc < 2)
return false;
895 const char *port = NULL;
896 const char *company = NULL;
905 if (company != NULL) {
932 DEF_CONSOLE_CMD(ConExec)
935 IConsoleHelp(
"Execute a local script file. Usage: 'exec <script> <?>'");
939 if (argc < 2)
return false;
943 if (script_file == NULL) {
944 if (argc == 2 || atoi(argv[2]) != 0)
IConsoleError(
"script file not found");
951 while (
_script_running && fgets(cmdline,
sizeof(cmdline), script_file) != NULL) {
953 for (
char *cmdptr = cmdline; *cmdptr !=
'\0'; cmdptr++) {
954 if (*cmdptr ==
'\n' || *cmdptr ==
'\r') {
962 if (ferror(script_file)) {
963 IConsoleError(
"Encountered error while trying to read from script file");
971 DEF_CONSOLE_CMD(ConReturn)
974 IConsoleHelp(
"Stop executing a running script. Usage: 'return'");
985 extern bool CloseConsoleLogIfActive();
987 DEF_CONSOLE_CMD(ConScript)
989 extern FILE *_iconsole_output_file;
992 IConsoleHelp(
"Start or stop logging console output to a file. Usage: 'script <filename>'");
993 IConsoleHelp(
"If filename is omitted, a running log is stopped if it is active");
997 if (!CloseConsoleLogIfActive()) {
998 if (argc < 2)
return false;
1001 _iconsole_output_file = fopen(argv[1],
"ab");
1002 if (_iconsole_output_file == NULL)
IConsoleError(
"could not open file");
1009 DEF_CONSOLE_CMD(ConEcho)
1012 IConsoleHelp(
"Print back the first argument to the console. Usage: 'echo <arg>'");
1016 if (argc < 2)
return false;
1021 DEF_CONSOLE_CMD(ConEchoC)
1024 IConsoleHelp(
"Print back the first argument to the console in a given colour. Usage: 'echoc <colour> <arg2>'");
1028 if (argc < 3)
return false;
1033 DEF_CONSOLE_CMD(ConNewGame)
1036 IConsoleHelp(
"Start a new game. Usage: 'newgame [seed]'");
1037 IConsoleHelp(
"The server can force a new game using 'newgame'; any client joined will rejoin after the server is done generating the new game.");
1045 DEF_CONSOLE_CMD(ConRestart)
1049 IConsoleHelp(
"Restarts a game. It tries to reproduce the exact same map as the game started with.");
1051 IConsoleHelp(
" * restarting games started in another version might create another map due to difference in map generation");
1052 IConsoleHelp(
" * restarting games based on scenarios, loaded games or heightmaps will start a new game based on the settings stored in the scenario/savegame");
1072 for (
char *p2 = buf; *p2 !=
'\0'; p2++) {
1081 DEF_CONSOLE_CMD(ConListAILibs)
1091 DEF_CONSOLE_CMD(ConListAI)
1101 DEF_CONSOLE_CMD(ConListGameLibs)
1111 DEF_CONSOLE_CMD(ConListGame)
1121 DEF_CONSOLE_CMD(ConStartAI)
1123 if (argc == 0 || argc > 3) {
1124 IConsoleHelp(
"Start a new AI. Usage: 'start_ai [<AI>] [<settings>]'");
1125 IConsoleHelp(
"Start a new AI. If <AI> is given, it starts that specific AI (if found).");
1126 IConsoleHelp(
"If <settings> is given, it is parsed and the AI settings are set to that.");
1130 if (_game_mode != GM_NORMAL) {
1144 IConsoleWarning(
"AIs are not allowed in multiplayer by configuration.");
1156 FOR_ALL_COMPANIES(c) {
1157 if (c->
index != n)
break;
1163 config->
Change(argv[1], -1,
true);
1179 DEF_CONSOLE_CMD(ConReloadAI)
1182 IConsoleHelp(
"Reload an AI. Usage: 'reload_ai <company-id>'");
1183 IConsoleHelp(
"Reload the AI with the given company id. For company-id's, see the list of companies from the dropdown menu. Company 1 is 1, etc.");
1187 if (_game_mode != GM_NORMAL) {
1216 DEF_CONSOLE_CMD(ConStopAI)
1219 IConsoleHelp(
"Stop an AI. Usage: 'stop_ai <company-id>'");
1220 IConsoleHelp(
"Stop the AI with the given company id. For company-id's, see the list of companies from the dropdown menu. Company 1 is 1, etc.");
1224 if (_game_mode != GM_NORMAL) {
1252 DEF_CONSOLE_CMD(ConRescanAI)
1255 IConsoleHelp(
"Rescan the AI dir for scripts. Usage: 'rescan_ai'");
1260 IConsoleWarning(
"Only the server can rescan the AI dir for scripts.");
1269 DEF_CONSOLE_CMD(ConRescanGame)
1272 IConsoleHelp(
"Rescan the Game Script dir for scripts. Usage: 'rescan_game'");
1277 IConsoleWarning(
"Only the server can rescan the Game Script dir for scripts.");
1286 DEF_CONSOLE_CMD(ConRescanNewGRF)
1289 IConsoleHelp(
"Rescan the data dir for NewGRFs. Usage: 'rescan_newgrf'");
1298 DEF_CONSOLE_CMD(ConGetSeed)
1301 IConsoleHelp(
"Returns the seed used to create this game. Usage: 'getseed'");
1302 IConsoleHelp(
"The seed can be used to reproduce the exact same map as the game started with.");
1310 DEF_CONSOLE_CMD(ConGetDate)
1313 IConsoleHelp(
"Returns the current date (day-month-year) of the game. Usage: 'getdate'");
1324 DEF_CONSOLE_CMD(ConAlias)
1329 IConsoleHelp(
"Add a new alias, or redefine the behaviour of an existing alias . Usage: 'alias <name> <command>'");
1333 if (argc < 3)
return false;
1336 if (alias == NULL) {
1345 DEF_CONSOLE_CMD(ConScreenShot)
1348 IConsoleHelp(
"Create a screenshot of the game. Usage: 'screenshot [big | giant | no_con] [file name]'");
1349 IConsoleHelp(
"'big' makes a zoomed-in screenshot of the visible area, 'giant' makes a screenshot of the "
1350 "whole map, 'no_con' hides the console to create the screenshot. 'big' or 'giant' "
1351 "screenshots are always drawn without console");
1355 if (argc > 3)
return false;
1358 const char *name = NULL;
1361 if (strcmp(argv[1],
"big") == 0) {
1364 if (argc > 2) name = argv[2];
1365 }
else if (strcmp(argv[1],
"giant") == 0) {
1368 if (argc > 2) name = argv[2];
1369 }
else if (strcmp(argv[1],
"no_con") == 0) {
1372 if (argc > 2) name = argv[2];
1373 }
else if (argc == 2) {
1386 DEF_CONSOLE_CMD(ConInfoCmd)
1389 IConsoleHelp(
"Print out debugging information about a command. Usage: 'info_cmd <cmd>'");
1393 if (argc < 2)
return false;
1409 DEF_CONSOLE_CMD(ConDebugLevel)
1412 IConsoleHelp(
"Get/set the default debugging level for the game. Usage: 'debug_level [<level>]'");
1413 IConsoleHelp(
"Level can be any combination of names, levels. Eg 'net=5 ms=4'. Remember to enclose it in \"'s");
1417 if (argc > 2)
return false;
1428 DEF_CONSOLE_CMD(ConExit)
1441 DEF_CONSOLE_CMD(ConPart)
1444 IConsoleHelp(
"Leave the currently joined/running game (only ingame). Usage: 'part'");
1448 if (_game_mode != GM_NORMAL)
return false;
1454 DEF_CONSOLE_CMD(ConHelp)
1468 if (alias != NULL) {
1494 DEF_CONSOLE_CMD(ConListCommands)
1497 IConsoleHelp(
"List all registered commands. Usage: 'list_cmds [<pre-filter>]'");
1502 if (argv[1] == NULL || strstr(cmd->
name, argv[1]) != NULL) {
1510 DEF_CONSOLE_CMD(ConListAliases)
1513 IConsoleHelp(
"List all registered aliases. Usage: 'list_aliases [<pre-filter>]'");
1518 if (argv[1] == NULL || strstr(alias->
name, argv[1]) != NULL) {
1526 DEF_CONSOLE_CMD(ConCompanies)
1529 IConsoleHelp(
"List the details of all companies in the game. Usage 'companies'");
1534 FOR_ALL_COMPANIES(c) {
1536 char company_name[512];
1538 GetString(company_name, STR_COMPANY_NAME,
lastof(company_name));
1540 const char *password_state =
"";
1542 password_state =
"AI";
1544 #ifdef ENABLE_NETWORK
1552 IConsolePrintF(
CC_INFO,
"#:%d(%s) Company Name: '%s' Year Founded: %d Money: " OTTD_PRINTF64
" Loan: " OTTD_PRINTF64
" Value: " OTTD_PRINTF64
" (T:%d, R:%d, P:%d, S:%d) %s",
1553 c->
index + 1, colour, company_name,
1565 #ifdef ENABLE_NETWORK
1567 DEF_CONSOLE_CMD(ConSay)
1570 IConsoleHelp(
"Chat to your fellow players in a multiplayer game. Usage: 'say \"<msg>\"'");
1574 if (argc != 2)
return false;
1586 DEF_CONSOLE_CMD(ConSayCompany)
1589 IConsoleHelp(
"Chat to a certain company in a multiplayer game. Usage: 'say_company <company-no> \"<msg>\"'");
1590 IConsoleHelp(
"CompanyNo is the company that plays as company <companyno>, 1 through max_companies");
1594 if (argc != 3)
return false;
1612 DEF_CONSOLE_CMD(ConSayClient)
1615 IConsoleHelp(
"Chat to a certain client in a multiplayer game. Usage: 'say_client <client-no> \"<msg>\"'");
1616 IConsoleHelp(
"For client-id's, see the command 'clients'");
1620 if (argc != 3)
return false;
1632 DEF_CONSOLE_CMD(ConCompanyPassword)
1635 const char *helpmsg;
1638 helpmsg =
"Change the password of a company. Usage: 'company_pw <company-no> \"<password>\"";
1640 helpmsg =
"Change the password of your or any other company. Usage: 'company_pw [<company-no>] \"<password>\"'";
1642 helpmsg =
"Change the password of your company. Usage: 'company_pw \"<password>\"'";
1651 const char *password;
1652 const char *errormsg;
1657 errormsg =
"You have to own a company to make use of this command.";
1659 company_id = (
CompanyID)(atoi(argv[1]) - 1);
1661 errormsg =
"You have to specify the ID of a valid human controlled company.";
1683 #if defined(WITH_ZLIB)
1689 static const char *
const inv_lookup[] = {
"",
"base",
"newgrf",
"ai",
"ailib",
"scenario",
"heightmap" };
1690 for (uint i = 1 ; i <
lengthof(inv_lookup); i++) {
1691 if (strcasecmp(str, inv_lookup[i]) == 0)
return (
ContentType)i;
1720 static const char *
const types[] = {
"Base graphics",
"NewGRF",
"AI",
"AI library",
"Scenario",
"Heightmap",
"Base sound",
"Base music",
"Game script",
"GS library" };
1722 static const char *
const states[] = {
"Not selected",
"Selected",
"Dep Selected",
"Installed",
"Unknown" };
1725 char buf[
sizeof(ci->
md5sum) * 2 + 1];
1727 IConsolePrintF(state_to_colour[ci->
state],
"%d, %s, %s, %s, %08X, %s", ci->
id, types[ci->
type - 1], states[ci->
state], ci->
name, ci->
unique_id, buf);
1730 DEF_CONSOLE_CMD(ConContent)
1739 IConsoleHelp(
"Query, select and download content. Usage: 'content update|upgrade|select [all|id]|unselect [all|id]|state [filter]|download'");
1740 IConsoleHelp(
" update: get a new list of downloadable content; must be run first");
1741 IConsoleHelp(
" upgrade: select all items that are upgrades");
1742 IConsoleHelp(
" select: select a specific item given by its id or 'all' to select all. If no parameter is given, all selected content will be listed");
1743 IConsoleHelp(
" unselect: unselect a specific item given by its id or 'all' to unselect all");
1744 IConsoleHelp(
" state: show the download/select state of all downloadable content. Optionally give a filter string");
1745 IConsoleHelp(
" download: download all content you've selected");
1749 if (strcasecmp(argv[1],
"update") == 0) {
1754 if (strcasecmp(argv[1],
"upgrade") == 0) {
1759 if (strcasecmp(argv[1],
"select") == 0) {
1767 }
else if (strcasecmp(argv[2],
"all") == 0) {
1775 if (strcasecmp(argv[1],
"unselect") == 0) {
1780 if (strcasecmp(argv[2],
"all") == 0) {
1788 if (strcasecmp(argv[1],
"state") == 0) {
1791 if (argc > 2 && strcasestr((*iter)->name, argv[2]) == NULL)
continue;
1797 if (strcasecmp(argv[1],
"download") == 0) {
1810 DEF_CONSOLE_CMD(ConSetting)
1813 IConsoleHelp(
"Change setting for all clients. Usage: 'setting <name> [<value>]'");
1814 IConsoleHelp(
"Omitting <value> will print out the current value of the setting.");
1818 if (argc == 1 || argc > 3)
return false;
1823 IConsoleSetSetting(argv[1], argv[2]);
1829 DEF_CONSOLE_CMD(ConSettingNewgame)
1832 IConsoleHelp(
"Change setting for the next game. Usage: 'setting_newgame <name> [<value>]'");
1833 IConsoleHelp(
"Omitting <value> will print out the current value of the setting.");
1837 if (argc == 1 || argc > 3)
return false;
1842 IConsoleSetSetting(argv[1], argv[2],
true);
1848 DEF_CONSOLE_CMD(ConListSettings)
1851 IConsoleHelp(
"List settings. Usage: 'list_settings [<pre-filter>]'");
1855 if (argc > 2)
return false;
1861 DEF_CONSOLE_CMD(ConGamelogPrint)
1867 DEF_CONSOLE_CMD(ConNewGRFReload)
1870 IConsoleHelp(
"Reloads all active NewGRFs from disk. Equivalent to reapplying NewGRFs via the settings, but without asking for confirmation. This might crash OpenTTD!");
1883 static void IConsoleDebugLibRegister()
1895 void IConsoleStdLibRegister()
1957 #ifdef ENABLE_NETWORK
1959 #if defined(WITH_ZLIB)
2019 IConsoleDebugLibRegister();