# console_cmds.cpp

Go to the documentation of this file.

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