File diff r4076:ac684fc44bc2 → r4077:259c4c4aacad
console_cmds.c
Show inline comments
 
@@ -182,26 +182,27 @@ DEF_CONSOLE_CMD(ConSave)
 
		IConsoleHelp("Save the current game. Usage: 'save <filename>'");
 
		return true;
 
	}
 

	
 
	if (argc == 2) {
 
		char buf[200];
 

	
 
		snprintf(buf, lengthof(buf), "%s%s%s.sav", _path.save_dir, PATHSEP, argv[1]);
 
		IConsolePrint(_icolour_def, "Saving map...");
 

	
 
		if (SaveOrLoad(buf, SL_SAVE) != SL_OK) {
 
			IConsolePrint(_icolour_err, "SaveMap failed");
 
		} else
 
		} else {
 
			IConsolePrintF(_icolour_def, "Map sucessfully saved to %s", buf);
 
		}
 
		return true;
 
	}
 

	
 
	return false;
 
}
 

	
 
static const FiosItem* GetFiosItem(const char* file)
 
{
 
	int i;
 

	
 
	_saveload_mode = SLD_LOAD_GAME;
 
	BuildFileList();
 
@@ -238,51 +239,53 @@ DEF_CONSOLE_CMD(ConLoad)
 
	item = GetFiosItem(file);
 
	if (item != NULL) {
 
		switch (item->type) {
 
			case FIOS_TYPE_FILE: case FIOS_TYPE_OLDFILE: {
 
				_switch_mode = SM_LOAD;
 
				SetFiosType(item->type);
 

	
 
				ttd_strlcpy(_file_to_saveload.name, FiosBrowseTo(item), sizeof(_file_to_saveload.name));
 
				ttd_strlcpy(_file_to_saveload.title, item->title, sizeof(_file_to_saveload.title));
 
			} break;
 
			default: IConsolePrintF(_icolour_err, "%s: Not a savegame.", file);
 
		}
 
	} else
 
	} else {
 
		IConsolePrintF(_icolour_err, "%s: No such file or directory.", file);
 
	}
 

	
 
	FiosFreeSavegameList();
 
	return true;
 
}
 

	
 

	
 
DEF_CONSOLE_CMD(ConRemove)
 
{
 
	const FiosItem* item;
 
	const char* file;
 

	
 
	if (argc == 0) {
 
		IConsoleHelp("Remove a savegame by name or index. Usage: 'rm <file | number>'");
 
		return true;
 
	}
 

	
 
	if (argc != 2) return false;
 

	
 
	file = argv[1];
 
	item = GetFiosItem(file);
 
	if (item != NULL) {
 
		if (!FiosDelete(item->name))
 
			IConsolePrintF(_icolour_err, "%s: Failed to delete file", file);
 
	} else
 
	} else {
 
		IConsolePrintF(_icolour_err, "%s: No such file or directory.", file);
 
	}
 

	
 
	FiosFreeSavegameList();
 
	return true;
 
}
 

	
 

	
 
/* List all the files in the current dir via console */
 
DEF_CONSOLE_CMD(ConListFiles)
 
{
 
	int i;
 

	
 
	if (argc == 0) {
 
@@ -314,26 +317,27 @@ DEF_CONSOLE_CMD(ConChangeDirectory)
 

	
 
	if (argc != 2) return false;
 

	
 
	file = argv[1];
 
	item = GetFiosItem(file);
 
	if (item != NULL) {
 
		switch (item->type) {
 
			case FIOS_TYPE_DIR: case FIOS_TYPE_DRIVE: case FIOS_TYPE_PARENT:
 
				FiosBrowseTo(item);
 
				break;
 
			default: IConsolePrintF(_icolour_err, "%s: Not a directory.", file);
 
		}
 
	} else
 
	} else {
 
		IConsolePrintF(_icolour_err, "%s: No such file or directory.", file);
 
	}
 

	
 
	FiosFreeSavegameList();
 
	return true;
 
}
 

	
 
DEF_CONSOLE_CMD(ConPrintWorkingDirectory)
 
