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