# console_cmds.cpp

Go to the documentation of this file.

    00001 /* $Id: console_cmds.cpp 19376 2010-03-08 22:19:39Z rubidium $ */
    00002
    00003 /*
    00004  * This file is part of OpenTTD.
    00005  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
    00006  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    00007  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
    00008  */
    00009
    00012 #include "stdafx.h"
    00013 #include "console_internal.h"
    00014 #include "debug.h"
    00015 #include "engine_func.h"
    00016 #include "landscape.h"
    00017 #include "saveload/saveload.h"
    00018 #include "network/network.h"
    00019 #include "network/network_func.h"
    00020 #include "network/network_base.h"
    00021 #include "command_func.h"
    00022 #include "settings_func.h"
    00023 #include "fios.h"
    00024 #include "fileio_func.h"
    00025 #include "screenshot.h"
    00026 #include "genworld.h"
    00027 #include "strings_func.h"
    00028 #include "viewport_func.h"
    00029 #include "window_func.h"
    00030 #include "date_func.h"
    00031 #include "vehicle_func.h"
    00032 #include "company_func.h"
    00033 #include "company_base.h"
    00034 #include "gamelog.h"
    00035 #include "ai/ai.hpp"
    00036 #include "ai/ai_config.hpp"
    00037 #include "console_func.h"
    00038
    00039 #ifdef ENABLE_NETWORK
    00040   #include "table/strings.h"
    00041 #endif /* ENABLE_NETWORK */
    00042
    00043 /* scriptfile handling */
    00044 static FILE *_script_file;
    00045 static bool _script_running;
    00046
    00047 /* console command defines */
    00048 #define DEF_CONSOLE_CMD(function) static bool function(byte argc, char *argv[])
    00049 #define DEF_CONSOLE_HOOK(function) static bool function()
    00050
    00051
    00052 /****************
    00053  * command hooks
    00054  ****************/
    00055
    00056 #ifdef ENABLE_NETWORK
    00057
    00058 static inline bool NetworkAvailable()
    00059 {
    00060   if (!_network_available) {
    00061     IConsoleError("You cannot use this command because there is no network available.");
    00062     return false;
    00063   }
    00064   return true;
    00065 }
    00066
    00067 DEF_CONSOLE_HOOK(ConHookServerOnly)
    00068 {
    00069   if (!NetworkAvailable()) return false;
    00070
    00071   if (!_network_server) {
    00072     IConsoleError("This command is only available to a network server.");
    00073     return false;
    00074   }
    00075   return true;
    00076 }
    00077
    00078 DEF_CONSOLE_HOOK(ConHookClientOnly)
    00079 {
    00080   if (!NetworkAvailable()) return false;
    00081
    00082   if (_network_server) {
    00083     IConsoleError("This command is not available to a network server.");
    00084     return false;
    00085   }
    00086   return true;
    00087 }
    00088
    00089 DEF_CONSOLE_HOOK(ConHookNeedNetwork)
    00090 {
    00091   if (!NetworkAvailable()) return false;
    00092
    00093   if (!_networking) {
    00094     IConsoleError("Not connected. This command is only available in multiplayer.");
    00095     return false;
    00096   }
    00097   return true;
    00098 }
    00099
    00100 DEF_CONSOLE_HOOK(ConHookNoNetwork)
    00101 {
    00102   if (_networking) {
    00103     IConsoleError("This command is forbidden in multiplayer.");
    00104     return false;
    00105   }
    00106   return true;
    00107 }
    00108
    00109 #else
    00110 # define ConHookNoNetwork NULL
    00111 #endif /* ENABLE_NETWORK */
    00112
    00113 static void IConsoleHelp(const char *str)
    00114 {
    00115   IConsolePrintF(CC_WARNING, "- %s", str);
    00116 }
    00117
    00118 DEF_CONSOLE_CMD(ConResetEngines)
    00119 {
    00120   if (argc == 0) {
    00121     IConsoleHelp("Reset status data of all engines. This might solve some issues with 'lost' engines. Usage: 'resetengines'");
    00122     return true;
    00123   }
    00124
    00125   StartupEngines();
    00126   return true;
    00127 }
    00128
    00129 #ifdef _DEBUG
    00130 DEF_CONSOLE_CMD(ConResetTile)
    00131 {
    00132   if (argc == 0) {
    00133     IConsoleHelp("Reset a tile to bare land. Usage: 'resettile <tile>'");
    00134     IConsoleHelp("Tile can be either decimal (34161) or hexadecimal (0x4a5B)");
    00135     return true;
    00136   }
    00137
    00138   if (argc == 2) {
    00139     uint32 result;
    00140     if (GetArgumentInteger(&result, argv[1])) {
    00141       DoClearSquare((TileIndex)result);
    00142       return true;
    00143     }
    00144   }
    00145
    00146   return false;
    00147 }
    00148
    00149 DEF_CONSOLE_CMD(ConStopAllVehicles)
    00150 {
    00151   if (argc == 0) {
    00152     IConsoleHelp("Stops all vehicles in the game. For debugging only! Use at your own risk... Usage: 'stopall'");
    00153     return true;
    00154   }
    00155
    00156   StopAllVehicles();
    00157   return true;
    00158 }
    00159 #endif /* _DEBUG */
    00160
    00161 DEF_CONSOLE_CMD(ConScrollToTile)
    00162 {
    00163   switch (argc) {
    00164     case 0:
    00165       IConsoleHelp("Center the screen on a given tile.");
    00166       IConsoleHelp("Usage: 'scrollto <tile>' or 'scrollto <x> <y>'");
    00167       IConsoleHelp("Numbers can be either decimal (34161) or hexadecimal (0x4a5B).");
    00168       return true;
    00169
    00170     case 2: {
    00171       uint32 result;
    00172       if (GetArgumentInteger(&result, argv[1])) {
    00173         if (result >= MapSize()) {
    00174           IConsolePrint(CC_ERROR, "Tile does not exist");
    00175           return true;
    00176         }
    00177         ScrollMainWindowToTile((TileIndex)result);
    00178         return true;
    00179       }
    00180       break;
    00181     }
    00182
    00183     case 3: {
    00184       uint32 x, y;
    00185       if (GetArgumentInteger(&x, argv[1]) && GetArgumentInteger(&y, argv[2])) {
    00186         if (x >= MapSizeX() || y >= MapSizeY()) {
    00187           IConsolePrint(CC_ERROR, "Tile does not exist");
    00188           return true;
    00189         }
    00190         ScrollMainWindowToTile(TileXY(x, y));
    00191         return true;
    00192       }
    00193       break;
    00194     }
    00195   }
    00196
    00197   return false;
    00198 }
    00199
    00200 extern void BuildFileList();
    00201 extern void SetFiosType(const byte fiostype);
    00202
    00203 /* Save the map to a file */
    00204 DEF_CONSOLE_CMD(ConSave)
    00205 {
    00206   if (argc == 0) {
    00207     IConsoleHelp("Save the current game. Usage: 'save <filename>'");
    00208     return true;
    00209   }
    00210
    00211   if (argc == 2) {
    00212     char *filename = str_fmt("%s.sav", argv[1]);
    00213     IConsolePrint(CC_DEFAULT, "Saving map...");
    00214
    00215     if (SaveOrLoad(filename, SL_SAVE, SAVE_DIR) != SL_OK) {
    00216       IConsolePrint(CC_ERROR, "Saving map failed");
    00217     } else {
    00218       IConsolePrintF(CC_DEFAULT, "Map successfully saved to %s", filename);
    00219     }
    00220     free(filename);
    00221     return true;
    00222   }
    00223
    00224   return false;
    00225 }
    00226
    00227 /* Explicitly save the configuration */
    00228 DEF_CONSOLE_CMD(ConSaveConfig)
    00229 {
    00230   if (argc == 0) {
    00231     IConsoleHelp("Saves the current config, typically to 'openttd.cfg'.");
    00232     return true;
    00233   }
    00234
    00235   SaveToConfig();
    00236   IConsolePrint(CC_DEFAULT, "Saved config.");
    00237   return true;
    00238 }
    00239
    00240 static const FiosItem *GetFiosItem(const char *file)
    00241 {
    00242   _saveload_mode = SLD_LOAD_GAME;
    00243   BuildFileList();
    00244
    00245   for (const FiosItem *item = _fios_items.Begin(); item != _fios_items.End(); item++) {
    00246     if (strcmp(file, item->name) == 0) return item;
    00247     if (strcmp(file, item->title) == 0) return item;
    00248   }
    00249
    00250   /* If no name matches, try to parse it as number */
    00251   char *endptr;
    00252   int i = strtol(file, &endptr, 10);
    00253   if (file == endptr || *endptr != '\0') i = -1;
    00254
    00255   return IsInsideMM(i, 0, _fios_items.Length()) ? _fios_items.Get(i) : NULL;
    00256 }
    00257
    00258
    00259 DEF_CONSOLE_CMD(ConLoad)
    00260 {
    00261   if (argc == 0) {
    00262     IConsoleHelp("Load a game by name or index. Usage: 'load <file | number>'");
    00263     return true;
    00264   }
    00265
    00266   if (argc != 2) return false;
    00267
    00268   const char *file = argv[1];
    00269   const FiosItem *item = GetFiosItem(file);
    00270   if (item != NULL) {
    00271     switch (item->type) {
    00272       case FIOS_TYPE_FILE: case FIOS_TYPE_OLDFILE: {
    00273         _switch_mode = SM_LOAD;
    00274         SetFiosType(item->type);
    00275
    00276         strecpy(_file_to_saveload.name, FiosBrowseTo(item), lastof(_file_to_saveload.name));
    00277         strecpy(_file_to_saveload.title, item->title, lastof(_file_to_saveload.title));
    00278       } break;
    00279       default: IConsolePrintF(CC_ERROR, "%s: Not a savegame.", file);
    00280     }
    00281   } else {
    00282     IConsolePrintF(CC_ERROR, "%s: No such file or directory.", file);
    00283   }
    00284
    00285   FiosFreeSavegameList();
    00286   return true;
    00287 }
    00288
    00289
    00290 DEF_CONSOLE_CMD(ConRemove)
    00291 {
    00292   if (argc == 0) {
    00293     IConsoleHelp("Remove a savegame by name or index. Usage: 'rm <file | number>'");
    00294     return true;
    00295   }
    00296
    00297   if (argc != 2) return false;
    00298
    00299   const char *file = argv[1];
    00300   const FiosItem *item = GetFiosItem(file);
    00301   if (item != NULL) {
    00302     if (!FiosDelete(item->name))
    00303       IConsolePrintF(CC_ERROR, "%s: Failed to delete file", file);
    00304   } else {
    00305     IConsolePrintF(CC_ERROR, "%s: No such file or directory.", file);
    00306   }
    00307
    00308   FiosFreeSavegameList();
    00309   return true;
    00310 }
    00311
    00312
    00313 /* List all the files in the current dir via console */
    00314 DEF_CONSOLE_CMD(ConListFiles)
    00315 {
    00316   if (argc == 0) {
    00317     IConsoleHelp("List all loadable savegames and directories in the current dir via console. Usage: 'ls | dir'");
    00318     return true;
    00319   }
    00320
    00321   BuildFileList();
    00322
    00323   for (uint i = 0; i < _fios_items.Length(); i++) {
    00324     IConsolePrintF(CC_DEFAULT, "%d) %s", i, _fios_items[i].title);
    00325   }
    00326
    00327   FiosFreeSavegameList();
    00328   return true;
    00329 }
    00330
    00331 /* Change the dir via console */
    00332 DEF_CONSOLE_CMD(ConChangeDirectory)
    00333 {
    00334   if (argc == 0) {
    00335     IConsoleHelp("Change the dir via console. Usage: 'cd <directory | number>'");
    00336     return true;
    00337   }
    00338
    00339   if (argc != 2) return false;
    00340
    00341   const char *file = argv[1];
    00342   const FiosItem *item = GetFiosItem(file);
    00343   if (item != NULL) {
    00344     switch (item->type) {
    00345       case FIOS_TYPE_DIR: case FIOS_TYPE_DRIVE: case FIOS_TYPE_PARENT:
    00346         FiosBrowseTo(item);
    00347         break;
    00348       default: IConsolePrintF(CC_ERROR, "%s: Not a directory.", file);
    00349     }
    00350   } else {
    00351     IConsolePrintF(CC_ERROR, "%s: No such file or directory.", file);
    00352   }
    00353
    00354   FiosFreeSavegameList();
    00355   return true;
    00356 }
    00357
    00358 DEF_CONSOLE_CMD(ConPrintWorkingDirectory)
    00359 {
    00360   const char *path;
    00361
    00362   if (argc == 0) {
    00363     IConsoleHelp("Print out the current working directory. Usage: 'pwd'");
    00364     return true;
    00365   }
    00366
    00367   /* XXX - Workaround for broken file handling */
    00368   FiosGetSavegameList(SLD_LOAD_GAME);
    00369   FiosFreeSavegameList();
    00370
    00371   FiosGetDescText(&path, NULL);
    00372   IConsolePrint(CC_DEFAULT, path);
    00373   return true;
    00374 }
    00375
    00376 DEF_CONSOLE_CMD(ConClearBuffer)
    00377 {
    00378   if (argc == 0) {
    00379     IConsoleHelp("Clear the console buffer. Usage: 'clear'");
    00380     return true;
    00381   }
    00382
    00383   IConsoleClearBuffer();
    00384   SetWindowDirty(WC_CONSOLE, 0);
    00385   return true;
    00386 }
    00387
    00388
    00389 /**********************************
    00390  * Network Core Console Commands
    00391  **********************************/
    00392 #ifdef ENABLE_NETWORK
    00393
    00394 DEF_CONSOLE_CMD(ConBan)
    00395 {
    00396   NetworkClientInfo *ci;
    00397   const char *banip = NULL;
    00398   ClientID client_id;
    00399
    00400   if (argc == 0) {
    00401     IConsoleHelp("Ban a client from a network game. Usage: 'ban <ip | client-id>'");
    00402     IConsoleHelp("For client-id's, see the command 'clients'");
    00403     IConsoleHelp("If the client is no longer online, you can still ban his/her IP");
    00404     return true;
    00405   }
    00406
    00407   if (argc != 2) return false;
    00408
    00409   if (strchr(argv[1], '.') == NULL && strchr(argv[1], ':') == NULL) { // banning with ID
    00410     client_id = (ClientID)atoi(argv[1]);
    00411     ci = NetworkFindClientInfoFromClientID(client_id);
    00412   } else { // banning IP
    00413     ci = NetworkFindClientInfoFromIP(argv[1]);
    00414     if (ci == NULL) {
    00415       banip = argv[1];
    00416       client_id = (ClientID)-1;
    00417     } else {
    00418       client_id = ci->client_id;
    00419     }
    00420   }
    00421
    00422   if (client_id == CLIENT_ID_SERVER) {
    00423     IConsoleError("Silly boy, you can not ban yourself!");
    00424     return true;
    00425   }
    00426
    00427   if (client_id == INVALID_CLIENT_ID || (ci == NULL && client_id != (ClientID)-1)) {
    00428     IConsoleError("Invalid client");
    00429     return true;
    00430   }
    00431
    00432   if (ci != NULL) {
    00433     IConsolePrint(CC_DEFAULT, "Client banned");
    00434     banip = GetClientIP(ci);
    00435   } else {
    00436     IConsolePrint(CC_DEFAULT, "Client not online, banned IP");
    00437   }
    00438
    00439   NetworkServerBanIP(banip);
    00440
    00441   return true;
    00442 }
    00443
    00444 DEF_CONSOLE_CMD(ConUnBan)
    00445 {
    00446
    00447   if (argc == 0) {
    00448     IConsoleHelp("Unban a client from a network game. Usage: 'unban <ip | client-id>'");
    00449     IConsoleHelp("For a list of banned IP's, see the command 'banlist'");
    00450     return true;
    00451   }
    00452
    00453   if (argc != 2) return false;
    00454
    00455   uint index = (strchr(argv[1], '.') == NULL) ? atoi(argv[1]) : 0;
    00456   index--;
    00457   uint i = 0;
    00458
    00459   for (char **iter = _network_ban_list.Begin(); iter != _network_ban_list.End(); iter++, i++) {
    00460     if (strcmp(_network_ban_list[i], argv[1]) == 0 || index == i) {
    00461       free(_network_ban_list[i]);
    00462       _network_ban_list.Erase(iter);
    00463       IConsolePrint(CC_DEFAULT, "IP unbanned.");
    00464       return true;
    00465     }
    00466   }
    00467
    00468   IConsolePrint(CC_DEFAULT, "IP not in ban-list.");
    00469   return true;
    00470 }
    00471
    00472 DEF_CONSOLE_CMD(ConBanList)
    00473 {
    00474   if (argc == 0) {
    00475     IConsoleHelp("List the IP's of banned clients: Usage 'banlist'");
    00476     return true;
    00477   }
    00478
    00479   IConsolePrint(CC_DEFAULT, "Banlist: ");
    00480
    00481   uint i = 1;
    00482   for (char **iter = _network_ban_list.Begin(); iter != _network_ban_list.End(); iter++, i++) {
    00483     IConsolePrintF(CC_DEFAULT, "  %d) %s", i, *iter);
    00484   }
    00485
    00486   return true;
    00487 }
    00488
    00489 DEF_CONSOLE_CMD(ConPauseGame)
    00490 {
    00491   if (argc == 0) {
    00492     IConsoleHelp("Pause a network game. Usage: 'pause'");
    00493     return true;
    00494   }
    00495
    00496   if ((_pause_mode & PM_PAUSED_NORMAL) == PM_UNPAUSED) {
    00497     DoCommandP(0, PM_PAUSED_NORMAL, 1, CMD_PAUSE);
    00498     if (!_networking) IConsolePrint(CC_DEFAULT, "Game paused.");
    00499   } else {
    00500     IConsolePrint(CC_DEFAULT, "Game is already paused.");
    00501   }
    00502
    00503   return true;
    00504 }
    00505
    00506 DEF_CONSOLE_CMD(ConUnPauseGame)
    00507 {
    00508   if (argc == 0) {
    00509     IConsoleHelp("Unpause a network game. Usage: 'unpause'");
    00510     return true;
    00511   }
    00512
    00513   if ((_pause_mode & PM_PAUSED_NORMAL) != PM_UNPAUSED) {
    00514     DoCommandP(0, PM_PAUSED_NORMAL, 0, CMD_PAUSE);
    00515     if (!_networking) IConsolePrint(CC_DEFAULT, "Game unpaused.");
    00516   } else if ((_pause_mode & PM_PAUSED_ERROR) != PM_UNPAUSED) {
    00517     IConsolePrint(CC_DEFAULT, "Game is in error state and cannot be unpaused via console.");
    00518   } else if (_pause_mode != PM_UNPAUSED) {
    00519     IConsolePrint(CC_DEFAULT, "Game cannot be unpaused manually; disable pause_on_join/min_active_clients.");
    00520   } else {
    00521     IConsolePrint(CC_DEFAULT, "Game is already unpaused.");
    00522   }
    00523
    00524   return true;
    00525 }
    00526
    00527 DEF_CONSOLE_CMD(ConRcon)
    00528 {
    00529   if (argc == 0) {
    00530     IConsoleHelp("Remote control the server from another client. Usage: 'rcon <password> <command>'");
    00531     IConsoleHelp("Remember to enclose the command in quotes, otherwise only the first parameter is sent");
    00532     return true;
    00533   }
    00534
    00535   if (argc < 3) return false;
    00536
    00537   if (_network_server) {
    00538     IConsoleCmdExec(argv[2]);
    00539   } else {
    00540     NetworkClientSendRcon(argv[1], argv[2]);
    00541   }
    00542   return true;
    00543 }
    00544
    00545 DEF_CONSOLE_CMD(ConStatus)
    00546 {
    00547   if (argc == 0) {
    00548     IConsoleHelp("List the status of all clients connected to the server. Usage 'status'");
    00549     return true;
    00550   }
    00551
    00552   NetworkServerShowStatusToConsole();
    00553   return true;
    00554 }
    00555
    00556 DEF_CONSOLE_CMD(ConServerInfo)
    00557 {
    00558   if (argc == 0) {
    00559     IConsoleHelp("List current and maximum client/company limits. Usage 'server_info'");
    00560     IConsoleHelp("You can change these values by modifying settings 'network.max_clients', 'network.max_companies' and 'network.max_spectators'");
    00561     return true;
    00562   }
    00563
    00564   IConsolePrintF(CC_DEFAULT, "Current/maximum clients:    %2d/%2d", _network_game_info.clients_on, _settings_client.network.max_clients);
    00565   IConsolePrintF(CC_DEFAULT, "Current/maximum companies:  %2d/%2d", (int)Company::GetNumItems(), _settings_client.network.max_companies);
    00566   IConsolePrintF(CC_DEFAULT, "Current/maximum spectators: %2d/%2d", NetworkSpectatorCount(), _settings_client.network.max_spectators);
    00567
    00568   return true;
    00569 }
    00570
    00571 DEF_CONSOLE_CMD(ConClientNickChange)
    00572 {
    00573   if (argc != 3) {
    00574     IConsoleHelp("Change the nickname of a connected client. Usage: 'client_name <client-id> <new-name>'");
    00575     IConsoleHelp("For client-id's, see the command 'clients'");
    00576     return true;
    00577   }
    00578
    00579   ClientID client_id = (ClientID)atoi(argv[1]);
    00580
    00581   if (client_id == CLIENT_ID_SERVER) {
    00582     IConsoleError("Please use the command 'name' to change your own name!");
    00583     return true;
    00584   }
    00585
    00586   if (NetworkFindClientInfoFromClientID(client_id) == NULL) {
    00587     IConsoleError("Invalid client");
    00588     return true;
    00589   }
    00590
    00591   if (!NetworkServerChangeClientName(client_id, argv[2])) {
    00592     IConsoleError("Cannot give a client a duplicate name");
    00593   }
    00594
    00595   return true;
    00596 }
    00597
    00598 DEF_CONSOLE_CMD(ConKick)
    00599 {
    00600   NetworkClientInfo *ci;
    00601   ClientID client_id;
    00602
    00603   if (argc == 0) {
    00604     IConsoleHelp("Kick a client from a network game. Usage: 'kick <ip | client-id>'");
    00605     IConsoleHelp("For client-id's, see the command 'clients'");
    00606     return true;
    00607   }
    00608
    00609   if (argc != 2) return false;
    00610
    00611   if (strchr(argv[1], '.') == NULL) {
    00612     client_id = (ClientID)atoi(argv[1]);
    00613     ci = NetworkFindClientInfoFromClientID(client_id);
    00614   } else {
    00615     ci = NetworkFindClientInfoFromIP(argv[1]);
    00616     client_id = (ci == NULL) ? INVALID_CLIENT_ID : ci->client_id;
    00617   }
    00618
    00619   if (client_id == CLIENT_ID_SERVER) {
    00620     IConsoleError("Silly boy, you can not kick yourself!");
    00621     return true;
    00622   }
    00623
    00624   if (client_id == INVALID_CLIENT_ID) {
    00625     IConsoleError("Invalid client");
    00626     return true;
    00627   }
    00628
    00629   if (ci != NULL) {
    00630     NetworkServerKickClient(client_id);
    00631   } else {
    00632     IConsoleError("Client not found");
    00633   }
    00634
    00635   return true;
    00636 }
    00637
    00638 DEF_CONSOLE_CMD(ConJoinCompany)
    00639 {
    00640   if (argc < 2) {
    00641     IConsoleHelp("Request joining another company. Usage: join <company-id> [<password>]");
    00642     IConsoleHelp("For valid company-id see company list, use 255 for spectator");
    00643     return true;
    00644   }
    00645
    00646   CompanyID company_id = (CompanyID)(atoi(argv[1]) <= MAX_COMPANIES ? atoi(argv[1]) - 1 : atoi(argv[1]));
    00647
    00648   /* Check we have a valid company id! */
    00649   if (!Company::IsValidID(company_id) && company_id != COMPANY_SPECTATOR) {
    00650     IConsolePrintF(CC_ERROR, "Company does not exist. Company-id must be between 1 and %d.", MAX_COMPANIES);
    00651     return true;
    00652   }
    00653
    00654   if (NetworkFindClientInfoFromClientID(_network_own_client_id)->client_playas == company_id) {
    00655     IConsoleError("You are already there!");
    00656     return true;
    00657   }
    00658
    00659   if (company_id == COMPANY_SPECTATOR && NetworkMaxSpectatorsReached()) {
    00660     IConsoleError("Cannot join spectators, maximum number of spectators reached.");
    00661     return true;
    00662   }
    00663
    00664   if (company_id != COMPANY_SPECTATOR && !Company::IsHumanID(company_id)) {
    00665     IConsoleError("Cannot join AI company.");
    00666     return true;
    00667   }
    00668
    00669   /* Check if the company requires a password */
    00670   if (NetworkCompanyIsPassworded(company_id) && argc < 3) {
    00671     IConsolePrintF(CC_ERROR, "Company %d requires a password to join.", company_id + 1);
    00672     return true;
    00673   }
    00674
    00675   /* non-dedicated server may just do the move! */
    00676   if (_network_server) {
    00677     NetworkServerDoMove(CLIENT_ID_SERVER, company_id);
    00678   } else {
    00679     NetworkClientRequestMove(company_id, NetworkCompanyIsPassworded(company_id) ? argv[2] : "");
    00680   }
    00681
    00682   return true;
    00683 }
    00684
    00685 DEF_CONSOLE_CMD(ConMoveClient)
    00686 {
    00687   if (argc < 3) {
    00688     IConsoleHelp("Move a client to another company. Usage: move <client-id> <company-id>");
    00689     IConsoleHelp("For valid client-id see 'clients', for valid company-id see 'companies', use 255 for moving to spectators");
    00690     return true;
    00691   }
    00692
    00693   const NetworkClientInfo *ci = NetworkFindClientInfoFromClientID((ClientID)atoi(argv[1]));
    00694   CompanyID company_id = (CompanyID)(atoi(argv[2]) <= MAX_COMPANIES ? atoi(argv[2]) - 1 : atoi(argv[2]));
    00695
    00696   /* check the client exists */
    00697   if (ci == NULL) {
    00698     IConsoleError("Invalid client-id, check the command 'clients' for valid client-id's.");
    00699     return true;
    00700   }
    00701
    00702   if (!Company::IsValidID(company_id) && company_id != COMPANY_SPECTATOR) {
    00703     IConsolePrintF(CC_ERROR, "Company does not exist. Company-id must be between 1 and %d.", MAX_COMPANIES);
    00704     return true;
    00705   }
    00706
    00707   if (company_id != COMPANY_SPECTATOR && !Company::IsHumanID(company_id)) {
    00708     IConsoleError("You cannot move clients to AI companies.");
    00709     return true;
    00710   }
    00711
    00712   if (ci->client_id == CLIENT_ID_SERVER && _network_dedicated) {
    00713     IConsoleError("Silly boy, you cannot move the server!");
    00714     return true;
    00715   }
    00716
    00717   if (ci->client_playas == company_id) {
    00718     IConsoleError("You cannot move someone to where he/she already is!");
    00719     return true;
    00720   }
    00721
    00722   /* we are the server, so force the update */
    00723   NetworkServerDoMove(ci->client_id, company_id);
    00724
    00725   return true;
    00726 }
    00727
    00728 DEF_CONSOLE_CMD(ConResetCompany)
    00729 {
    00730   if (argc == 0) {
    00731     IConsoleHelp("Remove an idle company from the game. Usage: 'reset_company <company-id>'");
    00732     IConsoleHelp("For company-id's, see the list of companies from the dropdown menu. Company 1 is 1, etc.");
    00733     return true;
    00734   }
    00735
    00736   if (argc != 2) return false;
    00737
    00738   CompanyID index = (CompanyID)(atoi(argv[1]) - 1);
    00739
    00740   /* Check valid range */
    00741   if (!Company::IsValidID(index)) {
    00742     IConsolePrintF(CC_ERROR, "Company does not exist. Company-id must be between 1 and %d.", MAX_COMPANIES);
    00743     return true;
    00744   }
    00745
    00746   if (!Company::IsHumanID(index)) {
    00747     IConsoleError("Company is owned by an AI.");
    00748     return true;
    00749   }
    00750
    00751   if (NetworkCompanyHasClients(index)) {
    00752     IConsoleError("Cannot remove company: a client is connected to that company.");
    00753     return false;
    00754   }
    00755   const NetworkClientInfo *ci = NetworkFindClientInfoFromClientID(CLIENT_ID_SERVER);
    00756   if (ci->client_playas == index) {
    00757     IConsoleError("Cannot remove company: the server is connected to that company.");
    00758     return true;
    00759   }
    00760
    00761   /* It is safe to remove this company */
    00762   DoCommandP(0, 2, index, CMD_COMPANY_CTRL);
    00763   IConsolePrint(CC_DEFAULT, "Company deleted.");
    00764
    00765   return true;
    00766 }
    00767
    00768 DEF_CONSOLE_CMD(ConNetworkClients)
    00769 {
    00770   if (argc == 0) {
    00771     IConsoleHelp("Get a list of connected clients including their ID, name, company-id, and IP. Usage: 'clients'");
    00772     return true;
    00773   }
    00774
    00775   NetworkPrintClients();
    00776
    00777   return true;
    00778 }
    00779
    00780 DEF_CONSOLE_CMD(ConNetworkReconnect)
    00781 {
    00782   if (argc == 0) {
    00783     IConsoleHelp("Reconnect to server to which you were connected last time. Usage: 'reconnect [<company>]'");
    00784     IConsoleHelp("Company 255 is spectator (default, if not specified), 0 means creating new company.");
    00785     IConsoleHelp("All others are a certain company with Company 1 being #1");
    00786     return true;
    00787   }
    00788
    00789   CompanyID playas = (argc >= 2) ? (CompanyID)atoi(argv[1]) : COMPANY_SPECTATOR;
    00790   switch (playas) {
    00791     case 0: playas = COMPANY_NEW_COMPANY; break;
    00792     case COMPANY_SPECTATOR: /* nothing to do */ break;
    00793     default:
    00794       /* From a user pov 0 is a new company, internally it's different and all
    00795        * companies are offset by one to ease up on users (eg companies 1-8 not 0-7) */
    00796       playas--;
    00797       if (playas < COMPANY_FIRST || playas >= MAX_COMPANIES) return false;
    00798       break;
    00799   }
    00800
    00801   if (StrEmpty(_settings_client.network.last_host)) {
    00802     IConsolePrint(CC_DEFAULT, "No server for reconnecting.");
    00803     return true;
    00804   }
    00805
    00806   /* Don't resolve the address first, just print it directly as it comes from the config file. */
    00807   IConsolePrintF(CC_DEFAULT, "Reconnecting to %s:%d...", _settings_client.network.last_host, _settings_client.network.last_port);
    00808
    00809   NetworkClientConnectGame(NetworkAddress(_settings_client.network.last_host, _settings_client.network.last_port), playas);
    00810   return true;
    00811 };
    00812
    00813 DEF_CONSOLE_CMD(ConNetworkConnect)
    00814 {
    00815   if (argc == 0) {
    00816     IConsoleHelp("Connect to a remote OTTD server and join the game. Usage: 'connect <ip>'");
    00817     IConsoleHelp("IP can contain port and company: 'IP[:Port][#Company]', eg: 'server.ottd.org:443#2'");
    00818     IConsoleHelp("Company #255 is spectator all others are a certain company with Company 1 being #1");
    00819     return true;
    00820   }
    00821
    00822   if (argc < 2) return false;
    00823   if (_networking) NetworkDisconnect(); // we are in network-mode, first close it!
    00824
    00825   const char *port = NULL;
    00826   const char *company = NULL;
    00827   char *ip = argv[1];
    00828   /* Default settings: default port and new company */
    00829   uint16 rport = NETWORK_DEFAULT_PORT;
    00830   CompanyID join_as = COMPANY_NEW_COMPANY;
    00831
    00832   ParseConnectionString(&company, &port, ip);
    00833
    00834   IConsolePrintF(CC_DEFAULT, "Connecting to %s...", ip);
    00835   if (company != NULL) {
    00836     join_as = (CompanyID)atoi(company);
    00837     IConsolePrintF(CC_DEFAULT, "    company-no: %d", join_as);
    00838
    00839     /* From a user pov 0 is a new company, internally it's different and all
    00840      * companies are offset by one to ease up on users (eg companies 1-8 not 0-7) */
    00841     if (join_as != COMPANY_SPECTATOR) {
    00842       if (join_as > MAX_COMPANIES) return false;
    00843       join_as--;
    00844     }
    00845   }
    00846   if (port != NULL) {
    00847     rport = atoi(port);
    00848     IConsolePrintF(CC_DEFAULT, "    port: %s", port);
    00849   }
    00850
    00851   NetworkClientConnectGame(NetworkAddress(ip, rport), join_as);
    00852
    00853   return true;
    00854 }
    00855
    00856 #endif /* ENABLE_NETWORK */
    00857
    00858 /*********************************
    00859  *  script file console commands
    00860  *********************************/
    00861
    00862 DEF_CONSOLE_CMD(ConExec)
    00863 {
    00864   char cmdline[ICON_CMDLN_SIZE];
    00865   char *cmdptr;
    00866
    00867   if (argc == 0) {
    00868     IConsoleHelp("Execute a local script file. Usage: 'exec <script> <?>'");
    00869     return true;
    00870   }
    00871
    00872   if (argc < 2) return false;
    00873
    00874   _script_file = FioFOpenFile(argv[1], "r", BASE_DIR);
    00875
    00876   if (_script_file == NULL) {
    00877     if (argc == 2 || atoi(argv[2]) != 0) IConsoleError("script file not found");
    00878     return true;
    00879   }
    00880
    00881   _script_running = true;
    00882
    00883   while (_script_running && fgets(cmdline, sizeof(cmdline), _script_file) != NULL) {
    00884     /* Remove newline characters from the executing script */
    00885     for (cmdptr = cmdline; *cmdptr != '\0'; cmdptr++) {
    00886       if (*cmdptr == '\n' || *cmdptr == '\r') {
    00887         *cmdptr = '\0';
    00888         break;
    00889       }
    00890     }
    00891     IConsoleCmdExec(cmdline);
    00892   }
    00893
    00894   if (ferror(_script_file))
    00895     IConsoleError("Encountered errror while trying to read from script file");
    00896
    00897   _script_running = false;
    00898   FioFCloseFile(_script_file);
    00899   return true;
    00900 }
    00901
    00902 DEF_CONSOLE_CMD(ConReturn)
    00903 {
    00904   if (argc == 0) {
    00905     IConsoleHelp("Stop executing a running script. Usage: 'return'");
    00906     return true;
    00907   }
    00908
    00909   _script_running = false;
    00910   return true;
    00911 }
    00912
    00913 /*****************************
    00914  *  default console commands
    00915  ******************************/
    00916 extern bool CloseConsoleLogIfActive();
    00917
    00918 DEF_CONSOLE_CMD(ConScript)
    00919 {
    00920   extern FILE *_iconsole_output_file;
    00921
    00922   if (argc == 0) {
    00923     IConsoleHelp("Start or stop logging console output to a file. Usage: 'script <filename>'");
    00924     IConsoleHelp("If filename is omitted, a running log is stopped if it is active");
    00925     return true;
    00926   }
    00927
    00928   if (!CloseConsoleLogIfActive()) {
    00929     if (argc < 2) return false;
    00930
    00931     IConsolePrintF(CC_DEFAULT, "file output started to: %s", argv[1]);
    00932     _iconsole_output_file = fopen(argv[1], "ab");
    00933     if (_iconsole_output_file == NULL) IConsoleError("could not open file");
    00934   }
    00935
    00936   return true;
    00937 }
    00938
    00939
    00940 DEF_CONSOLE_CMD(ConEcho)
    00941 {
    00942   if (argc == 0) {
    00943     IConsoleHelp("Print back the first argument to the console. Usage: 'echo <arg>'");
    00944     return true;
    00945   }
    00946
    00947   if (argc < 2) return false;
    00948   IConsolePrint(CC_DEFAULT, argv[1]);
    00949   return true;
    00950 }
    00951
    00952 DEF_CONSOLE_CMD(ConEchoC)
    00953 {
    00954   if (argc == 0) {
    00955     IConsoleHelp("Print back the first argument to the console in a given colour. Usage: 'echoc <colour> <arg2>'");
    00956     return true;
    00957   }
    00958
    00959   if (argc < 3) return false;
    00960   IConsolePrint((ConsoleColour)atoi(argv[1]), argv[2]);
    00961   return true;
    00962 }
    00963
    00964 DEF_CONSOLE_CMD(ConNewGame)
    00965 {
    00966   if (argc == 0) {
    00967     IConsoleHelp("Start a new game. Usage: 'newgame [seed]'");
    00968     IConsoleHelp("The server can force a new game using 'newgame'; any client joined will rejoin after the server is done generating the new game.");
    00969     return true;
    00970   }
    00971
    00972   StartNewGameWithoutGUI((argc == 2) ? (uint)atoi(argv[1]) : GENERATE_NEW_SEED);
    00973   return true;
    00974 }
    00975
    00976 extern void SwitchToMode(SwitchMode new_mode);
    00977
    00978 DEF_CONSOLE_CMD(ConRestart)
    00979 {
    00980   if (argc == 0) {
    00981     IConsoleHelp("Restart game. Usage: 'restart'");
    00982     IConsoleHelp("Restarts a game. It tries to reproduce the exact same map as the game started with.");
    00983     IConsoleHelp("However:");
    00984     IConsoleHelp(" * restarting games started in another version might create another map due to difference in map generation");
    00985     IConsoleHelp(" * restarting games based on scenarios, loaded games or heightmaps will start a new game based on the settings stored in the scenario/savegame");
    00986     return true;
    00987   }
    00988
    00989   /* Don't copy the _newgame pointers to the real pointers, so call SwitchToMode directly */
    00990   _settings_game.game_creation.map_x = MapLogX();
    00991   _settings_game.game_creation.map_y = FindFirstBit(MapSizeY());
    00992   SwitchToMode(SM_RESTARTGAME);
    00993   return true;
    00994 }
    00995
    00996 #ifdef ENABLE_AI
    00997 DEF_CONSOLE_CMD(ConListAI)
    00998 {
    00999   char buf[4096];
    01000   char *p = &buf[0];
    01001   p = AI::GetConsoleList(p, lastof(buf));
    01002
    01003   p = &buf[0];
    01004   /* Print output line by line */
    01005   for (char *p2 = &buf[0]; *p2 != '\0'; p2++) {
    01006     if (*p2 == '\n') {
    01007       *p2 = '\0';
    01008       IConsolePrintF(CC_DEFAULT, "%s", p);
    01009       p = p2 + 1;
    01010     }
    01011   }
    01012
    01013   return true;
    01014 }
    01015
    01016 DEF_CONSOLE_CMD(ConStartAI)
    01017 {
    01018   if (argc == 0 || argc > 3) {
    01019     IConsoleHelp("Start a new AI. Usage: 'start_ai [<AI>] [<settings>]'");
    01020     IConsoleHelp("Start a new AI. If <AI> is given, it starts that specific AI (if found).");
    01021     IConsoleHelp("If <settings> is given, it is parsed and the AI settings are set to that.");
    01022     return true;
    01023   }
    01024
    01025   if (_game_mode != GM_NORMAL) {
    01026     IConsoleWarning("AIs can only be managed in a game.");
    01027     return true;
    01028   }
    01029
    01030   if (Company::GetNumItems() == CompanyPool::MAX_SIZE) {
    01031     IConsoleWarning("Can't start a new AI (no more free slots).");
    01032     return true;
    01033   }
    01034   if (_networking && !_network_server) {
    01035     IConsoleWarning("Only the server can start a new AI.");
    01036     return true;
    01037   }
    01038   if (_networking && !_settings_game.ai.ai_in_multiplayer) {
    01039     IConsoleWarning("AIs are not allowed in multiplayer by configuration.");
    01040     IConsoleWarning("Switch AI -> AI in multiplayer to True.");
    01041     return true;
    01042   }
    01043   if (!AI::CanStartNew()) {
    01044     IConsoleWarning("Can't start a new AI.");
    01045     return true;
    01046   }
    01047
    01048   int n = 0;
    01049   Company *c;
    01050   /* Find the next free slot */
    01051   FOR_ALL_COMPANIES(c) {
    01052     if (c->index != n) break;
    01053     n++;
    01054   }
    01055
    01056   AIConfig *config = AIConfig::GetConfig((CompanyID)n);
    01057   if (argc >= 2) {
    01058     config->ChangeAI(argv[1], -1, true);
    01059     if (!config->HasAI()) {
    01060       IConsoleWarning("Failed to load the specified AI");
    01061       return true;
    01062     }
    01063     if (argc == 3) {
    01064       config->StringToSettings(argv[2]);
    01065     }
    01066   }
    01067
    01068   /* Start a new AI company */
    01069   DoCommandP(0, 1, INVALID_COMPANY, CMD_COMPANY_CTRL);
    01070
    01071   return true;
    01072 }
    01073
    01074 DEF_CONSOLE_CMD(ConReloadAI)
    01075 {
    01076   if (argc != 2) {
    01077     IConsoleHelp("Reload an AI. Usage: 'reload_ai <company-id>'");
    01078     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.");
    01079     return true;
    01080   }
    01081
    01082   if (_game_mode != GM_NORMAL) {
    01083     IConsoleWarning("AIs can only be managed in a game.");
    01084     return true;
    01085   }
    01086
    01087   if (_networking && !_network_server) {
    01088     IConsoleWarning("Only the server can reload an AI.");
    01089     return true;
    01090   }
    01091
    01092   CompanyID company_id = (CompanyID)(atoi(argv[1]) - 1);
    01093   if (!Company::IsValidID(company_id)) {
    01094     IConsolePrintF(CC_DEFAULT, "Unknown company. Company range is between 1 and %d.", MAX_COMPANIES);
    01095     return true;
    01096   }
    01097
    01098   if (Company::IsHumanID(company_id)) {
    01099     IConsoleWarning("Company is not controlled by an AI.");
    01100     return true;
    01101   }
    01102
    01103   /* First kill the company of the AI, then start a new one. This should start the current AI again */
    01104   DoCommandP(0, 2, company_id, CMD_COMPANY_CTRL);
    01105   DoCommandP(0, 1, company_id, CMD_COMPANY_CTRL);
    01106   IConsolePrint(CC_DEFAULT, "AI reloaded.");
    01107
    01108   return true;
    01109 }
    01110
    01111 DEF_CONSOLE_CMD(ConStopAI)
    01112 {
    01113   if (argc != 2) {
    01114     IConsoleHelp("Stop an AI. Usage: 'stop_ai <company-id>'");
    01115     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.");
    01116     return true;
    01117   }
    01118
    01119   if (_game_mode != GM_NORMAL) {
    01120     IConsoleWarning("AIs can only be managed in a game.");
    01121     return true;
    01122   }
    01123
    01124   if (_networking && !_network_server) {
    01125     IConsoleWarning("Only the server can stop an AI.");
    01126     return true;
    01127   }
    01128
    01129   CompanyID company_id = (CompanyID)(atoi(argv[1]) - 1);
    01130   if (!Company::IsValidID(company_id)) {
    01131     IConsolePrintF(CC_DEFAULT, "Unknown company. Company range is between 1 and %d.", MAX_COMPANIES);
    01132     return true;
    01133   }
    01134
    01135   if (Company::IsHumanID(company_id)) {
    01136     IConsoleWarning("Company is not controlled by an AI.");
    01137     return true;
    01138   }
    01139
    01140   /* Now kill the company of the AI. */
    01141   DoCommandP(0, 2, company_id, CMD_COMPANY_CTRL);
    01142   IConsolePrint(CC_DEFAULT, "AI stopped, company deleted.");
    01143
    01144   return true;
    01145 }
    01146
    01147 DEF_CONSOLE_CMD(ConRescanAI)
    01148 {
    01149   if (argc == 0) {
    01150     IConsoleHelp("Rescan the AI dir for scripts. Usage: 'rescan_ai'");
    01151     return true;
    01152   }
    01153
    01154   if (_networking && !_network_server) {
    01155     IConsoleWarning("Only the server can rescan the AI dir for scripts.");
    01156     return true;
    01157   }
    01158
    01159   AI::Rescan();
    01160
    01161   return true;
    01162 }
    01163 #endif /* ENABLE_AI */
    01164
    01165 DEF_CONSOLE_CMD(ConGetSeed)
    01166 {
    01167   if (argc == 0) {
    01168     IConsoleHelp("Returns the seed used to create this game. Usage: 'getseed'");
    01169     IConsoleHelp("The seed can be used to reproduce the exact same map as the game started with.");
    01170     return true;
    01171   }
    01172
    01173   IConsolePrintF(CC_DEFAULT, "Generation Seed: %u", _settings_game.game_creation.generation_seed);
    01174   return true;
    01175 }
    01176
    01177 DEF_CONSOLE_CMD(ConGetDate)
    01178 {
    01179   if (argc == 0) {
    01180     IConsoleHelp("Returns the current date (day-month-year) of the game. Usage: 'getdate'");
    01181     return true;
    01182   }
    01183
    01184   YearMonthDay ymd;
    01185   ConvertDateToYMD(_date, &ymd);
    01186   IConsolePrintF(CC_DEFAULT, "Date: %d-%d-%d", ymd.day, ymd.month + 1, ymd.year);
    01187   return true;
    01188 }
    01189
    01190
    01191 DEF_CONSOLE_CMD(ConAlias)
    01192 {
    01193   IConsoleAlias *alias;
    01194
    01195   if (argc == 0) {
    01196     IConsoleHelp("Add a new alias, or redefine the behaviour of an existing alias . Usage: 'alias <name> <command>'");
    01197     return true;
    01198   }
    01199
    01200   if (argc < 3) return false;
    01201
    01202   alias = IConsoleAliasGet(argv[1]);
    01203   if (alias == NULL) {
    01204     IConsoleAliasRegister(argv[1], argv[2]);
    01205   } else {
    01206     free(alias->cmdline);
    01207     alias->cmdline = strdup(argv[2]);
    01208   }
    01209   return true;
    01210 }
    01211
    01212 DEF_CONSOLE_CMD(ConScreenShot)
    01213 {
    01214   if (argc == 0) {
    01215     IConsoleHelp("Create a screenshot of the game. Usage: 'screenshot [big | no_con] [file name]'");
    01216     IConsoleHelp("'big' makes a screenshot of the whole map, 'no_con' hides the console to create "
    01217         "the screenshot. Screenshots of whole map are always drawn without console");
    01218     return true;
    01219   }
    01220
    01221   if (argc > 3) return false;
    01222
    01223   ScreenshotType type = SC_VIEWPORT;
    01224   const char *name = NULL;
    01225
    01226   if (argc > 1) {
    01227     if (strcmp(argv[1], "big") == 0) {
    01228       /* screenshot big [filename] */
    01229       type = SC_WORLD;
    01230       if (argc > 2) name = argv[2];
    01231     } else if (strcmp(argv[1], "no_con") == 0) {
    01232       /* screenshot no_con [filename] */
    01233       IConsoleClose();
    01234       if (argc > 2) name = argv[2];
    01235     } else if (argc == 2) {
    01236       /* screenshot filename */
    01237       name = argv[1];
    01238     } else {
    01239       /* screenshot argv[1] argv[2] - invalid */
    01240       return false;
    01241     }
    01242   }
    01243
    01244   MakeScreenshot(type, name);
    01245   return true;
    01246 }
    01247
    01248 DEF_CONSOLE_CMD(ConInfoCmd)
    01249 {
    01250   const IConsoleCmd *cmd;
    01251
    01252   if (argc == 0) {
    01253     IConsoleHelp("Print out debugging information about a command. Usage: 'info_cmd <cmd>'");
    01254     return true;
    01255   }
    01256
    01257   if (argc < 2) return false;
    01258
    01259   cmd = IConsoleCmdGet(argv[1]);
    01260   if (cmd == NULL) {
    01261     IConsoleError("the given command was not found");
    01262     return true;
    01263   }
    01264
    01265   IConsolePrintF(CC_DEFAULT, "command name: %s", cmd->name);
    01266   IConsolePrintF(CC_DEFAULT, "command proc: %p", cmd->proc);
    01267
    01268   if (cmd->hook != NULL) IConsoleWarning("command is hooked");
    01269
    01270   return true;
    01271 }
    01272
    01273 DEF_CONSOLE_CMD(ConDebugLevel)
    01274 {
    01275   if (argc == 0) {
    01276     IConsoleHelp("Get/set the default debugging level for the game. Usage: 'debug_level [<level>]'");
    01277     IConsoleHelp("Level can be any combination of names, levels. Eg 'net=5 ms=4'. Remember to enclose it in \"'s");
    01278     return true;
    01279   }
    01280
    01281   if (argc > 2) return false;
    01282
    01283   if (argc == 1) {
    01284     IConsolePrintF(CC_DEFAULT, "Current debug-level: '%s'", GetDebugString());
    01285   } else {
    01286     SetDebugString(argv[1]);
    01287   }
    01288
    01289   return true;
    01290 }
    01291
    01292 DEF_CONSOLE_CMD(ConExit)
    01293 {
    01294   if (argc == 0) {
    01295     IConsoleHelp("Exit the game. Usage: 'exit'");
    01296     return true;
    01297   }
    01298
    01299   if (_game_mode == GM_NORMAL && _settings_client.gui.autosave_on_exit) DoExitSave();
    01300
    01301   _exit_game = true;
    01302   return true;
    01303 }
    01304
    01305 DEF_CONSOLE_CMD(ConPart)
    01306 {
    01307   if (argc == 0) {
    01308     IConsoleHelp("Leave the currently joined/running game (only ingame). Usage: 'part'");
    01309     return true;
    01310   }
    01311
    01312   if (_game_mode != GM_NORMAL) return false;
    01313
    01314   _switch_mode = SM_MENU;
    01315   return true;
    01316 }
    01317
    01318 DEF_CONSOLE_CMD(ConHelp)
    01319 {
    01320   if (argc == 2) {
    01321     const IConsoleCmd *cmd;
    01322     const IConsoleAlias *alias;
    01323
    01324     cmd = IConsoleCmdGet(argv[1]);
    01325     if (cmd != NULL) {
    01326       cmd->proc(0, NULL);
    01327       return true;
    01328     }
    01329
    01330     alias = IConsoleAliasGet(argv[1]);
    01331     if (alias != NULL) {
    01332       cmd = IConsoleCmdGet(alias->cmdline);
    01333       if (cmd != NULL) {
    01334         cmd->proc(0, NULL);
    01335         return true;
    01336       }
    01337       IConsolePrintF(CC_ERROR, "ERROR: alias is of special type, please see its execution-line: '%s'", alias->cmdline);
    01338       return true;
    01339     }
    01340
    01341     IConsoleError("command not found");
    01342     return true;
    01343   }
    01344
    01345   IConsolePrint(CC_WARNING, " ---- OpenTTD Console Help ---- ");
    01346   IConsolePrint(CC_DEFAULT, " - commands: [command to list all commands: list_cmds]");
    01347   IConsolePrint(CC_DEFAULT, " call commands with '<command> <arg2> <arg3>...'");
    01348   IConsolePrint(CC_DEFAULT, " - to assign strings, or use them as arguments, enclose it within quotes");
    01349   IConsolePrint(CC_DEFAULT, " like this: '<command> \"string argument with spaces\"'");
    01350   IConsolePrint(CC_DEFAULT, " - use 'help <command>' to get specific information");
    01351   IConsolePrint(CC_DEFAULT, " - scroll console output with shift + (up | down) | (pageup | pagedown))");
    01352   IConsolePrint(CC_DEFAULT, " - scroll console input history with the up | down arrows");
    01353   IConsolePrint(CC_DEFAULT, "");
    01354   return true;
    01355 }
    01356
    01357 DEF_CONSOLE_CMD(ConListCommands)
    01358 {
    01359   const IConsoleCmd *cmd;
    01360
    01361   if (argc == 0) {
    01362     IConsoleHelp("List all registered commands. Usage: 'list_cmds [<pre-filter>]'");
    01363     return true;
    01364   }
    01365
    01366   for (cmd = _iconsole_cmds; cmd != NULL; cmd = cmd->next) {
    01367     if (argv[1] == NULL || strstr(cmd->name, argv[1]) != NULL) {
    01368         IConsolePrintF(CC_DEFAULT, "%s", cmd->name);
    01369     }
    01370   }
    01371
    01372   return true;
    01373 }
    01374
    01375 DEF_CONSOLE_CMD(ConListAliases)
    01376 {
    01377   const IConsoleAlias *alias;
    01378
    01379   if (argc == 0) {
    01380     IConsoleHelp("List all registered aliases. Usage: 'list_aliases [<pre-filter>]'");
    01381     return true;
    01382   }
    01383
    01384   for (alias = _iconsole_aliases; alias != NULL; alias = alias->next) {
    01385     if (argv[1] == NULL || strstr(alias->name, argv[1]) != NULL) {
    01386       IConsolePrintF(CC_DEFAULT, "%s => %s", alias->name, alias->cmdline);
    01387     }
    01388   }
    01389
    01390   return true;
    01391 }
    01392
    01393 #ifdef ENABLE_NETWORK
    01394
    01395 DEF_CONSOLE_CMD(ConSay)
    01396 {
    01397   if (argc == 0) {
    01398     IConsoleHelp("Chat to your fellow players in a multiplayer game. Usage: 'say \"<msg>\"'");
    01399     return true;
    01400   }
    01401
    01402   if (argc != 2) return false;
    01403
    01404   if (!_network_server) {
    01405     NetworkClientSendChat(NETWORK_ACTION_CHAT, DESTTYPE_BROADCAST, 0 /* param does not matter */, argv[1]);
    01406   } else {
    01407     NetworkServerSendChat(NETWORK_ACTION_CHAT, DESTTYPE_BROADCAST, 0, argv[1], CLIENT_ID_SERVER);
    01408   }
    01409
    01410   return true;
    01411 }
    01412
    01413 DEF_CONSOLE_CMD(ConCompanies)
    01414 {
    01415   Company *c;
    01416
    01417   if (argc == 0) {
    01418     IConsoleHelp("List the in-game details of all clients connected to the server. Usage 'companies'");
    01419     return true;
    01420   }
    01421   NetworkCompanyStats company_stats[MAX_COMPANIES];
    01422   NetworkPopulateCompanyStats(company_stats);
    01423
    01424   FOR_ALL_COMPANIES(c) {
    01425     /* Grab the company name */
    01426     char company_name[NETWORK_COMPANY_NAME_LENGTH];
    01427     SetDParam(0, c->index);
    01428     GetString(company_name, STR_COMPANY_NAME, lastof(company_name));
    01429
    01430     char buffer[512];
    01431     const NetworkCompanyStats *stats = &company_stats[c->index];
    01432
    01433     GetString(buffer, STR_COLOUR_DARK_BLUE + _company_colours[c->index], lastof(buffer));
    01434     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) %sprotected",
    01435       c->index + 1, buffer, company_name, c->inaugurated_year, (int64)c->money, (int64)c->current_loan, (int64)CalculateCompanyValue(c),
    01436       /* trains      */ stats->num_vehicle[0],
    01437       /* lorry + bus */ stats->num_vehicle[1] + stats->num_vehicle[2],
    01438       /* planes      */ stats->num_vehicle[3],
    01439       /* ships       */ stats->num_vehicle[4],
    01440       /* protected   */ StrEmpty(_network_company_states[c->index].password) ? "un" : "");
    01441   }
    01442
    01443   return true;
    01444 }
    01445
    01446 DEF_CONSOLE_CMD(ConSayCompany)
    01447 {
    01448   if (argc == 0) {
    01449     IConsoleHelp("Chat to a certain company in a multiplayer game. Usage: 'say_company <company-no> \"<msg>\"'");
    01450     IConsoleHelp("CompanyNo is the company that plays as company <companyno>, 1 through max_companies");
    01451     return true;
    01452   }
    01453
    01454   if (argc != 3) return false;
    01455
    01456   CompanyID company_id = (CompanyID)(atoi(argv[1]) - 1);
    01457   if (!Company::IsValidID(company_id)) {
    01458     IConsolePrintF(CC_DEFAULT, "Unknown company. Company range is between 1 and %d.", MAX_COMPANIES);
    01459     return true;
    01460   }
    01461
    01462   if (!_network_server) {
    01463     NetworkClientSendChat(NETWORK_ACTION_CHAT_COMPANY, DESTTYPE_TEAM, company_id, argv[2]);
    01464   } else {
    01465     NetworkServerSendChat(NETWORK_ACTION_CHAT_COMPANY, DESTTYPE_TEAM, company_id, argv[2], CLIENT_ID_SERVER);
    01466   }
    01467
    01468   return true;
    01469 }
    01470
    01471 DEF_CONSOLE_CMD(ConSayClient)
    01472 {
    01473   if (argc == 0) {
    01474     IConsoleHelp("Chat to a certain client in a multiplayer game. Usage: 'say_client <client-no> \"<msg>\"'");
    01475     IConsoleHelp("For client-id's, see the command 'clients'");
    01476     return true;
    01477   }
    01478
    01479   if (argc != 3) return false;
    01480
    01481   if (!_network_server) {
    01482     NetworkClientSendChat(NETWORK_ACTION_CHAT_CLIENT, DESTTYPE_CLIENT, atoi(argv[1]), argv[2]);
    01483   } else {
    01484     NetworkServerSendChat(NETWORK_ACTION_CHAT_CLIENT, DESTTYPE_CLIENT, atoi(argv[1]), argv[2], CLIENT_ID_SERVER);
    01485   }
    01486
    01487   return true;
    01488 }
    01489
    01490 extern void HashCurrentCompanyPassword(const char *password);
    01491
    01492 DEF_CONSOLE_CMD(ConCompanyPassword)
    01493 {
    01494   if (argc == 0) {
    01495     IConsoleHelp("Change the password of your company. Usage: 'company_pw \"<password>\"'");
    01496     IConsoleHelp("Use \"*\" to disable the password.");
    01497     return true;
    01498   }
    01499
    01500   if (argc != 2) return false;
    01501
    01502   if (!Company::IsValidID(_local_company)) {
    01503     IConsoleError("You have to own a company to make use of this command.");
    01504     return false;
    01505   }
    01506
    01507   const char *password = NetworkChangeCompanyPassword(argv[1]);
    01508
    01509   if (StrEmpty(password)) {
    01510     IConsolePrintF(CC_WARNING, "Company password cleared");
    01511   } else {
    01512     IConsolePrintF(CC_WARNING, "Company password changed to: %s", password);
    01513   }
    01514
    01515   return true;
    01516 }
    01517
    01518 /* Content downloading only is available with ZLIB */
    01519 #if defined(WITH_ZLIB)
    01520 #include "network/network_content.h"
    01521
    01523 static ContentType StringToContentType(const char *str)
    01524 {
    01525   static const char * const inv_lookup[] = { "", "base", "newgrf", "ai", "ailib", "scenario", "heightmap" };
    01526   for (uint i = 1 /* there is no type 0 */; i < lengthof(inv_lookup); i++) {
    01527     if (strcasecmp(str, inv_lookup[i]) == 0) return (ContentType)i;
    01528   }
    01529   return CONTENT_TYPE_END;
    01530 }
    01531
    01533 struct ConsoleContentCallback : public ContentCallback {
    01534   void OnConnect(bool success)
    01535   {
    01536     IConsolePrintF(CC_DEFAULT, "Content server connection %s", success ? "established" : "failed");
    01537   }
    01538
    01539   void OnDisconnect()
    01540   {
    01541     IConsolePrintF(CC_DEFAULT, "Content server connection closed");
    01542   }
    01543
    01544   void OnDownloadComplete(ContentID cid)
    01545   {
    01546     IConsolePrintF(CC_DEFAULT, "Completed download of %d", cid);
    01547   }
    01548 };
    01549
    01550 DEF_CONSOLE_CMD(ConContent)
    01551 {
    01552   static ContentCallback *cb = NULL;
    01553   if (cb == NULL) {
    01554     cb = new ConsoleContentCallback();
    01555     _network_content_client.AddCallback(cb);
    01556   }
    01557
    01558   if (argc <= 1) {
    01559     IConsoleHelp("Query, select and download content. Usage: 'content update|upgrade|select [all|id]|unselect [all|id]|state|download'");
    01560     IConsoleHelp("  update: get a new list of downloadable content; must be run first");
    01561     IConsoleHelp("  upgrade: select all items that are upgrades");
    01562     IConsoleHelp("  select: select a specific item given by its id or 'all' to select all");
    01563     IConsoleHelp("  unselect: unselect a specific item given by its id or 'all' to unselect all");
    01564     IConsoleHelp("  state: show the download/select state of all downloadable content");
    01565     IConsoleHelp("  download: download all content you've selected");
    01566     return true;
    01567   }
    01568
    01569   if (strcasecmp(argv[1], "update") == 0) {
    01570     _network_content_client.RequestContentList((argc > 2) ? StringToContentType(argv[2]) : CONTENT_TYPE_END);
    01571     return true;
    01572   }
    01573
    01574   if (strcasecmp(argv[1], "upgrade") == 0) {
    01575     _network_content_client.SelectUpgrade();
    01576     return true;
    01577   }
    01578
    01579   if (strcasecmp(argv[1], "select") == 0) {
    01580     if (argc <= 2) {
    01581       IConsoleError("You must enter the id.");
    01582       return false;
    01583     }
    01584     if (strcasecmp(argv[2], "all") == 0) {
    01585       _network_content_client.SelectAll();
    01586     } else {
    01587       _network_content_client.Select((ContentID)atoi(argv[2]));
    01588     }
    01589     return true;
    01590   }
    01591
    01592   if (strcasecmp(argv[1], "unselect") == 0) {
    01593     if (argc <= 2) {
    01594       IConsoleError("You must enter the id.");
    01595       return false;
    01596     }
    01597     if (strcasecmp(argv[2], "all") == 0) {
    01598       _network_content_client.UnselectAll();
    01599     } else {
    01600       _network_content_client.Unselect((ContentID)atoi(argv[2]));
    01601     }
    01602     return true;
    01603   }
    01604
    01605   if (strcasecmp(argv[1], "state") == 0) {
    01606     IConsolePrintF(CC_WHITE, "id, type, state, name");
    01607     for (ConstContentIterator iter = _network_content_client.Begin(); iter != _network_content_client.End(); iter++) {
    01608       static const char * const types[] = { "Base graphics", "NewGRF", "AI", "AI library", "Scenario", "Heightmap", "Base sound", "Base music" };
    01609       assert_compile(lengthof(types) == CONTENT_TYPE_END - CONTENT_TYPE_BEGIN);
    01610       static const char * const states[] = { "Not selected", "Selected", "Dep Selected", "Installed", "Unknown" };
    01611       static const ConsoleColour state_to_colour[] = { CC_COMMAND, CC_INFO, CC_INFO, CC_WHITE, CC_ERROR };
    01612
    01613       const ContentInfo *ci = *iter;
    01614       IConsolePrintF(state_to_colour[ci->state], "%d, %s, %s, %s", ci->id, types[ci->type - 1], states[ci->state], ci->name);
    01615     }
    01616     return true;
    01617   }
    01618
    01619   if (strcasecmp(argv[1], "download") == 0) {
    01620     uint files;
    01621     uint bytes;
    01622     _network_content_client.DownloadSelectedContent(files, bytes);
    01623     IConsolePrintF(CC_DEFAULT, "Downloading %d file(s) (%d bytes)", files, bytes);
    01624     return true;
    01625   }
    01626
    01627   return false;
    01628 }
    01629 #endif /* defined(WITH_ZLIB) */
    01630 #endif /* ENABLE_NETWORK */
    01631
    01632 DEF_CONSOLE_CMD(ConSetting)
    01633 {
    01634   if (argc == 0) {
    01635     IConsoleHelp("Change setting for all clients. Usage: 'setting <name> [<value>]'");
    01636     IConsoleHelp("Omitting <value> will print out the current value of the setting.");
    01637     return true;
    01638   }
    01639
    01640   if (argc == 1 || argc > 3) return false;
    01641
    01642   if (argc == 2) {
    01643     IConsoleGetSetting(argv[1]);
    01644   } else {
    01645     IConsoleSetSetting(argv[1], argv[2]);
    01646   }
    01647
    01648   return true;
    01649 }
    01650
    01651 DEF_CONSOLE_CMD(ConSettingNewgame)
    01652 {
    01653   if (argc == 0) {
    01654     IConsoleHelp("Change setting for the next game. Usage: 'setting_newgame <name> [<value>]'");
    01655     IConsoleHelp("Omitting <value> will print out the current value of the setting.");
    01656     return true;
    01657   }
    01658
    01659   if (argc == 1 || argc > 3) return false;
    01660
    01661   if (argc == 2) {
    01662     IConsoleGetSetting(argv[1], true);
    01663   } else {
    01664     IConsoleSetSetting(argv[1], argv[2], true);
    01665   }
    01666
    01667   return true;
    01668 }
    01669
    01670 DEF_CONSOLE_CMD(ConListSettings)
    01671 {
    01672   if (argc == 0) {
    01673     IConsoleHelp("List settings. Usage: 'list_settings [<pre-filter>]'");
    01674     return true;
    01675   }
    01676
    01677   if (argc > 2) return false;
    01678
    01679   IConsoleListSettings((argc == 2) ? argv[1] : NULL);
    01680   return true;
    01681 }
    01682
    01683 DEF_CONSOLE_CMD(ConGamelogPrint)
    01684 {
    01685   GamelogPrintConsole();
    01686   return true;
    01687 }
    01688
    01689 #ifdef _DEBUG
    01690 /******************
    01691  *  debug commands
    01692  ******************/
    01693
    01694 static void IConsoleDebugLibRegister()
    01695 {
    01696   IConsoleCmdRegister("resettile",        ConResetTile);
    01697   IConsoleCmdRegister("stopall",          ConStopAllVehicles);
    01698   IConsoleAliasRegister("dbg_echo",       "echo %A; echo %B");
    01699   IConsoleAliasRegister("dbg_echo2",      "echo %!");
    01700 }
    01701 #endif
    01702
    01703 /*******************************
    01704  * console command registration
    01705  *******************************/
    01706
    01707 void IConsoleStdLibRegister()
    01708 {
    01709   IConsoleCmdRegister("debug_level",  ConDebugLevel);
    01710   IConsoleCmdRegister("echo",         ConEcho);
    01711   IConsoleCmdRegister("echoc",        ConEchoC);
    01712   IConsoleCmdRegister("exec",         ConExec);
    01713   IConsoleCmdRegister("exit",         ConExit);
    01714   IConsoleCmdRegister("part",         ConPart);
    01715   IConsoleCmdRegister("help",         ConHelp);
    01716   IConsoleCmdRegister("info_cmd",     ConInfoCmd);
    01717   IConsoleCmdRegister("list_cmds",    ConListCommands);
    01718   IConsoleCmdRegister("list_aliases", ConListAliases);
    01719   IConsoleCmdRegister("newgame",      ConNewGame);
    01720   IConsoleCmdRegister("restart",      ConRestart);
    01721   IConsoleCmdRegister("getseed",      ConGetSeed);
    01722   IConsoleCmdRegister("getdate",      ConGetDate);
    01723   IConsoleCmdRegister("quit",         ConExit);
    01724   IConsoleCmdRegister("resetengines", ConResetEngines, ConHookNoNetwork);
    01725   IConsoleCmdRegister("return",       ConReturn);
    01726   IConsoleCmdRegister("screenshot",   ConScreenShot);
    01727   IConsoleCmdRegister("script",       ConScript);
    01728   IConsoleCmdRegister("scrollto",     ConScrollToTile);
    01729   IConsoleCmdRegister("alias",        ConAlias);
    01730   IConsoleCmdRegister("load",         ConLoad);
    01731   IConsoleCmdRegister("rm",           ConRemove);
    01732   IConsoleCmdRegister("save",         ConSave);
    01733   IConsoleCmdRegister("saveconfig",   ConSaveConfig);
    01734   IConsoleCmdRegister("ls",           ConListFiles);
    01735   IConsoleCmdRegister("cd",           ConChangeDirectory);
    01736   IConsoleCmdRegister("pwd",          ConPrintWorkingDirectory);
    01737   IConsoleCmdRegister("clear",        ConClearBuffer);
    01738   IConsoleCmdRegister("setting",      ConSetting);
    01739   IConsoleCmdRegister("setting_newgame", ConSettingNewgame);
    01740   IConsoleCmdRegister("list_settings",ConListSettings);
    01741   IConsoleCmdRegister("gamelog",      ConGamelogPrint);
    01742
    01743   IConsoleAliasRegister("dir",          "ls");
    01744   IConsoleAliasRegister("del",          "rm %+");
    01745   IConsoleAliasRegister("newmap",       "newgame");
    01746   IConsoleAliasRegister("new_map",      "newgame");
    01747   IConsoleAliasRegister("new_game",     "newgame");
    01748   IConsoleAliasRegister("patch",        "setting %+");
    01749   IConsoleAliasRegister("set",          "setting %+");
    01750   IConsoleAliasRegister("set_newgame",  "setting_newgame %+");
    01751   IConsoleAliasRegister("list_patches", "list_settings %+");
    01752   IConsoleAliasRegister("developer",    "setting developer %+");
    01753
    01754 #ifdef ENABLE_AI
    01755   IConsoleCmdRegister("list_ai",      ConListAI);
    01756   IConsoleCmdRegister("reload_ai",    ConReloadAI);
    01757   IConsoleCmdRegister("rescan_ai",    ConRescanAI);
    01758   IConsoleCmdRegister("start_ai",     ConStartAI);
    01759   IConsoleCmdRegister("stop_ai",      ConStopAI);
    01760 #endif /* ENABLE_AI */
    01761
    01762   /* networking functions */
    01763 #ifdef ENABLE_NETWORK
    01764 /* Content downloading is only available with ZLIB */
    01765 #if defined(WITH_ZLIB)
    01766   IConsoleCmdRegister("content",         ConContent);
    01767 #endif /* defined(WITH_ZLIB) */
    01768
    01769   /*** Networking commands ***/
    01770   IConsoleCmdRegister("say",             ConSay, ConHookNeedNetwork);
    01771   IConsoleCmdRegister("companies",       ConCompanies, ConHookServerOnly);
    01772   IConsoleAliasRegister("players",       "companies");
    01773   IConsoleCmdRegister("say_company",     ConSayCompany, ConHookNeedNetwork);
    01774   IConsoleAliasRegister("say_player",    "say_company %+");
    01775   IConsoleCmdRegister("say_client",      ConSayClient, ConHookNeedNetwork);
    01776
    01777   IConsoleCmdRegister("connect",         ConNetworkConnect, ConHookClientOnly);
    01778   IConsoleCmdRegister("clients",         ConNetworkClients, ConHookNeedNetwork);
    01779   IConsoleCmdRegister("status",          ConStatus, ConHookServerOnly);
    01780   IConsoleCmdRegister("server_info",     ConServerInfo, ConHookServerOnly);
    01781   IConsoleAliasRegister("info",          "server_info");
    01782   IConsoleCmdRegister("reconnect",       ConNetworkReconnect, ConHookClientOnly);
    01783   IConsoleCmdRegister("rcon",            ConRcon, ConHookNeedNetwork);
    01784
    01785   IConsoleCmdRegister("join",            ConJoinCompany, ConHookNeedNetwork);
    01786   IConsoleAliasRegister("spectate",      "join 255");
    01787   IConsoleCmdRegister("move",            ConMoveClient, ConHookServerOnly);
    01788   IConsoleCmdRegister("reset_company",   ConResetCompany, ConHookServerOnly);
    01789   IConsoleAliasRegister("clean_company", "reset_company %A");
    01790   IConsoleCmdRegister("client_name",     ConClientNickChange, ConHookServerOnly);
    01791   IConsoleCmdRegister("kick",            ConKick, ConHookServerOnly);
    01792   IConsoleCmdRegister("ban",             ConBan, ConHookServerOnly);
    01793   IConsoleCmdRegister("unban",           ConUnBan, ConHookServerOnly);
    01794   IConsoleCmdRegister("banlist",         ConBanList, ConHookServerOnly);
    01795
    01796   IConsoleCmdRegister("pause",           ConPauseGame, ConHookServerOnly);
    01797   IConsoleCmdRegister("unpause",         ConUnPauseGame, ConHookServerOnly);
    01798
    01799   IConsoleCmdRegister("company_pw",      ConCompanyPassword, ConHookNeedNetwork);
    01800   IConsoleAliasRegister("company_password",      "company_pw %+");
    01801
    01802   IConsoleAliasRegister("net_frame_freq",        "setting frame_freq %+");
    01803   IConsoleAliasRegister("net_sync_freq",         "setting sync_freq %+");
    01804   IConsoleAliasRegister("server_pw",             "setting server_password %+");
    01805   IConsoleAliasRegister("server_password",       "setting server_password %+");
    01806   IConsoleAliasRegister("rcon_pw",               "setting rcon_password %+");
    01807   IConsoleAliasRegister("rcon_password",         "setting rcon_password %+");
    01808   IConsoleAliasRegister("name",                  "setting client_name %+");
    01809   IConsoleAliasRegister("server_name",           "setting server_name %+");
    01810   IConsoleAliasRegister("server_port",           "setting server_port %+");
    01811   IConsoleAliasRegister("server_advertise",      "setting server_advertise %+");
    01812   IConsoleAliasRegister("max_clients",           "setting max_clients %+");
    01813   IConsoleAliasRegister("max_companies",         "setting max_companies %+");
    01814   IConsoleAliasRegister("max_spectators",        "setting max_spectators %+");
    01815   IConsoleAliasRegister("max_join_time",         "setting max_join_time %+");
    01816   IConsoleAliasRegister("pause_on_join",         "setting pause_on_join %+");
    01817   IConsoleAliasRegister("autoclean_companies",   "setting autoclean_companies %+");
    01818   IConsoleAliasRegister("autoclean_protected",   "setting autoclean_protected %+");
    01819   IConsoleAliasRegister("autoclean_unprotected", "setting autoclean_unprotected %+");
    01820   IConsoleAliasRegister("restart_game_year",     "setting restart_game_year %+");
    01821   IConsoleAliasRegister("min_players",           "setting min_active_clients %+");
    01822   IConsoleAliasRegister("reload_cfg",            "setting reload_cfg %+");
    01823 #endif /* ENABLE_NETWORK */
    01824
    01825   /* debugging stuff */
    01826 #ifdef _DEBUG
    01827   IConsoleDebugLibRegister();
    01828 #endif
    01829 }