diff --git a/src/lang/english.txt b/src/lang/english.txt index ca26d695c1..a691635603 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -1788,6 +1788,9 @@ STR_NETWORK_ERROR_CLIENT_SERVER_FULL :server full STR_NETWORK_ERROR_CLIENT_TOO_MANY_COMMANDS :was sending too many commands ############ End of leave-in-this-order +STR_NETWORK_ERROR_CLIENT_GUI_LOST_CONNECTION_CAPTION :{WHITE}Possible connection loss +STR_NETWORK_ERROR_CLIENT_GUI_LOST_CONNECTION :{WHITE}The last {NUM} second{P "" s} no data has arrived from the server + # Network related errors STR_NETWORK_SERVER_MESSAGE :*** {1:RAW_STRING} ############ Leave those lines in this order!! diff --git a/src/network/network_client.cpp b/src/network/network_client.cpp index 9b9b55d971..0882c644bb 100644 --- a/src/network/network_client.cpp +++ b/src/network/network_client.cpp @@ -27,6 +27,7 @@ #include "../company_gui.h" #include "../core/random_func.hpp" #include "../date_func.h" +#include "../gui.h" #include "../rev.h" #include "network.h" #include "network_base.h" @@ -140,6 +141,7 @@ void ClientNetworkGameSocketHandler::ClientError(NetworkRecvStatus res) /*static */ void ClientNetworkGameSocketHandler::Send() { my_client->Send_Packets(); + my_client->CheckConnection(); } /** @@ -1032,6 +1034,40 @@ DEF_GAME_RECEIVE_COMMAND(Client, PACKET_SERVER_COMPANY_UPDATE) return NETWORK_RECV_STATUS_OKAY; } +/** + * Check the connection's state, i.e. is the connection still up? + */ +void ClientNetworkGameSocketHandler::CheckConnection() +{ + /* Only once we're authorized we can expect a steady stream of packets. */ + if (this->status < STATUS_AUTHORIZED) return; + + /* It might... sometimes occur that the realtime ticker overflows. */ + if (_realtime_tick < this->last_packet) this->last_packet = _realtime_tick; + + /* Lag is in milliseconds; 2 seconds are roughly the server's + * "you're slow" threshold (1 game day). */ + uint lag = (_realtime_tick - this->last_packet) / 1000; + if (lag < 2) return; + + /* 10 seconds are (way) more than 4 game days after which + * the server will forcefully disconnect you. */ + if (lag > 10) { + this->NetworkGameSocketHandler::CloseConnection(); + _switch_mode_errorstr = STR_NETWORK_ERROR_LOSTCONNECTION; + return; + } + + /* Prevent showing the lag message every tick; just update it when needed. */ + static uint last_lag = 0; + if (last_lag == lag) return; + + last_lag = lag; + SetDParam(0, lag); + ShowErrorMessage(STR_NETWORK_ERROR_CLIENT_GUI_LOST_CONNECTION_CAPTION, STR_NETWORK_ERROR_CLIENT_GUI_LOST_CONNECTION, WL_INFO); +} + + /* Is called after a client is connected to the server */ void NetworkClient_Connected() { diff --git a/src/network/network_client.h b/src/network/network_client.h index f47fe0b659..597aec1931 100644 --- a/src/network/network_client.h +++ b/src/network/network_client.h @@ -73,6 +73,7 @@ protected: static NetworkRecvStatus SendNewGRFsOk(); static NetworkRecvStatus SendGetMap(); static NetworkRecvStatus SendMapOk(); + void CheckConnection(); public: ClientNetworkGameSocketHandler(SOCKET s); ~ClientNetworkGameSocketHandler();