00001
00002
00005 #include "stdafx.h"
00006 #include "openttd.h"
00007 #include "console.h"
00008 #include "debug.h"
00009 #include "engine.h"
00010 #include "landscape.h"
00011 #include "saveload.h"
00012 #include "variables.h"
00013 #include "network/network_data.h"
00014 #include "network/network_client.h"
00015 #include "network/network_server.h"
00016 #include "network/network_udp.h"
00017 #include "command_func.h"
00018 #include "settings_func.h"
00019 #include "fios.h"
00020 #include "fileio.h"
00021 #include "station.h"
00022 #include "screenshot.h"
00023 #include "genworld.h"
00024 #include "network/network.h"
00025 #include "strings_func.h"
00026 #include "viewport_func.h"
00027 #include "window_func.h"
00028 #include "functions.h"
00029 #include "map_func.h"
00030 #include "date_func.h"
00031 #include "vehicle_func.h"
00032 #include "string_func.h"
00033 #include "player_func.h"
00034 #include "player_base.h"
00035 #include "settings_type.h"
00036
00037 #ifdef ENABLE_NETWORK
00038 #include "table/strings.h"
00039 #endif
00040
00041
00042 static FILE *_script_file;
00043 static bool _script_running;
00044
00045
00046 #define DEF_CONSOLE_CMD(function) static bool function(byte argc, char *argv[])
00047 #define DEF_CONSOLE_HOOK(function) static bool function()
00048
00049
00050
00051
00052
00053
00054 #ifdef ENABLE_NETWORK
00055
00056 static inline bool NetworkAvailable()
00057 {
00058 if (!_network_available) {
00059 IConsoleError("You cannot use this command because there is no network available.");
00060 return false;
00061 }
00062 return true;
00063 }
00064
00065 DEF_CONSOLE_HOOK(ConHookServerOnly)
00066 {
00067 if (!NetworkAvailable()) return false;
00068
00069 if (!_network_server) {
00070 IConsoleError("This command/variable is only available to a network server.");
00071 return false;
00072 }
00073 return true;
00074 }
00075
00076 DEF_CONSOLE_HOOK(ConHookClientOnly)
00077 {
00078 if (!NetworkAvailable()) return false;
00079
00080 if (_network_server) {
00081 IConsoleError("This command/variable is not available to a network server.");
00082 return false;
00083 }
00084 return true;
00085 }
00086
00087 DEF_CONSOLE_HOOK(ConHookNeedNetwork)
00088 {
00089 if (!NetworkAvailable()) return false;
00090
00091 if (!_networking) {
00092 IConsoleError("Not connected. This command/variable is only available in multiplayer.");
00093 return false;
00094 }
00095 return true;
00096 }
00097
00098 DEF_CONSOLE_HOOK(ConHookNoNetwork)
00099 {
00100 if (_networking) {
00101 IConsoleError("This command/variable is forbidden in multiplayer.");
00102 return false;
00103 }
00104 return true;
00105 }
00106
00107 #endif
00108
00109 static void IConsoleHelp(const char *str)
00110 {
00111 IConsolePrintF(_icolour_warn, "- %s", str);
00112 }
00113
00114 DEF_CONSOLE_CMD(ConResetEngines)
00115 {
00116 if (argc == 0) {
00117 IConsoleHelp("Reset status data of all engines. This might solve some issues with 'lost' engines. Usage: 'resetengines'");
00118 return true;
00119 }
00120
00121 StartupEngines();
00122 return true;
00123 }
00124
00125 #ifdef _DEBUG
00126 DEF_CONSOLE_CMD(ConResetTile)
00127 {
00128 if (argc == 0) {
00129 IConsoleHelp("Reset a tile to bare land. Usage: 'resettile <tile>'");
00130 IConsoleHelp("Tile can be either decimal (34161) or hexadecimal (0x4a5B)");
00131 return true;
00132 }
00133
00134 if (argc == 2) {
00135 uint32 result;
00136 if (GetArgumentInteger(&result, argv[1])) {
00137 DoClearSquare((TileIndex)result);
00138 return true;
00139 }
00140 }
00141
00142 return false;
00143 }
00144
00145 DEF_CONSOLE_CMD(ConStopAllVehicles)
00146 {
00147 if (argc == 0) {
00148 IConsoleHelp("Stops all vehicles in the game. For debugging only! Use at your own risk... Usage: 'stopall'");
00149 return true;
00150 }
00151
00152 StopAllVehicles();
00153 return true;
00154 }
00155 #endif
00156
00157 DEF_CONSOLE_CMD(ConScrollToTile)
00158 {
00159 if (argc == 0) {
00160 IConsoleHelp("Center the screen on a given tile. Usage: 'scrollto <tile>'");
00161 IConsoleHelp("Tile can be either decimal (34161) or hexadecimal (0x4a5B)");
00162 return true;
00163 }
00164
00165 if (argc == 2) {
00166 uint32 result;
00167 if (GetArgumentInteger(&result, argv[1])) {
00168 if (result >= MapSize()) {
00169 IConsolePrint(_icolour_err, "Tile does not exist");
00170 return true;
00171 }
00172 ScrollMainWindowToTile((TileIndex)result);
00173 return true;
00174 }
00175 }
00176
00177 return false;
00178 }
00179
00180 extern void BuildFileList();
00181 extern void SetFiosType(const byte fiostype);
00182
00183
00184 DEF_CONSOLE_CMD(ConSave)
00185 {
00186 if (argc == 0) {
00187 IConsoleHelp("Save the current game. Usage: 'save <filename>'");
00188 return true;
00189 }
00190
00191 if (argc == 2) {
00192 char *filename = str_fmt("%s.sav", argv[1]);
00193 IConsolePrint(_icolour_def, "Saving map...");
00194
00195 if (SaveOrLoad(filename, SL_SAVE, SAVE_DIR) != SL_OK) {
00196 IConsolePrint(_icolour_err, "Saving map failed");
00197 } else {
00198 IConsolePrintF(_icolour_def, "Map sucessfully saved to %s", filename);
00199 }
00200 free(filename);
00201 return true;
00202 }
00203
00204 return false;
00205 }
00206
00207
00208 DEF_CONSOLE_CMD(ConSaveConfig)
00209 {
00210 if (argc == 0) {
00211 IConsoleHelp("Saves the current config, typically to 'openttd.cfg'.");
00212 return true;
00213 }
00214
00215 SaveToConfig();
00216 IConsolePrint(_icolour_def, "Saved config.");
00217 return true;
00218 }
00219
00220 static const FiosItem* GetFiosItem(const char* file)
00221 {
00222 int i;
00223
00224 _saveload_mode = SLD_LOAD_GAME;
00225 BuildFileList();
00226
00227 for (i = 0; i < _fios_num; i++) {
00228 if (strcmp(file, _fios_list[i].name) == 0) break;
00229 if (strcmp(file, _fios_list[i].title) == 0) break;
00230 }
00231
00232 if (i == _fios_num) {
00233 char* endptr;
00234
00235 i = strtol(file, &endptr, 10);
00236 if (file == endptr || *endptr != '\0') i = -1;
00237 }
00238
00239 return IsInsideMM(i, 0, _fios_num) ? &_fios_list[i] : NULL;
00240 }
00241
00242
00243 DEF_CONSOLE_CMD(ConLoad)
00244 {
00245 const FiosItem *item;
00246 const char *file;
00247
00248 if (argc == 0) {
00249 IConsoleHelp("Load a game by name or index. Usage: 'load <file | number>'");
00250 return true;
00251 }
00252
00253 if (argc != 2) return false;
00254
00255 file = argv[1];
00256 item = GetFiosItem(file);
00257 if (item != NULL) {
00258 switch (item->type) {
00259 case FIOS_TYPE_FILE: case FIOS_TYPE_OLDFILE: {
00260 _switch_mode = SM_LOAD;
00261 SetFiosType(item->type);
00262
00263 ttd_strlcpy(_file_to_saveload.name, FiosBrowseTo(item), sizeof(_file_to_saveload.name));
00264 ttd_strlcpy(_file_to_saveload.title, item->title, sizeof(_file_to_saveload.title));
00265 } break;
00266 default: IConsolePrintF(_icolour_err, "%s: Not a savegame.", file);
00267 }
00268 } else {
00269 IConsolePrintF(_icolour_err, "%s: No such file or directory.", file);
00270 }
00271
00272 FiosFreeSavegameList();
00273 return true;
00274 }
00275
00276
00277 DEF_CONSOLE_CMD(ConRemove)
00278 {
00279 const FiosItem* item;
00280 const char* file;
00281
00282 if (argc == 0) {
00283 IConsoleHelp("Remove a savegame by name or index. Usage: 'rm <file | number>'");
00284 return true;
00285 }
00286
00287 if (argc != 2) return false;
00288
00289 file = argv[1];
00290 item = GetFiosItem(file);
00291 if (item != NULL) {
00292 if (!FiosDelete(item->name))
00293 IConsolePrintF(_icolour_err, "%s: Failed to delete file", file);
00294 } else {
00295 IConsolePrintF(_icolour_err, "%s: No such file or directory.", file);
00296 }
00297
00298 FiosFreeSavegameList();
00299 return true;
00300 }
00301
00302
00303
00304 DEF_CONSOLE_CMD(ConListFiles)
00305 {
00306 int i;
00307
00308 if (argc == 0) {
00309 IConsoleHelp("List all loadable savegames and directories in the current dir via console. Usage: 'ls | dir'");
00310 return true;
00311 }
00312
00313 BuildFileList();
00314
00315 for (i = 0; i < _fios_num; i++) {
00316 const FiosItem *item = &_fios_list[i];
00317 IConsolePrintF(_icolour_def, "%d) %s", i, item->title);
00318 }
00319
00320 FiosFreeSavegameList();
00321 return true;
00322 }
00323
00324
00325 DEF_CONSOLE_CMD(ConChangeDirectory)
00326 {
00327 const FiosItem *item;
00328 const char *file;
00329
00330 if (argc == 0) {
00331 IConsoleHelp("Change the dir via console. Usage: 'cd <directory | number>'");
00332 return true;
00333 }
00334
00335 if (argc != 2) return false;
00336
00337 file = argv[1];
00338 item = GetFiosItem(file);
00339 if (item != NULL) {
00340 switch (item->type) {
00341 case FIOS_TYPE_DIR: case FIOS_TYPE_DRIVE: case FIOS_TYPE_PARENT:
00342 FiosBrowseTo(item);
00343 break;
00344 default: IConsolePrintF(_icolour_err, "%s: Not a directory.", file);
00345 }
00346 } else {
00347 IConsolePrintF(_icolour_err, "%s: No such file or directory.", file);
00348 }
00349
00350 FiosFreeSavegameList();
00351 return true;
00352 }
00353
00354 DEF_CONSOLE_CMD(ConPrintWorkingDirectory)
00355 {
00356 const char *path;
00357
00358 if (argc == 0) {
00359 IConsoleHelp("Print out the current working directory. Usage: 'pwd'");
00360 return true;
00361 }
00362
00363
00364 FiosGetSavegameList(SLD_LOAD_GAME);
00365 FiosFreeSavegameList();
00366
00367 FiosGetDescText(&path, NULL);
00368 IConsolePrint(_icolour_def, path);
00369 return true;
00370 }
00371
00372 DEF_CONSOLE_CMD(ConClearBuffer)
00373 {
00374 if (argc == 0) {
00375 IConsoleHelp("Clear the console buffer. Usage: 'clear'");
00376 return true;
00377 }
00378
00379 IConsoleClearBuffer();
00380 InvalidateWindow(WC_CONSOLE, 0);
00381 return true;
00382 }
00383
00384
00385
00386
00387
00388 #ifdef ENABLE_NETWORK
00389
00390 DEF_CONSOLE_CMD(ConBan)
00391 {
00392 NetworkClientInfo *ci;
00393 const char *banip = NULL;
00394 uint32 index;
00395
00396 if (argc == 0) {
00397 IConsoleHelp("Ban a player from a network game. Usage: 'ban <ip | client-id>'");
00398 IConsoleHelp("For client-id's, see the command 'clients'");
00399 IConsoleHelp("If the client is no longer online, you can still ban his/her IP");
00400 return true;
00401 }
00402
00403 if (argc != 2) return false;
00404
00405 if (strchr(argv[1], '.') == NULL) {
00406 index = atoi(argv[1]);
00407 ci = NetworkFindClientInfoFromIndex(index);
00408 } else {
00409 ci = NetworkFindClientInfoFromIP(argv[1]);
00410 if (ci == NULL) {
00411 banip = argv[1];
00412 index = (uint32)-1;
00413 } else {
00414 index = ci->client_index;
00415 }
00416 }
00417
00418 if (index == NETWORK_SERVER_INDEX) {
00419 IConsoleError("Silly boy, you can not ban yourself!");
00420 return true;
00421 }
00422
00423 if (index == 0 || (ci == NULL && index != (uint32)-1)) {
00424 IConsoleError("Invalid client");
00425 return true;
00426 }
00427
00428 if (ci != NULL) {
00429 IConsolePrint(_icolour_def, "Client banned");
00430 banip = inet_ntoa(*(struct in_addr *)&ci->client_ip);
00431 SEND_COMMAND(PACKET_SERVER_ERROR)(NetworkFindClientStateFromIndex(index), NETWORK_ERROR_KICKED);
00432 } else {
00433 IConsolePrint(_icolour_def, "Client not online, banned IP");
00434 }
00435
00436
00437 for (index = 0; index < lengthof(_network_ban_list); index++) {
00438 if (_network_ban_list[index] == NULL) {
00439 _network_ban_list[index] = strdup(banip);
00440 break;
00441 }
00442 }
00443
00444 return true;
00445 }
00446
00447 DEF_CONSOLE_CMD(ConUnBan)
00448 {
00449 uint i, index;
00450
00451 if (argc == 0) {
00452 IConsoleHelp("Unban a player from a network game. Usage: 'unban <ip | client-id>'");
00453 IConsoleHelp("For a list of banned IP's, see the command 'banlist'");
00454 return true;
00455 }
00456
00457 if (argc != 2) return false;
00458
00459 index = (strchr(argv[1], '.') == NULL) ? atoi(argv[1]) : 0;
00460 index--;
00461
00462 for (i = 0; i < lengthof(_network_ban_list); i++) {
00463 if (_network_ban_list[i] == NULL) continue;
00464
00465 if (strcmp(_network_ban_list[i], argv[1]) == 0 || index == i) {
00466 free(_network_ban_list[i]);
00467 _network_ban_list[i] = NULL;
00468 IConsolePrint(_icolour_def, "IP unbanned.");
00469 return true;
00470 }
00471 }
00472
00473 IConsolePrint(_icolour_def, "IP not in ban-list.");
00474 return true;
00475 }
00476
00477 DEF_CONSOLE_CMD(ConBanList)
00478 {
00479 uint i;
00480
00481 if (argc == 0) {
00482 IConsoleHelp("List the IP's of banned clients: Usage 'banlist'");
00483 return true;
00484 }
00485
00486 IConsolePrint(_icolour_def, "Banlist: ");
00487
00488 for (i = 0; i < lengthof(_network_ban_list); i++) {
00489 if (_network_ban_list[i] != NULL)
00490 IConsolePrintF(_icolour_def, " %d) %s", i + 1, _network_ban_list[i]);
00491 }
00492
00493 return true;
00494 }
00495
00496 DEF_CONSOLE_CMD(ConPauseGame)
00497 {
00498 if (argc == 0) {
00499 IConsoleHelp("Pause a network game. Usage: 'pause'");
00500 return true;
00501 }
00502
00503 if (_pause_game == 0) {
00504 DoCommandP(0, 1, 0, NULL, CMD_PAUSE);
00505 IConsolePrint(_icolour_def, "Game paused.");
00506 } else {
00507 IConsolePrint(_icolour_def, "Game is already paused.");
00508 }
00509
00510 return true;
00511 }
00512
00513 DEF_CONSOLE_CMD(ConUnPauseGame)
00514 {
00515 if (argc == 0) {
00516 IConsoleHelp("Unpause a network game. Usage: 'unpause'");
00517 return true;
00518 }
00519
00520 if (_pause_game != 0) {
00521 DoCommandP(0, 0, 0, NULL, CMD_PAUSE);
00522 IConsolePrint(_icolour_def, "Game unpaused.");
00523 } else {
00524 IConsolePrint(_icolour_def, "Game is already unpaused.");
00525 }
00526
00527 return true;
00528 }
00529
00530 DEF_CONSOLE_CMD(ConRcon)
00531 {
00532 if (argc == 0) {
00533 IConsoleHelp("Remote control the server from another client. Usage: 'rcon <password> <command>'");
00534 IConsoleHelp("Remember to enclose the command in quotes, otherwise only the first parameter is sent");
00535 return true;
00536 }
00537
00538 if (argc < 3) return false;
00539
00540 if (_network_server) {
00541 IConsoleCmdExec(argv[2]);
00542 } else {
00543 SEND_COMMAND(PACKET_CLIENT_RCON)(argv[1], argv[2]);
00544 }
00545 return true;
00546 }
00547
00548 DEF_CONSOLE_CMD(ConStatus)
00549 {
00550 static const char* const stat_str[] = {
00551 "inactive",
00552 "authorizing",
00553 "authorized",
00554 "waiting",
00555 "loading map",
00556 "map done",
00557 "ready",
00558 "active"
00559 };
00560
00561 NetworkTCPSocketHandler *cs;
00562
00563 if (argc == 0) {
00564 IConsoleHelp("List the status of all clients connected to the server. Usage 'status'");
00565 return true;
00566 }
00567
00568 FOR_ALL_CLIENTS(cs) {
00569 int lag = NetworkCalculateLag(cs);
00570 const NetworkClientInfo *ci = DEREF_CLIENT_INFO(cs);
00571 const char* status;
00572
00573 status = (cs->status < (ptrdiff_t)lengthof(stat_str) ? stat_str[cs->status] : "unknown");
00574 IConsolePrintF(8, "Client #%1d name: '%s' status: '%s' frame-lag: %3d company: %1d IP: %s unique-id: '%s'",
00575 cs->index, ci->client_name, status, lag,
00576 ci->client_playas + (IsValidPlayer(ci->client_playas) ? 1 : 0),
00577 GetPlayerIP(ci), ci->unique_id);
00578 }
00579
00580 return true;
00581 }
00582
00583 DEF_CONSOLE_CMD(ConServerInfo)
00584 {
00585 const NetworkGameInfo *gi;
00586
00587 if (argc == 0) {
00588 IConsoleHelp("List current and maximum client/player limits. Usage 'server_info'");
00589 IConsoleHelp("You can change these values by setting the variables 'max_clients', 'max_companies' and 'max_spectators'");
00590 return true;
00591 }
00592
00593 gi = &_network_game_info;
00594 IConsolePrintF(_icolour_def, "Current/maximum clients: %2d/%2d", gi->clients_on, gi->clients_max);
00595 IConsolePrintF(_icolour_def, "Current/maximum companies: %2d/%2d", ActivePlayerCount(), gi->companies_max);
00596 IConsolePrintF(_icolour_def, "Current/maximum spectators: %2d/%2d", NetworkSpectatorCount(), gi->spectators_max);
00597
00598 return true;
00599 }
00600
00601 DEF_CONSOLE_HOOK(ConHookValidateMaxClientsCount)
00602 {
00603 if (_network_game_info.clients_max > MAX_CLIENTS) {
00604 _network_game_info.clients_max = MAX_CLIENTS;
00605 IConsoleError("Maximum clients out of bounds, truncating to limit.");
00606 }
00607
00608 return true;
00609 }
00610
00611 DEF_CONSOLE_HOOK(ConHookValidateMaxCompaniesCount)
00612 {
00613 if (_network_game_info.companies_max > MAX_PLAYERS) {
00614 _network_game_info.companies_max = MAX_PLAYERS;
00615 IConsoleError("Maximum companies out of bounds, truncating to limit.");
00616 }
00617
00618 return true;
00619 }
00620
00621 DEF_CONSOLE_HOOK(ConHookValidateMaxSpectatorsCount)
00622 {
00623
00624 if (_network_game_info.spectators_max > 10) {
00625 _network_game_info.spectators_max = 10;
00626 IConsoleError("Maximum spectators out of bounds, truncating to limit.");
00627 }
00628
00629 return true;
00630 }
00631
00632 DEF_CONSOLE_HOOK(ConHookCheckMinPlayers)
00633 {
00634 CheckMinPlayers();
00635 return true;
00636 }
00637
00638 DEF_CONSOLE_CMD(ConKick)
00639 {
00640 NetworkClientInfo *ci;
00641 uint32 index;
00642
00643 if (argc == 0) {
00644 IConsoleHelp("Kick a player from a network game. Usage: 'kick <ip | client-id>'");
00645 IConsoleHelp("For client-id's, see the command 'clients'");
00646 return true;
00647 }
00648
00649 if (argc != 2) return false;
00650
00651 if (strchr(argv[1], '.') == NULL) {
00652 index = atoi(argv[1]);
00653 ci = NetworkFindClientInfoFromIndex(index);
00654 } else {
00655 ci = NetworkFindClientInfoFromIP(argv[1]);
00656 index = (ci == NULL) ? 0 : ci->client_index;
00657 }
00658
00659 if (index == NETWORK_SERVER_INDEX) {
00660 IConsoleError("Silly boy, you can not kick yourself!");
00661 return true;
00662 }
00663
00664 if (index == 0) {
00665 IConsoleError("Invalid client");
00666 return true;
00667 }
00668
00669 if (ci != NULL) {
00670 SEND_COMMAND(PACKET_SERVER_ERROR)(NetworkFindClientStateFromIndex(index), NETWORK_ERROR_KICKED);
00671 } else {
00672 IConsoleError("Client not found");
00673 }
00674
00675 return true;
00676 }
00677
00678 DEF_CONSOLE_CMD(ConResetCompany)
00679 {
00680 const Player *p;
00681 NetworkTCPSocketHandler *cs;
00682 const NetworkClientInfo *ci;
00683 PlayerID index;
00684
00685 if (argc == 0) {
00686 IConsoleHelp("Remove an idle company from the game. Usage: 'reset_company <company-id>'");
00687 IConsoleHelp("For company-id's, see the list of companies from the dropdown menu. Player 1 is 1, etc.");
00688 return true;
00689 }
00690
00691 if (argc != 2) return false;
00692
00693 index = (PlayerID)(atoi(argv[1]) - 1);
00694
00695
00696 if (!IsValidPlayer(index)) {
00697 IConsolePrintF(_icolour_err, "Company does not exist. Company-id must be between 1 and %d.", MAX_PLAYERS);
00698 return true;
00699 }
00700
00701
00702 p = GetPlayer(index);
00703 if (!p->is_active) {
00704 IConsoleError("Company does not exist.");
00705 return true;
00706 }
00707
00708 if (p->is_ai) {
00709 IConsoleError("Company is owned by an AI.");
00710 return true;
00711 }
00712
00713
00714 FOR_ALL_CLIENTS(cs) {
00715 ci = DEREF_CLIENT_INFO(cs);
00716 if (ci->client_playas == index) {
00717 IConsoleError("Cannot remove company: a client is connected to that company.");
00718 return true;
00719 }
00720 }
00721 ci = NetworkFindClientInfoFromIndex(NETWORK_SERVER_INDEX);
00722 if (ci->client_playas == index) {
00723 IConsoleError("Cannot remove company: the server is connected to that company.");
00724 return true;
00725 }
00726
00727
00728 DoCommandP(0, 2, index, NULL, CMD_PLAYER_CTRL);
00729 IConsolePrint(_icolour_def, "Company deleted.");
00730
00731 return true;
00732 }
00733
00734 DEF_CONSOLE_CMD(ConNetworkClients)
00735 {
00736 NetworkClientInfo *ci;
00737
00738 if (argc == 0) {
00739 IConsoleHelp("Get a list of connected clients including their ID, name, company-id, and IP. Usage: 'clients'");
00740 return true;
00741 }
00742
00743 FOR_ALL_ACTIVE_CLIENT_INFOS(ci) {
00744 IConsolePrintF(8, "Client #%1d name: '%s' company: %1d IP: %s",
00745 ci->client_index, ci->client_name,
00746 ci->client_playas + (IsValidPlayer(ci->client_playas) ? 1 : 0),
00747 GetPlayerIP(ci));
00748 }
00749
00750 return true;
00751 }
00752
00753 DEF_CONSOLE_CMD(ConNetworkConnect)
00754 {
00755 char *ip;
00756 const char *port = NULL;
00757 const char *player = NULL;
00758 uint16 rport;
00759
00760 if (argc == 0) {
00761 IConsoleHelp("Connect to a remote OTTD server and join the game. Usage: 'connect <ip>'");
00762 IConsoleHelp("IP can contain port and player: 'IP[[#Player]:Port]', eg: 'server.ottd.org#2:443'");
00763 IConsoleHelp("Player #255 is spectator all others are a certain company with Company 1 being #1");
00764 return true;
00765 }
00766
00767 if (argc < 2) return false;
00768 if (_networking) NetworkDisconnect();
00769
00770 ip = argv[1];
00771
00772 rport = NETWORK_DEFAULT_PORT;
00773 _network_playas = PLAYER_NEW_COMPANY;
00774
00775 ParseConnectionString(&player, &port, ip);
00776
00777 IConsolePrintF(_icolour_def, "Connecting to %s...", ip);
00778 if (player != NULL) {
00779 _network_playas = (PlayerID)atoi(player);
00780 IConsolePrintF(_icolour_def, " player-no: %d", _network_playas);
00781
00782
00783
00784 if (_network_playas != PLAYER_SPECTATOR) {
00785 _network_playas--;
00786 if (!IsValidPlayer(_network_playas)) return false;
00787 }
00788 }
00789 if (port != NULL) {
00790 rport = atoi(port);
00791 IConsolePrintF(_icolour_def, " port: %s", port);
00792 }
00793
00794 NetworkClientConnectGame(ip, rport);
00795
00796 return true;
00797 }
00798
00799 #endif
00800
00801
00802
00803
00804
00805 DEF_CONSOLE_CMD(ConExec)
00806 {
00807 char cmdline[ICON_CMDLN_SIZE];
00808 char *cmdptr;
00809
00810 if (argc == 0) {
00811 IConsoleHelp("Execute a local script file. Usage: 'exec <script> <?>'");
00812 return true;
00813 }
00814
00815 if (argc < 2) return false;
00816
00817 _script_file = FioFOpenFile(argv[1], "r", BASE_DIR);
00818
00819 if (_script_file == NULL) {
00820 if (argc == 2 || atoi(argv[2]) != 0) IConsoleError("script file not found");
00821 return true;
00822 }
00823
00824 _script_running = true;
00825
00826 while (_script_running && fgets(cmdline, sizeof(cmdline), _script_file) != NULL) {
00827
00828 for (cmdptr = cmdline; *cmdptr != '\0'; cmdptr++) {
00829 if (*cmdptr == '\n' || *cmdptr == '\r') {
00830 *cmdptr = '\0';
00831 break;
00832 }
00833 }
00834 IConsoleCmdExec(cmdline);
00835 }
00836
00837 if (ferror(_script_file))
00838 IConsoleError("Encountered errror while trying to read from script file");
00839
00840 _script_running = false;
00841 FioFCloseFile(_script_file);
00842 return true;
00843 }
00844
00845 DEF_CONSOLE_CMD(ConReturn)
00846 {
00847 if (argc == 0) {
00848 IConsoleHelp("Stop executing a running script. Usage: 'return'");
00849 return true;
00850 }
00851
00852 _script_running = false;
00853 return true;
00854 }
00855
00856
00857
00858
00859 extern bool CloseConsoleLogIfActive();
00860
00861 DEF_CONSOLE_CMD(ConScript)
00862 {
00863 extern FILE* _iconsole_output_file;
00864
00865 if (argc == 0) {
00866 IConsoleHelp("Start or stop logging console output to a file. Usage: 'script <filename>'");
00867 IConsoleHelp("If filename is omitted, a running log is stopped if it is active");
00868 return true;
00869 }
00870
00871 if (!CloseConsoleLogIfActive()) {
00872 if (argc < 2) return false;
00873
00874 IConsolePrintF(_icolour_def, "file output started to: %s", argv[1]);
00875 _iconsole_output_file = fopen(argv[1], "ab");
00876 if (_iconsole_output_file == NULL) IConsoleError("could not open file");
00877 }
00878
00879 return true;
00880 }
00881
00882
00883 DEF_CONSOLE_CMD(ConEcho)
00884 {
00885 if (argc == 0) {
00886 IConsoleHelp("Print back the first argument to the console. Usage: 'echo <arg>'");
00887 return true;
00888 }
00889
00890 if (argc < 2) return false;
00891 IConsolePrint(_icolour_def, argv[1]);
00892 return true;
00893 }
00894
00895 DEF_CONSOLE_CMD(ConEchoC)
00896 {
00897 if (argc == 0) {
00898 IConsoleHelp("Print back the first argument to the console in a given colour. Usage: 'echoc <colour> <arg2>'");
00899 return true;
00900 }
00901
00902 if (argc < 3) return false;
00903 IConsolePrint(atoi(argv[1]), argv[2]);
00904 return true;
00905 }
00906
00907 DEF_CONSOLE_CMD(ConNewGame)
00908 {
00909 if (argc == 0) {
00910 IConsoleHelp("Start a new game. Usage: 'newgame [seed]'");
00911 IConsoleHelp("The server can force a new game using 'newgame'; any client joined will rejoin after the server is done generating the new game.");
00912 return true;
00913 }
00914
00915 StartNewGameWithoutGUI((argc == 2) ? (uint)atoi(argv[1]) : GENERATE_NEW_SEED);
00916 return true;
00917 }
00918
00919 extern void SwitchMode(int new_mode);
00920
00921 DEF_CONSOLE_CMD(ConRestart)
00922 {
00923 if (argc == 0) {
00924 IConsoleHelp("Restart game. Usage: 'restart'");
00925 IConsoleHelp("Restarts a game. It tries to reproduce the exact same map as the game started with.");
00926 return true;
00927 }
00928
00929
00930 _patches.map_x = MapLogX();
00931 _patches.map_y = FindFirstBit(MapSizeY());
00932 SwitchMode(SM_NEWGAME);
00933 return true;
00934 }
00935
00936 DEF_CONSOLE_CMD(ConGetSeed)
00937 {
00938 if (argc == 0) {
00939 IConsoleHelp("Returns the seed used to create this game. Usage: 'getseed'");
00940 IConsoleHelp("The seed can be used to reproduce the exact same map as the game started with.");
00941 return true;
00942 }
00943
00944 IConsolePrintF(_icolour_def, "Generation Seed: %u", _patches.generation_seed);
00945 return true;
00946 }
00947
00948 DEF_CONSOLE_CMD(ConGetDate)
00949 {
00950 if (argc == 0) {
00951 IConsoleHelp("Returns the current date (day-month-year) of the game. Usage: 'getdate'");
00952 return true;
00953 }
00954
00955 YearMonthDay ymd;
00956 ConvertDateToYMD(_date, &ymd);
00957 IConsolePrintF(_icolour_def, "Date: %d-%d-%d", ymd.day, ymd.month + 1, ymd.year);
00958 return true;
00959 }
00960
00961
00962 DEF_CONSOLE_CMD(ConAlias)
00963 {
00964 IConsoleAlias *alias;
00965
00966 if (argc == 0) {
00967 IConsoleHelp("Add a new alias, or redefine the behaviour of an existing alias . Usage: 'alias <name> <command>'");
00968 return true;
00969 }
00970
00971 if (argc < 3) return false;
00972
00973 alias = IConsoleAliasGet(argv[1]);
00974 if (alias == NULL) {
00975 IConsoleAliasRegister(argv[1], argv[2]);
00976 } else {
00977 free(alias->cmdline);
00978 alias->cmdline = strdup(argv[2]);
00979 }
00980 return true;
00981 }
00982
00983 DEF_CONSOLE_CMD(ConScreenShot)
00984 {
00985 if (argc == 0) {
00986 IConsoleHelp("Create a screenshot of the game. Usage: 'screenshot [big | no_con]'");
00987 IConsoleHelp("'big' makes a screenshot of the whole map, 'no_con' hides the console to create the screenshot");
00988 return true;
00989 }
00990
00991 if (argc > 3) return false;
00992
00993 SetScreenshotType(SC_VIEWPORT);
00994 if (argc > 1) {
00995 if (strcmp(argv[1], "big") == 0 || (argc == 3 && strcmp(argv[2], "big") == 0))
00996 SetScreenshotType(SC_WORLD);
00997
00998 if (strcmp(argv[1], "no_con") == 0 || (argc == 3 && strcmp(argv[2], "no_con") == 0))
00999 IConsoleClose();
01000 }
01001
01002 return true;
01003 }
01004
01005 DEF_CONSOLE_CMD(ConInfoVar)
01006 {
01007 static const char *_icon_vartypes[] = {"boolean", "byte", "uint16", "uint32", "int16", "int32", "string"};
01008 const IConsoleVar *var;
01009
01010 if (argc == 0) {
01011 IConsoleHelp("Print out debugging information about a variable. Usage: 'info_var <var>'");
01012 return true;
01013 }
01014
01015 if (argc < 2) return false;
01016
01017 var = IConsoleVarGet(argv[1]);
01018 if (var == NULL) {
01019 IConsoleError("the given variable was not found");
01020 return true;
01021 }
01022
01023 IConsolePrintF(_icolour_def, "variable name: %s", var->name);
01024 IConsolePrintF(_icolour_def, "variable type: %s", _icon_vartypes[var->type]);
01025 IConsolePrintF(_icolour_def, "variable addr: 0x%X", var->addr);
01026
01027 if (var->hook.access) IConsoleWarning("variable is access hooked");
01028 if (var->hook.pre) IConsoleWarning("variable is pre hooked");
01029 if (var->hook.post) IConsoleWarning("variable is post hooked");
01030 return true;
01031 }
01032
01033
01034 DEF_CONSOLE_CMD(ConInfoCmd)
01035 {
01036 const IConsoleCmd *cmd;
01037
01038 if (argc == 0) {
01039 IConsoleHelp("Print out debugging information about a command. Usage: 'info_cmd <cmd>'");
01040 return true;
01041 }
01042
01043 if (argc < 2) return false;
01044
01045 cmd = IConsoleCmdGet(argv[1]);
01046 if (cmd == NULL) {
01047 IConsoleError("the given command was not found");
01048 return true;
01049 }
01050
01051 IConsolePrintF(_icolour_def, "command name: %s", cmd->name);
01052 IConsolePrintF(_icolour_def, "command proc: 0x%X", cmd->proc);
01053
01054 if (cmd->hook.access) IConsoleWarning("command is access hooked");
01055 if (cmd->hook.pre) IConsoleWarning("command is pre hooked");
01056 if (cmd->hook.post) IConsoleWarning("command is post hooked");
01057
01058 return true;
01059 }
01060
01061 DEF_CONSOLE_CMD(ConDebugLevel)
01062 {
01063 if (argc == 0) {
01064 IConsoleHelp("Get/set the default debugging level for the game. Usage: 'debug_level [<level>]'");
01065 IConsoleHelp("Level can be any combination of names, levels. Eg 'net=5 ms=4'. Remember to enclose it in \"'s");
01066 return true;
01067 }
01068
01069 if (argc > 2) return false;
01070
01071 if (argc == 1) {
01072 IConsolePrintF(_icolour_def, "Current debug-level: '%s'", GetDebugString());
01073 } else {
01074 SetDebugString(argv[1]);
01075 }
01076
01077 return true;
01078 }
01079
01080 DEF_CONSOLE_CMD(ConExit)
01081 {
01082 if (argc == 0) {
01083 IConsoleHelp("Exit the game. Usage: 'exit'");
01084 return true;
01085 }
01086
01087 if (_game_mode == GM_NORMAL && _patches.autosave_on_exit) DoExitSave();
01088
01089 _exit_game = true;
01090 return true;
01091 }
01092
01093 DEF_CONSOLE_CMD(ConPart)
01094 {
01095 if (argc == 0) {
01096 IConsoleHelp("Leave the currently joined/running game (only ingame). Usage: 'part'");
01097 return true;
01098 }
01099
01100 if (_game_mode != GM_NORMAL) return false;
01101
01102 _switch_mode = SM_MENU;
01103 return true;
01104 }
01105
01106 DEF_CONSOLE_CMD(ConHelp)
01107 {
01108 if (argc == 2) {
01109 const IConsoleCmd *cmd;
01110 const IConsoleVar *var;
01111 const IConsoleAlias *alias;
01112
01113 cmd = IConsoleCmdGet(argv[1]);
01114 if (cmd != NULL) {
01115 cmd->proc(0, NULL);
01116 return true;
01117 }
01118
01119 alias = IConsoleAliasGet(argv[1]);
01120 if (alias != NULL) {
01121 cmd = IConsoleCmdGet(alias->cmdline);
01122 if (cmd != NULL) {
01123 cmd->proc(0, NULL);
01124 return true;
01125 }
01126 IConsolePrintF(_icolour_err, "ERROR: alias is of special type, please see its execution-line: '%s'", alias->cmdline);
01127 return true;
01128 }
01129
01130 var = IConsoleVarGet(argv[1]);
01131 if (var != NULL && var->help != NULL) {
01132 IConsoleHelp(var->help);
01133 return true;
01134 }
01135
01136 IConsoleError("command or variable not found");
01137 return true;
01138 }
01139
01140 IConsolePrint(13, " ---- OpenTTD Console Help ---- ");
01141 IConsolePrint( 1, " - variables: [command to list all variables: list_vars]");
01142 IConsolePrint( 1, " set value with '<var> = <value>', use '++/--' to in-or decrement");
01143 IConsolePrint( 1, " or omit '=' and just '<var> <value>'. get value with typing '<var>'");
01144 IConsolePrint( 1, " - commands: [command to list all commands: list_cmds]");
01145 IConsolePrint( 1, " call commands with '<command> <arg2> <arg3>...'");
01146 IConsolePrint( 1, " - to assign strings, or use them as arguments, enclose it within quotes");
01147 IConsolePrint( 1, " like this: '<command> \"string argument with spaces\"'");
01148 IConsolePrint( 1, " - use 'help <command> | <variable>' to get specific information");
01149 IConsolePrint( 1, " - scroll console output with shift + (up | down) | (pageup | pagedown))");
01150 IConsolePrint( 1, " - scroll console input history with the up | down arrows");
01151 IConsolePrint( 1, "");
01152 return true;
01153 }
01154
01155 DEF_CONSOLE_CMD(ConListCommands)
01156 {
01157 const IConsoleCmd *cmd;
01158 size_t l = 0;
01159
01160 if (argc == 0) {
01161 IConsoleHelp("List all registered commands. Usage: 'list_cmds [<pre-filter>]'");
01162 return true;
01163 }
01164
01165 if (argv[1] != NULL) l = strlen(argv[1]);
01166
01167 for (cmd = _iconsole_cmds; cmd != NULL; cmd = cmd->next) {
01168 if (argv[1] == NULL || strncmp(cmd->name, argv[1], l) == 0) {
01169 IConsolePrintF(_icolour_def, "%s", cmd->name);
01170 }
01171 }
01172
01173 return true;
01174 }
01175
01176 DEF_CONSOLE_CMD(ConListVariables)
01177 {
01178 const IConsoleVar *var;
01179 size_t l = 0;
01180
01181 if (argc == 0) {
01182 IConsoleHelp("List all registered variables. Usage: 'list_vars [<pre-filter>]'");
01183 return true;
01184 }
01185
01186 if (argv[1] != NULL) l = strlen(argv[1]);
01187
01188 for (var = _iconsole_vars; var != NULL; var = var->next) {
01189 if (argv[1] == NULL || strncmp(var->name, argv[1], l) == 0)
01190 IConsolePrintF(_icolour_def, "%s", var->name);
01191 }
01192
01193 return true;
01194 }
01195
01196 DEF_CONSOLE_CMD(ConListAliases)
01197 {
01198 const IConsoleAlias *alias;
01199 size_t l = 0;
01200
01201 if (argc == 0) {
01202 IConsoleHelp("List all registered aliases. Usage: 'list_aliases [<pre-filter>]'");
01203 return true;
01204 }
01205
01206 if (argv[1] != NULL) l = strlen(argv[1]);
01207
01208 for (alias = _iconsole_aliases; alias != NULL; alias = alias->next) {
01209 if (argv[1] == NULL || strncmp(alias->name, argv[1], l) == 0)
01210 IConsolePrintF(_icolour_def, "%s => %s", alias->name, alias->cmdline);
01211 }
01212
01213 return true;
01214 }
01215
01216 #ifdef ENABLE_NETWORK
01217
01218 DEF_CONSOLE_CMD(ConSay)
01219 {
01220 if (argc == 0) {
01221 IConsoleHelp("Chat to your fellow players in a multiplayer game. Usage: 'say \"<msg>\"'");
01222 return true;
01223 }
01224
01225 if (argc != 2) return false;
01226
01227 if (!_network_server) {
01228 SEND_COMMAND(PACKET_CLIENT_CHAT)(NETWORK_ACTION_CHAT, DESTTYPE_BROADCAST, 0 , argv[1]);
01229 } else {
01230 NetworkServer_HandleChat(NETWORK_ACTION_CHAT, DESTTYPE_BROADCAST, 0, argv[1], NETWORK_SERVER_INDEX);
01231 }
01232
01233 return true;
01234 }
01235
01236 DEF_CONSOLE_CMD(ConPlayers)
01237 {
01238 Player *p;
01239
01240 if (argc == 0) {
01241 IConsoleHelp("List the in-game details of all clients connected to the server. Usage 'players'");
01242 return true;
01243 }
01244 NetworkPopulateCompanyInfo();
01245
01246 FOR_ALL_PLAYERS(p) {
01247 char buffer[512];
01248
01249 if (!p->is_active) continue;
01250
01251 const NetworkPlayerInfo *npi = &_network_player_info[p->index];
01252
01253 GetString(buffer, STR_00D1_DARK_BLUE + _player_colors[p->index], lastof(buffer));
01254 IConsolePrintF(8, "#:%d(%s) Company Name: '%s' Year Founded: %d Money: %" OTTD_PRINTF64 "d Loan: %" OTTD_PRINTF64 "d Value: %" OTTD_PRINTF64 "d (T:%d, R:%d, P:%d, S:%d) %sprotected",
01255 p->index + 1, buffer, npi->company_name, p->inaugurated_year, (int64)p->player_money, (int64)p->current_loan, (int64)CalculateCompanyValue(p),
01256 npi->num_vehicle[0],
01257 npi->num_vehicle[1] + npi->num_vehicle[2],
01258 npi->num_vehicle[3],
01259 npi->num_vehicle[4],
01260 StrEmpty(npi->password) ? "un" : "");
01261 }
01262
01263 return true;
01264 }
01265
01266 DEF_CONSOLE_CMD(ConSayPlayer)
01267 {
01268 if (argc == 0) {
01269 IConsoleHelp("Chat to a certain player in a multiplayer game. Usage: 'say_player <player-no> \"<msg>\"'");
01270 IConsoleHelp("PlayerNo is the player that plays as company <playerno>, 1 through max_players");
01271 return true;
01272 }
01273
01274 if (argc != 3) return false;
01275
01276 if (atoi(argv[1]) < 1 || atoi(argv[1]) > MAX_PLAYERS) {
01277 IConsolePrintF(_icolour_def, "Unknown player. Player range is between 1 and %d.", MAX_PLAYERS);
01278 return true;
01279 }
01280
01281 if (!_network_server) {
01282 SEND_COMMAND(PACKET_CLIENT_CHAT)(NETWORK_ACTION_CHAT_COMPANY, DESTTYPE_TEAM, atoi(argv[1]), argv[2]);
01283 } else {
01284 NetworkServer_HandleChat(NETWORK_ACTION_CHAT_COMPANY, DESTTYPE_TEAM, atoi(argv[1]), argv[2], NETWORK_SERVER_INDEX);
01285 }
01286
01287 return true;
01288 }
01289
01290 DEF_CONSOLE_CMD(ConSayClient)
01291 {
01292 if (argc == 0) {
01293 IConsoleHelp("Chat to a certain player in a multiplayer game. Usage: 'say_client <client-no> \"<msg>\"'");
01294 IConsoleHelp("For client-id's, see the command 'clients'");
01295 return true;
01296 }
01297
01298 if (argc != 3) return false;
01299
01300 if (!_network_server) {
01301 SEND_COMMAND(PACKET_CLIENT_CHAT)(NETWORK_ACTION_CHAT_CLIENT, DESTTYPE_CLIENT, atoi(argv[1]), argv[2]);
01302 } else {
01303 NetworkServer_HandleChat(NETWORK_ACTION_CHAT_CLIENT, DESTTYPE_CLIENT, atoi(argv[1]), argv[2], NETWORK_SERVER_INDEX);
01304 }
01305
01306 return true;
01307 }
01308
01309 DEF_CONSOLE_HOOK(ConHookServerPW)
01310 {
01311 if (strcmp(_network_server_password, "*") == 0) {
01312 _network_server_password[0] = '\0';
01313 _network_game_info.use_password = 0;
01314 } else {
01315 ttd_strlcpy(_network_game_info.server_password, _network_server_password, sizeof(_network_server_password));
01316 _network_game_info.use_password = 1;
01317 }
01318
01319 return true;
01320 }
01321
01322 DEF_CONSOLE_HOOK(ConHookRconPW)
01323 {
01324 if (strcmp(_network_rcon_password, "*") == 0)
01325 _network_rcon_password[0] = '\0';
01326
01327 ttd_strlcpy(_network_game_info.rcon_password, _network_rcon_password, sizeof(_network_game_info.rcon_password));
01328
01329 return true;
01330 }
01331
01332 extern void HashCurrentCompanyPassword();
01333
01334
01335 bool NetworkChangeCompanyPassword(byte argc, char *argv[])
01336 {
01337 if (argc == 0) {
01338 if (!IsValidPlayer(_local_player)) return true;
01339 IConsolePrintF(_icolour_warn, "Current value for 'company_pw': %s", _network_player_info[_local_player].password);
01340 return true;
01341 }
01342
01343 if (!IsValidPlayer(_local_player)) {
01344 IConsoleError("You have to own a company to make use of this command.");
01345 return false;
01346 }
01347
01348 if (argc != 1) return false;
01349
01350 if (strcmp(argv[0], "*") == 0) argv[0][0] = '\0';
01351
01352 ttd_strlcpy(_network_player_info[_local_player].password, argv[0], sizeof(_network_player_info[_local_player].password));
01353
01354 if (!_network_server) {
01355 SEND_COMMAND(PACKET_CLIENT_SET_PASSWORD)(_network_player_info[_local_player].password);
01356 } else {
01357 HashCurrentCompanyPassword();
01358 }
01359
01360 IConsolePrintF(_icolour_warn, "'company_pw' changed to: %s", _network_player_info[_local_player].password);
01361
01362 return true;
01363 }
01364
01365 DEF_CONSOLE_HOOK(ConProcPlayerName)
01366 {
01367 NetworkClientInfo *ci = NetworkFindClientInfoFromIndex(_network_own_client_index);
01368
01369 if (ci == NULL) return false;
01370
01371
01372 if (strcmp(ci->client_name, _network_player_name) != 0) {
01373 if (!_network_server) {
01374 SEND_COMMAND(PACKET_CLIENT_SET_NAME)(_network_player_name);
01375 } else {
01376 if (NetworkFindName(_network_player_name)) {
01377 NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, 1, false, ci->client_name, "%s", _network_player_name);
01378 ttd_strlcpy(ci->client_name, _network_player_name, sizeof(ci->client_name));
01379 NetworkUpdateClientInfo(NETWORK_SERVER_INDEX);
01380 }
01381 }
01382 }
01383
01384 return true;
01385 }
01386
01387 DEF_CONSOLE_HOOK(ConHookServerName)
01388 {
01389 ttd_strlcpy(_network_game_info.server_name, _network_server_name, sizeof(_network_game_info.server_name));
01390 return true;
01391 }
01392
01393 DEF_CONSOLE_HOOK(ConHookServerAdvertise)
01394 {
01395 if (!_network_advertise)
01396 NetworkUDPRemoveAdvertise();
01397
01398 return true;
01399 }
01400
01401 DEF_CONSOLE_CMD(ConProcServerIP)
01402 {
01403 if (argc == 0) {
01404 IConsolePrintF(_icolour_warn, "Current value for 'server_ip': %s", inet_ntoa(*(struct in_addr *)&_network_server_bind_ip));
01405 return true;
01406 }
01407
01408 if (argc != 1) return false;
01409
01410 _network_server_bind_ip = (strcmp(argv[0], "all") == 0) ? inet_addr("0.0.0.0") : inet_addr(argv[0]);
01411 snprintf(_network_server_bind_ip_host, sizeof(_network_server_bind_ip_host), "%s", inet_ntoa(*(struct in_addr *)&_network_server_bind_ip));
01412 IConsolePrintF(_icolour_warn, "'server_ip' changed to: %s", inet_ntoa(*(struct in_addr *)&_network_server_bind_ip));
01413 return true;
01414 }
01415 #endif
01416
01417 DEF_CONSOLE_CMD(ConPatch)
01418 {
01419 if (argc == 0) {
01420 IConsoleHelp("Change patch variables for all players. Usage: 'patch <name> [<value>]'");
01421 IConsoleHelp("Omitting <value> will print out the current value of the patch-setting.");
01422 return true;
01423 }
01424
01425 if (argc == 1 || argc > 3) return false;
01426
01427 if (argc == 2) {
01428 IConsoleGetPatchSetting(argv[1]);
01429 } else {
01430 uint32 val;
01431
01432 if (GetArgumentInteger(&val, argv[2])) {
01433 if (!IConsoleSetPatchSetting(argv[1], val)) {
01434 if (_network_server) {
01435 IConsoleError("This command/variable is not available during network games.");
01436 } else {
01437 IConsoleError("This command/variable is only available to a network server.");
01438 }
01439 }
01440 }
01441 }
01442
01443 return true;
01444 }
01445
01446 DEF_CONSOLE_CMD(ConListPatches)
01447 {
01448 if (argc == 0) {
01449 IConsoleHelp("List patch options. Usage: 'list_patches'");
01450 return true;
01451 }
01452
01453 if (argc != 1) return false;
01454
01455 IConsoleListPatches();
01456 return true;
01457 }
01458
01459 DEF_CONSOLE_CMD(ConListDumpVariables)
01460 {
01461 const IConsoleVar *var;
01462 size_t l = 0;
01463
01464 if (argc == 0) {
01465 IConsoleHelp("List all variables with their value. Usage: 'dump_vars [<pre-filter>]'");
01466 return true;
01467 }
01468
01469 if (argv[1] != NULL) l = strlen(argv[1]);
01470
01471 for (var = _iconsole_vars; var != NULL; var = var->next) {
01472 if (argv[1] == NULL || strncmp(var->name, argv[1], l) == 0)
01473 IConsoleVarPrintGetValue(var);
01474 }
01475
01476 return true;
01477 }
01478
01479
01480 #ifdef _DEBUG
01481
01482
01483
01484
01485 static void IConsoleDebugLibRegister()
01486 {
01487
01488 extern bool _stdlib_con_developer;
01489
01490 IConsoleVarRegister("con_developer", &_stdlib_con_developer, ICONSOLE_VAR_BOOLEAN, "Enable/disable console debugging information (internal)");
01491 IConsoleCmdRegister("resettile", ConResetTile);
01492 IConsoleCmdRegister("stopall", ConStopAllVehicles);
01493 IConsoleAliasRegister("dbg_echo", "echo %A; echo %B");
01494 IConsoleAliasRegister("dbg_echo2", "echo %!");
01495 }
01496 #endif
01497
01498
01499
01500
01501
01502 void IConsoleStdLibRegister()
01503 {
01504
01505 extern byte _stdlib_developer;
01506
01507
01508 IConsoleCmdRegister("debug_level", ConDebugLevel);
01509 IConsoleCmdRegister("dump_vars", ConListDumpVariables);
01510 IConsoleCmdRegister("echo", ConEcho);
01511 IConsoleCmdRegister("echoc", ConEchoC);
01512 IConsoleCmdRegister("exec", ConExec);
01513 IConsoleCmdRegister("exit", ConExit);
01514 IConsoleCmdRegister("part", ConPart);
01515 IConsoleCmdRegister("help", ConHelp);
01516 IConsoleCmdRegister("info_cmd", ConInfoCmd);
01517 IConsoleCmdRegister("info_var", ConInfoVar);
01518 IConsoleCmdRegister("list_cmds", ConListCommands);
01519 IConsoleCmdRegister("list_vars", ConListVariables);
01520 IConsoleCmdRegister("list_aliases", ConListAliases);
01521 IConsoleCmdRegister("newgame", ConNewGame);
01522 IConsoleCmdRegister("restart", ConRestart);
01523 IConsoleCmdRegister("getseed", ConGetSeed);
01524 IConsoleCmdRegister("getdate", ConGetDate);
01525 IConsoleCmdRegister("quit", ConExit);
01526 IConsoleCmdRegister("resetengines", ConResetEngines);
01527 IConsoleCmdRegister("return", ConReturn);
01528 IConsoleCmdRegister("screenshot", ConScreenShot);
01529 IConsoleCmdRegister("script", ConScript);
01530 IConsoleCmdRegister("scrollto", ConScrollToTile);
01531 IConsoleCmdRegister("alias", ConAlias);
01532 IConsoleCmdRegister("load", ConLoad);
01533 IConsoleCmdRegister("rm", ConRemove);
01534 IConsoleCmdRegister("save", ConSave);
01535 IConsoleCmdRegister("saveconfig", ConSaveConfig);
01536 IConsoleCmdRegister("ls", ConListFiles);
01537 IConsoleCmdRegister("cd", ConChangeDirectory);
01538 IConsoleCmdRegister("pwd", ConPrintWorkingDirectory);
01539 IConsoleCmdRegister("clear", ConClearBuffer);
01540 IConsoleCmdRegister("patch", ConPatch);
01541 IConsoleCmdRegister("list_patches", ConListPatches);
01542
01543 IConsoleAliasRegister("dir", "ls");
01544 IConsoleAliasRegister("del", "rm %+");
01545 IConsoleAliasRegister("newmap", "newgame");
01546 IConsoleAliasRegister("new_map", "newgame");
01547 IConsoleAliasRegister("new_game", "newgame");
01548
01549
01550 IConsoleVarRegister("developer", &_stdlib_developer, ICONSOLE_VAR_BYTE, "Redirect debugging output from the console/command line to the ingame console (value 2). Default value: 1");
01551
01552
01553 #ifdef ENABLE_NETWORK
01554
01555 IConsoleCmdHookAdd ("resetengines", ICONSOLE_HOOK_ACCESS, ConHookNoNetwork);
01556
01557
01558 IConsoleCmdRegister("say", ConSay);
01559 IConsoleCmdHookAdd("say", ICONSOLE_HOOK_ACCESS, ConHookNeedNetwork);
01560 IConsoleCmdRegister("players", ConPlayers);
01561 IConsoleCmdHookAdd("players", ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
01562 IConsoleCmdRegister("say_player", ConSayPlayer);
01563 IConsoleCmdHookAdd("say_player", ICONSOLE_HOOK_ACCESS, ConHookNeedNetwork);
01564 IConsoleCmdRegister("say_client", ConSayClient);
01565 IConsoleCmdHookAdd("say_client", ICONSOLE_HOOK_ACCESS, ConHookNeedNetwork);
01566
01567 IConsoleCmdRegister("connect", ConNetworkConnect);
01568 IConsoleCmdHookAdd("connect", ICONSOLE_HOOK_ACCESS, ConHookClientOnly);
01569 IConsoleAliasRegister("join", "connect %A");
01570 IConsoleCmdRegister("clients", ConNetworkClients);
01571 IConsoleCmdHookAdd("clients", ICONSOLE_HOOK_ACCESS, ConHookNeedNetwork);
01572 IConsoleCmdRegister("status", ConStatus);
01573 IConsoleCmdHookAdd("status", ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
01574 IConsoleCmdRegister("server_info", ConServerInfo);
01575 IConsoleCmdHookAdd("server_info", ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
01576 IConsoleAliasRegister("info", "server_info");
01577 IConsoleCmdRegister("rcon", ConRcon);
01578 IConsoleCmdHookAdd("rcon", ICONSOLE_HOOK_ACCESS, ConHookNeedNetwork);
01579
01580 IConsoleCmdRegister("reset_company", ConResetCompany);
01581 IConsoleCmdHookAdd("reset_company", ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
01582 IConsoleAliasRegister("clean_company", "reset_company %A");
01583 IConsoleCmdRegister("kick", ConKick);
01584 IConsoleCmdHookAdd("kick", ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
01585 IConsoleCmdRegister("ban", ConBan);
01586 IConsoleCmdHookAdd("ban", ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
01587 IConsoleCmdRegister("unban", ConUnBan);
01588 IConsoleCmdHookAdd("unban", ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
01589 IConsoleCmdRegister("banlist", ConBanList);
01590 IConsoleCmdHookAdd("banlist", ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
01591
01592 IConsoleCmdRegister("pause", ConPauseGame);
01593 IConsoleCmdHookAdd("pause", ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
01594 IConsoleCmdRegister("unpause", ConUnPauseGame);
01595 IConsoleCmdHookAdd("unpause", ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
01596
01597
01598 IConsoleVarRegister("net_frame_freq", &_network_frame_freq, ICONSOLE_VAR_BYTE, "The amount of frames before a command will be (visibly) executed. Default value: 1");
01599 IConsoleVarHookAdd("net_frame_freq", ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
01600 IConsoleVarRegister("net_sync_freq", &_network_sync_freq, ICONSOLE_VAR_UINT16, "The amount of frames to check if the game is still in sync. Default value: 100");
01601 IConsoleVarHookAdd("net_sync_freq", ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
01602
01603 IConsoleVarStringRegister("server_pw", &_network_server_password, sizeof(_network_server_password), "Set the server password to protect your server. Use '*' to clear the password");
01604 IConsoleVarHookAdd("server_pw", ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
01605 IConsoleVarHookAdd("server_pw", ICONSOLE_HOOK_POST_ACTION, ConHookServerPW);
01606 IConsoleAliasRegister("server_password", "server_pw %+");
01607 IConsoleVarStringRegister("rcon_pw", &_network_rcon_password, sizeof(_network_rcon_password), "Set the rcon-password to change server behaviour. Use '*' to disable rcon");
01608 IConsoleVarHookAdd("rcon_pw", ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
01609 IConsoleVarHookAdd("rcon_pw", ICONSOLE_HOOK_POST_ACTION, ConHookRconPW);
01610 IConsoleAliasRegister("rcon_password", "rcon_pw %+");
01611 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");
01612 IConsoleVarHookAdd("company_pw", ICONSOLE_HOOK_ACCESS, ConHookNeedNetwork);
01613 IConsoleVarProcAdd("company_pw", NetworkChangeCompanyPassword);
01614 IConsoleAliasRegister("company_password", "company_pw %+");
01615
01616 IConsoleVarStringRegister("name", &_network_player_name, sizeof(_network_player_name), "Set your name for multiplayer");
01617 IConsoleVarHookAdd("name", ICONSOLE_HOOK_ACCESS, ConHookNeedNetwork);
01618 IConsoleVarHookAdd("name", ICONSOLE_HOOK_POST_ACTION, ConProcPlayerName);
01619 IConsoleVarStringRegister("server_name", &_network_server_name, sizeof(_network_server_name), "Set the name of the server for multiplayer");
01620 IConsoleVarHookAdd("server_name", ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
01621 IConsoleVarHookAdd("server_name", ICONSOLE_HOOK_POST_ACTION, ConHookServerName);
01622
01623 IConsoleVarRegister("server_port", &_network_server_port, ICONSOLE_VAR_UINT32, "Set the server port. Changes take effect the next time you start a server");
01624 IConsoleVarRegister("server_ip", &_network_server_bind_ip, ICONSOLE_VAR_UINT32, "Set the IP the server binds to. Changes take effect the next time you start a server. Use 'all' to bind to any IP.");
01625 IConsoleVarProcAdd("server_ip", ConProcServerIP);
01626 IConsoleAliasRegister("server_bind_ip", "server_ip %+");
01627 IConsoleAliasRegister("server_ip_bind", "server_ip %+");
01628 IConsoleAliasRegister("server_bind", "server_ip %+");
01629 IConsoleVarRegister("server_advertise", &_network_advertise, ICONSOLE_VAR_BOOLEAN, "Set if the server will advertise to the master server and show up there");
01630 IConsoleVarHookAdd("server_advertise", ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
01631 IConsoleVarHookAdd("server_advertise", ICONSOLE_HOOK_POST_ACTION, ConHookServerAdvertise);
01632
01633 IConsoleVarRegister("max_clients", &_network_game_info.clients_max, ICONSOLE_VAR_BYTE, "Control the maximum amount of connected players during runtime. Default value: 10");
01634 IConsoleVarHookAdd("max_clients", ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
01635 IConsoleVarHookAdd("max_clients", ICONSOLE_HOOK_POST_ACTION, ConHookValidateMaxClientsCount);
01636 IConsoleVarRegister("max_companies", &_network_game_info.companies_max, ICONSOLE_VAR_BYTE, "Control the maximum amount of active companies during runtime. Default value: 8");
01637 IConsoleVarHookAdd("max_companies", ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
01638 IConsoleVarHookAdd("max_companies", ICONSOLE_HOOK_POST_ACTION, ConHookValidateMaxCompaniesCount);
01639 IConsoleVarRegister("max_spectators", &_network_game_info.spectators_max, ICONSOLE_VAR_BYTE, "Control the maximum amount of active spectators during runtime. Default value: 9");
01640 IConsoleVarHookAdd("max_spectators", ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
01641 IConsoleVarHookAdd("max_spectators", ICONSOLE_HOOK_POST_ACTION, ConHookValidateMaxSpectatorsCount);
01642
01643 IConsoleVarRegister("max_join_time", &_network_max_join_time, ICONSOLE_VAR_UINT16, "Set the maximum amount of time (ticks) a client is allowed to join. Default value: 500");
01644
01645 IConsoleVarRegister("pause_on_join", &_network_pause_on_join, ICONSOLE_VAR_BOOLEAN, "Set if the server should pause gameplay while a client is joining. This might help slow users");
01646 IConsoleVarHookAdd("pause_on_join", ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
01647
01648 IConsoleVarRegister("autoclean_companies", &_network_autoclean_companies, ICONSOLE_VAR_BOOLEAN, "Automatically shut down inactive companies to free them up for other players. Customize with 'autoclean_(un)protected'");
01649 IConsoleVarHookAdd("autoclean_companies", ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
01650 IConsoleVarRegister("autoclean_protected", &_network_autoclean_protected, ICONSOLE_VAR_BYTE, "Automatically remove the password from an inactive company after the given amount of months");
01651 IConsoleVarHookAdd("autoclean_protected", ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
01652 IConsoleVarRegister("autoclean_unprotected", &_network_autoclean_unprotected, ICONSOLE_VAR_BYTE, "Automatically shut down inactive companies after the given amount of months");
01653 IConsoleVarHookAdd("autoclean_unprotected", ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
01654 IConsoleVarRegister("restart_game_year", &_network_restart_game_year, ICONSOLE_VAR_UINT16, "Auto-restart the server when Jan 1st of the set year is reached. Use '0' to disable this");
01655 IConsoleVarHookAdd("restart_game_year", ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
01656
01657 IConsoleVarRegister("min_players", &_network_min_players, ICONSOLE_VAR_BYTE, "Automatically pause the game when the number of active players passes below the given amount");
01658 IConsoleVarHookAdd("min_players", ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
01659 IConsoleVarHookAdd("min_players", ICONSOLE_HOOK_POST_ACTION, ConHookCheckMinPlayers);
01660 IConsoleVarRegister("reload_cfg", &_network_reload_cfg, ICONSOLE_VAR_BOOLEAN, "reload the entire config file between the end of this game, and starting the next new game - dedicated servers");
01661 IConsoleVarHookAdd("reload_cfg", ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
01662
01663 #endif
01664
01665
01666 #ifdef _DEBUG
01667 IConsoleDebugLibRegister();
01668 #endif
01669 }