console_cmds.cpp

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

Generated on Tue Jul 21 18:48:22 2009 for OpenTTD by  doxygen 1.5.6