src/console_cmds.cpp
branchcustombridgeheads
changeset 5649 55c8267c933f
parent 5648 1608018c5ff2
child 5650 aefc131bf5ce
equal deleted inserted replaced
5648:1608018c5ff2 5649:55c8267c933f
       
     1 /* $Id$ */
       
     2 
       
     3 #include "stdafx.h"
       
     4 #include "openttd.h"
       
     5 #include "console.h"
       
     6 #include "debug.h"
       
     7 #include "engine.h"
       
     8 #include "functions.h"
       
     9 #include "saveload.h"
       
    10 #include "string.h"
       
    11 #include "variables.h"
       
    12 #include "network/network_data.h"
       
    13 #include "network/network_client.h"
       
    14 #include "network/network_server.h"
       
    15 #include "network/network_udp.h"
       
    16 #include "command.h"
       
    17 #include "settings.h"
       
    18 #include "fios.h"
       
    19 #include "vehicle.h"
       
    20 #include "station.h"
       
    21 #include "strings.h"
       
    22 #include "screenshot.h"
       
    23 #include "genworld.h"
       
    24 #include "date.h"
       
    25 #include "network/network.h"
       
    26 
       
    27 // ** scriptfile handling ** //
       
    28 static FILE *_script_file;
       
    29 static bool _script_running;
       
    30 
       
    31 // ** console command / variable defines ** //
       
    32 #define DEF_CONSOLE_CMD(function) static bool function(byte argc, char *argv[])
       
    33 #define DEF_CONSOLE_HOOK(function) static bool function(void)
       
    34 
       
    35 
       
    36 /* **************************** */
       
    37 /* variable and command hooks   */
       
    38 /* **************************** */
       
    39 
       
    40 #ifdef ENABLE_NETWORK
       
    41 
       
    42 static inline bool NetworkAvailable(void)
       
    43 {
       
    44 	if (!_network_available) {
       
    45 		IConsoleError("You cannot use this command because there is no network available.");
       
    46 		return false;
       
    47 	}
       
    48 	return true;
       
    49 }
       
    50 
       
    51 DEF_CONSOLE_HOOK(ConHookServerOnly)
       
    52 {
       
    53 	if (!NetworkAvailable()) return false;
       
    54 
       
    55 	if (!_network_server) {
       
    56 		IConsoleError("This command/variable is only available to a network server.");
       
    57 		return false;
       
    58 	}
       
    59 	return true;
       
    60 }
       
    61 
       
    62 DEF_CONSOLE_HOOK(ConHookClientOnly)
       
    63 {
       
    64 	if (!NetworkAvailable()) return false;
       
    65 
       
    66 	if (_network_server) {
       
    67 		IConsoleError("This command/variable is not available to a network server.");
       
    68 		return false;
       
    69 	}
       
    70 	return true;
       
    71 }
       
    72 
       
    73 DEF_CONSOLE_HOOK(ConHookNeedNetwork)
       
    74 {
       
    75 	if (!NetworkAvailable()) return false;
       
    76 
       
    77 	if (!_networking) {
       
    78 		IConsoleError("Not connected. This command/variable is only available in multiplayer.");
       
    79 		return false;
       
    80 	}
       
    81 	return true;
       
    82 }
       
    83 
       
    84 DEF_CONSOLE_HOOK(ConHookNoNetwork)
       
    85 {
       
    86 	if (_networking) {
       
    87 		IConsoleError("This command/variable is forbidden in multiplayer.");
       
    88 		return false;
       
    89 	}
       
    90 	return true;
       
    91 }
       
    92 
       
    93 #endif /* ENABLE_NETWORK */
       
    94 
       
    95 static void IConsoleHelp(const char *str)
       
    96 {
       
    97 	IConsolePrintF(_icolour_warn, "- %s", str);
       
    98 }
       
    99 
       
   100 DEF_CONSOLE_CMD(ConResetEngines)
       
   101 {
       
   102 	if (argc == 0) {
       
   103 		IConsoleHelp("Reset status data of all engines. This might solve some issues with 'lost' engines. Usage: 'resetengines'");
       
   104 		return true;
       
   105 	}
       
   106 
       
   107 	StartupEngines();
       
   108 	return true;
       
   109 }
       
   110 
       
   111 #ifdef _DEBUG
       
   112 DEF_CONSOLE_CMD(ConResetTile)
       
   113 {
       
   114 	if (argc == 0) {
       
   115 		IConsoleHelp("Reset a tile to bare land. Usage: 'resettile <tile>'");
       
   116 		IConsoleHelp("Tile can be either decimal (34161) or hexadecimal (0x4a5B)");
       
   117 		return true;
       
   118 	}
       
   119 
       
   120 	if (argc == 2) {
       
   121 		uint32 result;
       
   122 		if (GetArgumentInteger(&result, argv[1])) {
       
   123 			DoClearSquare((TileIndex)result);
       
   124 			return true;
       
   125 		}
       
   126 	}
       
   127 
       
   128 	return false;
       
   129 }
       
   130 
       
   131 DEF_CONSOLE_CMD(ConStopAllVehicles)
       
   132 {
       
   133 	Vehicle* v;
       
   134 	if (argc == 0) {
       
   135 		IConsoleHelp("Stops all vehicles in the game. For debugging only! Use at your own risk... Usage: 'stopall'");
       
   136 		return true;
       
   137 	}
       
   138 
       
   139 	FOR_ALL_VEHICLES(v) {
       
   140 		/* Code ripped from CmdStartStopTrain. Can't call it, because of
       
   141 		 * ownership problems, so we'll duplicate some code, for now */
       
   142 		if (v->type == VEH_Train)
       
   143 			v->u.rail.days_since_order_progr = 0;
       
   144 		v->vehstatus |= VS_STOPPED;
       
   145 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
       
   146 		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
       
   147 	}
       
   148 	return true;
       
   149 }
       
   150 #endif /* _DEBUG */
       
   151 
       
   152 DEF_CONSOLE_CMD(ConScrollToTile)
       
   153 {
       
   154 	if (argc == 0) {
       
   155 		IConsoleHelp("Center the screen on a given tile. Usage: 'scrollto <tile>'");
       
   156 		IConsoleHelp("Tile can be either decimal (34161) or hexadecimal (0x4a5B)");
       
   157 		return true;
       
   158 	}
       
   159 
       
   160 	if (argc == 2) {
       
   161 		uint32 result;
       
   162 		if (GetArgumentInteger(&result, argv[1])) {
       
   163 			if (result >= MapSize()) {
       
   164 				IConsolePrint(_icolour_err, "Tile does not exist");
       
   165 				return true;
       
   166 			}
       
   167 			ScrollMainWindowToTile((TileIndex)result);
       
   168 			return true;
       
   169 		}
       
   170 	}
       
   171 
       
   172 	return false;
       
   173 }
       
   174 
       
   175 extern bool SafeSaveOrLoad(const char *filename, int mode, int newgm);
       
   176 extern void BuildFileList(void);
       
   177 extern void SetFiosType(const byte fiostype);
       
   178 
       
   179 /* Save the map to a file */
       
   180 DEF_CONSOLE_CMD(ConSave)
       
   181 {
       
   182 	if (argc == 0) {
       
   183 		IConsoleHelp("Save the current game. Usage: 'save <filename>'");
       
   184 		return true;
       
   185 	}
       
   186 
       
   187 	if (argc == 2) {
       
   188 		char buf[200];
       
   189 
       
   190 		snprintf(buf, lengthof(buf), "%s%s%s.sav", _paths.save_dir, PATHSEP, argv[1]);
       
   191 		IConsolePrint(_icolour_def, "Saving map...");
       
   192 
       
   193 		if (SaveOrLoad(buf, SL_SAVE) != SL_OK) {
       
   194 			IConsolePrint(_icolour_err, "SaveMap failed");
       
   195 		} else {
       
   196 			IConsolePrintF(_icolour_def, "Map sucessfully saved to %s", buf);
       
   197 		}
       
   198 		return true;
       
   199 	}
       
   200 
       
   201 	return false;
       
   202 }
       
   203 
       
   204 /* Explicitly save the configuration */
       
   205 DEF_CONSOLE_CMD(ConSaveConfig)
       
   206 {
       
   207 	if (argc == 0) {
       
   208 		IConsoleHelp("Saves the current config, typically to 'openttd.cfg'.");
       
   209 		return true;
       
   210 	}
       
   211 
       
   212 	SaveToConfig();
       
   213 	IConsolePrint(_icolour_def, "Saved config.");
       
   214 	return true;
       
   215 }
       
   216 
       
   217 static const FiosItem* GetFiosItem(const char* file)
       
   218 {
       
   219 	int i;
       
   220 
       
   221 	_saveload_mode = SLD_LOAD_GAME;
       
   222 	BuildFileList();
       
   223 
       
   224 	for (i = 0; i < _fios_num; i++) {
       
   225 		if (strcmp(file, _fios_list[i].name) == 0) break;
       
   226 		if (strcmp(file, _fios_list[i].title) == 0) break;
       
   227 	}
       
   228 
       
   229 	if (i == _fios_num) { /* If no name matches, try to parse it as number */
       
   230 		char* endptr;
       
   231 
       
   232 		i = strtol(file, &endptr, 10);
       
   233 		if (file == endptr || *endptr != '\0') i = -1;
       
   234 	}
       
   235 
       
   236 	return IS_INT_INSIDE(i, 0, _fios_num) ? &_fios_list[i] : NULL;
       
   237 }
       
   238 
       
   239 
       
   240 DEF_CONSOLE_CMD(ConLoad)
       
   241 {
       
   242 	const FiosItem *item;
       
   243 	const char *file;
       
   244 
       
   245 	if (argc == 0) {
       
   246 		IConsoleHelp("Load a game by name or index. Usage: 'load <file | number>'");
       
   247 		return true;
       
   248 	}
       
   249 
       
   250 	if (argc != 2) return false;
       
   251 
       
   252 	file = argv[1];
       
   253 	item = GetFiosItem(file);
       
   254 	if (item != NULL) {
       
   255 		switch (item->type) {
       
   256 			case FIOS_TYPE_FILE: case FIOS_TYPE_OLDFILE: {
       
   257 				_switch_mode = SM_LOAD;
       
   258 				SetFiosType(item->type);
       
   259 
       
   260 				ttd_strlcpy(_file_to_saveload.name, FiosBrowseTo(item), sizeof(_file_to_saveload.name));
       
   261 				ttd_strlcpy(_file_to_saveload.title, item->title, sizeof(_file_to_saveload.title));
       
   262 			} break;
       
   263 			default: IConsolePrintF(_icolour_err, "%s: Not a savegame.", file);
       
   264 		}
       
   265 	} else {
       
   266 		IConsolePrintF(_icolour_err, "%s: No such file or directory.", file);
       
   267 	}
       
   268 
       
   269 	FiosFreeSavegameList();
       
   270 	return true;
       
   271 }
       
   272 
       
   273 
       
   274 DEF_CONSOLE_CMD(ConRemove)
       
   275 {
       
   276 	const FiosItem* item;
       
   277 	const char* file;
       
   278 
       
   279 	if (argc == 0) {
       
   280 		IConsoleHelp("Remove a savegame by name or index. Usage: 'rm <file | number>'");
       
   281 		return true;
       
   282 	}
       
   283 
       
   284 	if (argc != 2) return false;
       
   285 
       
   286 	file = argv[1];
       
   287 	item = GetFiosItem(file);
       
   288 	if (item != NULL) {
       
   289 		if (!FiosDelete(item->name))
       
   290 			IConsolePrintF(_icolour_err, "%s: Failed to delete file", file);
       
   291 	} else {
       
   292 		IConsolePrintF(_icolour_err, "%s: No such file or directory.", file);
       
   293 	}
       
   294 
       
   295 	FiosFreeSavegameList();
       
   296 	return true;
       
   297 }
       
   298 
       
   299 
       
   300 /* List all the files in the current dir via console */
       
   301 DEF_CONSOLE_CMD(ConListFiles)
       
   302 {
       
   303 	int i;
       
   304 
       
   305 	if (argc == 0) {
       
   306 		IConsoleHelp("List all loadable savegames and directories in the current dir via console. Usage: 'ls | dir'");
       
   307 		return true;
       
   308 	}
       
   309 
       
   310 	BuildFileList();
       
   311 
       
   312 	for (i = 0; i < _fios_num; i++) {
       
   313 		const FiosItem *item = &_fios_list[i];
       
   314 		IConsolePrintF(_icolour_def, "%d) %s", i, item->title);
       
   315 	}
       
   316 
       
   317 	FiosFreeSavegameList();
       
   318 	return true;
       
   319 }
       
   320 
       
   321 /* Change the dir via console */
       
   322 DEF_CONSOLE_CMD(ConChangeDirectory)
       
   323 {
       
   324 	const FiosItem *item;
       
   325 	const char *file;
       
   326 
       
   327 	if (argc == 0) {
       
   328 		IConsoleHelp("Change the dir via console. Usage: 'cd <directory | number>'");
       
   329 		return true;
       
   330 	}
       
   331 
       
   332 	if (argc != 2) return false;
       
   333 
       
   334 	file = argv[1];
       
   335 	item = GetFiosItem(file);
       
   336 	if (item != NULL) {
       
   337 		switch (item->type) {
       
   338 			case FIOS_TYPE_DIR: case FIOS_TYPE_DRIVE: case FIOS_TYPE_PARENT:
       
   339 				FiosBrowseTo(item);
       
   340 				break;
       
   341 			default: IConsolePrintF(_icolour_err, "%s: Not a directory.", file);
       
   342 		}
       
   343 	} else {
       
   344 		IConsolePrintF(_icolour_err, "%s: No such file or directory.", file);
       
   345 	}
       
   346 
       
   347 	FiosFreeSavegameList();
       
   348 	return true;
       
   349 }
       
   350 
       
   351 DEF_CONSOLE_CMD(ConPrintWorkingDirectory)
       
   352 {
       
   353 	const char *path;
       
   354 
       
   355 	if (argc == 0) {
       
   356 		IConsoleHelp("Print out the current working directory. Usage: 'pwd'");
       
   357 		return true;
       
   358 	}
       
   359 
       
   360 	// XXX - Workaround for broken file handling
       
   361 	FiosGetSavegameList(SLD_LOAD_GAME);
       
   362 	FiosFreeSavegameList();
       
   363 
       
   364 	FiosGetDescText(&path, NULL);
       
   365 	IConsolePrint(_icolour_def, path);
       
   366 	return true;
       
   367 }
       
   368 
       
   369 DEF_CONSOLE_CMD(ConClearBuffer)
       
   370 {
       
   371 	if (argc == 0) {
       
   372 		IConsoleHelp("Clear the console buffer. Usage: 'clear'");
       
   373 		return true;
       
   374 	}
       
   375 
       
   376 	IConsoleClearBuffer();
       
   377 	InvalidateWindow(WC_CONSOLE, 0);
       
   378 	return true;
       
   379 }
       
   380 
       
   381 
       
   382 // ********************************* //
       
   383 // * Network Core Console Commands * //
       
   384 // ********************************* //
       
   385 #ifdef ENABLE_NETWORK
       
   386 
       
   387 DEF_CONSOLE_CMD(ConBan)
       
   388 {
       
   389 	NetworkClientInfo *ci;
       
   390 	const char *banip = NULL;
       
   391 	uint32 index;
       
   392 
       
   393 	if (argc == 0) {
       
   394 		IConsoleHelp("Ban a player from a network game. Usage: 'ban <ip | client-id>'");
       
   395 		IConsoleHelp("For client-id's, see the command 'clients'");
       
   396 		IConsoleHelp("If the client is no longer online, you can still ban his/her IP");
       
   397 		return true;
       
   398 	}
       
   399 
       
   400 	if (argc != 2) return false;
       
   401 
       
   402 	if (strchr(argv[1], '.') == NULL) { // banning with ID
       
   403 		index = atoi(argv[1]);
       
   404 		ci = NetworkFindClientInfoFromIndex(index);
       
   405 	} else { // banning IP
       
   406 		ci = NetworkFindClientInfoFromIP(argv[1]);
       
   407 		if (ci == NULL) {
       
   408 			banip = argv[1];
       
   409 			index = (uint32)-1;
       
   410 		} else {
       
   411 			index = ci->client_index;
       
   412 		}
       
   413 	}
       
   414 
       
   415 	if (index == NETWORK_SERVER_INDEX) {
       
   416 		IConsoleError("Silly boy, you can not ban yourself!");
       
   417 		return true;
       
   418 	}
       
   419 
       
   420 	if (index == 0 || (ci == NULL && index != (uint32)-1)) {
       
   421 		IConsoleError("Invalid client");
       
   422 		return true;
       
   423 	}
       
   424 
       
   425 	if (ci != NULL) {
       
   426 		banip = inet_ntoa(*(struct in_addr *)&ci->client_ip);
       
   427 		SEND_COMMAND(PACKET_SERVER_ERROR)(NetworkFindClientStateFromIndex(index), NETWORK_ERROR_KICKED);
       
   428 		IConsolePrint(_icolour_def, "Client banned");
       
   429 	} else {
       
   430 		IConsolePrint(_icolour_def, "Client not online, banned IP");
       
   431 	}
       
   432 
       
   433 	/* Add user to ban-list */
       
   434 	for (index = 0; index < lengthof(_network_ban_list); index++) {
       
   435 		if (_network_ban_list[index] == NULL) {
       
   436 			_network_ban_list[index] = strdup(banip);
       
   437 			break;
       
   438 		}
       
   439 	}
       
   440 
       
   441 	return true;
       
   442 }
       
   443 
       
   444 DEF_CONSOLE_CMD(ConUnBan)
       
   445 {
       
   446 	uint i, index;
       
   447 
       
   448 	if (argc == 0) {
       
   449 		IConsoleHelp("Unban a player from a network game. Usage: 'unban <ip | client-id>'");
       
   450 		IConsoleHelp("For a list of banned IP's, see the command 'banlist'");
       
   451 		return true;
       
   452 	}
       
   453 
       
   454 	if (argc != 2) return false;
       
   455 
       
   456 	index = (strchr(argv[1], '.') == NULL) ? atoi(argv[1]) : 0;
       
   457 	index--;
       
   458 
       
   459 	for (i = 0; i < lengthof(_network_ban_list); i++) {
       
   460 		if (_network_ban_list[i] == NULL) continue;
       
   461 
       
   462 		if (strcmp(_network_ban_list[i], argv[1]) == 0 || index == i) {
       
   463 			free(_network_ban_list[i]);
       
   464 			_network_ban_list[i] = NULL;
       
   465 			IConsolePrint(_icolour_def, "IP unbanned.");
       
   466 			return true;
       
   467 		}
       
   468 	}
       
   469 
       
   470 	IConsolePrint(_icolour_def, "IP not in ban-list.");
       
   471 	return true;
       
   472 }
       
   473 
       
   474 DEF_CONSOLE_CMD(ConBanList)
       
   475 {
       
   476 	uint i;
       
   477 
       
   478 	if (argc == 0) {
       
   479 		IConsoleHelp("List the IP's of banned clients: Usage 'banlist'");
       
   480 		return true;
       
   481 	}
       
   482 
       
   483 	IConsolePrint(_icolour_def, "Banlist: ");
       
   484 
       
   485 	for (i = 0; i < lengthof(_network_ban_list); i++) {
       
   486 		if (_network_ban_list[i] != NULL)
       
   487 			IConsolePrintF(_icolour_def, "  %d) %s", i + 1, _network_ban_list[i]);
       
   488 	}
       
   489 
       
   490 	return true;
       
   491 }
       
   492 
       
   493 DEF_CONSOLE_CMD(ConPauseGame)
       
   494 {
       
   495 	if (argc == 0) {
       
   496 		IConsoleHelp("Pause a network game. Usage: 'pause'");
       
   497 		return true;
       
   498 	}
       
   499 
       
   500 	if (_pause == 0) {
       
   501 		DoCommandP(0, 1, 0, NULL, CMD_PAUSE);
       
   502 		IConsolePrint(_icolour_def, "Game paused.");
       
   503 	} else {
       
   504 		IConsolePrint(_icolour_def, "Game is already paused.");
       
   505 	}
       
   506 
       
   507 	return true;
       
   508 }
       
   509 
       
   510 DEF_CONSOLE_CMD(ConUnPauseGame)
       
   511 {
       
   512 	if (argc == 0) {
       
   513 		IConsoleHelp("Unpause a network game. Usage: 'unpause'");
       
   514 		return true;
       
   515 	}
       
   516 
       
   517 	if (_pause != 0) {
       
   518 		DoCommandP(0, 0, 0, NULL, CMD_PAUSE);
       
   519 		IConsolePrint(_icolour_def, "Game unpaused.");
       
   520 	} else {
       
   521 		IConsolePrint(_icolour_def, "Game is already unpaused.");
       
   522 	}
       
   523 
       
   524 	return true;
       
   525 }
       
   526 
       
   527 DEF_CONSOLE_CMD(ConRcon)
       
   528 {
       
   529 	if (argc == 0) {
       
   530 		IConsoleHelp("Remote control the server from another client. Usage: 'rcon <password> <command>'");
       
   531 		IConsoleHelp("Remember to enclose the command in quotes, otherwise only the first parameter is sent");
       
   532 		return true;
       
   533 	}
       
   534 
       
   535 	if (argc < 3) return false;
       
   536 
       
   537 	SEND_COMMAND(PACKET_CLIENT_RCON)(argv[1], argv[2]);
       
   538 	return true;
       
   539 }
       
   540 
       
   541 DEF_CONSOLE_CMD(ConStatus)
       
   542 {
       
   543 	static const char* const stat_str[] = {
       
   544 		"inactive",
       
   545 		"authorized",
       
   546 		"waiting",
       
   547 		"loading map",
       
   548 		"map done",
       
   549 		"ready",
       
   550 		"active"
       
   551 	};
       
   552 
       
   553 	const NetworkClientState *cs;
       
   554 
       
   555 	if (argc == 0) {
       
   556 		IConsoleHelp("List the status of all clients connected to the server. Usage 'status'");
       
   557 		return true;
       
   558 	}
       
   559 
       
   560 	FOR_ALL_CLIENTS(cs) {
       
   561 		int lag = NetworkCalculateLag(cs);
       
   562 		const NetworkClientInfo *ci = DEREF_CLIENT_INFO(cs);
       
   563 		const char* status;
       
   564 
       
   565 		status = (cs->status < lengthof(stat_str) ? stat_str[cs->status] : "unknown");
       
   566 		IConsolePrintF(8, "Client #%1d  name: '%s'  status: '%s'  frame-lag: %3d  company: %1d  IP: %s  unique-id: '%s'",
       
   567 			cs->index, ci->client_name, status, lag,
       
   568 			ci->client_playas + (IsValidPlayer(ci->client_playas) ? 1 : 0),
       
   569 			GetPlayerIP(ci), ci->unique_id);
       
   570 	}
       
   571 
       
   572 	return true;
       
   573 }
       
   574 
       
   575 DEF_CONSOLE_CMD(ConServerInfo)
       
   576 {
       
   577 	const NetworkGameInfo *gi;
       
   578 
       
   579 	if (argc == 0) {
       
   580 		IConsoleHelp("List current and maximum client/player limits. Usage 'server_info'");
       
   581 		IConsoleHelp("You can change these values by setting the variables 'max_clients', 'max_companies' and 'max_spectators'");
       
   582 		return true;
       
   583 	}
       
   584 
       
   585 	gi = &_network_game_info;
       
   586 	IConsolePrintF(_icolour_def, "Current/maximum clients:    %2d/%2d", gi->clients_on, gi->clients_max);
       
   587 	IConsolePrintF(_icolour_def, "Current/maximum companies:  %2d/%2d", ActivePlayerCount(), gi->companies_max);
       
   588 	IConsolePrintF(_icolour_def, "Current/maximum spectators: %2d/%2d", NetworkSpectatorCount(), gi->spectators_max);
       
   589 
       
   590 	return true;
       
   591 }
       
   592 
       
   593 DEF_CONSOLE_HOOK(ConHookValidateMaxClientsCount)
       
   594 {
       
   595 	/* XXX - hardcoded, string limiation -- TrueLight
       
   596 	 * XXX - also see network.c:NetworkStartup ~1356 */
       
   597 	if (_network_game_info.clients_max > 10) {
       
   598 		_network_game_info.clients_max = 10;
       
   599 		IConsoleError("Maximum clients out of bounds, truncating to limit.");
       
   600 	}
       
   601 
       
   602 	return true;
       
   603 }
       
   604 
       
   605 DEF_CONSOLE_HOOK(ConHookValidateMaxCompaniesCount)
       
   606 {
       
   607 	if (_network_game_info.companies_max > MAX_PLAYERS) {
       
   608 		_network_game_info.companies_max = MAX_PLAYERS;
       
   609 		IConsoleError("Maximum companies out of bounds, truncating to limit.");
       
   610 	}
       
   611 
       
   612 	return true;
       
   613 }
       
   614 
       
   615 DEF_CONSOLE_HOOK(ConHookValidateMaxSpectatorsCount)
       
   616 {
       
   617 	/* XXX @see ConHookValidateMaxClientsCount */
       
   618 	if (_network_game_info.spectators_max > 10) {
       
   619 		_network_game_info.spectators_max = 10;
       
   620 		IConsoleError("Maximum spectators out of bounds, truncating to limit.");
       
   621 	}
       
   622 
       
   623 	return true;
       
   624 }
       
   625 
       
   626 DEF_CONSOLE_HOOK(ConHookCheckMinPlayers)
       
   627 {
       
   628 	CheckMinPlayers();
       
   629 	return true;
       
   630 }
       
   631 
       
   632 DEF_CONSOLE_CMD(ConKick)
       
   633 {
       
   634 	NetworkClientInfo *ci;
       
   635 	uint32 index;
       
   636 
       
   637 	if (argc == 0) {
       
   638 		IConsoleHelp("Kick a player from a network game. Usage: 'kick <ip | client-id>'");
       
   639 		IConsoleHelp("For client-id's, see the command 'clients'");
       
   640 		return true;
       
   641 	}
       
   642 
       
   643 	if (argc != 2) return false;
       
   644 
       
   645 	if (strchr(argv[1], '.') == NULL) {
       
   646 		index = atoi(argv[1]);
       
   647 		ci = NetworkFindClientInfoFromIndex(index);
       
   648 	} else {
       
   649 		ci = NetworkFindClientInfoFromIP(argv[1]);
       
   650 		index = (ci == NULL) ? 0 : ci->client_index;
       
   651 	}
       
   652 
       
   653 	if (index == NETWORK_SERVER_INDEX) {
       
   654 		IConsoleError("Silly boy, you can not kick yourself!");
       
   655 		return true;
       
   656 	}
       
   657 
       
   658 	if (index == 0) {
       
   659 		IConsoleError("Invalid client");
       
   660 		return true;
       
   661 	}
       
   662 
       
   663 	if (ci != NULL) {
       
   664 		SEND_COMMAND(PACKET_SERVER_ERROR)(NetworkFindClientStateFromIndex(index), NETWORK_ERROR_KICKED);
       
   665 	} else {
       
   666 		IConsoleError("Client not found");
       
   667 	}
       
   668 
       
   669 	return true;
       
   670 }
       
   671 
       
   672 DEF_CONSOLE_CMD(ConResetCompany)
       
   673 {
       
   674 	const Player *p;
       
   675 	const NetworkClientState *cs;
       
   676 	const NetworkClientInfo *ci;
       
   677 	PlayerID index;
       
   678 
       
   679 	if (argc == 0) {
       
   680 		IConsoleHelp("Remove an idle company from the game. Usage: 'reset_company <company-id>'");
       
   681 		IConsoleHelp("For company-id's, see the list of companies from the dropdown menu. Player 1 is 1, etc.");
       
   682 		return true;
       
   683 	}
       
   684 
       
   685 	if (argc != 2) return false;
       
   686 
       
   687 	index = atoi(argv[1]) - 1;
       
   688 
       
   689 	/* Check valid range */
       
   690 	if (!IsValidPlayer(index)) {
       
   691 		IConsolePrintF(_icolour_err, "Company does not exist. Company-id must be between 1 and %d.", MAX_PLAYERS);
       
   692 		return true;
       
   693 	}
       
   694 
       
   695 	/* Check if company does exist */
       
   696 	p = GetPlayer(index);
       
   697 	if (!p->is_active) {
       
   698 		IConsoleError("Company does not exist.");
       
   699 		return true;
       
   700 	}
       
   701 
       
   702 	if (p->is_ai) {
       
   703 		IConsoleError("Company is owned by an AI.");
       
   704 		return true;
       
   705 	}
       
   706 
       
   707 	/* Check if the company has active players */
       
   708 	FOR_ALL_CLIENTS(cs) {
       
   709 		ci = DEREF_CLIENT_INFO(cs);
       
   710 		if (ci->client_playas == index) {
       
   711 			IConsoleError("Cannot remove company: a client is connected to that company.");
       
   712 			return true;
       
   713 		}
       
   714 	}
       
   715 	ci = NetworkFindClientInfoFromIndex(NETWORK_SERVER_INDEX);
       
   716 	if (ci->client_playas == index) {
       
   717 		IConsoleError("Cannot remove company: the server is connected to that company.");
       
   718 		return true;
       
   719 	}
       
   720 
       
   721 	/* It is safe to remove this company */
       
   722 	DoCommandP(0, 2, index, NULL, CMD_PLAYER_CTRL);
       
   723 	IConsolePrint(_icolour_def, "Company deleted.");
       
   724 
       
   725 	return true;
       
   726 }
       
   727 
       
   728 DEF_CONSOLE_CMD(ConNetworkClients)
       
   729 {
       
   730 	NetworkClientInfo *ci;
       
   731 
       
   732 	if (argc == 0) {
       
   733 		IConsoleHelp("Get a list of connected clients including their ID, name, company-id, and IP. Usage: 'clients'");
       
   734 		return true;
       
   735 	}
       
   736 
       
   737 	FOR_ALL_ACTIVE_CLIENT_INFOS(ci) {
       
   738 		IConsolePrintF(8, "Client #%1d  name: '%s'  company: %1d  IP: %s",
       
   739 		               ci->client_index, ci->client_name,
       
   740 		               ci->client_playas + (IsValidPlayer(ci->client_playas) ? 1 : 0),
       
   741 		               GetPlayerIP(ci));
       
   742 	}
       
   743 
       
   744 	return true;
       
   745 }
       
   746 
       
   747 DEF_CONSOLE_CMD(ConNetworkConnect)
       
   748 {
       
   749 	char *ip;
       
   750 	const char *port = NULL;
       
   751 	const char *player = NULL;
       
   752 	uint16 rport;
       
   753 
       
   754 	if (argc == 0) {
       
   755 		IConsoleHelp("Connect to a remote OTTD server and join the game. Usage: 'connect <ip>'");
       
   756 		IConsoleHelp("IP can contain port and player: 'IP[[#Player]:Port]', eg: 'server.ottd.org#2:443'");
       
   757 		IConsoleHelp("Player #255 is spectator all others are a certain company with Company 1 being #1");
       
   758 		return true;
       
   759 	}
       
   760 
       
   761 	if (argc < 2) return false;
       
   762 	if (_networking) NetworkDisconnect(); // we are in network-mode, first close it!
       
   763 
       
   764 	ip = argv[1];
       
   765 	/* Default settings: default port and new company */
       
   766 	rport = NETWORK_DEFAULT_PORT;
       
   767 	_network_playas = PLAYER_NEW_COMPANY;
       
   768 
       
   769 	ParseConnectionString(&player, &port, ip);
       
   770 
       
   771 	IConsolePrintF(_icolour_def, "Connecting to %s...", ip);
       
   772 	if (player != NULL) {
       
   773 		_network_playas = atoi(player);
       
   774 		IConsolePrintF(_icolour_def, "    player-no: %d", _network_playas);
       
   775 
       
   776 		/* From a user pov 0 is a new player, internally it's different and all
       
   777 		 * players are offset by one to ease up on users (eg players 1-8 not 0-7) */
       
   778 		if (_network_playas != PLAYER_SPECTATOR) {
       
   779 			_network_playas--;
       
   780 			if (!IsValidPlayer(_network_playas)) return false;
       
   781 		}
       
   782 	}
       
   783 	if (port != NULL) {
       
   784 		rport = atoi(port);
       
   785 		IConsolePrintF(_icolour_def, "    port: %s", port);
       
   786 	}
       
   787 
       
   788 	NetworkClientConnectGame(ip, rport);
       
   789 
       
   790 	return true;
       
   791 }
       
   792 
       
   793 #endif /* ENABLE_NETWORK */
       
   794 
       
   795 /* ******************************** */
       
   796 /*   script file console commands   */
       
   797 /* ******************************** */
       
   798 
       
   799 DEF_CONSOLE_CMD(ConExec)
       
   800 {
       
   801 	char cmdline[ICON_CMDLN_SIZE];
       
   802 	char *cmdptr;
       
   803 
       
   804 	if (argc == 0) {
       
   805 		IConsoleHelp("Execute a local script file. Usage: 'exec <script> <?>'");
       
   806 		return true;
       
   807 	}
       
   808 
       
   809 	if (argc < 2) return false;
       
   810 
       
   811 	_script_file = fopen(argv[1], "r");
       
   812 
       
   813 	if (_script_file == NULL) {
       
   814 		if (argc == 2 || atoi(argv[2]) != 0) IConsoleError("script file not found");
       
   815 		return true;
       
   816 	}
       
   817 
       
   818 	_script_running = true;
       
   819 
       
   820 	while (_script_running && fgets(cmdline, sizeof(cmdline), _script_file) != NULL) {
       
   821 		/* Remove newline characters from the executing script */
       
   822 		for (cmdptr = cmdline; *cmdptr != '\0'; cmdptr++) {
       
   823 			if (*cmdptr == '\n' || *cmdptr == '\r') {
       
   824 				*cmdptr = '\0';
       
   825 				break;
       
   826 			}
       
   827 		}
       
   828 		IConsoleCmdExec(cmdline);
       
   829 	}
       
   830 
       
   831 	if (ferror(_script_file))
       
   832 		IConsoleError("Encountered errror while trying to read from script file");
       
   833 
       
   834 	_script_running = false;
       
   835 	fclose(_script_file);
       
   836 	return true;
       
   837 }
       
   838 
       
   839 DEF_CONSOLE_CMD(ConReturn)
       
   840 {
       
   841 	if (argc == 0) {
       
   842 		IConsoleHelp("Stop executing a running script. Usage: 'return'");
       
   843 		return true;
       
   844 	}
       
   845 
       
   846 	_script_running = false;
       
   847 	return true;
       
   848 }
       
   849 
       
   850 /* **************************** */
       
   851 /*   default console commands   */
       
   852 /* **************************** */
       
   853 extern bool CloseConsoleLogIfActive(void);
       
   854 
       
   855 DEF_CONSOLE_CMD(ConScript)
       
   856 {
       
   857 	extern FILE* _iconsole_output_file;
       
   858 
       
   859 	if (argc == 0) {
       
   860 		IConsoleHelp("Start or stop logging console output to a file. Usage: 'script <filename>'");
       
   861 		IConsoleHelp("If filename is omitted, a running log is stopped if it is active");
       
   862 		return true;
       
   863 	}
       
   864 
       
   865 	if (!CloseConsoleLogIfActive()) {
       
   866 		if (argc < 2) return false;
       
   867 
       
   868 		IConsolePrintF(_icolour_def, "file output started to: %s", argv[1]);
       
   869 		_iconsole_output_file = fopen(argv[1], "ab");
       
   870 		if (_iconsole_output_file == NULL) IConsoleError("could not open file");
       
   871 	}
       
   872 
       
   873 	return true;
       
   874 }
       
   875 
       
   876 
       
   877 DEF_CONSOLE_CMD(ConEcho)
       
   878 {
       
   879 	if (argc == 0) {
       
   880 		IConsoleHelp("Print back the first argument to the console. Usage: 'echo <arg>'");
       
   881 		return true;
       
   882 	}
       
   883 
       
   884 	if (argc < 2) return false;
       
   885 	IConsolePrint(_icolour_def, argv[1]);
       
   886 	return true;
       
   887 }
       
   888 
       
   889 DEF_CONSOLE_CMD(ConEchoC)
       
   890 {
       
   891 	if (argc == 0) {
       
   892 		IConsoleHelp("Print back the first argument to the console in a given colour. Usage: 'echoc <colour> <arg2>'");
       
   893 		return true;
       
   894 	}
       
   895 
       
   896 	if (argc < 3) return false;
       
   897 	IConsolePrint(atoi(argv[1]), argv[2]);
       
   898 	return true;
       
   899 }
       
   900 
       
   901 DEF_CONSOLE_CMD(ConNewGame)
       
   902 {
       
   903 	if (argc == 0) {
       
   904 		IConsoleHelp("Start a new game. Usage: 'newgame [seed]'");
       
   905 		IConsoleHelp("The server can force a new game using 'newgame'; any client joined will rejoin after the server is done generating the new game.");
       
   906 		return true;
       
   907 	}
       
   908 
       
   909 	StartNewGameWithoutGUI((argc == 2) ? (uint)atoi(argv[1]) : GENERATE_NEW_SEED);
       
   910 	return true;
       
   911 }
       
   912 
       
   913 extern void SwitchMode(int new_mode);
       
   914 
       
   915 DEF_CONSOLE_CMD(ConRestart)
       
   916 {
       
   917 	if (argc == 0) {
       
   918 		IConsoleHelp("Restart game. Usage: 'restart'");
       
   919 		IConsoleHelp("Restarts a game. It tries to reproduce the exact same map as the game started with.");
       
   920 		return true;
       
   921 	}
       
   922 
       
   923 	/* Don't copy the _newgame pointers to the real pointers, so call SwitchMode directly */
       
   924 	_patches.map_x = MapLogX();
       
   925 	_patches.map_y = FindFirstBit(MapSizeY());
       
   926 	SwitchMode(SM_NEWGAME);
       
   927 	return true;
       
   928 }
       
   929 
       
   930 DEF_CONSOLE_CMD(ConGetSeed)
       
   931 {
       
   932 	if (argc == 0) {
       
   933 		IConsoleHelp("Returns the seed used to create this game. Usage: 'getseed'");
       
   934 		IConsoleHelp("The seed can be used to reproduce the exact same map as the game started with.");
       
   935 		return true;
       
   936 	}
       
   937 
       
   938 	IConsolePrintF(_icolour_def, "Generation Seed: %u", _patches.generation_seed);
       
   939 	return true;
       
   940 }
       
   941 
       
   942 DEF_CONSOLE_CMD(ConAlias)
       
   943 {
       
   944 	IConsoleAlias *alias;
       
   945 
       
   946 	if (argc == 0) {
       
   947 		IConsoleHelp("Add a new alias, or redefine the behaviour of an existing alias . Usage: 'alias <name> <command>'");
       
   948 		return true;
       
   949 	}
       
   950 
       
   951 	if (argc < 3) return false;
       
   952 
       
   953 	alias = IConsoleAliasGet(argv[1]);
       
   954 	if (alias == NULL) {
       
   955 		IConsoleAliasRegister(argv[1], argv[2]);
       
   956 	} else {
       
   957 		free(alias->cmdline);
       
   958 		alias->cmdline = strdup(argv[2]);
       
   959 	}
       
   960 	return true;
       
   961 }
       
   962 
       
   963 DEF_CONSOLE_CMD(ConScreenShot)
       
   964 {
       
   965 	if (argc == 0) {
       
   966 		IConsoleHelp("Create a screenshot of the game. Usage: 'screenshot [big | no_con]'");
       
   967 		IConsoleHelp("'big' makes a screenshot of the whole map, 'no_con' hides the console to create the screenshot");
       
   968 		return true;
       
   969 	}
       
   970 
       
   971 	if (argc > 3) return false;
       
   972 
       
   973 	SetScreenshotType(SC_VIEWPORT);
       
   974 	if (argc > 1) {
       
   975 		if (strcmp(argv[1], "big") == 0 || (argc == 3 && strcmp(argv[2], "big") == 0))
       
   976 			SetScreenshotType(SC_WORLD);
       
   977 
       
   978 		if (strcmp(argv[1], "no_con") == 0 || (argc == 3 && strcmp(argv[2], "no_con") == 0))
       
   979 			IConsoleClose();
       
   980 	}
       
   981 
       
   982 	return true;
       
   983 }
       
   984 
       
   985 DEF_CONSOLE_CMD(ConInfoVar)
       
   986 {
       
   987 	static const char *_icon_vartypes[] = {"boolean", "byte", "uint16", "uint32", "int16", "int32", "string"};
       
   988 	const IConsoleVar *var;
       
   989 
       
   990 	if (argc == 0) {
       
   991 		IConsoleHelp("Print out debugging information about a variable. Usage: 'info_var <var>'");
       
   992 		return true;
       
   993 	}
       
   994 
       
   995 	if (argc < 2) return false;
       
   996 
       
   997 	var = IConsoleVarGet(argv[1]);
       
   998 	if (var == NULL) {
       
   999 		IConsoleError("the given variable was not found");
       
  1000 		return true;
       
  1001 	}
       
  1002 
       
  1003 	IConsolePrintF(_icolour_def, "variable name: %s", var->name);
       
  1004 	IConsolePrintF(_icolour_def, "variable type: %s", _icon_vartypes[var->type]);
       
  1005 	IConsolePrintF(_icolour_def, "variable addr: 0x%X", var->addr);
       
  1006 
       
  1007 	if (var->hook.access) IConsoleWarning("variable is access hooked");
       
  1008 	if (var->hook.pre) IConsoleWarning("variable is pre hooked");
       
  1009 	if (var->hook.post) IConsoleWarning("variable is post hooked");
       
  1010 	return true;
       
  1011 }
       
  1012 
       
  1013 
       
  1014 DEF_CONSOLE_CMD(ConInfoCmd)
       
  1015 {
       
  1016 	const IConsoleCmd *cmd;
       
  1017 
       
  1018 	if (argc == 0) {
       
  1019 		IConsoleHelp("Print out debugging information about a command. Usage: 'info_cmd <cmd>'");
       
  1020 		return true;
       
  1021 	}
       
  1022 
       
  1023 	if (argc < 2) return false;
       
  1024 
       
  1025 	cmd = IConsoleCmdGet(argv[1]);
       
  1026 	if (cmd == NULL) {
       
  1027 		IConsoleError("the given command was not found");
       
  1028 		return true;
       
  1029 	}
       
  1030 
       
  1031 	IConsolePrintF(_icolour_def, "command name: %s", cmd->name);
       
  1032 	IConsolePrintF(_icolour_def, "command proc: 0x%X", cmd->proc);
       
  1033 
       
  1034 	if (cmd->hook.access) IConsoleWarning("command is access hooked");
       
  1035 	if (cmd->hook.pre) IConsoleWarning("command is pre hooked");
       
  1036 	if (cmd->hook.post) IConsoleWarning("command is post hooked");
       
  1037 
       
  1038 	return true;
       
  1039 }
       
  1040 
       
  1041 DEF_CONSOLE_CMD(ConDebugLevel)
       
  1042 {
       
  1043 	if (argc == 0) {
       
  1044 		IConsoleHelp("Get/set the default debugging level for the game. Usage: 'debug_level [<level>]'");
       
  1045 		IConsoleHelp("Level can be any combination of names, levels. Eg 'net=5 ms=4'. Remember to enclose it in \"'s");
       
  1046 		return true;
       
  1047 	}
       
  1048 
       
  1049 	if (argc > 2) return false;
       
  1050 
       
  1051 	if (argc == 1) {
       
  1052 		IConsolePrintF(_icolour_def, "Current debug-level: '%s'", GetDebugString());
       
  1053 	} else {
       
  1054 		SetDebugString(argv[1]);
       
  1055 	}
       
  1056 
       
  1057 	return true;
       
  1058 }
       
  1059 
       
  1060 DEF_CONSOLE_CMD(ConExit)
       
  1061 {
       
  1062 	if (argc == 0) {
       
  1063 		IConsoleHelp("Exit the game. Usage: 'exit'");
       
  1064 		return true;
       
  1065 	}
       
  1066 
       
  1067 	_exit_game = true;
       
  1068 	return true;
       
  1069 }
       
  1070 
       
  1071 DEF_CONSOLE_CMD(ConPart)
       
  1072 {
       
  1073 	if (argc == 0) {
       
  1074 		IConsoleHelp("Leave the currently joined/running game (only ingame). Usage: 'part'");
       
  1075 		return true;
       
  1076 	}
       
  1077 
       
  1078 	if (_game_mode != GM_NORMAL) return false;
       
  1079 
       
  1080 	_switch_mode = SM_MENU;
       
  1081 	return true;
       
  1082 }
       
  1083 
       
  1084 DEF_CONSOLE_CMD(ConHelp)
       
  1085 {
       
  1086 	if (argc == 2) {
       
  1087 		const IConsoleCmd *cmd;
       
  1088 		const IConsoleVar *var;
       
  1089 		const IConsoleAlias *alias;
       
  1090 
       
  1091 		cmd = IConsoleCmdGet(argv[1]);
       
  1092 		if (cmd != NULL) {
       
  1093 			cmd->proc(0, NULL);
       
  1094 			return true;
       
  1095 		}
       
  1096 
       
  1097 		alias = IConsoleAliasGet(argv[1]);
       
  1098 		if (alias != NULL) {
       
  1099 			cmd = IConsoleCmdGet(alias->cmdline);
       
  1100 			if (cmd != NULL) {
       
  1101 				cmd->proc(0, NULL);
       
  1102 				return true;
       
  1103 			}
       
  1104 			IConsolePrintF(_icolour_err, "ERROR: alias is of special type, please see its execution-line: '%s'", alias->cmdline);
       
  1105 			return true;
       
  1106 		}
       
  1107 
       
  1108 		var = IConsoleVarGet(argv[1]);
       
  1109 		if (var != NULL && var->help != NULL) {
       
  1110 			IConsoleHelp(var->help);
       
  1111 			return true;
       
  1112 		}
       
  1113 
       
  1114 		IConsoleError("command or variable not found");
       
  1115 		return true;
       
  1116 	}
       
  1117 
       
  1118 	IConsolePrint(13, " ---- OpenTTD Console Help ---- ");
       
  1119 	IConsolePrint( 1, " - variables: [command to list all variables: list_vars]");
       
  1120 	IConsolePrint( 1, " set value with '<var> = <value>', use '++/--' to in-or decrement");
       
  1121 	IConsolePrint( 1, " or omit '=' and just '<var> <value>'. get value with typing '<var>'");
       
  1122 	IConsolePrint( 1, " - commands: [command to list all commands: list_cmds]");
       
  1123 	IConsolePrint( 1, " call commands with '<command> <arg2> <arg3>...'");
       
  1124 	IConsolePrint( 1, " - to assign strings, or use them as arguments, enclose it within quotes");
       
  1125 	IConsolePrint( 1, " like this: '<command> \"string argument with spaces\"'");
       
  1126 	IConsolePrint( 1, " - use 'help <command> | <variable>' to get specific information");
       
  1127 	IConsolePrint( 1, " - scroll console output with shift + (up | down) | (pageup | pagedown))");
       
  1128 	IConsolePrint( 1, " - scroll console input history with the up | down arrows");
       
  1129 	IConsolePrint( 1, "");
       
  1130 	return true;
       
  1131 }
       
  1132 
       
  1133 DEF_CONSOLE_CMD(ConListCommands)
       
  1134 {
       
  1135 	const IConsoleCmd *cmd;
       
  1136 	size_t l = 0;
       
  1137 
       
  1138 	if (argc == 0) {
       
  1139 		IConsoleHelp("List all registered commands. Usage: 'list_cmds [<pre-filter>]'");
       
  1140 		return true;
       
  1141 	}
       
  1142 
       
  1143 	if (argv[1] != NULL) l = strlen(argv[1]);
       
  1144 
       
  1145 	for (cmd = _iconsole_cmds; cmd != NULL; cmd = cmd->next) {
       
  1146 		if (argv[1] == NULL || strncmp(cmd->name, argv[1], l) == 0) {
       
  1147 				IConsolePrintF(_icolour_def, "%s", cmd->name);
       
  1148 		}
       
  1149 	}
       
  1150 
       
  1151 	return true;
       
  1152 }
       
  1153 
       
  1154 DEF_CONSOLE_CMD(ConListVariables)
       
  1155 {
       
  1156 	const IConsoleVar *var;
       
  1157 	size_t l = 0;
       
  1158 
       
  1159 	if (argc == 0) {
       
  1160 		IConsoleHelp("List all registered variables. Usage: 'list_vars [<pre-filter>]'");
       
  1161 		return true;
       
  1162 	}
       
  1163 
       
  1164 	if (argv[1] != NULL) l = strlen(argv[1]);
       
  1165 
       
  1166 	for (var = _iconsole_vars; var != NULL; var = var->next) {
       
  1167 		if (argv[1] == NULL || strncmp(var->name, argv[1], l) == 0)
       
  1168 			IConsolePrintF(_icolour_def, "%s", var->name);
       
  1169 	}
       
  1170 
       
  1171 	return true;
       
  1172 }
       
  1173 
       
  1174 DEF_CONSOLE_CMD(ConListAliases)
       
  1175 {
       
  1176 	const IConsoleAlias *alias;
       
  1177 	size_t l = 0;
       
  1178 
       
  1179 	if (argc == 0) {
       
  1180 		IConsoleHelp("List all registered aliases. Usage: 'list_aliases [<pre-filter>]'");
       
  1181 		return true;
       
  1182 	}
       
  1183 
       
  1184 	if (argv[1] != NULL) l = strlen(argv[1]);
       
  1185 
       
  1186 	for (alias = _iconsole_aliases; alias != NULL; alias = alias->next) {
       
  1187 		if (argv[1] == NULL || strncmp(alias->name, argv[1], l) == 0)
       
  1188 			IConsolePrintF(_icolour_def, "%s => %s", alias->name, alias->cmdline);
       
  1189 	}
       
  1190 
       
  1191 	return true;
       
  1192 }
       
  1193 
       
  1194 #ifdef ENABLE_NETWORK
       
  1195 
       
  1196 DEF_CONSOLE_CMD(ConSay)
       
  1197 {
       
  1198 	if (argc == 0) {
       
  1199 		IConsoleHelp("Chat to your fellow players in a multiplayer game. Usage: 'say \"<msg>\"'");
       
  1200 		return true;
       
  1201 	}
       
  1202 
       
  1203 	if (argc != 2) return false;
       
  1204 
       
  1205 	if (!_network_server) {
       
  1206 		SEND_COMMAND(PACKET_CLIENT_CHAT)(NETWORK_ACTION_CHAT, DESTTYPE_BROADCAST, 0 /* param does not matter */, argv[1]);
       
  1207 	} else {
       
  1208 		NetworkServer_HandleChat(NETWORK_ACTION_CHAT, DESTTYPE_BROADCAST, 0, argv[1], NETWORK_SERVER_INDEX);
       
  1209 	}
       
  1210 
       
  1211 	return true;
       
  1212 }
       
  1213 
       
  1214 #ifdef ENABLE_NETWORK
       
  1215 	#include "table/strings.h"
       
  1216 #endif /* ENABLE_NETWORK */
       
  1217 
       
  1218 DEF_CONSOLE_CMD(ConPlayers)
       
  1219 {
       
  1220 	Player *p;
       
  1221 
       
  1222 	if (argc == 0) {
       
  1223 		IConsoleHelp("List the in-game details of all clients connected to the server. Usage 'players'");
       
  1224 		return true;
       
  1225 	}
       
  1226 	NetworkPopulateCompanyInfo();
       
  1227 
       
  1228 	FOR_ALL_PLAYERS(p) {
       
  1229 		char buffer[512];
       
  1230 
       
  1231 		if (!p->is_active) continue;
       
  1232 
       
  1233 		GetString(buffer, STR_00D1_DARK_BLUE + _player_colors[p->index], lastof(buffer));
       
  1234 		IConsolePrintF(8, "#:%d(%s) Company Name: '%s'  Year Founded: %d  Money: %d  Loan: %d  Value: %" OTTD_PRINTF64 "d  (T:%d, R:%d, P:%d, S:%d)",
       
  1235 			p->index + 1, buffer, _network_player_info[p->index].company_name, p->inaugurated_year, p->player_money, p->current_loan, CalculateCompanyValue(p),
       
  1236 			/* trains      */ _network_player_info[p->index].num_vehicle[0],
       
  1237 			/* lorry + bus */ _network_player_info[p->index].num_vehicle[1] + _network_player_info[p->index].num_vehicle[2],
       
  1238 			/* planes      */ _network_player_info[p->index].num_vehicle[3],
       
  1239 			/* ships       */ _network_player_info[p->index].num_vehicle[4]);
       
  1240 	}
       
  1241 
       
  1242 	return true;
       
  1243 }
       
  1244 
       
  1245 DEF_CONSOLE_CMD(ConSayPlayer)
       
  1246 {
       
  1247 	if (argc == 0) {
       
  1248 		IConsoleHelp("Chat to a certain player in a multiplayer game. Usage: 'say_player <player-no> \"<msg>\"'");
       
  1249 		IConsoleHelp("PlayerNo is the player that plays as company <playerno>, 1 through max_players");
       
  1250 		return true;
       
  1251 	}
       
  1252 
       
  1253 	if (argc != 3) return false;
       
  1254 
       
  1255 	if (atoi(argv[1]) < 1 || atoi(argv[1]) > MAX_PLAYERS) {
       
  1256 		IConsolePrintF(_icolour_def, "Unknown player. Player range is between 1 and %d.", MAX_PLAYERS);
       
  1257 		return true;
       
  1258 	}
       
  1259 
       
  1260 	if (!_network_server) {
       
  1261 		SEND_COMMAND(PACKET_CLIENT_CHAT)(NETWORK_ACTION_CHAT_COMPANY, DESTTYPE_TEAM, atoi(argv[1]), argv[2]);
       
  1262 	} else {
       
  1263 		NetworkServer_HandleChat(NETWORK_ACTION_CHAT_COMPANY, DESTTYPE_TEAM, atoi(argv[1]), argv[2], NETWORK_SERVER_INDEX);
       
  1264 	}
       
  1265 
       
  1266 	return true;
       
  1267 }
       
  1268 
       
  1269 DEF_CONSOLE_CMD(ConSayClient)
       
  1270 {
       
  1271 	if (argc == 0) {
       
  1272 		IConsoleHelp("Chat to a certain player in a multiplayer game. Usage: 'say_client <client-no> \"<msg>\"'");
       
  1273 		IConsoleHelp("For client-id's, see the command 'clients'");
       
  1274 		return true;
       
  1275 	}
       
  1276 
       
  1277 	if (argc != 3) return false;
       
  1278 
       
  1279 	if (!_network_server) {
       
  1280 		SEND_COMMAND(PACKET_CLIENT_CHAT)(NETWORK_ACTION_CHAT_CLIENT, DESTTYPE_CLIENT, atoi(argv[1]), argv[2]);
       
  1281 	} else {
       
  1282 		NetworkServer_HandleChat(NETWORK_ACTION_CHAT_CLIENT, DESTTYPE_CLIENT, atoi(argv[1]), argv[2], NETWORK_SERVER_INDEX);
       
  1283 	}
       
  1284 
       
  1285 	return true;
       
  1286 }
       
  1287 
       
  1288 DEF_CONSOLE_HOOK(ConHookServerPW)
       
  1289 {
       
  1290 	if (strcmp(_network_server_password, "*") == 0) {
       
  1291 		_network_server_password[0] = '\0';
       
  1292 		_network_game_info.use_password = 0;
       
  1293 	} else {
       
  1294 		ttd_strlcpy(_network_game_info.server_password, _network_server_password, sizeof(_network_server_password));
       
  1295 		_network_game_info.use_password = 1;
       
  1296 	}
       
  1297 
       
  1298 	return true;
       
  1299 }
       
  1300 
       
  1301 DEF_CONSOLE_HOOK(ConHookRconPW)
       
  1302 {
       
  1303 	if (strcmp(_network_rcon_password, "*") == 0)
       
  1304 		_network_rcon_password[0] = '\0';
       
  1305 
       
  1306 	ttd_strlcpy(_network_game_info.rcon_password, _network_rcon_password, sizeof(_network_game_info.rcon_password));
       
  1307 
       
  1308 	return true;
       
  1309 }
       
  1310 
       
  1311 /* Also use from within player_gui to change the password graphically */
       
  1312 bool NetworkChangeCompanyPassword(byte argc, char *argv[])
       
  1313 {
       
  1314 	if (argc == 0) {
       
  1315 		if (!IsValidPlayer(_local_player)) return true; // dedicated server
       
  1316 		IConsolePrintF(_icolour_warn, "Current value for 'company_pw': %s", _network_player_info[_local_player].password);
       
  1317 		return true;
       
  1318 	}
       
  1319 
       
  1320 	if (!IsValidPlayer(_local_player)) {
       
  1321 		IConsoleError("You have to own a company to make use of this command.");
       
  1322 		return false;
       
  1323 	}
       
  1324 
       
  1325 	if (argc != 1) return false;
       
  1326 
       
  1327 	if (strcmp(argv[0], "*") == 0) argv[0][0] = '\0';
       
  1328 
       
  1329 	ttd_strlcpy(_network_player_info[_local_player].password, argv[0], sizeof(_network_player_info[_local_player].password));
       
  1330 
       
  1331 	if (!_network_server)
       
  1332 		SEND_COMMAND(PACKET_CLIENT_SET_PASSWORD)(_network_player_info[_local_player].password);
       
  1333 
       
  1334 	IConsolePrintF(_icolour_warn, "'company_pw' changed to:  %s", _network_player_info[_local_player].password);
       
  1335 
       
  1336 	return true;
       
  1337 }
       
  1338 
       
  1339 DEF_CONSOLE_HOOK(ConProcPlayerName)
       
  1340 {
       
  1341 	NetworkClientInfo *ci = NetworkFindClientInfoFromIndex(_network_own_client_index);
       
  1342 
       
  1343 	if (ci == NULL) return false;
       
  1344 
       
  1345 	// Don't change the name if it is the same as the old name
       
  1346 	if (strcmp(ci->client_name, _network_player_name) != 0) {
       
  1347 		if (!_network_server) {
       
  1348 			SEND_COMMAND(PACKET_CLIENT_SET_NAME)(_network_player_name);
       
  1349 		} else {
       
  1350 			if (NetworkFindName(_network_player_name)) {
       
  1351 				NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, 1, false, ci->client_name, "%s", _network_player_name);
       
  1352 				ttd_strlcpy(ci->client_name, _network_player_name, sizeof(ci->client_name));
       
  1353 				NetworkUpdateClientInfo(NETWORK_SERVER_INDEX);
       
  1354 			}
       
  1355 		}
       
  1356 	}
       
  1357 
       
  1358 	return true;
       
  1359 }
       
  1360 
       
  1361 DEF_CONSOLE_HOOK(ConHookServerName)
       
  1362 {
       
  1363 	ttd_strlcpy(_network_game_info.server_name, _network_server_name, sizeof(_network_game_info.server_name));
       
  1364 	return true;
       
  1365 }
       
  1366 
       
  1367 DEF_CONSOLE_HOOK(ConHookServerAdvertise)
       
  1368 {
       
  1369 	if (!_network_advertise) // remove us from advertising
       
  1370 		NetworkUDPRemoveAdvertise();
       
  1371 
       
  1372 	return true;
       
  1373 }
       
  1374 
       
  1375 DEF_CONSOLE_CMD(ConProcServerIP)
       
  1376 {
       
  1377 	if (argc == 0) {
       
  1378 		IConsolePrintF(_icolour_warn, "Current value for 'server_ip': %s", inet_ntoa(*(struct in_addr *)&_network_server_bind_ip));
       
  1379 		return true;
       
  1380 	}
       
  1381 
       
  1382 	if (argc != 1) return false;
       
  1383 
       
  1384 	_network_server_bind_ip = (strcmp(argv[0], "all") == 0) ? inet_addr("0.0.0.0") : inet_addr(argv[0]);
       
  1385 	snprintf(_network_server_bind_ip_host, sizeof(_network_server_bind_ip_host), "%s", inet_ntoa(*(struct in_addr *)&_network_server_bind_ip));
       
  1386 	IConsolePrintF(_icolour_warn, "'server_ip' changed to:  %s", inet_ntoa(*(struct in_addr *)&_network_server_bind_ip));
       
  1387 	return true;
       
  1388 }
       
  1389 #endif /* ENABLE_NETWORK */
       
  1390 
       
  1391 DEF_CONSOLE_CMD(ConPatch)
       
  1392 {
       
  1393 	if (argc == 0) {
       
  1394 		IConsoleHelp("Change patch variables for all players. Usage: 'patch <name> [<value>]'");
       
  1395 		IConsoleHelp("Omitting <value> will print out the current value of the patch-setting.");
       
  1396 		return true;
       
  1397 	}
       
  1398 
       
  1399 	if (argc == 1 || argc > 3) return false;
       
  1400 
       
  1401 	if (argc == 2) {
       
  1402 		IConsoleGetPatchSetting(argv[1]);
       
  1403 	} else {
       
  1404 		uint32 val;
       
  1405 
       
  1406 		if (GetArgumentInteger(&val, argv[2])) {
       
  1407 			if (!IConsoleSetPatchSetting(argv[1], val)) {
       
  1408 				IConsoleError("This command/variable is only available to a network server.");
       
  1409 			}
       
  1410 		}
       
  1411 	}
       
  1412 
       
  1413 	return true;
       
  1414 }
       
  1415 
       
  1416 DEF_CONSOLE_CMD(ConListDumpVariables)
       
  1417 {
       
  1418 	const IConsoleVar *var;
       
  1419 	size_t l = 0;
       
  1420 
       
  1421 	if (argc == 0) {
       
  1422 		IConsoleHelp("List all variables with their value. Usage: 'dump_vars [<pre-filter>]'");
       
  1423 		return true;
       
  1424 	}
       
  1425 
       
  1426 	if (argv[1] != NULL) l = strlen(argv[1]);
       
  1427 
       
  1428 	for (var = _iconsole_vars; var != NULL; var = var->next) {
       
  1429 		if (argv[1] == NULL || strncmp(var->name, argv[1], l) == 0)
       
  1430 			IConsoleVarPrintGetValue(var);
       
  1431 	}
       
  1432 
       
  1433 	return true;
       
  1434 }
       
  1435 
       
  1436 
       
  1437 #ifdef _DEBUG
       
  1438 /* ****************************************** */
       
  1439 /*  debug commands and variables */
       
  1440 /* ****************************************** */
       
  1441 
       
  1442 static void IConsoleDebugLibRegister(void)
       
  1443 {
       
  1444 	// debugging variables and functions
       
  1445 	extern bool _stdlib_con_developer; /* XXX extern in .c */
       
  1446 
       
  1447 	IConsoleVarRegister("con_developer",    &_stdlib_con_developer, ICONSOLE_VAR_BOOLEAN, "Enable/disable console debugging information (internal)");
       
  1448 	IConsoleCmdRegister("resettile",        ConResetTile);
       
  1449 	IConsoleCmdRegister("stopall",          ConStopAllVehicles);
       
  1450 	IConsoleAliasRegister("dbg_echo",       "echo %A; echo %B");
       
  1451 	IConsoleAliasRegister("dbg_echo2",      "echo %!");
       
  1452 }
       
  1453 #endif
       
  1454 
       
  1455 /* ****************************************** */
       
  1456 /*  console command and variable registration */
       
  1457 /* ****************************************** */
       
  1458 
       
  1459 void IConsoleStdLibRegister(void)
       
  1460 {
       
  1461 	// stdlib
       
  1462 	extern byte _stdlib_developer; /* XXX extern in .c */
       
  1463 
       
  1464 	// default variables and functions
       
  1465 	IConsoleCmdRegister("debug_level",  ConDebugLevel);
       
  1466 	IConsoleCmdRegister("dump_vars",    ConListDumpVariables);
       
  1467 	IConsoleCmdRegister("echo",         ConEcho);
       
  1468 	IConsoleCmdRegister("echoc",        ConEchoC);
       
  1469 	IConsoleCmdRegister("exec",         ConExec);
       
  1470 	IConsoleCmdRegister("exit",         ConExit);
       
  1471 	IConsoleCmdRegister("part",         ConPart);
       
  1472 	IConsoleCmdRegister("help",         ConHelp);
       
  1473 	IConsoleCmdRegister("info_cmd",     ConInfoCmd);
       
  1474 	IConsoleCmdRegister("info_var",     ConInfoVar);
       
  1475 	IConsoleCmdRegister("list_cmds",    ConListCommands);
       
  1476 	IConsoleCmdRegister("list_vars",    ConListVariables);
       
  1477 	IConsoleCmdRegister("list_aliases", ConListAliases);
       
  1478 	IConsoleCmdRegister("newgame",      ConNewGame);
       
  1479 	IConsoleCmdRegister("restart",      ConRestart);
       
  1480 	IConsoleCmdRegister("getseed",      ConGetSeed);
       
  1481 	IConsoleCmdRegister("quit",         ConExit);
       
  1482 	IConsoleCmdRegister("resetengines", ConResetEngines);
       
  1483 	IConsoleCmdRegister("return",       ConReturn);
       
  1484 	IConsoleCmdRegister("screenshot",   ConScreenShot);
       
  1485 	IConsoleCmdRegister("script",       ConScript);
       
  1486 	IConsoleCmdRegister("scrollto",     ConScrollToTile);
       
  1487 	IConsoleCmdRegister("alias",        ConAlias);
       
  1488 	IConsoleCmdRegister("load",         ConLoad);
       
  1489 	IConsoleCmdRegister("rm",           ConRemove);
       
  1490 	IConsoleCmdRegister("save",         ConSave);
       
  1491 	IConsoleCmdRegister("saveconfig",   ConSaveConfig);
       
  1492 	IConsoleCmdRegister("ls",           ConListFiles);
       
  1493 	IConsoleCmdRegister("cd",           ConChangeDirectory);
       
  1494 	IConsoleCmdRegister("pwd",          ConPrintWorkingDirectory);
       
  1495 	IConsoleCmdRegister("clear",        ConClearBuffer);
       
  1496 	IConsoleCmdRegister("patch",        ConPatch);
       
  1497 
       
  1498 	IConsoleAliasRegister("dir",      "ls");
       
  1499 	IConsoleAliasRegister("del",      "rm %+");
       
  1500 	IConsoleAliasRegister("newmap",   "newgame");
       
  1501 	IConsoleAliasRegister("new_map",  "newgame");
       
  1502 	IConsoleAliasRegister("new_game", "newgame");
       
  1503 
       
  1504 
       
  1505 	IConsoleVarRegister("developer", &_stdlib_developer, ICONSOLE_VAR_BYTE, "Redirect debugging output from the console/command line to the ingame console (value 2). Default value: 1");
       
  1506 
       
  1507 	/* networking variables and functions */
       
  1508 #ifdef ENABLE_NETWORK
       
  1509 	/* Network hooks; only active in network */
       
  1510 	IConsoleCmdHookAdd ("resetengines", ICONSOLE_HOOK_ACCESS, ConHookNoNetwork);
       
  1511 
       
  1512 	/*** Networking commands ***/
       
  1513 	IConsoleCmdRegister("say",             ConSay);
       
  1514 	IConsoleCmdHookAdd("say",              ICONSOLE_HOOK_ACCESS, ConHookNeedNetwork);
       
  1515 	IConsoleCmdRegister("players",             ConPlayers);
       
  1516 	IConsoleCmdHookAdd("players",              ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
       
  1517 	IConsoleCmdRegister("say_player",      ConSayPlayer);
       
  1518 	IConsoleCmdHookAdd("say_player",       ICONSOLE_HOOK_ACCESS, ConHookNeedNetwork);
       
  1519 	IConsoleCmdRegister("say_client",      ConSayClient);
       
  1520 	IConsoleCmdHookAdd("say_client",       ICONSOLE_HOOK_ACCESS, ConHookNeedNetwork);
       
  1521 
       
  1522 	IConsoleCmdRegister("connect",         ConNetworkConnect);
       
  1523 	IConsoleCmdHookAdd("connect",          ICONSOLE_HOOK_ACCESS, ConHookClientOnly);
       
  1524 	IConsoleAliasRegister("join",          "connect %A");
       
  1525 	IConsoleCmdRegister("clients",         ConNetworkClients);
       
  1526 	IConsoleCmdHookAdd("clients",          ICONSOLE_HOOK_ACCESS, ConHookNeedNetwork);
       
  1527 	IConsoleCmdRegister("status",          ConStatus);
       
  1528 	IConsoleCmdHookAdd("status",           ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
       
  1529 	IConsoleCmdRegister("server_info",     ConServerInfo);
       
  1530 	IConsoleCmdHookAdd("server_info",      ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
       
  1531 	IConsoleAliasRegister("info",          "server_info");
       
  1532 	IConsoleCmdRegister("rcon",            ConRcon);
       
  1533 	IConsoleCmdHookAdd("rcon",             ICONSOLE_HOOK_ACCESS, ConHookNeedNetwork);
       
  1534 
       
  1535 	IConsoleCmdRegister("reset_company",   ConResetCompany);
       
  1536 	IConsoleCmdHookAdd("reset_company",    ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
       
  1537 	IConsoleAliasRegister("clean_company", "reset_company %A");
       
  1538 	IConsoleCmdRegister("kick",            ConKick);
       
  1539 	IConsoleCmdHookAdd("kick",             ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
       
  1540 	IConsoleCmdRegister("ban",             ConBan);
       
  1541 	IConsoleCmdHookAdd("ban",              ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
       
  1542 	IConsoleCmdRegister("unban",           ConUnBan);
       
  1543 	IConsoleCmdHookAdd("unban",            ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
       
  1544 	IConsoleCmdRegister("banlist",         ConBanList);
       
  1545 	IConsoleCmdHookAdd("banlist",          ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
       
  1546 
       
  1547 	IConsoleCmdRegister("pause",           ConPauseGame);
       
  1548 	IConsoleCmdHookAdd("pause",            ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
       
  1549 	IConsoleCmdRegister("unpause",         ConUnPauseGame);
       
  1550 	IConsoleCmdHookAdd("unpause",          ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
       
  1551 
       
  1552 	/*** Networking variables ***/
       
  1553 	IConsoleVarRegister("net_frame_freq",        &_network_frame_freq, ICONSOLE_VAR_BYTE, "The amount of frames before a command will be (visibly) executed. Default value: 1");
       
  1554 	IConsoleVarHookAdd("net_frame_freq",         ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
       
  1555 	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");
       
  1556 	IConsoleVarHookAdd("net_sync_freq",          ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
       
  1557 
       
  1558 	IConsoleVarStringRegister("server_pw",       &_network_server_password, sizeof(_network_server_password), "Set the server password to protect your server. Use '*' to clear the password");
       
  1559 	IConsoleVarHookAdd("server_pw",              ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
       
  1560 	IConsoleVarHookAdd("server_pw",              ICONSOLE_HOOK_POST_ACTION, ConHookServerPW);
       
  1561 	IConsoleAliasRegister("server_password",     "server_pw %+");
       
  1562 	IConsoleVarStringRegister("rcon_pw",         &_network_rcon_password, sizeof(_network_rcon_password), "Set the rcon-password to change server behaviour. Use '*' to disable rcon");
       
  1563 	IConsoleVarHookAdd("rcon_pw",                ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
       
  1564 	IConsoleVarHookAdd("rcon_pw",                ICONSOLE_HOOK_POST_ACTION, ConHookRconPW);
       
  1565 	IConsoleAliasRegister("rcon_password",       "rcon_pw %+");
       
  1566 	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");
       
  1567 	IConsoleVarHookAdd("company_pw",             ICONSOLE_HOOK_ACCESS, ConHookNeedNetwork);
       
  1568 	IConsoleVarProcAdd("company_pw",             NetworkChangeCompanyPassword);
       
  1569 	IConsoleAliasRegister("company_password",    "company_pw %+");
       
  1570 
       
  1571 	IConsoleVarStringRegister("name",            &_network_player_name, sizeof(_network_player_name), "Set your name for multiplayer");
       
  1572 	IConsoleVarHookAdd("name",                   ICONSOLE_HOOK_ACCESS, ConHookNeedNetwork);
       
  1573 	IConsoleVarHookAdd("name",                   ICONSOLE_HOOK_POST_ACTION, ConProcPlayerName);
       
  1574 	IConsoleVarStringRegister("server_name",     &_network_server_name, sizeof(_network_server_name), "Set the name of the server for multiplayer");
       
  1575 	IConsoleVarHookAdd("server_name",            ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
       
  1576 	IConsoleVarHookAdd("server_name",            ICONSOLE_HOOK_POST_ACTION, ConHookServerName);
       
  1577 
       
  1578 	IConsoleVarRegister("server_port",           &_network_server_port, ICONSOLE_VAR_UINT32, "Set the server port. Changes take effect the next time you start a server");
       
  1579 	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.");
       
  1580 	IConsoleVarProcAdd("server_ip",              ConProcServerIP);
       
  1581 	IConsoleAliasRegister("server_bind_ip",      "server_ip %+");
       
  1582 	IConsoleAliasRegister("server_ip_bind",      "server_ip %+");
       
  1583 	IConsoleAliasRegister("server_bind",         "server_ip %+");
       
  1584 	IConsoleVarRegister("server_advertise",      &_network_advertise, ICONSOLE_VAR_BOOLEAN, "Set if the server will advertise to the master server and show up there");
       
  1585 	IConsoleVarHookAdd("server_advertise",       ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
       
  1586 	IConsoleVarHookAdd("server_advertise",       ICONSOLE_HOOK_POST_ACTION, ConHookServerAdvertise);
       
  1587 
       
  1588 	IConsoleVarRegister("max_clients",           &_network_game_info.clients_max, ICONSOLE_VAR_BYTE, "Control the maximum amount of connected players during runtime. Default value: 10");
       
  1589 	IConsoleVarHookAdd("max_clients",            ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
       
  1590 	IConsoleVarHookAdd("max_clients",            ICONSOLE_HOOK_POST_ACTION, ConHookValidateMaxClientsCount);
       
  1591 	IConsoleVarRegister("max_companies",         &_network_game_info.companies_max, ICONSOLE_VAR_BYTE, "Control the maximum amount of active companies during runtime. Default value: 8");
       
  1592 	IConsoleVarHookAdd("max_companies",          ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
       
  1593 	IConsoleVarHookAdd("max_companies",          ICONSOLE_HOOK_POST_ACTION, ConHookValidateMaxCompaniesCount);
       
  1594 	IConsoleVarRegister("max_spectators",        &_network_game_info.spectators_max, ICONSOLE_VAR_BYTE, "Control the maximum amount of active spectators during runtime. Default value: 9");
       
  1595 	IConsoleVarHookAdd("max_spectators",         ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
       
  1596 	IConsoleVarHookAdd("max_spectators",         ICONSOLE_HOOK_POST_ACTION, ConHookValidateMaxSpectatorsCount);
       
  1597 
       
  1598 	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");
       
  1599 
       
  1600 	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");
       
  1601 	IConsoleVarHookAdd("pause_on_join",          ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
       
  1602 
       
  1603 	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'");
       
  1604 	IConsoleVarHookAdd("autoclean_companies",    ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
       
  1605 	IConsoleVarRegister("autoclean_protected",   &_network_autoclean_protected, ICONSOLE_VAR_BYTE, "Automatically remove the password from an inactive company after the given amount of months");
       
  1606 	IConsoleVarHookAdd("autoclean_protected",    ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
       
  1607 	IConsoleVarRegister("autoclean_unprotected", &_network_autoclean_unprotected, ICONSOLE_VAR_BYTE, "Automatically shut down inactive companies after the given amount of months");
       
  1608 	IConsoleVarHookAdd("autoclean_unprotected",  ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
       
  1609 	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");
       
  1610 	IConsoleVarHookAdd("restart_game_year",      ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
       
  1611 
       
  1612 	IConsoleVarRegister("min_players",           &_network_min_players, ICONSOLE_VAR_BYTE, "Automatically pause the game when the number of active players passes below the given amount");
       
  1613 	IConsoleVarHookAdd("min_players",            ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
       
  1614 	IConsoleVarHookAdd("min_players",            ICONSOLE_HOOK_POST_ACTION, ConHookCheckMinPlayers);
       
  1615 
       
  1616 #endif /* ENABLE_NETWORK */
       
  1617 
       
  1618 	// debugging stuff
       
  1619 #ifdef _DEBUG
       
  1620 	IConsoleDebugLibRegister();
       
  1621 #endif
       
  1622 }