Changeset - r9426:3751599964ec
[Not reviewed]
master
0 6 0
rubidium - 16 years ago 2008-05-30 09:23:05
rubidium@openttd.org
(svn r13341) -Codechange: make most of the network settings configurable via the patch command.
6 files changed with 224 insertions and 278 deletions:
0 comments (0 inline, 0 general)
src/console_cmds.cpp
Show inline comments
 
@@ -597,43 +597,6 @@ DEF_CONSOLE_CMD(ConServerInfo)
 
	return true;
 
}
 

	
 
DEF_CONSOLE_HOOK(ConHookValidateMaxClientsCount)
 
{
 
	if (_network_game_info.clients_max > MAX_CLIENTS) {
 
		_network_game_info.clients_max = MAX_CLIENTS;
 
		IConsoleError("Maximum clients out of bounds, truncating to limit.");
 
	}
 

	
 
	return true;
 
}
 

	
 
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)
 
{
 
	/* 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_HOOK(ConHookCheckMinPlayers)
 
{
 
	CheckMinPlayers();
 
	return true;
 
}
 

	
 
DEF_CONSOLE_CMD(ConKick)
 
{
 
	NetworkClientInfo *ci;
 
@@ -1305,30 +1268,6 @@ DEF_CONSOLE_CMD(ConSayClient)
 
	return true;
 
}
 

	
 
DEF_CONSOLE_HOOK(ConHookServerPW)
 
{
 
	if (strcmp(_settings_client.network.server_password, "*") == 0) {
 
		_settings_client.network.server_password[0] = '\0';
 
		_network_game_info.use_password = false;
 
	} else {
 
		ttd_strlcpy(_network_game_info.server_password, _settings_client.network.server_password, sizeof(_network_game_info.server_password));
 
		_network_game_info.use_password = true;
 
	}
 

	
 
	return true;
 
}
 

	
 
DEF_CONSOLE_HOOK(ConHookRconPW)
 
{
 
	if (strcmp(_settings_client.network.rcon_password, "*") == 0) {
 
		_settings_client.network.rcon_password[0] = '\0';
 
	}
 

	
 
	ttd_strlcpy(_network_game_info.rcon_password, _settings_client.network.rcon_password, sizeof(_network_game_info.rcon_password));
 

	
 
	return true;
 
}
 

	
 
extern void HashCurrentCompanyPassword();
 

	
 
/* Also use from within player_gui to change the password graphically */
 
@@ -1362,56 +1301,6 @@ bool NetworkChangeCompanyPassword(byte a
 
	return true;
 
}
 

	
 
DEF_CONSOLE_HOOK(ConProcPlayerName)
 
{
 
	NetworkClientInfo *ci = NetworkFindClientInfoFromIndex(_network_own_client_index);
 

	
 
	if (ci == NULL) return false;
 

	
 
	/* Don't change the name if it is the same as the old name */
 
	if (strcmp(ci->client_name, _settings_client.network.player_name) != 0) {
 
		if (!_network_server) {
 
			SEND_COMMAND(PACKET_CLIENT_SET_NAME)(_settings_client.network.player_name);
 
		} else {
 
			if (NetworkFindName(_settings_client.network.player_name)) {
 
				NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, false, ci->client_name, "%s", _settings_client.network.player_name);
 
				ttd_strlcpy(ci->client_name, _settings_client.network.player_name, sizeof(ci->client_name));
 
				NetworkUpdateClientInfo(NETWORK_SERVER_INDEX);
 
			}
 
		}
 
	}
 

	
 
	return true;
 
}
 

	
 
DEF_CONSOLE_HOOK(ConHookServerName)
 
{
 
	ttd_strlcpy(_network_game_info.server_name, _settings_client.network.server_name, sizeof(_network_game_info.server_name));
 
	return true;
 
}
 

	
 
DEF_CONSOLE_HOOK(ConHookServerAdvertise)
 
{
 
	if (!_network_advertise) // remove us from advertising
 
		NetworkUDPRemoveAdvertise();
 

	
 
	return true;
 
}
 

	
 
DEF_CONSOLE_CMD(ConProcServerIP)
 
{
 
	if (argc == 0) {
 
		IConsolePrintF(CC_WARNING, "Current value for 'server_ip': %s", inet_ntoa(*(struct in_addr *)&_network_server_bind_ip));
 
		return true;
 
	}
 

	
 
	if (argc != 1) return false;
 

	
 
	_network_server_bind_ip = (strcmp(argv[0], "all") == 0) ? inet_addr("0.0.0.0") : inet_addr(argv[0]);
 
	snprintf(_settings_client.network.server_bind_ip, sizeof(_settings_client.network.server_bind_ip), "%s", inet_ntoa(*(struct in_addr *)&_network_server_bind_ip));
 
	IConsolePrintF(CC_WARNING, "'server_ip' changed to:  %s", inet_ntoa(*(struct in_addr *)&_network_server_bind_ip));
 
	return true;
 
}
 
#endif /* ENABLE_NETWORK */
 

	
 
DEF_CONSOLE_CMD(ConPatch)
 
@@ -1427,17 +1316,7 @@ DEF_CONSOLE_CMD(ConPatch)
 
	if (argc == 2) {
 
		IConsoleGetPatchSetting(argv[1]);
 
	} else {
 
		uint32 val;
 

	
 
		if (GetArgumentInteger(&val, argv[2])) {
 
			if (!IConsoleSetPatchSetting(argv[1], val)) {
 
				if (_network_server) {
 
					IConsoleError("This command/variable is not available during network games.");
 
				} else {
 
					IConsoleError("This command/variable is only available to a network server.");
 
				}
 
			}
 
		}
 
		IConsoleSetPatchSetting(argv[1], argv[2]);
 
	}
 

	
 
	return true;
 