{
 
	const char *path;
 

	
 
	if (argc == 0) {
 
		IConsoleHelp("Print out the current working directory. Usage: 'pwd'");
 
		return true;
 
@@ -399,26 +403,27 @@ DEF_CONSOLE_CMD(ConBan)
 
		return true;
 
	}
 

	
 
	if (index == 0 || (ci == NULL && index != (uint32)-1)) {
 
		IConsoleError("Invalid client");
 
		return true;
 
	}
 

	
 
	if (ci != NULL) {
 
		banip = inet_ntoa(*(struct in_addr *)&ci->client_ip);
 
		SEND_COMMAND(PACKET_SERVER_ERROR)(NetworkFindClientStateFromIndex(index), NETWORK_ERROR_KICKED);
 
		IConsolePrint(_icolour_def, "Client banned");
 
	} else
 
	} else {
 
		IConsolePrint(_icolour_def, "Client not online, banned IP");
 
	}
 

	
 
	/* Add user to ban-list */
 
	for (index = 0; index < lengthof(_network_ban_list); index++) {
 
		if (_network_ban_list[index] == NULL) {
 
			_network_ban_list[index] = strdup(banip);
 
			break;
 
		}
 
	}
 

	
 
	return true;
 
}
 

	
 
@@ -472,76 +477,87 @@ DEF_CONSOLE_CMD(ConBanList)
 
}
 

	
 
DEF_CONSOLE_CMD(ConPauseGame)
 
{
 
	if (argc == 0) {
 
		IConsoleHelp("Pause a network game. Usage: 'pause'");
 
		return true;
 
	}
 

	
 
	if (_pause == 0) {
 
		DoCommandP(0, 1, 0, NULL, CMD_PAUSE);
 
		IConsolePrint(_icolour_def, "Game paused.");
 
	} else
 
	} else {
 
		IConsolePrint(_icolour_def, "Game is already paused.");
 
	}
 

	
 
	return true;
 
}
 

	
 
DEF_CONSOLE_CMD(ConUnPauseGame)
 
{
 
	if (argc == 0) {
 
		IConsoleHelp("Unpause a network game. Usage: 'unpause'");
 
		return true;
 
	}
 

	
 
	if (_pause != 0) {
 
		DoCommandP(0, 0, 0, NULL, CMD_PAUSE);
 
		IConsolePrint(_icolour_def, "Game unpaused.");
 
	} else
 
	} else {
 
		IConsolePrint(_icolour_def, "Game is already unpaused.");
 
	}
 

	
 
	return true;
 
}
 

	
 
DEF_CONSOLE_CMD(ConRcon)
 
{
 
	if (argc == 0) {
 
		IConsoleHelp("Remote control the server from another client. Usage: 'rcon <password> <command>'");
 
		IConsoleHelp("Remember to enclose the command in quotes, otherwise only the first parameter is sent");
 
		return true;
 
	}
 

	
 
	if (argc < 3) return false;
 

	
 
	SEND_COMMAND(PACKET_CLIENT_RCON)(argv[1], argv[2]);
 
	return true;
 
}
 

	
 
DEF_CONSOLE_CMD(ConStatus)
 
{
 
	static const char *stat_str[] = {"inactive", "authorized", "waiting", "loading map", "map done", "ready", "active"};
 
	const char *status;
 
	static const char* const stat_str[] = {
 
		"inactive",
 
		"authorized",
 
		"waiting",
 
		"loading map",
 
		"map done",
 
		"ready",
 
		"active"
 
	};
 

	
 
	const NetworkClientState *cs;
 

	
 
	if (argc == 0) {
 
		IConsoleHelp("List the status of all clients connected to the server. Usage 'status'");
 
		return true;
 
	}
 

	
 
	FOR_ALL_CLIENTS(cs) {
 
		int lag = NetworkCalculateLag(cs);
 
		const NetworkClientInfo *ci = DEREF_CLIENT_INFO(cs);
 
		const char* status;
 

	
 
		status = (cs->status <= STATUS_ACTIVE) ? stat_str[cs->status] : "unknown";
 
		status = (cs->status <= lengthof(stat_str) ? stat_str[cs->status] : "unknown");
 
		IConsolePrintF(8, "Client #%1d  name: '%s'  status: '%s'  frame-lag: %3d  company: %1d  IP: %s  unique-id: '%s'",
 
			cs->index, ci->client_name, status, lag, ci->client_playas, GetPlayerIP(ci), ci->unique_id);
 
	}
 

	
 
	return true;
 
}
 

	
 
DEF_CONSOLE_CMD(ConServerInfo)
 
