@ -1794,55 +1794,94 @@ void NetworkServer_Tick(bool send_frame)
_settings_client . network . bytes_per_frame_burst ) ;
/* Check if the speed of the client is what we can expect from a client */
if ( cs - > status = = NetworkClientSocket : : STATUS_ACTIVE ) {
/* 1 lag-point per day */
uint lag = NetworkCalculateLag ( cs ) / DAY_TICKS ;
if ( lag > 0 ) {
if ( lag > 3 ) {
/* Client did still not report in after 4 game-day, drop him
* ( that is , the 3 of above , + 1 before any lag is counted ) */
IConsolePrintF ( CC_ERROR , cs - > last_packet + 3 * DAY_TICKS * MILLISECONDS_PER_TICK > _realtime_tick ?
/* A packet was received in the last three game days, so the client is likely lagging behind. */
" Client #%d is dropped because the client's game state is more than 4 game-days behind " :
/* No packet was received in the last three game days; sounds like a lost connection. */
" Client #%d is dropped because the client did not respond for more than 4 game-days " ,
cs - > client_id ) ;
cs - > CloseConnection ( NETWORK_RECV_STATUS_SERVER_ERROR ) ;
uint lag = NetworkCalculateLag ( cs ) ;
switch ( cs - > status ) {
case NetworkClientSocket : : STATUS_ACTIVE :
/* 1 lag-point per day */
lag / = DAY_TICKS ;
if ( lag > 0 ) {
if ( lag > 3 ) {
/* Client did still not report in after 4 game-day, drop him
* ( that is , the 3 of above , + 1 before any lag is counted ) */
IConsolePrintF ( CC_ERROR , cs - > last_packet + 3 * DAY_TICKS * MILLISECONDS_PER_TICK > _realtime_tick ?
/* A packet was received in the last three game days, so the client is likely lagging behind. */
" Client #%d is dropped because the client's game state is more than 4 game-days behind " :
/* No packet was received in the last three game days; sounds like a lost connection. */
" 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 ;
}
break ;
/* 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 ;
case NetworkClientSocket : : STATUS_INACTIVE :
case NetworkClientSocket : : STATUS_NEWGRFS_CHECK :
case NetworkClientSocket : : STATUS_AUTHORIZED :
/* NewGRF check and authorized states should be handled almost instantly.
* So give them some lee - way , likewise for the query with inactive . */
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 ) ;
cs - > SendError ( NETWORK_ERROR_TIMEOUT_COMPUTER ) ;
continue ;
}
} 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 - > CloseConnection ( NETWORK_RECV_STATUS_SERVER_ERROR ) ;
continue ;
}
} else if ( cs - > status = = NetworkClientSocket : : STATUS_PRE_ACTIVE ) {
uint lag = NetworkCalculateLag ( cs ) ;
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 ) ;
cs - > CloseConnection ( NETWORK_RECV_STATUS_SERVER_ERROR ) ;
continue ;
}
} else if ( cs - > status = = NetworkClientSocket : : STATUS_INACTIVE ) {
uint lag = NetworkCalculateLag ( cs ) ;
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 ) ;
cs - > CloseConnection ( NETWORK_RECV_STATUS_SERVER_ERROR ) ;
continue ;
}
break ;
case NetworkClientSocket : : STATUS_MAP :
/* Downloading the map... this is the amount of time since starting the saving. */
if ( lag > _settings_client . network . max_download_time ) {
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 - > SendError ( NETWORK_ERROR_TIMEOUT_COMPUTER ) ;
continue ;
}
break ;
case NetworkClientSocket : : STATUS_DONE_MAP :
case NetworkClientSocket : : STATUS_PRE_ACTIVE :
/* The map has been sent, so this is for loading the map and syncing up. */
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 ) ;
cs - > SendError ( NETWORK_ERROR_TIMEOUT_COMPUTER ) ;
continue ;
}
break ;
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 ) {