@@ -1595,71 +1474,36 @@ void IConsoleStdLibRegister()
 
	IConsoleCmdHookAdd("unpause",          ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
 

	
 
	/*** Networking variables ***/
 
	IConsoleVarRegister("net_frame_freq",        &_settings_client.network.frame_freq, ICONSOLE_VAR_BYTE, "The amount of frames before a command will be (visibly) executed. Default value: 1");
 
	IConsoleVarHookAdd("net_frame_freq",         ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
 
	IConsoleVarRegister("net_sync_freq",         &_settings_client.network.sync_freq,  ICONSOLE_VAR_UINT16, "The amount of frames to check if the game is still in sync. Default value: 100");
 
	IConsoleVarHookAdd("net_sync_freq",          ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
 

	
 
	IConsoleVarStringRegister("server_pw",       &_settings_client.network.server_password, sizeof(_settings_client.network.server_password), "Set the server password to protect your server. Use '*' to clear the password");
 
	IConsoleVarHookAdd("server_pw",              ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
 
	IConsoleVarHookAdd("server_pw",              ICONSOLE_HOOK_POST_ACTION, ConHookServerPW);
 
	IConsoleAliasRegister("server_password",     "server_pw %+");
 
	IConsoleVarStringRegister("rcon_pw",         &_settings_client.network.rcon_password, sizeof(_settings_client.network.rcon_password), "Set the rcon-password to change server behaviour. Use '*' to disable rcon");
 
	IConsoleVarHookAdd("rcon_pw",                ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
 
	IConsoleVarHookAdd("rcon_pw",                ICONSOLE_HOOK_POST_ACTION, ConHookRconPW);
 
	IConsoleAliasRegister("rcon_password",       "rcon_pw %+");
 
	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");
 
	IConsoleVarHookAdd("company_pw",             ICONSOLE_HOOK_ACCESS, ConHookNeedNetwork);
 
	IConsoleVarProcAdd("company_pw",             NetworkChangeCompanyPassword);
 
	IConsoleAliasRegister("company_password",    "company_pw %+");
 

	
 
	IConsoleVarStringRegister("name",            &_settings_client.network.player_name, sizeof(_settings_client.network.player_name), "Set your name for multiplayer");
 
	IConsoleVarHookAdd("name",                   ICONSOLE_HOOK_ACCESS, ConHookNeedNetwork);
 
	IConsoleVarHookAdd("name",                   ICONSOLE_HOOK_POST_ACTION, ConProcPlayerName);
 
	IConsoleVarStringRegister("server_name",     &_settings_client.network.server_name, sizeof(_settings_client.network.server_name), "Set the name of the server for multiplayer");
 
	IConsoleVarHookAdd("server_name",            ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
 
	IConsoleVarHookAdd("server_name",            ICONSOLE_HOOK_POST_ACTION, ConHookServerName);
 

	
 
	IConsoleVarRegister("server_port",           &_settings_client.network.server_port, ICONSOLE_VAR_UINT32, "Set the server port. Changes take effect the next time you start a server");
 
	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.");
 
	IConsoleVarProcAdd("server_ip",              ConProcServerIP);
 
	IConsoleAliasRegister("server_bind_ip",      "server_ip %+");
 
	IConsoleAliasRegister("server_ip_bind",      "server_ip %+");
 
	IConsoleAliasRegister("server_bind",         "server_ip %+");
 
	IConsoleVarRegister("server_advertise",      &_settings_client.network.server_advertise, ICONSOLE_VAR_BOOLEAN, "Set if the server will advertise to the master server and show up there");
 
	IConsoleVarHookAdd("server_advertise",       ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
 
	IConsoleVarHookAdd("server_advertise",       ICONSOLE_HOOK_POST_ACTION, ConHookServerAdvertise);
 

	
 
	IConsoleVarRegister("max_clients",           &_network_game_info.clients_max, ICONSOLE_VAR_BYTE, "Control the maximum amount of connected players during runtime. Default value: 10");
 
	IConsoleVarHookAdd("max_clients",            ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
 
	IConsoleVarHookAdd("max_clients",            ICONSOLE_HOOK_POST_ACTION, ConHookValidateMaxClientsCount);
 
	IConsoleVarRegister("max_companies",         &_network_game_info.companies_max, ICONSOLE_VAR_BYTE, "Control the maximum amount of active companies during runtime. Default value: 8");
 
	IConsoleVarHookAdd("max_companies",          ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
 
	IConsoleVarHookAdd("max_companies",          ICONSOLE_HOOK_POST_ACTION, ConHookValidateMaxCompaniesCount);
 
	IConsoleVarRegister("max_spectators",        &_network_game_info.spectators_max, ICONSOLE_VAR_BYTE, "Control the maximum amount of active spectators during runtime. Default value: 9");
 
	IConsoleVarHookAdd("max_spectators",         ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
 
	IConsoleVarHookAdd("max_spectators",         ICONSOLE_HOOK_POST_ACTION, ConHookValidateMaxSpectatorsCount);
 

	
 
	IConsoleVarRegister("max_join_time",         &_settings_client.network.max_join_time, ICONSOLE_VAR_UINT16, "Set the maximum amount of time (ticks) a client is allowed to join. Default value: 500");
 

	
 
	IConsoleVarRegister("pause_on_join",         &_settings_client.network.pause_on_join, ICONSOLE_VAR_BOOLEAN, "Set if the server should pause gameplay while a client is joining. This might help slow users");
 
	IConsoleVarHookAdd("pause_on_join",          ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
 

	
 
	IConsoleVarRegister("autoclean_companies",   &_settings_client.network.autoclean_companies, ICONSOLE_VAR_BOOLEAN, "Automatically shut down inactive companies to free them up for other players. Customize with 'autoclean_(un)protected'");
 
	IConsoleVarHookAdd("autoclean_companies",    ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
 
	IConsoleVarRegister("autoclean_protected",   &_settings_client.network.autoclean_protected, ICONSOLE_VAR_BYTE, "Automatically remove the password from an inactive company after the given amount of months");
 
	IConsoleVarHookAdd("autoclean_protected",    ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
 
	IConsoleVarRegister("autoclean_unprotected", &_settings_client.network.autoclean_unprotected, ICONSOLE_VAR_BYTE, "Automatically shut down inactive companies after the given amount of months");
 
	IConsoleVarHookAdd("autoclean_unprotected",  ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
 
	IConsoleVarRegister("restart_game_year",     &_settings_client.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");
 
	IConsoleVarHookAdd("restart_game_year",      ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
 

	
 
	IConsoleVarRegister("min_players",           &_settings_client.network.min_players, ICONSOLE_VAR_BYTE, "Automatically pause the game when the number of active players passes below the given amount");
 
	IConsoleVarHookAdd("min_players",            ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
 
	IConsoleVarHookAdd("min_players",            ICONSOLE_HOOK_POST_ACTION, ConHookCheckMinPlayers);
 
	IConsoleVarRegister("reload_cfg",            &_settings_client.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");
 
	IConsoleVarHookAdd("reload_cfg",             ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
 

	
 
	IConsoleAliasRegister("net_frame_freq",        "patch frame_freq %+");
 
	IConsoleAliasRegister("net_sync_freq",         "patch sync_freq %+");
 
	IConsoleAliasRegister("server_pw",             "patch server_password %+");
 
	IConsoleAliasRegister("server_password",       "patch server_password %+");
 
	IConsoleAliasRegister("rcon_pw",               "patch rcon_password %+");
 
	IConsoleAliasRegister("rcon_password",         "patch rcon_password %+");
 
	IConsoleAliasRegister("name",                  "patch player_name %+");
 
	IConsoleAliasRegister("server_name",           "patch server_name %+");
 
	IConsoleAliasRegister("server_port",           "patch server_port %+");
 
	IConsoleAliasRegister("server_ip",             "patch server_bind_ip %+");
 
	IConsoleAliasRegister("server_bind_ip",        "patch server_bind_ip %+");
 
	IConsoleAliasRegister("server_ip_bind",        "patch server_bind_ip %+");
 
	IConsoleAliasRegister("server_bind",           "patch server_bind_ip %+");
 
	IConsoleAliasRegister("server_advertise",      "patch server_advertise %+");
 
	IConsoleAliasRegister("max_clients",           "patch max_clients %+");
 
	IConsoleAliasRegister("max_companies",         "patch max_companies %+");
 
	IConsoleAliasRegister("max_spectators",        "patch max_spectators %+");
 
	IConsoleAliasRegister("max_join_time",         "patch max_join_time %+");
 
	IConsoleAliasRegister("pause_on_join",         "patch pause_on_join %+");
 
	IConsoleAliasRegister("autoclean_companies",   "patch autoclean_companies %+");
 
	IConsoleAliasRegister("autoclean_protected",   "patch autoclean_protected %+");
 
	IConsoleAliasRegister("autoclean_unprotected", "patch autoclean_unprotected %+");
 
	IConsoleAliasRegister("restart_game_year",     "patch restart_game_year %+");
 
	IConsoleAliasRegister("min_players",           "patch min_players %+");
 
	IConsoleAliasRegister("reload_cfg",            "patch reload_cfg %+");
 
#endif /* ENABLE_NETWORK */
 

	
 
	// debugging stuff
src/console_func.h
Show inline comments
 
@@ -19,6 +19,8 @@ void IConsoleClose();
 
void IConsolePrint(ConsoleColour color_code, const char *string);
 
void CDECL IConsolePrintF(ConsoleColour color_code, const char *s, ...);
 
void IConsoleDebug(const char *dbg, const char *string);
 
void IConsoleWarning(const char *string);
 
void IConsoleError(const char *string);
 

	
 
/* Parser */
 
void IConsoleCmdExec(const char *cmdstr);
src/console_internal.h
Show inline comments
 
@@ -105,10 +105,6 @@ extern IConsoleAlias *_iconsole_aliases;
 
void IConsoleClearBuffer();
 
void IConsoleOpen();
 

	
 
/* console output */
 
void IConsoleWarning(const char *string);
 
void IConsoleError(const char *string);
 

	
 
/* Commands */
 
void IConsoleCmdRegister(const char *name, IConsoleCmdProc *proc);
 
void IConsoleAliasRegister(const char *name, const char *cmd);
src/settings.cpp
Show inline comments
 
@@ -25,7 +25,10 @@
 
#include "screenshot.h"
 
#include "variables.h"
 
#include "network/network.h"
 
#include "network/network_internal.h"
 
#include "network/network_data.h"
 
#include "network/network_client.h"
 
#include "network/network_server.h"
 
#include "network/network_udp.h"
 
#include "settings_internal.h"
 
#include "command_func.h"
 
#include "console_func.h"
 
@@ -1135,12 +1138,12 @@ static void ini_save_setting_list(IniFil
 
#define SDTC_CONDLIST(var, type, length, flags, guiflags, def, str, proc, from, to)\
 
	SDTG_GENERAL(#var, SDT_INTLIST, SL_ARR, type, flags, guiflags, _settings_client.var, length, def, 0, 0, 0, NULL, str, proc, from, to)
 
#define SDTC_LIST(var, type, flags, guiflags, def, str, proc)\
 
	SDTG_GENERAL(var, SDT_INTLIST, SL_ARR, type, flags, guiflags, _settings_client.var, lengthof(_settings_client.var), def, 0, 0, 0, NULL, str, proc, 0, SL_MAX_VERSION)
 
	SDTG_GENERAL(#var, SDT_INTLIST, SL_ARR, type, flags, guiflags, _settings_client.var, lengthof(_settings_client.var), def, 0, 0, 0, NULL, str, proc, 0, SL_MAX_VERSION)
 

	
 
#define SDTC_CONDSTR(var, type, length, flags, guiflags, def, str, proc, from, to)\
 
	SDTG_GENERAL(#var, SDT_STRING, SL_STR, type, flags, guiflags, _settings_client.var, length, def, 0, 0, 0, NULL, str, proc, from, to)
 
#define SDTC_STR(var, type, flags, guiflags, def, str, proc)\
 
	SDTG_GENERAL(var, SDT_STRING, SL_STR, type, flags, guiflags, _settings_client.var, lengthof(_settings_client.var), def, 0, 0, 0, NULL, str, proc, 0, SL_MAX_VERSION)
 
	SDTG_GENERAL(#var, SDT_STRING, SL_STR, type, flags, guiflags, _settings_client.var, lengthof(_settings_client.var), def, 0, 0, 0, NULL, str, proc, 0, SL_MAX_VERSION)
 

	
 
#define SDTC_CONDOMANY(var, type, from, to, flags, guiflags, def, max, full, str, proc)\
 
	SDTG_GENERAL(#var, SDT_ONEOFMANY, SL_VAR, type, flags, guiflags, _settings_client.var, 1, def, 0, max, 0, full, str, proc, from, to)
 
@@ -1433,6 +1436,69 @@ static int32 CheckNoiseToleranceLevel(co
 
	return 0;
 
}
 

	
 
#ifdef ENABLE_NETWORK
 

	
 
static int32 UpdateMinPlayers(int32 p1)
 
{
 
	CheckMinPlayers();
 
	return 0;
 
}
 

	
 
static int32 UpdatePlayerName(int32 p1)
 
{
 
	NetworkClientInfo *ci = NetworkFindClientInfoFromIndex(_network_own_client_index);
 

	
 
	if (ci == NULL) return 0;
 

	
 
	/* Don't change the name if it is the same as the old name */
 
	if (strcmp(ci->client_name, _settings_client.network.player_name) != 0) {
 
		if (!_network_server) {
 
			SEND_COMMAND(PACKET_CLIENT_SET_NAME)(_settings_client.network.player_name);
 
		} else {
 
			if (NetworkFindName(_settings_client.network.player_name)) {
 
				NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, false, ci->client_name, "%s", _settings_client.network.player_name);
 
				ttd_strlcpy(ci->client_name, _settings_client.network.player_name, sizeof(ci->client_name));
 
				NetworkUpdateClientInfo(NETWORK_SERVER_INDEX);
 
			}
 
		}
 
	}
 

	
 
	return 0;
 
}
 

	
 
static int32 UpdateServerName(int32 p1)
 
{
 
	ttd_strlcpy(_network_game_info.server_name, _settings_client.network.server_name, sizeof(_network_game_info.server_name));
 
	return 0;
 
}
 

	
 
static int32 UpdateServerPassword(int32 p1)
 
{
 
	if (strcmp(_settings_client.network.server_password, "*") == 0) {
 
		_settings_client.network.server_password[0] = '\0';
 
		_network_game_info.use_password = false;
 
	} else {
 
		ttd_strlcpy(_network_game_info.server_password, _settings_client.network.server_password, sizeof(_network_game_info.server_password));
 
		_network_game_info.use_password = true;
 
	}
 

	
 
	return 0;
 
}
 

	
 
static int32 UpdateRconPassword(int32 p1)
 
{
 
	if (strcmp(_settings_client.network.rcon_password, "*") == 0) {
 
		_settings_client.network.rcon_password[0] = '\0';
 
	}
 

	
 
	ttd_strlcpy(_network_game_info.rcon_password, _settings_client.network.rcon_password, sizeof(_network_game_info.rcon_password));
 

	
 
	return 0;
 
}
 

	
 
#endif /* ENABLE_NETWORK */
 

	
 

	
 
/* End - Callback Functions */
 

	
 
#ifndef EXTERNAL_PLAYER
 
@@ -1499,39 +1565,6 @@ static const SettingDescGlobVarList _mis
 
	  SDTG_END()
 
};
 

	
 
#ifdef ENABLE_NETWORK
 
static const SettingDescGlobVarList _network_settings[] = {
 
	  SDTG_VAR("sync_freq",           SLE_UINT16,C|S,0, _settings_client.network.sync_freq,            100, 0,   100,   0, STR_NULL, NULL),
 
	  SDTG_VAR("frame_freq",           SLE_UINT8,C|S,0, _settings_client.network.frame_freq,             0, 0,   100,   0, STR_NULL, NULL),
 
	  SDTG_VAR("max_join_time",       SLE_UINT16, S, 0, _settings_client.network.max_join_time,        500, 0, 32000,   0, STR_NULL, NULL),
 
	 SDTG_BOOL("pause_on_join",                   S, 0, _settings_client.network.pause_on_join,        true,               STR_NULL, NULL),
 
	  SDTG_STR("server_bind_ip",        SLE_STRB, S, 0, _settings_client.network.server_bind_ip,       "0.0.0.0",          STR_NULL, NULL),
 
	  SDTG_VAR("server_port",         SLE_UINT16, S, 0, _settings_client.network.server_port,          NETWORK_DEFAULT_PORT, 0, 65535, 0, STR_NULL, NULL),
 
	 SDTG_BOOL("server_advertise",                S, 0, _settings_client.network.server_advertise,     false,              STR_NULL, NULL),
 
	  SDTG_VAR("lan_internet",         SLE_UINT8, S, 0, _settings_client.network.lan_internet,           0, 0,     1,   0, STR_NULL, NULL),
 
	  SDTG_STR("player_name",           SLE_STRB, S, 0, _settings_client.network.player_name,          NULL,               STR_NULL, NULL),
 
	  SDTG_STR("server_password",       SLE_STRB, S, 0, _settings_client.network.server_password,      NULL,               STR_NULL, NULL),
 
	  SDTG_STR("rcon_password",         SLE_STRB, S, 0, _settings_client.network.rcon_password,        NULL,               STR_NULL, NULL),
 
	  SDTG_STR("default_company_pass",  SLE_STRB, S, 0, _settings_client.network.default_company_pass, NULL,               STR_NULL, NULL),
 
	  SDTG_STR("server_name",           SLE_STRB, S, 0, _settings_client.network.server_name,          NULL,               STR_NULL, NULL),
 
	  SDTG_STR("connect_to_ip",         SLE_STRB, S, 0, _settings_client.network.connect_to_ip,        NULL,               STR_NULL, NULL),
 
	  SDTG_STR("network_id",            SLE_STRB, S, 0, _settings_client.network.network_id,           NULL,               STR_NULL, NULL),
 
	 SDTG_BOOL("autoclean_companies",             S, 0, _settings_client.network.autoclean_companies,  false,              STR_NULL, NULL),
 
	  SDTG_VAR("autoclean_unprotected",SLE_UINT8, S, 0, _settings_client.network.autoclean_unprotected,12, 0,     60,   0, STR_NULL, NULL),
 
	  SDTG_VAR("autoclean_protected",  SLE_UINT8, S, 0, _settings_client.network.autoclean_protected,  36, 0,    180,   0, STR_NULL, NULL),
 
	  SDTG_VAR("max_companies",        SLE_UINT8, S, 0, _settings_client.network.max_companies,      8, 1, MAX_PLAYERS, 0, STR_NULL, NULL),
 
	  SDTG_VAR("max_clients",          SLE_UINT8, S, 0, _settings_client.network.max_clients,       10, 2, MAX_CLIENTS, 0, STR_NULL, NULL),
 
	  SDTG_VAR("max_spectators",       SLE_UINT8, S, 0, _settings_client.network.max_spectators,    10, 0, MAX_CLIENTS, 0, STR_NULL, NULL),
 
	  SDTG_VAR("restart_game_year",    SLE_INT32, S,D0, _settings_client.network.restart_game_year,  0, MIN_YEAR, MAX_YEAR, 1, STR_NULL, NULL),
 
	  SDTG_VAR("min_players",          SLE_UINT8, S, 0, _settings_client.network.min_players,               0, 0, 10,   0, STR_NULL, NULL),
 
	SDTG_OMANY("server_lang",          SLE_UINT8, S, 0, _settings_client.network.server_lang,     0, 35, "ANY|ENGLISH|GERMAN|FRENCH|BRAZILIAN|BULGARIAN|CHINESE|CZECH|DANISH|DUTCH|ESPERANTO|FINNISH|HUNGARIAN|ICELANDIC|ITALIAN|JAPANESE|KOREAN|LITHUANIAN|NORWEGIAN|POLISH|PORTUGUESE|ROMANIAN|RUSSIAN|SLOVAK|SLOVENIAN|SPANISH|SWEDISH|TURKISH|UKRAINIAN|AFRIKAANS|CROATIAN|CATALAN|ESTONIAN|GALICIAN|GREEK|LATVIAN", STR_NULL, NULL),
 
	 SDTG_BOOL("reload_cfg",                      S, 0, _settings_client.network.reload_cfg,           false,              STR_NULL, NULL),
 
	  SDTG_STR("last_host",             SLE_STRB, S, 0, _settings_client.network.last_host,            "0.0.0.0",          STR_NULL, NULL),
 
	  SDTG_VAR("last_port",           SLE_UINT16, S, 0, _settings_client.network.last_port,            0, 0, UINT16_MAX, 0, STR_NULL ,NULL),
 
	  SDTG_END()
 
};
 
#endif /* ENABLE_NETWORK */
 

	
 
static const uint GAME_DIFFICULTY_NUM = 18;
 
uint16 _old_diff_custom[GAME_DIFFICULTY_NUM];
 

	
 
@@ -1746,45 +1779,75 @@ SDTC_CONDOMANY(              gui.units, 
 

	
 
	/***************************************************************************/
 
	/* Unsaved patch variables. */
 
	SDTC_OMANY(gui.autosave,               SLE_UINT8, S, 0, 1, 4, "off|monthly|quarterly|half year|yearly", STR_NULL,                     NULL),
 
	 SDTC_BOOL(gui.vehicle_speed,                     S, 0,  true,                        STR_CONFIG_PATCHES_VEHICLESPEED,                NULL),
 
	 SDTC_BOOL(gui.status_long_date,                  S, 0,  true,                        STR_CONFIG_PATCHES_LONGDATE,                    NULL),
 
	 SDTC_BOOL(gui.show_finances,                     S, 0,  true,                        STR_CONFIG_PATCHES_SHOWFINANCES,                NULL),
 
	 SDTC_BOOL(gui.autoscroll,                        S, 0, false,                        STR_CONFIG_PATCHES_AUTOSCROLL,                  NULL),
 
	 SDTC_BOOL(gui.reverse_scroll,                    S, 0, false,                        STR_CONFIG_PATCHES_REVERSE_SCROLLING,           NULL),
 
	 SDTC_BOOL(gui.smooth_scroll,                     S, 0, false,                        STR_CONFIG_PATCHES_SMOOTH_SCROLLING,            NULL),
 
	 SDTC_BOOL(gui.measure_tooltip,                   S, 0, false,                        STR_CONFIG_PATCHES_MEASURE_TOOLTIP,             NULL),
 
	  SDTC_VAR(gui.errmsg_duration,        SLE_UINT8, S, 0,     5,        0,       20, 0, STR_CONFIG_PATCHES_ERRMSG_DURATION,             NULL),
 
	  SDTC_VAR(gui.toolbar_pos,            SLE_UINT8, S,MS,     0,        0,        2, 0, STR_CONFIG_PATCHES_TOOLBAR_POS,                 v_PositionMainToolbar),
 
	  SDTC_VAR(gui.window_snap_radius,     SLE_UINT8, S,D0,    10,        1,       32, 0, STR_CONFIG_PATCHES_SNAP_RADIUS,                 NULL),
 
	 SDTC_BOOL(gui.population_in_label,               S, 0,  true,                        STR_CONFIG_PATCHES_POPULATION_IN_LABEL,         PopulationInLabelActive),
 
	 SDTC_BOOL(gui.link_terraform_toolbar,            S, 0, false,                        STR_CONFIG_PATCHES_LINK_TERRAFORM_TOOLBAR,      NULL),
 
	  SDTC_VAR(gui.liveries,               SLE_UINT8, S,MS,     2,        0,        2, 0, STR_CONFIG_PATCHES_LIVERIES,                    RedrawScreen),
 
	 SDTC_BOOL(gui.prefer_teamchat,                   S, 0, false,                        STR_CONFIG_PATCHES_PREFER_TEAMCHAT,             NULL),
 
	  SDTC_VAR(gui.scrollwheel_scrolling,  SLE_UINT8, S,MS,     0,        0,        2, 0, STR_CONFIG_PATCHES_SCROLLWHEEL_SCROLLING,       NULL),
 
	  SDTC_VAR(gui.scrollwheel_multiplier, SLE_UINT8, S, 0,     5,        1,       15, 1, STR_CONFIG_PATCHES_SCROLLWHEEL_MULTIPLIER,      NULL),
 
	 SDTC_BOOL(gui.pause_on_newgame,                  S, 0, false,                        STR_CONFIG_PATCHES_PAUSE_ON_NEW_GAME,           NULL),
 
	  SDTC_VAR(gui.advanced_vehicle_list,  SLE_UINT8, S,MS,     1,        0,        2, 0, STR_CONFIG_PATCHES_ADVANCED_VEHICLE_LISTS,      NULL),
 
	 SDTC_BOOL(gui.timetable_in_ticks,                S, 0, false,                        STR_CONFIG_PATCHES_TIMETABLE_IN_TICKS,          NULL),
 
	  SDTC_VAR(gui.loading_indicators,     SLE_UINT8, S,MS,     1,        0,        2, 0, STR_CONFIG_PATCHES_LOADING_INDICATORS,          RedrawScreen),
 
	  SDTC_VAR(gui.default_rail_type,      SLE_UINT8, S,MS,     4,        0,        6, 0, STR_CONFIG_PATCHES_DEFAULT_RAIL_TYPE,           NULL),
 
	 SDTC_BOOL(gui.enable_signal_gui,                 S, 0, false,                        STR_CONFIG_PATCHES_ENABLE_SIGNAL_GUI,           CloseSignalGUI),
 
	  SDTC_VAR(gui.drag_signals_density,   SLE_UINT8, S, 0,     4,        1,       20, 0, STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY,        DragSignalsDensityChanged),
 
	  SDTC_VAR(gui.semaphore_build_before, SLE_INT32, S, NC, 1975, MIN_YEAR, MAX_YEAR, 1, STR_CONFIG_PATCHES_SEMAPHORE_BUILD_BEFORE_DATE, ResetSignalVariant),
 
	 SDTC_BOOL(gui.train_income_warn,                 S, 0,  true,                        STR_CONFIG_PATCHES_WARN_INCOME_LESS,            NULL),
 
	  SDTC_VAR(gui.order_review_system,    SLE_UINT8, S,MS,     2,        0,        2, 0, STR_CONFIG_PATCHES_ORDER_REVIEW,                NULL),
 
	 SDTC_BOOL(gui.lost_train_warn,                   S, 0,  true,                        STR_CONFIG_PATCHES_WARN_LOST_TRAIN,             NULL),
 
	 SDTC_BOOL(gui.autorenew,                         S, 0, false,                        STR_CONFIG_PATCHES_AUTORENEW_VEHICLE,           EngineRenewUpdate),
 
	  SDTC_VAR(gui.autorenew_months,       SLE_INT16, S, 0,     6,      -12,       12, 0, STR_CONFIG_PATCHES_AUTORENEW_MONTHS,            EngineRenewMonthsUpdate),
 
	  SDTC_VAR(gui.autorenew_money,         SLE_UINT, S,CR,100000,        0,  2000000, 0, STR_CONFIG_PATCHES_AUTORENEW_MONEY,             EngineRenewMoneyUpdate),
 
	 SDTC_BOOL(gui.always_build_infrastructure,       S, 0, false,                        STR_CONFIG_PATCHES_ALWAYS_BUILD_INFRASTRUCTURE, RedrawScreen),
 
	 SDTC_BOOL(gui.new_nonstop,                       S, 0, false,                        STR_CONFIG_PATCHES_NEW_NONSTOP,                 NULL),
 
	 SDTC_BOOL(gui.keep_all_autosave,                 S, 0, false,                        STR_NULL,                                       NULL),
 
	 SDTC_BOOL(gui.autosave_on_exit,                  S, 0, false,                        STR_NULL,                                       NULL),
 
	  SDTC_VAR(gui.max_num_autosaves,      SLE_UINT8, S, 0,    16,        0,      255, 0, STR_NULL,                                       NULL),
 
	 SDTC_BOOL(gui.bridge_pillars,                    S, 0,  true,                        STR_NULL,                                       NULL),
 
	 SDTC_BOOL(gui.auto_euro,                         S, 0,  true,                        STR_NULL,                                       NULL),
 
	  SDTC_VAR(gui.news_message_timeout,   SLE_UINT8, S, 0,     2,        1,      255, 0, STR_NULL,                                       NULL),
 
	SDTC_OMANY(gui.autosave,                  SLE_UINT8, S,  0, 1, 4, "off|monthly|quarterly|half year|yearly", STR_NULL,                     NULL),
 
	 SDTC_BOOL(gui.vehicle_speed,                        S,  0,  true,                        STR_CONFIG_PATCHES_VEHICLESPEED,                NULL),
 
	 SDTC_BOOL(gui.status_long_date,                     S,  0,  true,                        STR_CONFIG_PATCHES_LONGDATE,                    NULL),
 
	 SDTC_BOOL(gui.show_finances,                        S,  0,  true,                        STR_CONFIG_PATCHES_SHOWFINANCES,                NULL),
 
	 SDTC_BOOL(gui.autoscroll,                           S,  0, false,                        STR_CONFIG_PATCHES_AUTOSCROLL,                  NULL),
 
	 SDTC_BOOL(gui.reverse_scroll,                       S,  0, false,                        STR_CONFIG_PATCHES_REVERSE_SCROLLING,           NULL),
 
	 SDTC_BOOL(gui.smooth_scroll,                        S,  0, false,                        STR_CONFIG_PATCHES_SMOOTH_SCROLLING,            NULL),
 
	 SDTC_BOOL(gui.measure_tooltip,                      S,  0, false,                        STR_CONFIG_PATCHES_MEASURE_TOOLTIP,             NULL),
 
	  SDTC_VAR(gui.errmsg_duration,           SLE_UINT8, S,  0,     5,        0,       20, 0, STR_CONFIG_PATCHES_ERRMSG_DURATION,             NULL),
 
	  SDTC_VAR(gui.toolbar_pos,               SLE_UINT8, S, MS,     0,        0,        2, 0, STR_CONFIG_PATCHES_TOOLBAR_POS,                 v_PositionMainToolbar),
 
	  SDTC_VAR(gui.window_snap_radius,        SLE_UINT8, S, D0,    10,        1,       32, 0, STR_CONFIG_PATCHES_SNAP_RADIUS,                 NULL),
 
	 SDTC_BOOL(gui.population_in_label,                  S,  0,  true,                        STR_CONFIG_PATCHES_POPULATION_IN_LABEL,         PopulationInLabelActive),
 
	 SDTC_BOOL(gui.link_terraform_toolbar,               S,  0, false,                        STR_CONFIG_PATCHES_LINK_TERRAFORM_TOOLBAR,      NULL),
 
	  SDTC_VAR(gui.liveries,                  SLE_UINT8, S, MS,     2,        0,        2, 0, STR_CONFIG_PATCHES_LIVERIES,                    RedrawScreen),
 
	 SDTC_BOOL(gui.prefer_teamchat,                      S,  0, false,                        STR_CONFIG_PATCHES_PREFER_TEAMCHAT,             NULL),
 
	  SDTC_VAR(gui.scrollwheel_scrolling,     SLE_UINT8, S, MS,     0,        0,        2, 0, STR_CONFIG_PATCHES_SCROLLWHEEL_SCROLLING,       NULL),
 
	  SDTC_VAR(gui.scrollwheel_multiplier,    SLE_UINT8, S,  0,     5,        1,       15, 1, STR_CONFIG_PATCHES_SCROLLWHEEL_MULTIPLIER,      NULL),
 
	 SDTC_BOOL(gui.pause_on_newgame,                     S,  0, false,                        STR_CONFIG_PATCHES_PAUSE_ON_NEW_GAME,           NULL),
 
	  SDTC_VAR(gui.advanced_vehicle_list,     SLE_UINT8, S, MS,     1,        0,        2, 0, STR_CONFIG_PATCHES_ADVANCED_VEHICLE_LISTS,      NULL),
 
	 SDTC_BOOL(gui.timetable_in_ticks,                   S,  0, false,                        STR_CONFIG_PATCHES_TIMETABLE_IN_TICKS,          NULL),
 
	  SDTC_VAR(gui.loading_indicators,        SLE_UINT8, S, MS,     1,        0,        2, 0, STR_CONFIG_PATCHES_LOADING_INDICATORS,          RedrawScreen),
 
	  SDTC_VAR(gui.default_rail_type,         SLE_UINT8, S, MS,     4,        0,        6, 0, STR_CONFIG_PATCHES_DEFAULT_RAIL_TYPE,           NULL),
 
	 SDTC_BOOL(gui.enable_signal_gui,                    S,  0, false,                        STR_CONFIG_PATCHES_ENABLE_SIGNAL_GUI,           CloseSignalGUI),
 
	  SDTC_VAR(gui.drag_signals_density,      SLE_UINT8, S,  0,     4,        1,       20, 0, STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY,        DragSignalsDensityChanged),
 
	  SDTC_VAR(gui.semaphore_build_before,    SLE_INT32, S, NC,  1975, MIN_YEAR, MAX_YEAR, 1, STR_CONFIG_PATCHES_SEMAPHORE_BUILD_BEFORE_DATE, ResetSignalVariant),
 
	 SDTC_BOOL(gui.train_income_warn,                    S,  0,  true,                        STR_CONFIG_PATCHES_WARN_INCOME_LESS,            NULL),
 
	  SDTC_VAR(gui.order_review_system,       SLE_UINT8, S, MS,     2,        0,        2, 0, STR_CONFIG_PATCHES_ORDER_REVIEW,                NULL),
 
	 SDTC_BOOL(gui.lost_train_warn,                      S,  0,  true,                        STR_CONFIG_PATCHES_WARN_LOST_TRAIN,             NULL),
 
	 SDTC_BOOL(gui.autorenew,                            S,  0, false,                        STR_CONFIG_PATCHES_AUTORENEW_VEHICLE,           EngineRenewUpdate),
 
	  SDTC_VAR(gui.autorenew_months,          SLE_INT16, S,  0,     6,      -12,       12, 0, STR_CONFIG_PATCHES_AUTORENEW_MONTHS,            EngineRenewMonthsUpdate),
 
	  SDTC_VAR(gui.autorenew_money,            SLE_UINT, S, CR,100000,        0,  2000000, 0, STR_CONFIG_PATCHES_AUTORENEW_MONEY,             EngineRenewMoneyUpdate),
 
	 SDTC_BOOL(gui.always_build_infrastructure,          S,  0, false,                        STR_CONFIG_PATCHES_ALWAYS_BUILD_INFRASTRUCTURE, RedrawScreen),
 
	 SDTC_BOOL(gui.new_nonstop,                          S,  0, false,                        STR_CONFIG_PATCHES_NEW_NONSTOP,                 NULL),
 
	 SDTC_BOOL(gui.keep_all_autosave,                    S,  0, false,                        STR_NULL,                                       NULL),
 
	 SDTC_BOOL(gui.autosave_on_exit,                     S,  0, false,                        STR_NULL,                                       NULL),
 
	  SDTC_VAR(gui.max_num_autosaves,         SLE_UINT8, S,  0,    16,        0,      255, 0, STR_NULL,                                       NULL),
 
	 SDTC_BOOL(gui.bridge_pillars,                       S,  0,  true,                        STR_NULL,                                       NULL),
 
	 SDTC_BOOL(gui.auto_euro,                            S,  0,  true,                        STR_NULL,                                       NULL),
 
	  SDTC_VAR(gui.news_message_timeout,      SLE_UINT8, S,  0,     2,        1,      255, 0, STR_NULL,                                       NULL),
 

	
 
#ifdef ENABLE_NETWORK
 
	  SDTC_VAR(network.sync_freq,            SLE_UINT16,C|S,NO,   100,        0,      100, 0, STR_NULL,                                       NULL),
 
	  SDTC_VAR(network.frame_freq,            SLE_UINT8,C|S,NO,     0,        0,      100, 0, STR_NULL,                                       NULL),
 
	  SDTC_VAR(network.max_join_time,        SLE_UINT16, S, NO,   500,        0,    32000, 0, STR_NULL,                                       NULL),
 
	 SDTC_BOOL(network.pause_on_join,                    S, NO,  true,                        STR_NULL,                                       NULL),
 
	  SDTC_STR(network.server_bind_ip,         SLE_STRB, S, NO, "0.0.0.0",                    STR_NULL,                                       NULL),
 
	  SDTC_VAR(network.server_port,          SLE_UINT16, S, NO,NETWORK_DEFAULT_PORT,0,65535,0,STR_NULL,                                       NULL),
 
	 SDTC_BOOL(network.server_advertise,                 S, NO, false,                        STR_NULL,                                       NULL),
 
	  SDTC_VAR(network.lan_internet,          SLE_UINT8, S, NO,     0,        0,        1, 0, STR_NULL,                                       NULL),
 
	  SDTC_STR(network.player_name,            SLE_STRB, S,  0,  NULL,                        STR_NULL,                                       UpdatePlayerName),
 
	  SDTC_STR(network.server_password,        SLE_STRB, S, NO,  NULL,                        STR_NULL,                                       UpdateServerPassword),
 
	  SDTC_STR(network.rcon_password,          SLE_STRB, S, NO,  NULL,                        STR_NULL,                                       UpdateRconPassword),
 
	  SDTC_STR(network.default_company_pass,   SLE_STRB, S,  0,  NULL,                        STR_NULL,                                       NULL),
 
	  SDTC_STR(network.server_name,            SLE_STRB, S, NO,  NULL,                        STR_NULL,                                       UpdateServerName),
 
	  SDTC_STR(network.connect_to_ip,          SLE_STRB, S,  0,  NULL,                        STR_NULL,                                       NULL),
 
	  SDTC_STR(network.network_id,             SLE_STRB, S, NO,  NULL,                        STR_NULL,                                       NULL),
 
	 SDTC_BOOL(network.autoclean_companies,              S, NO, false,                        STR_NULL,                                       NULL),
 
	  SDTC_VAR(network.autoclean_unprotected, SLE_UINT8, S, NO,    12,     0,          60, 0, STR_NULL,                                       NULL),
 
	  SDTC_VAR(network.autoclean_protected,   SLE_UINT8, S, NO,    36,     0,         180, 0, STR_NULL,                                       NULL),
 
	  SDTC_VAR(network.max_companies,         SLE_UINT8, S, NO,     8,     1, MAX_PLAYERS, 0, STR_NULL,                                       NULL),
 
	  SDTC_VAR(network.max_clients,           SLE_UINT8, S, NO,    10,     2, MAX_CLIENTS, 0, STR_NULL,                                       NULL),
 
	  SDTC_VAR(network.max_spectators,        SLE_UINT8, S, NO,    10,     0, MAX_CLIENTS, 0, STR_NULL,                                       NULL),
 
	  SDTC_VAR(network.restart_game_year,     SLE_INT32, S,D0|NO|NC,0, MIN_YEAR, MAX_YEAR, 1, STR_NULL,                                       NULL),
 
	  SDTC_VAR(network.min_players,           SLE_UINT8, S, NO,     0,     0,        10,   0, STR_NULL,                                       UpdateMinPlayers),
 
	SDTC_OMANY(network.server_lang,           SLE_UINT8, S, NO,     0,    35, "ANY|ENGLISH|GERMAN|FRENCH|BRAZILIAN|BULGARIAN|CHINESE|CZECH|DANISH|DUTCH|ESPERANTO|FINNISH|HUNGARIAN|ICELANDIC|ITALIAN|JAPANESE|KOREAN|LITHUANIAN|NORWEGIAN|POLISH|PORTUGUESE|ROMANIAN|RUSSIAN|SLOVAK|SLOVENIAN|SPANISH|SWEDISH|TURKISH|UKRAINIAN|AFRIKAANS|CROATIAN|CATALAN|ESTONIAN|GALICIAN|GREEK|LATVIAN", STR_NULL, NULL),
 
	 SDTC_BOOL(network.reload_cfg,                       S, NO, false,                        STR_NULL,                                       NULL),
 
	  SDTC_STR(network.last_host,              SLE_STRB, S,  0, "0.0.0.0",                    STR_NULL,                                       NULL),
 
	  SDTC_VAR(network.last_port,            SLE_UINT16, S,  0,     0,     0,  UINT16_MAX, 0, STR_NULL,                                       NULL),
 
#endif /* ENABLE_NETWORK */
 

	
 
	/*
 
	 * Since the network code (CmdChangePatchSetting and friends) use the index in this array to decide
 
@@ -2026,7 +2089,6 @@ static void HandleSettingDescs(IniFile *
 
	proc(ini, _currency_settings,"currency", &_custom_currency);
 

	
 
#ifdef ENABLE_NETWORK
 
	proc(ini, (const SettingDesc*)_network_settings, "network", NULL);
 
	proc_list(ini, "servers", _network_host_list, lengthof(_network_host_list), NULL);
 
	proc_list(ini, "bans",    _network_ban_list,  lengthof(_network_ban_list), NULL);
 
#endif /* ENABLE_NETWORK */
 
@@ -2090,7 +2152,7 @@ CommandCost CmdChangePatchSetting(TileIn
 
	if (sd == NULL) return CMD_ERROR;
 
	if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to)) return CMD_ERROR;
 

	
 
	if ((sd->desc.flags & SGF_NETWORK_ONLY) && !_networking) return CMD_ERROR;
 
	if ((sd->desc.flags & SGF_NETWORK_ONLY) && !_networking && _game_mode != GM_MENU) return CMD_ERROR;
 
	if ((sd->desc.flags & SGF_NO_NETWORK) && _networking) return CMD_ERROR;
 
	if ((sd->desc.flags & SGF_NEWGAME_ONLY) && _game_mode != GM_MENU) return CMD_ERROR;
 

	
 
@@ -2140,6 +2202,23 @@ bool SetPatchValue(uint index, int32 val
 
	return false;
 
}
 

	
 
/**
 
 * Set a patch value with a string.
 
 * @param index the patch settings index.
 
 * @param value the value to write
 
 * @note CANNOT BE SAVED IN THE SAVEGAME.
 
 */
 
bool SetPatchValue(uint index, const char *value)
 
{
 
	const SettingDesc *sd = &_patch_settings[index];
 
	assert(sd->save.conv & SLF_NETWORK_NO);
 

	
 
	char *var = (char*)GetVariableAddress(NULL, &sd->save);
 
	ttd_strlcpy(var, value, sd->save.length);
 

	
 
	return true;
 
}
 

	
 
const SettingDesc *GetPatchFromName(const char *name, uint *i)
 
{
 
	const SettingDesc *sd;
 
@@ -2165,23 +2244,40 @@ const SettingDesc *GetPatchFromName(cons
 

	
 
/* Those 2 functions need to be here, else we have to make some stuff non-static
 
 * and besides, it is also better to keep stuff like this at the same place */
 
bool IConsoleSetPatchSetting(const char *name, int32 value)
 
void IConsoleSetPatchSetting(const char *name, const char *value)
 
{
 
	bool success;
 
	uint index;
 
	const SettingDesc *sd = GetPatchFromName(name, &index);
 
	void *ptr;
 

	
 
	if (sd == NULL) {
 
		IConsolePrintF(CC_WARNING, "'%s' is an unknown patch setting.", name);
 
		return true;
 
	}
 

	
 
	bool success;
 
	if (sd->desc.cmd == SDT_STRING) {
 
		success = SetPatchValue(index, value);
 
	} else {
 
		uint32 val;
 
		extern bool GetArgumentInteger(uint32 *value, const char *arg);
 
		success = GetArgumentInteger(&val, value);
 
		if (success) success = SetPatchValue(index, val);
 
	}
 

	
 
	GameSettings *s = (_game_mode == GM_MENU) ? &_settings_newgame : &_settings_game;
 
	ptr = GetVariableAddress(s, &sd->save);
 
	if (!success) {
 
		if (_network_server) {
 
			IConsoleError("This command/variable is not available during network games.");
 
		} else {
 
			IConsoleError("This command/variable is only available to a network server.");
 
		}
 
	}
 
}
 

	
 
	success = SetPatchValue(index, value);
 
	return success;
 
void IConsoleSetPatchSetting(const char *name, int value)
 
{
 
	uint index;
 
	const SettingDesc *sd = GetPatchFromName(name, &index);
 
	assert(sd != NULL);
 
	SetPatchValue(index, value);
 
}
 

	
 
void IConsoleGetPatchSetting(const char *name)
 
@@ -2198,14 +2294,18 @@ void IConsoleGetPatchSetting(const char 
 

	
 
	ptr = GetVariableAddress((_game_mode == GM_MENU) ? &_settings_newgame : &_settings_game, &sd->save);
 

	
 
	if (sd->desc.cmd == SDT_BOOLX) {
 
		snprintf(value, sizeof(value), (*(bool*)ptr == 1) ? "on" : "off");
 
	if (sd->desc.cmd == SDT_STRING) {
 
		IConsolePrintF(CC_WARNING, "Current value for '%s' is: '%s'", name, (const char *)ptr);
 
	} else {
 
		snprintf(value, sizeof(value), "%d", (int32)ReadValue(ptr, sd->save.conv));
 
	}
 
		if (sd->desc.cmd == SDT_BOOLX) {
 
			snprintf(value, sizeof(value), (*(bool*)ptr == 1) ? "on" : "off");
 
		} else {
 
			snprintf(value, sizeof(value), "%d", (int32)ReadValue(ptr, sd->save.conv));
 
		}
 

	
 
	IConsolePrintF(CC_WARNING, "Current value for '%s' is: '%s' (min: %s%d, max: %d)",
 
		name, value, (sd->desc.flags & SGF_0ISDISABLED) ? "(0) " : "", sd->desc.min, sd->desc.max);
 
		IConsolePrintF(CC_WARNING, "Current value for '%s' is: '%s' (min: %s%d, max: %d)",
 
			name, value, (sd->desc.flags & SGF_0ISDISABLED) ? "(0) " : "", sd->desc.min, sd->desc.max);
 
	}
 
}
 

	
 
void IConsoleListPatches()
 
@@ -2218,6 +2318,8 @@ void IConsoleListPatches()
 

	
 
		if (sd->desc.cmd == SDT_BOOLX) {
 
			snprintf(value, lengthof(value), (*(bool*)ptr == 1) ? "on" : "off");
 
		} else if (sd->desc.cmd == SDT_STRING) {
 
			snprintf(value, sizeof(value), "%s", (const char *)ptr);
 
		} else {
 
			snprintf(value, lengthof(value), "%d", (uint32)ReadValue(ptr, sd->save.conv));
 
		}
src/settings_func.h
Show inline comments
 
@@ -5,7 +5,8 @@
 
#ifndef SETTINGS_FUNC_H
 
#define SETTINGS_FUNC_H
 

	
 
bool IConsoleSetPatchSetting(const char *name, int32 value);
 
void IConsoleSetPatchSetting(const char *name, const char *value);
 
void IConsoleSetPatchSetting(const char *name, int32 value);
 
void IConsoleGetPatchSetting(const char *name);
 
void IConsoleListPatches();
 

	
src/settings_internal.h
Show inline comments
 
@@ -85,5 +85,6 @@ enum IniGroupType {
 

	
 
const SettingDesc *GetPatchFromName(const char *name, uint *i);
 
bool SetPatchValue(uint index, int32 value);
 
bool SetPatchValue(uint index, const char *value);
 

	
 
#endif /* SETTINGS_H */
0 comments (0 inline, 0 general)