{
 
	const NetworkGameInfo *gi;
 

	
 
	if (argc == 0) {
 
@@ -549,45 +565,48 @@ DEF_CONSOLE_CMD(ConServerInfo)
 
		IConsoleHelp("You can change these values by setting the variables 'max_clients', 'max_companies' and 'max_spectators'");
 
		return true;
 
	}
 

	
 
	gi = &_network_game_info;
 
	IConsolePrintF(_icolour_def, "Current/maximum clients:    %2d/%2d", gi->clients_on, gi->clients_max);
 
	IConsolePrintF(_icolour_def, "Current/maximum companies:  %2d/%2d", ActivePlayerCount(), gi->companies_max);
 
	IConsolePrintF(_icolour_def, "Current/maximum spectators: %2d/%2d", NetworkSpectatorCount(), gi->spectators_max);
 

	
 
	return true;
 
}
 

	
 
DEF_CONSOLE_HOOK(ConHookValidateMaxClientsCount) {
 
DEF_CONSOLE_HOOK(ConHookValidateMaxClientsCount)
 
{
 
	/* XXX - hardcoded, string limiation -- TrueLight
 
	 * XXX - also see network.c:NetworkStartup ~1356 */
 
	if (_network_game_info.clients_max > 10) {
 
		_network_game_info.clients_max = 10;
 
		IConsoleError("Maximum clients out of bounds, truncating to limit.");
 
	}
 

	
 
	return true;
 
}
 

	
 
DEF_CONSOLE_HOOK(ConHookValidateMaxCompaniesCount) {
 
DEF_CONSOLE_HOOK(ConHookValidateMaxCompaniesCount)
 
{
 
	if (_network_game_info.companies_max > MAX_PLAYERS) {
 
		_network_game_info.companies_max = MAX_PLAYERS;
 
		IConsoleError("Maximum companies out of bounds, truncating to limit.");
 
	}
 

	
 
	return true;
 
}
 

	
 
DEF_CONSOLE_HOOK(ConHookValidateMaxSpectatorsCount) {
 
DEF_CONSOLE_HOOK(ConHookValidateMaxSpectatorsCount)
 
{
 
	/* XXX @see ConHookValidateMaxClientsCount */
 
	if (_network_game_info.spectators_max > 10) {
 
		_network_game_info.spectators_max = 10;
 
		IConsoleError("Maximum spectators out of bounds, truncating to limit.");
 
	}
 

	
 
	return true;
 
}
 

	
 
DEF_CONSOLE_CMD(ConKick)
 
{
 
	NetworkClientInfo *ci;
 
@@ -612,26 +631,27 @@ DEF_CONSOLE_CMD(ConKick)
 
	if (index == NETWORK_SERVER_INDEX) {
 
		IConsoleError("Silly boy, you can not kick yourself!");
 
		return true;
 
	}
 

	
 
	if (index == 0) {
 
		IConsoleError("Invalid client");
 
		return true;
 
	}
 

	
 
	if (ci != NULL) {
 
		SEND_COMMAND(PACKET_SERVER_ERROR)(NetworkFindClientStateFromIndex(index), NETWORK_ERROR_KICKED);
 
	} else
 
	} else {
 
		IConsoleError("Client not found");
 
	}
 

	
 
	return true;
 
}
 

	
 
DEF_CONSOLE_CMD(ConResetCompany)
 
{
 
	Player *p;
 
	NetworkClientState *cs;
 
	NetworkClientInfo *ci;
 
	byte index;
 

	
 
	if (argc == 0) {
 
@@ -965,25 +985,27 @@ DEF_CONSOLE_CMD(ConInfoCmd)
 
DEF_CONSOLE_CMD(ConDebugLevel)
 
{
 
	if (argc == 0) {
 
		IConsoleHelp("Get/set the default debugging level for the game. Usage: 'debug_level [<level>]'");
 
		IConsoleHelp("Level can be any combination of names, levels. Eg 'net=5 ms=4'. Remember to enclose it in \"'s");
 
		return true;
 
	}
 

	
 
	if (argc > 2) return false;
 

	
 
	if (argc == 1) {
 
		IConsolePrintF(_icolour_def, "Current debug-level: '%s'", GetDebugString());
 
	} else SetDebugString(argv[1]);
 
	} else {
 
		SetDebugString(argv[1]);
 
	}
 

	
 
	return true;
 
}
 

	
 
DEF_CONSOLE_CMD(ConExit)
 
{
 
	if (argc == 0) {
 
		IConsoleHelp("Exit the game. Usage: 'exit'");
 
		return true;
 
	}
 

	
 
	_exit_game = true;
 
@@ -1117,26 +1139,27 @@ DEF_CONSOLE_CMD(ConListAliases)
 

	
 
DEF_CONSOLE_CMD(ConSay)
 
{
 
	if (argc == 0) {
 
		IConsoleHelp("Chat to your fellow players in a multiplayer game. Usage: 'say \"<msg>\"'");
 
		return true;
 
	}
 

	
 
	if (argc != 2) return false;
 

	
 
	if (!_network_server) {
 
		SEND_COMMAND(PACKET_CLIENT_CHAT)(NETWORK_ACTION_CHAT, DESTTYPE_BROADCAST, 0 /* param does not matter */, argv[1]);
 
	} else
 
	} else {
 
		NetworkServer_HandleChat(NETWORK_ACTION_CHAT, DESTTYPE_BROADCAST, 0, argv[1], NETWORK_SERVER_INDEX);
 
	}
 

	
 
	return true;
 
}
 

	
 
DEF_CONSOLE_CMD(ConPlayers)
 
{
 
	Player *p;
 

	
 
	if (argc == 0) {
 
		IConsoleHelp("List the in-game details of all clients connected to the server. Usage 'players'");
 
		return true;
 
	}
 
@@ -1167,44 +1190,46 @@ DEF_CONSOLE_CMD(ConSayPlayer)
 
		return true;
 
	}
 

	
 
	if (argc != 3) return false;
 

	
 
	if (atoi(argv[1]) < 1 || atoi(argv[1]) > MAX_PLAYERS) {
 
		IConsolePrintF(_icolour_def, "Unknown player. Player range is between 1 and %d.", MAX_PLAYERS);
 
		return true;
 
	}
 

	
 
	if (!_network_server) {
 
		SEND_COMMAND(PACKET_CLIENT_CHAT)(NETWORK_ACTION_CHAT_PLAYER, DESTTYPE_PLAYER, atoi(argv[1]), argv[2]);
 
	} else
 
	} else {
 
		NetworkServer_HandleChat(NETWORK_ACTION_CHAT_PLAYER, DESTTYPE_PLAYER, atoi(argv[1]), argv[2], NETWORK_SERVER_INDEX);
 
	}
 

	
 
	return true;
 
}
 

	
 
DEF_CONSOLE_CMD(ConSayClient)
 
{
 
	if (argc == 0) {
 
		IConsoleHelp("Chat to a certain player in a multiplayer game. Usage: 'say_client <client-no> \"<msg>\"'");
 
		IConsoleHelp("For client-id's, see the command 'clients'");
 
		return true;
 
	}
 

	
 
	if (argc != 3) return false;
 

	
 
	if (!_network_server) {
 
		SEND_COMMAND(PACKET_CLIENT_CHAT)(NETWORK_ACTION_CHAT_CLIENT, DESTTYPE_CLIENT, atoi(argv[1]), argv[2]);
 
	} else
 
	} else {
 
		NetworkServer_HandleChat(NETWORK_ACTION_CHAT_CLIENT, DESTTYPE_CLIENT, atoi(argv[1]), argv[2], NETWORK_SERVER_INDEX);
 
	}
 

	
 
	return true;
 
}
 

	
 
