# console_cmds.cpp

Go to the documentation of this file.

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