41 #include "table/strings.h"
49 #define DEF_CONSOLE_CMD(function) static bool function(byte argc, char *argv[])
50 #define DEF_CONSOLE_HOOK(function) static ConsoleHookResult function(bool echo)
66 if (echo)
IConsoleError(
"You cannot use this command because there is no network available.");
76 DEF_CONSOLE_HOOK(ConHookServerOnly)
81 if (echo)
IConsoleError(
"This command is only available to a network server.");
91 DEF_CONSOLE_HOOK(ConHookClientOnly)
96 if (echo)
IConsoleError(
"This command is not available to a network server.");
106 DEF_CONSOLE_HOOK(ConHookNeedNetwork)
111 if (echo)
IConsoleError(
"Not connected. This command is only available in multiplayer.");
121 DEF_CONSOLE_HOOK(ConHookNoNetwork)
124 if (echo)
IConsoleError(
"This command is forbidden in multiplayer.");
131 # define ConHookNoNetwork NULL
134 DEF_CONSOLE_HOOK(ConHookNewGRFDeveloperTool)
137 if (_game_mode == GM_MENU) {
138 if (echo)
IConsoleError(
"This command is only available in game and editor.");
141 #ifdef ENABLE_NETWORK
142 return ConHookNoNetwork(echo);
163 DEF_CONSOLE_CMD(ConResetEngines)
166 IConsoleHelp(
"Reset status data of all engines. This might solve some issues with 'lost' engines. Usage: 'resetengines'");
179 DEF_CONSOLE_CMD(ConResetEnginePool)
182 IConsoleHelp(
"Reset NewGRF allocations of engine slots. This will remove invalid engine definitions, and might make default engines available again.");
186 if (_game_mode == GM_MENU) {
187 IConsoleError(
"This command is only available in game and editor.");
192 IConsoleError(
"This can only be done when there are no vehicles in the game.");
205 DEF_CONSOLE_CMD(ConResetTile)
208 IConsoleHelp(
"Reset a tile to bare land. Usage: 'resettile <tile>'");
209 IConsoleHelp(
"Tile can be either decimal (34161) or hexadecimal (0x4a5B)");
234 DEF_CONSOLE_CMD(ConScrollToTile)
239 IConsoleHelp(
"Usage: 'scrollto <tile>' or 'scrollto <x> <y>'");
240 IConsoleHelp(
"Numbers can be either decimal (34161) or hexadecimal (0x4a5B).");
278 DEF_CONSOLE_CMD(ConSave)
281 IConsoleHelp(
"Save the current game. Usage: 'save <filename>'");
286 char *filename =
str_fmt(
"%s.sav", argv[1]);
305 DEF_CONSOLE_CMD(ConSaveConfig)
308 IConsoleHelp(
"Saves the configuration for new games to the configuration file, typically 'openttd.cfg'.");
309 IConsoleHelp(
"It does not save the configuration of the current game to the configuration file.");
329 for (
const FiosItem *item = _fios_items.Begin(); item != _fios_items.End(); item++) {
330 if (strcmp(file, item->name) == 0)
return item;
331 if (strcmp(file, item->title) == 0)
return item;
336 int i = strtol(file, &endptr, 10);
337 if (file == endptr || *endptr !=
'\0') i = -1;
339 if (
IsInsideMM(i, 0, _fios_items.Length()))
return _fios_items.Get(i);
343 char long_file[MAX_PATH];
345 for (
const FiosItem *item = _fios_items.Begin(); item != _fios_items.End(); item++) {
346 if (strcmp(long_file, item->name) == 0)
return item;
347 if (strcmp(long_file, item->title) == 0)
return item;
354 DEF_CONSOLE_CMD(ConLoad)
357 IConsoleHelp(
"Load a game by name or index. Usage: 'load <file | number>'");
361 if (argc != 2)
return false;
363 const char *file = argv[1];
366 switch (item->type) {
367 case FIOS_TYPE_FILE:
case FIOS_TYPE_OLDFILE: {
369 SetFiosType(item->type);
386 DEF_CONSOLE_CMD(ConRemove)
389 IConsoleHelp(
"Remove a savegame by name or index. Usage: 'rm <file | number>'");
393 if (argc != 2)
return false;
395 const char *file = argv[1];
411 DEF_CONSOLE_CMD(ConListFiles)
414 IConsoleHelp(
"List all loadable savegames and directories in the current dir via console. Usage: 'ls | dir'");
420 for (uint i = 0; i < _fios_items.Length(); i++) {
429 DEF_CONSOLE_CMD(ConChangeDirectory)
432 IConsoleHelp(
"Change the dir via console. Usage: 'cd <directory | number>'");
436 if (argc != 2)
return false;
438 const char *file = argv[1];
441 switch (item->type) {
442 case FIOS_TYPE_DIR:
case FIOS_TYPE_DRIVE:
case FIOS_TYPE_PARENT:
455 DEF_CONSOLE_CMD(ConPrintWorkingDirectory)
460 IConsoleHelp(
"Print out the current working directory. Usage: 'pwd'");
473 DEF_CONSOLE_CMD(ConClearBuffer)
476 IConsoleHelp(
"Clear the console buffer. Usage: 'clear'");
480 IConsoleClearBuffer();
489 #ifdef ENABLE_NETWORK
491 static bool ConKickOrBan(
const char *argv,
bool ban)
495 if (strchr(argv,
'.') == NULL && strchr(argv,
':') == NULL) {
534 DEF_CONSOLE_CMD(ConKick)
537 IConsoleHelp(
"Kick a client from a network game. Usage: 'kick <ip | client-id>'");
538 IConsoleHelp(
"For client-id's, see the command 'clients'");
542 if (argc != 2)
return false;
544 return ConKickOrBan(argv[1],
false);
547 DEF_CONSOLE_CMD(ConBan)
550 IConsoleHelp(
"Ban a client from a network game. Usage: 'ban <ip | client-id>'");
551 IConsoleHelp(
"For client-id's, see the command 'clients'");
552 IConsoleHelp(
"If the client is no longer online, you can still ban his/her IP");
556 if (argc != 2)
return false;
558 return ConKickOrBan(argv[1],
true);
561 DEF_CONSOLE_CMD(ConUnBan)
565 IConsoleHelp(
"Unban a client from a network game. Usage: 'unban <ip | client-id>'");
566 IConsoleHelp(
"For a list of banned IP's, see the command 'banlist'");
570 if (argc != 2)
return false;
572 uint
index = (strchr(argv[1],
'.') == NULL) ? atoi(argv[1]) : 0;
589 DEF_CONSOLE_CMD(ConBanList)
592 IConsoleHelp(
"List the IP's of banned clients: Usage 'banlist'");
606 DEF_CONSOLE_CMD(ConPauseGame)
623 DEF_CONSOLE_CMD(ConUnpauseGame)
626 IConsoleHelp(
"Unpause a network game. Usage: 'unpause'");
644 DEF_CONSOLE_CMD(ConRcon)
647 IConsoleHelp(
"Remote control the server from another client. Usage: 'rcon <password> <command>'");
648 IConsoleHelp(
"Remember to enclose the command in quotes, otherwise only the first parameter is sent");
652 if (argc < 3)
return false;
662 DEF_CONSOLE_CMD(ConStatus)
665 IConsoleHelp(
"List the status of all clients connected to the server. Usage 'status'");
673 DEF_CONSOLE_CMD(ConServerInfo)
676 IConsoleHelp(
"List current and maximum client/company limits. Usage 'server_info'");
677 IConsoleHelp(
"You can change these values by modifying settings 'network.max_clients', 'network.max_companies' and 'network.max_spectators'");
688 DEF_CONSOLE_CMD(ConClientNickChange)
691 IConsoleHelp(
"Change the nickname of a connected client. Usage: 'client_name <client-id> <new-name>'");
692 IConsoleHelp(
"For client-id's, see the command 'clients'");
699 IConsoleError(
"Please use the command 'name' to change your own name!");
715 DEF_CONSOLE_CMD(ConJoinCompany)
718 IConsoleHelp(
"Request joining another company. Usage: join <company-id> [<password>]");
719 IConsoleHelp(
"For valid company-id see company list, use 255 for spectator");
737 IConsoleError(
"Cannot join spectators, maximum number of spectators reached.");
762 DEF_CONSOLE_CMD(ConMoveClient)
765 IConsoleHelp(
"Move a client to another company. Usage: move <client-id> <company-id>");
766 IConsoleHelp(
"For valid client-id see 'clients', for valid company-id see 'companies', use 255 for moving to spectators");
775 IConsoleError(
"Invalid client-id, check the command 'clients' for valid client-id's.");
795 IConsoleError(
"You cannot move someone to where he/she already is!");
805 DEF_CONSOLE_CMD(ConResetCompany)
808 IConsoleHelp(
"Remove an idle company from the game. Usage: 'reset_company <company-id>'");
809 IConsoleHelp(
"For company-id's, see the list of companies from the dropdown menu. Company 1 is 1, etc.");
813 if (argc != 2)
return false;
829 IConsoleError(
"Cannot remove company: a client is connected to that company.");
834 IConsoleError(
"Cannot remove company: the server is connected to that company.");
845 DEF_CONSOLE_CMD(ConNetworkClients)
848 IConsoleHelp(
"Get a list of connected clients including their ID, name, company-id, and IP. Usage: 'clients'");
857 DEF_CONSOLE_CMD(ConNetworkReconnect)
860 IConsoleHelp(
"Reconnect to server to which you were connected last time. Usage: 'reconnect [<company>]'");
861 IConsoleHelp(
"Company 255 is spectator (default, if not specified), 0 means creating new company.");
862 IConsoleHelp(
"All others are a certain company with Company 1 being #1");
874 if (playas < COMPANY_FIRST || playas >=
MAX_COMPANIES)
return false;
890 DEF_CONSOLE_CMD(ConNetworkConnect)
893 IConsoleHelp(
"Connect to a remote OTTD server and join the game. Usage: 'connect <ip>'");
894 IConsoleHelp(
"IP can contain port and company: 'IP[:Port][#Company]', eg: 'server.ottd.org:443#2'");
895 IConsoleHelp(
"Company #255 is spectator all others are a certain company with Company 1 being #1");
899 if (argc < 2)
return false;
902 const char *port = NULL;
903 const char *company = NULL;
912 if (company != NULL) {
939 DEF_CONSOLE_CMD(ConExec)
942 IConsoleHelp(
"Execute a local script file. Usage: 'exec <script> <?>'");
946 if (argc < 2)
return false;
950 if (script_file == NULL) {
951 if (argc == 2 || atoi(argv[2]) != 0)
IConsoleError(
"script file not found");
958 while (
_script_running && fgets(cmdline,
sizeof(cmdline), script_file) != NULL) {
960 for (
char *cmdptr = cmdline; *cmdptr !=
'\0'; cmdptr++) {
961 if (*cmdptr ==
'\n' || *cmdptr ==
'\r') {
969 if (ferror(script_file)) {
970 IConsoleError(
"Encountered error while trying to read from script file");
978 DEF_CONSOLE_CMD(ConReturn)
981 IConsoleHelp(
"Stop executing a running script. Usage: 'return'");
992 extern bool CloseConsoleLogIfActive();
994 DEF_CONSOLE_CMD(ConScript)
996 extern FILE *_iconsole_output_file;
999 IConsoleHelp(
"Start or stop logging console output to a file. Usage: 'script <filename>'");
1000 IConsoleHelp(
"If filename is omitted, a running log is stopped if it is active");
1004 if (!CloseConsoleLogIfActive()) {
1005 if (argc < 2)
return false;
1008 _iconsole_output_file = fopen(argv[1],
"ab");
1009 if (_iconsole_output_file == NULL)
IConsoleError(
"could not open file");
1016 DEF_CONSOLE_CMD(ConEcho)
1019 IConsoleHelp(
"Print back the first argument to the console. Usage: 'echo <arg>'");
1023 if (argc < 2)
return false;
1028 DEF_CONSOLE_CMD(ConEchoC)
1031 IConsoleHelp(
"Print back the first argument to the console in a given colour. Usage: 'echoc <colour> <arg2>'");
1035 if (argc < 3)
return false;
1040 DEF_CONSOLE_CMD(ConNewGame)
1043 IConsoleHelp(
"Start a new game. Usage: 'newgame [seed]'");
1044 IConsoleHelp(
"The server can force a new game using 'newgame'; any client joined will rejoin after the server is done generating the new game.");
1052 DEF_CONSOLE_CMD(ConRestart)
1056 IConsoleHelp(
"Restarts a game. It tries to reproduce the exact same map as the game started with.");
1058 IConsoleHelp(
" * restarting games started in another version might create another map due to difference in map generation");
1059 IConsoleHelp(
" * restarting games based on scenarios, loaded games or heightmaps will start a new game based on the settings stored in the scenario/savegame");
1079 for (
char *p2 = buf; *p2 !=
'\0'; p2++) {
1088 DEF_CONSOLE_CMD(ConListAILibs)
1098 DEF_CONSOLE_CMD(ConListAI)
1108 DEF_CONSOLE_CMD(ConListGameLibs)
1118 DEF_CONSOLE_CMD(ConListGame)
1128 DEF_CONSOLE_CMD(ConStartAI)
1130 if (argc == 0 || argc > 3) {
1131 IConsoleHelp(
"Start a new AI. Usage: 'start_ai [<AI>] [<settings>]'");
1132 IConsoleHelp(
"Start a new AI. If <AI> is given, it starts that specific AI (if found).");
1133 IConsoleHelp(
"If <settings> is given, it is parsed and the AI settings are set to that.");
1137 if (_game_mode != GM_NORMAL) {
1151 IConsoleWarning(
"AIs are not allowed in multiplayer by configuration.");
1163 FOR_ALL_COMPANIES(c) {
1164 if (c->
index != n)
break;
1170 config->
Change(argv[1], -1,
true);
1186 DEF_CONSOLE_CMD(ConReloadAI)
1189 IConsoleHelp(
"Reload an AI. Usage: 'reload_ai <company-id>'");
1190 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.");
1194 if (_game_mode != GM_NORMAL) {
1223 DEF_CONSOLE_CMD(ConStopAI)
1226 IConsoleHelp(
"Stop an AI. Usage: 'stop_ai <company-id>'");
1227 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.");
1231 if (_game_mode != GM_NORMAL) {
1259 DEF_CONSOLE_CMD(ConRescanAI)
1262 IConsoleHelp(
"Rescan the AI dir for scripts. Usage: 'rescan_ai'");
1267 IConsoleWarning(
"Only the server can rescan the AI dir for scripts.");
1276 DEF_CONSOLE_CMD(ConRescanGame)
1279 IConsoleHelp(
"Rescan the Game Script dir for scripts. Usage: 'rescan_game'");
1284 IConsoleWarning(
"Only the server can rescan the Game Script dir for scripts.");
1293 DEF_CONSOLE_CMD(ConRescanNewGRF)
1296 IConsoleHelp(
"Rescan the data dir for NewGRFs. Usage: 'rescan_newgrf'");
1305 DEF_CONSOLE_CMD(ConGetSeed)
1308 IConsoleHelp(
"Returns the seed used to create this game. Usage: 'getseed'");
1309 IConsoleHelp(
"The seed can be used to reproduce the exact same map as the game started with.");
1317 DEF_CONSOLE_CMD(ConGetDate)
1320 IConsoleHelp(
"Returns the current date (day-month-year) of the game. Usage: 'getdate'");
1331 DEF_CONSOLE_CMD(ConAlias)
1336 IConsoleHelp(
"Add a new alias, or redefine the behaviour of an existing alias . Usage: 'alias <name> <command>'");
1340 if (argc < 3)
return false;
1343 if (alias == NULL) {
1352 DEF_CONSOLE_CMD(ConScreenShot)
1355 IConsoleHelp(
"Create a screenshot of the game. Usage: 'screenshot [big | giant | no_con] [file name]'");
1356 IConsoleHelp(
"'big' makes a zoomed-in screenshot of the visible area, 'giant' makes a screenshot of the "
1357 "whole map, 'no_con' hides the console to create the screenshot. 'big' or 'giant' "
1358 "screenshots are always drawn without console");
1362 if (argc > 3)
return false;
1365 const char *
name = NULL;
1368 if (strcmp(argv[1],
"big") == 0) {
1371 if (argc > 2) name = argv[2];
1372 }
else if (strcmp(argv[1],
"giant") == 0) {
1375 if (argc > 2) name = argv[2];
1376 }
else if (strcmp(argv[1],
"no_con") == 0) {
1379 if (argc > 2) name = argv[2];
1380 }
else if (argc == 2) {
1393 DEF_CONSOLE_CMD(ConInfoCmd)
1396 IConsoleHelp(
"Print out debugging information about a command. Usage: 'info_cmd <cmd>'");
1400 if (argc < 2)
return false;
1416 DEF_CONSOLE_CMD(ConDebugLevel)
1419 IConsoleHelp(
"Get/set the default debugging level for the game. Usage: 'debug_level [<level>]'");
1420 IConsoleHelp(
"Level can be any combination of names, levels. Eg 'net=5 ms=4'. Remember to enclose it in \"'s");
1424 if (argc > 2)
return false;
1435 DEF_CONSOLE_CMD(ConExit)
1448 DEF_CONSOLE_CMD(ConPart)
1451 IConsoleHelp(
"Leave the currently joined/running game (only ingame). Usage: 'part'");
1455 if (_game_mode != GM_NORMAL)
return false;
1461 DEF_CONSOLE_CMD(ConHelp)
1475 if (alias != NULL) {
1501 DEF_CONSOLE_CMD(ConListCommands)
1504 IConsoleHelp(
"List all registered commands. Usage: 'list_cmds [<pre-filter>]'");
1509 if (argv[1] == NULL || strstr(cmd->
name, argv[1]) != NULL) {
1517 DEF_CONSOLE_CMD(ConListAliases)
1520 IConsoleHelp(
"List all registered aliases. Usage: 'list_aliases [<pre-filter>]'");
1525 if (argv[1] == NULL || strstr(alias->
name, argv[1]) != NULL) {
1533 DEF_CONSOLE_CMD(ConCompanies)
1536 IConsoleHelp(
"List the details of all companies in the game. Usage 'companies'");
1541 FOR_ALL_COMPANIES(c) {
1543 char company_name[512];
1545 GetString(company_name, STR_COMPANY_NAME,
lastof(company_name));
1547 const char *password_state =
"";
1549 password_state =
"AI";
1551 #ifdef ENABLE_NETWORK
1559 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",
1560 c->
index + 1, colour, company_name,
1572 #ifdef ENABLE_NETWORK
1574 DEF_CONSOLE_CMD(ConSay)
1577 IConsoleHelp(
"Chat to your fellow players in a multiplayer game. Usage: 'say \"<msg>\"'");
1581 if (argc != 2)
return false;
1593 DEF_CONSOLE_CMD(ConSayCompany)
1596 IConsoleHelp(
"Chat to a certain company in a multiplayer game. Usage: 'say_company <company-no> \"<msg>\"'");
1597 IConsoleHelp(
"CompanyNo is the company that plays as company <companyno>, 1 through max_companies");
1601 if (argc != 3)
return false;
1619 DEF_CONSOLE_CMD(ConSayClient)
1622 IConsoleHelp(
"Chat to a certain client in a multiplayer game. Usage: 'say_client <client-no> \"<msg>\"'");
1623 IConsoleHelp(
"For client-id's, see the command 'clients'");
1627 if (argc != 3)
return false;
1639 DEF_CONSOLE_CMD(ConCompanyPassword)
1642 const char *helpmsg;
1645 helpmsg =
"Change the password of a company. Usage: 'company_pw <company-no> \"<password>\"";
1647 helpmsg =
"Change the password of your or any other company. Usage: 'company_pw [<company-no>] \"<password>\"'";
1649 helpmsg =
"Change the password of your company. Usage: 'company_pw \"<password>\"'";
1658 const char *password;
1659 const char *errormsg;
1664 errormsg =
"You have to own a company to make use of this command.";
1666 company_id = (
CompanyID)(atoi(argv[1]) - 1);
1668 errormsg =
"You have to specify the ID of a valid human controlled company.";
1690 #if defined(WITH_ZLIB)
1696 static const char *
const inv_lookup[] = {
"",
"base",
"newgrf",
"ai",
"ailib",
"scenario",
"heightmap" };
1697 for (uint i = 1 ; i <
lengthof(inv_lookup); i++) {
1698 if (strcasecmp(str, inv_lookup[i]) == 0)
return (
ContentType)i;
1727 static const char *
const types[] = {
"Base graphics",
"NewGRF",
"AI",
"AI library",
"Scenario",
"Heightmap",
"Base sound",
"Base music",
"Game script",
"GS library" };
1729 static const char *
const states[] = {
"Not selected",
"Selected",
"Dep Selected",
"Installed",
"Unknown" };
1732 char buf[
sizeof(ci->
md5sum) * 2 + 1];
1734 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);
1737 DEF_CONSOLE_CMD(ConContent)
1746 IConsoleHelp(
"Query, select and download content. Usage: 'content update|upgrade|select [all|id]|unselect [all|id]|state [filter]|download'");
1747 IConsoleHelp(
" update: get a new list of downloadable content; must be run first");
1748 IConsoleHelp(
" upgrade: select all items that are upgrades");
1749 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");
1750 IConsoleHelp(
" unselect: unselect a specific item given by its id or 'all' to unselect all");
1751 IConsoleHelp(
" state: show the download/select state of all downloadable content. Optionally give a filter string");
1752 IConsoleHelp(
" download: download all content you've selected");
1756 if (strcasecmp(argv[1],
"update") == 0) {
1761 if (strcasecmp(argv[1],
"upgrade") == 0) {
1766 if (strcasecmp(argv[1],
"select") == 0) {
1774 }
else if (strcasecmp(argv[2],
"all") == 0) {
1782 if (strcasecmp(argv[1],
"unselect") == 0) {
1787 if (strcasecmp(argv[2],
"all") == 0) {
1795 if (strcasecmp(argv[1],
"state") == 0) {
1798 if (argc > 2 && strcasestr((*iter)->name, argv[2]) == NULL)
continue;
1804 if (strcasecmp(argv[1],
"download") == 0) {
1817 DEF_CONSOLE_CMD(ConSetting)
1820 IConsoleHelp(
"Change setting for all clients. Usage: 'setting <name> [<value>]'");
1821 IConsoleHelp(
"Omitting <value> will print out the current value of the setting.");
1825 if (argc == 1 || argc > 3)
return false;
1830 IConsoleSetSetting(argv[1], argv[2]);
1836 DEF_CONSOLE_CMD(ConSettingNewgame)
1839 IConsoleHelp(
"Change setting for the next game. Usage: 'setting_newgame <name> [<value>]'");
1840 IConsoleHelp(
"Omitting <value> will print out the current value of the setting.");
1844 if (argc == 1 || argc > 3)
return false;
1849 IConsoleSetSetting(argv[1], argv[2],
true);
1855 DEF_CONSOLE_CMD(ConListSettings)
1858 IConsoleHelp(
"List settings. Usage: 'list_settings [<pre-filter>]'");
1862 if (argc > 2)
return false;
1868 DEF_CONSOLE_CMD(ConGamelogPrint)
1874 DEF_CONSOLE_CMD(ConNewGRFReload)
1877 IConsoleHelp(
"Reloads all active NewGRFs from disk. Equivalent to reapplying NewGRFs via the settings, but without asking for confirmation. This might crash OpenTTD!");
1890 static void IConsoleDebugLibRegister()
1902 void IConsoleStdLibRegister()
1964 #ifdef ENABLE_NETWORK
1966 #if defined(WITH_ZLIB)
2026 IConsoleDebugLibRegister();