DEF_CONSOLE_HOOK(ConHookServerPW)
 
{
 
	if (strcmp(_network_server_password, "*") == 0) {
 
		_network_server_password[0] = '\0';
 
		_network_game_info.use_password = 0;
 
	} else {
 
		ttd_strlcpy(_network_game_info.server_password, _network_server_password, sizeof(_network_server_password));
 
		_network_game_info.use_password = 1;
 
@@ -1305,26 +1330,27 @@ DEF_CONSOLE_CMD(ConProcServerIP)
 
DEF_CONSOLE_CMD(ConPatch)
 
{
 
	if (argc == 0) {
 
		IConsoleHelp("Change patch variables for all players. Usage: 'patch <name> [<value>]'");
 
		IConsoleHelp("Omitting <value> will print out the current value of the patch-setting.");
 
		return true;
 
	}
 

	
 
	if (argc == 1 || argc > 3) return false;
 

	
 
	if (argc == 2) {
 
		IConsoleGetPatchSetting(argv[1]);
 
	} else
 
	} else {
 
		IConsoleSetPatchSetting(argv[1], argv[2]);
 
	}
 

	
 
	return true;
 
}
 
#endif /* ENABLE_NETWORK */
 

	
 
DEF_CONSOLE_CMD(ConListDumpVariables)
 
{
 
	const IConsoleVar *var;
 
	size_t l = 0;
 

	
 
	if (argc == 0) {
 
		IConsoleHelp("List all variables with their value. Usage: 'dump_vars [<pre-filter>]'");