mirror of https://github.com/OpenTTD/OpenTTD
(svn r23764) -Fix [FS#4955]: make default timeouts for certain states lower and configurable
parent
9d958ff581
commit
bddfcaef95
|
@ -1799,6 +1799,8 @@ STR_NETWORK_ERROR_SERVER_BANNED :{WHITE}You are
|
||||||
STR_NETWORK_ERROR_KICKED :{WHITE}You were kicked out of the game
|
STR_NETWORK_ERROR_KICKED :{WHITE}You were kicked out of the game
|
||||||
STR_NETWORK_ERROR_CHEATER :{WHITE}Cheating is not allowed on this server
|
STR_NETWORK_ERROR_CHEATER :{WHITE}Cheating is not allowed on this server
|
||||||
STR_NETWORK_ERROR_TOO_MANY_COMMANDS :{WHITE}You were sending too many commands to the server
|
STR_NETWORK_ERROR_TOO_MANY_COMMANDS :{WHITE}You were sending too many commands to the server
|
||||||
|
STR_NETWORK_ERROR_TIMEOUT_PASSWORD :{WHITE}You took too long to enter the password
|
||||||
|
STR_NETWORK_ERROR_TIMEOUT_COMPUTER :{WHITE}Your computer took too long to join
|
||||||
|
|
||||||
############ Leave those lines in this order!!
|
############ Leave those lines in this order!!
|
||||||
STR_NETWORK_ERROR_CLIENT_GENERAL :general error
|
STR_NETWORK_ERROR_CLIENT_GENERAL :general error
|
||||||
|
|
|
@ -670,6 +670,12 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_ERROR(Packet *p
|
||||||
case NETWORK_ERROR_TOO_MANY_COMMANDS:
|
case NETWORK_ERROR_TOO_MANY_COMMANDS:
|
||||||
ShowErrorMessage(STR_NETWORK_ERROR_TOO_MANY_COMMANDS, INVALID_STRING_ID, WL_CRITICAL);
|
ShowErrorMessage(STR_NETWORK_ERROR_TOO_MANY_COMMANDS, INVALID_STRING_ID, WL_CRITICAL);
|
||||||
break;
|
break;
|
||||||
|
case NETWORK_ERROR_TIMEOUT_PASSWORD:
|
||||||
|
ShowErrorMessage(STR_NETWORK_ERROR_TIMEOUT_PASSWORD, INVALID_STRING_ID, WL_CRITICAL);
|
||||||
|
break;
|
||||||
|
case NETWORK_ERROR_TIMEOUT_COMPUTER:
|
||||||
|
ShowErrorMessage(STR_NETWORK_ERROR_TIMEOUT_COMPUTER, INVALID_STRING_ID, WL_CRITICAL);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
ShowErrorMessage(STR_NETWORK_ERROR_LOSTCONNECTION, INVALID_STRING_ID, WL_CRITICAL);
|
ShowErrorMessage(STR_NETWORK_ERROR_LOSTCONNECTION, INVALID_STRING_ID, WL_CRITICAL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1794,55 +1794,94 @@ void NetworkServer_Tick(bool send_frame)
|
||||||
_settings_client.network.bytes_per_frame_burst);
|
_settings_client.network.bytes_per_frame_burst);
|
||||||
|
|
||||||
/* Check if the speed of the client is what we can expect from a client */
|
/* Check if the speed of the client is what we can expect from a client */
|
||||||
if (cs->status == NetworkClientSocket::STATUS_ACTIVE) {
|
uint lag = NetworkCalculateLag(cs);
|
||||||
/* 1 lag-point per day */
|
switch (cs->status) {
|
||||||
uint lag = NetworkCalculateLag(cs) / DAY_TICKS;
|
case NetworkClientSocket::STATUS_ACTIVE:
|
||||||
if (lag > 0) {
|
/* 1 lag-point per day */
|
||||||
if (lag > 3) {
|
lag /= DAY_TICKS;
|
||||||
/* Client did still not report in after 4 game-day, drop him
|
if (lag > 0) {
|
||||||
* (that is, the 3 of above, + 1 before any lag is counted) */
|
if (lag > 3) {
|
||||||
IConsolePrintF(CC_ERROR, cs->last_packet + 3 * DAY_TICKS * MILLISECONDS_PER_TICK > _realtime_tick ?
|
/* Client did still not report in after 4 game-day, drop him
|
||||||
/* A packet was received in the last three game days, so the client is likely lagging behind. */
|
* (that is, the 3 of above, + 1 before any lag is counted) */
|
||||||
"Client #%d is dropped because the client's game state is more than 4 game-days behind" :
|
IConsolePrintF(CC_ERROR, cs->last_packet + 3 * DAY_TICKS * MILLISECONDS_PER_TICK > _realtime_tick ?
|
||||||
/* No packet was received in the last three game days; sounds like a lost connection. */
|
/* A packet was received in the last three game days, so the client is likely lagging behind. */
|
||||||
"Client #%d is dropped because the client did not respond for more than 4 game-days",
|
"Client #%d is dropped because the client's game state is more than 4 game-days behind" :
|
||||||
cs->client_id);
|
/* No packet was received in the last three game days; sounds like a lost connection. */
|
||||||
cs->CloseConnection(NETWORK_RECV_STATUS_SERVER_ERROR);
|
"Client #%d is dropped because the client did not respond for more than 4 game-days",
|
||||||
|
cs->client_id);
|
||||||
|
cs->SendError(NETWORK_ERROR_TIMEOUT_COMPUTER);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Report once per time we detect the lag, and only when we
|
||||||
|
* received a packet in the last 2000 milliseconds. If we
|
||||||
|
* did not receive a packet, then the client is not just
|
||||||
|
* slow, but the connection is likely severed. Mentioning
|
||||||
|
* frame_freq is not useful in this case. */
|
||||||
|
if (cs->lag_test == 0 && cs->last_packet + DAY_TICKS * MILLISECONDS_PER_TICK > _realtime_tick) {
|
||||||
|
IConsolePrintF(CC_WARNING,"[%d] Client #%d is slow, try increasing [network.]frame_freq to a higher value!", _frame_counter, cs->client_id);
|
||||||
|
cs->lag_test = 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cs->lag_test = 0;
|
||||||
|
}
|
||||||
|
if (cs->last_frame_server - cs->last_token_frame >= 5 * DAY_TICKS) {
|
||||||
|
/* This is a bad client! It didn't send the right token back. */
|
||||||
|
IConsolePrintF(CC_ERROR, "Client #%d is dropped because it fails to send valid acks", cs->client_id);
|
||||||
|
cs->SendError(NETWORK_ERROR_TIMEOUT_COMPUTER);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
/* Report once per time we detect the lag, and only when we
|
case NetworkClientSocket::STATUS_INACTIVE:
|
||||||
* received a packet in the last 2000 milliseconds. If we
|
case NetworkClientSocket::STATUS_NEWGRFS_CHECK:
|
||||||
* did not receive a packet, then the client is not just
|
case NetworkClientSocket::STATUS_AUTHORIZED:
|
||||||
* slow, but the connection is likely severed. Mentioning
|
/* NewGRF check and authorized states should be handled almost instantly.
|
||||||
* frame_freq is not useful in this case. */
|
* So give them some lee-way, likewise for the query with inactive. */
|
||||||
if (cs->lag_test == 0 && cs->last_packet + DAY_TICKS * MILLISECONDS_PER_TICK > _realtime_tick) {
|
if (lag > 4 * DAY_TICKS) {
|
||||||
IConsolePrintF(CC_WARNING,"[%d] Client #%d is slow, try increasing [network.]frame_freq to a higher value!", _frame_counter, cs->client_id);
|
IConsolePrintF(CC_ERROR,"Client #%d is dropped because it took longer than %d ticks to start the joining process", cs->client_id, 4 * DAY_TICKS);
|
||||||
cs->lag_test = 1;
|
cs->SendError(NETWORK_ERROR_TIMEOUT_COMPUTER);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
} else {
|
break;
|
||||||
cs->lag_test = 0;
|
|
||||||
}
|
case NetworkClientSocket::STATUS_MAP:
|
||||||
if (cs->last_frame_server - cs->last_token_frame >= 5 * DAY_TICKS) {
|
/* Downloading the map... this is the amount of time since starting the saving. */
|
||||||
/* This is a bad client! It didn't send the right token back. */
|
if (lag > _settings_client.network.max_download_time) {
|
||||||
IConsolePrintF(CC_ERROR, "Client #%d is dropped because it fails to send valid acks", cs->client_id);
|
IConsolePrintF(CC_ERROR,"Client #%d is dropped because it took longer than %d ticks for him to download the map", cs->client_id, _settings_client.network.max_download_time);
|
||||||
cs->CloseConnection(NETWORK_RECV_STATUS_SERVER_ERROR);
|
cs->SendError(NETWORK_ERROR_TIMEOUT_COMPUTER);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else if (cs->status == NetworkClientSocket::STATUS_PRE_ACTIVE) {
|
break;
|
||||||
uint lag = NetworkCalculateLag(cs);
|
|
||||||
if (lag > _settings_client.network.max_join_time) {
|
case NetworkClientSocket::STATUS_DONE_MAP:
|
||||||
IConsolePrintF(CC_ERROR,"Client #%d is dropped because it took longer than %d ticks for him to join", cs->client_id, _settings_client.network.max_join_time);
|
case NetworkClientSocket::STATUS_PRE_ACTIVE:
|
||||||
cs->CloseConnection(NETWORK_RECV_STATUS_SERVER_ERROR);
|
/* The map has been sent, so this is for loading the map and syncing up. */
|
||||||
continue;
|
if (lag > _settings_client.network.max_join_time) {
|
||||||
}
|
IConsolePrintF(CC_ERROR,"Client #%d is dropped because it took longer than %d ticks for him to join", cs->client_id, _settings_client.network.max_join_time);
|
||||||
} else if (cs->status == NetworkClientSocket::STATUS_INACTIVE) {
|
cs->SendError(NETWORK_ERROR_TIMEOUT_COMPUTER);
|
||||||
uint lag = NetworkCalculateLag(cs);
|
continue;
|
||||||
if (lag > 4 * DAY_TICKS) {
|
}
|
||||||
IConsolePrintF(CC_ERROR,"Client #%d is dropped because it took longer than %d ticks to start the joining process", cs->client_id, 4 * DAY_TICKS);
|
break;
|
||||||
cs->CloseConnection(NETWORK_RECV_STATUS_SERVER_ERROR);
|
|
||||||
continue;
|
case NetworkClientSocket::STATUS_AUTH_GAME:
|
||||||
}
|
case NetworkClientSocket::STATUS_AUTH_COMPANY:
|
||||||
|
/* These don't block? */
|
||||||
|
if (lag > _settings_client.network.max_password_time) {
|
||||||
|
IConsolePrintF(CC_ERROR,"Client #%d is dropped because it took longer than %d to enter the password", cs->client_id, _settings_client.network.max_password_time);
|
||||||
|
cs->SendError(NETWORK_ERROR_TIMEOUT_PASSWORD);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NetworkClientSocket::STATUS_MAP_WAIT:
|
||||||
|
/* This is an internal state where we do not wait
|
||||||
|
* on the client to move to a different state. */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NetworkClientSocket::STATUS_END:
|
||||||
|
/* Bad server/code. */
|
||||||
|
NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cs->status >= NetworkClientSocket::STATUS_PRE_ACTIVE) {
|
if (cs->status >= NetworkClientSocket::STATUS_PRE_ACTIVE) {
|
||||||
|
|
|
@ -122,6 +122,8 @@ enum NetworkErrorCode {
|
||||||
NETWORK_ERROR_CHEATER,
|
NETWORK_ERROR_CHEATER,
|
||||||
NETWORK_ERROR_FULL,
|
NETWORK_ERROR_FULL,
|
||||||
NETWORK_ERROR_TOO_MANY_COMMANDS,
|
NETWORK_ERROR_TOO_MANY_COMMANDS,
|
||||||
|
NETWORK_ERROR_TIMEOUT_PASSWORD,
|
||||||
|
NETWORK_ERROR_TIMEOUT_COMPUTER,
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* ENABLE_NETWORK */
|
#endif /* ENABLE_NETWORK */
|
||||||
|
|
|
@ -173,6 +173,8 @@ struct NetworkSettings {
|
||||||
uint16 bytes_per_frame; ///< how many bytes may, over a long period, be received per frame?
|
uint16 bytes_per_frame; ///< how many bytes may, over a long period, be received per frame?
|
||||||
uint16 bytes_per_frame_burst; ///< how many bytes may, over a short period, be received?
|
uint16 bytes_per_frame_burst; ///< how many bytes may, over a short period, be received?
|
||||||
uint16 max_join_time; ///< maximum amount of time, in game ticks, a client may take to join
|
uint16 max_join_time; ///< maximum amount of time, in game ticks, a client may take to join
|
||||||
|
uint16 max_download_time; ///< maximum amount of time, in game ticks, a client may take to download the map
|
||||||
|
uint16 max_password_time; ///< maximum amount of time, in game ticks, a client may take to enter the password
|
||||||
bool pause_on_join; ///< pause the game when people join
|
bool pause_on_join; ///< pause the game when people join
|
||||||
uint16 server_port; ///< port the server listens on
|
uint16 server_port; ///< port the server listens on
|
||||||
uint16 server_admin_port; ///< port the server listens on for the admin network
|
uint16 server_admin_port; ///< port the server listens on for the admin network
|
||||||
|
|
|
@ -2653,6 +2653,26 @@ def = 500
|
||||||
min = 0
|
min = 0
|
||||||
max = 32000
|
max = 32000
|
||||||
|
|
||||||
|
[SDTC_VAR]
|
||||||
|
ifdef = ENABLE_NETWORK
|
||||||
|
var = network.max_download_time
|
||||||
|
type = SLE_UINT16
|
||||||
|
flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
|
||||||
|
guiflags = SGF_NETWORK_ONLY
|
||||||
|
def = 1000
|
||||||
|
min = 0
|
||||||
|
max = 32000
|
||||||
|
|
||||||
|
[SDTC_VAR]
|
||||||
|
ifdef = ENABLE_NETWORK
|
||||||
|
var = network.max_password_time
|
||||||
|
type = SLE_UINT16
|
||||||
|
flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
|
||||||
|
guiflags = SGF_NETWORK_ONLY
|
||||||
|
def = 2000
|
||||||
|
min = 0
|
||||||
|
max = 32000
|
||||||
|
|
||||||
[SDTC_BOOL]
|
[SDTC_BOOL]
|
||||||
ifdef = ENABLE_NETWORK
|
ifdef = ENABLE_NETWORK
|
||||||
var = network.pause_on_join
|
var = network.pause_on_join
|
||||||
|
|
Loading…
Reference in New Issue