mirror of https://github.com/OpenTTD/OpenTTD
Merge dc73aa50dd
into 1addeddc07
commit
4ace84513e
|
@ -2641,6 +2641,7 @@ STR_NETWORK_MESSAGE_GIVE_MONEY :*** {0:RAW_STRI
|
||||||
STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}The server closed the session
|
STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}The server closed the session
|
||||||
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}The server is restarting...{}Please wait...
|
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}The server is restarting...{}Please wait...
|
||||||
STR_NETWORK_MESSAGE_KICKED :*** {RAW_STRING} was kicked. Reason: ({RAW_STRING})
|
STR_NETWORK_MESSAGE_KICKED :*** {RAW_STRING} was kicked. Reason: ({RAW_STRING})
|
||||||
|
STR_NETWORK_MESSAGE_SERVER_REBOOT_REJOIN_FAILED :{WHITE}Failed to reconnect to server
|
||||||
|
|
||||||
STR_NETWORK_ERROR_COORDINATOR_REGISTRATION_FAILED :{WHITE}Server registration failed
|
STR_NETWORK_ERROR_COORDINATOR_REGISTRATION_FAILED :{WHITE}Server registration failed
|
||||||
STR_NETWORK_ERROR_COORDINATOR_REUSE_OF_INVITE_CODE :{WHITE}Another server with the same invite-code registered itself. Switching to "local" game-type.
|
STR_NETWORK_ERROR_COORDINATOR_REUSE_OF_INVITE_CODE :{WHITE}Another server with the same invite-code registered itself. Switching to "local" game-type.
|
||||||
|
|
|
@ -74,6 +74,8 @@ static const uint NETWORK_TOKEN_LENGTH = 64; ///< The m
|
||||||
|
|
||||||
static const uint NETWORK_GRF_NAME_LENGTH = 80; ///< Maximum length of the name of a GRF
|
static const uint NETWORK_GRF_NAME_LENGTH = 80; ///< Maximum length of the name of a GRF
|
||||||
|
|
||||||
|
static const uint32_t NETWORK_RECONNECT_ATTEMPTS = 8; ///< How many attempts before we give up reconnecting.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maximum number of GRFs that can be sent.
|
* Maximum number of GRFs that can be sent.
|
||||||
*
|
*
|
||||||
|
|
|
@ -64,7 +64,9 @@ bool _is_network_server; ///< Does this client wants to be a network-server?
|
||||||
NetworkCompanyState *_network_company_states = nullptr; ///< Statistics about some companies.
|
NetworkCompanyState *_network_company_states = nullptr; ///< Statistics about some companies.
|
||||||
ClientID _network_own_client_id; ///< Our client identifier.
|
ClientID _network_own_client_id; ///< Our client identifier.
|
||||||
ClientID _redirect_console_to_client; ///< If not invalid, redirect the console output to a client.
|
ClientID _redirect_console_to_client; ///< If not invalid, redirect the console output to a client.
|
||||||
uint8_t _network_reconnect; ///< Reconnect timeout
|
uint32_t _network_reconnect_attempts = 0; ///< How many attempts to reconnect left.
|
||||||
|
std::chrono::seconds _network_reconnect_backoff = {}; ///< How much time to wait for the next reconnect attempt.
|
||||||
|
std::chrono::steady_clock::time_point _network_reconnect = {}; ///< The time when to attempt another reconnect.
|
||||||
StringList _network_bind_list; ///< The addresses to bind on.
|
StringList _network_bind_list; ///< The addresses to bind on.
|
||||||
StringList _network_host_list; ///< The servers we know.
|
StringList _network_host_list; ///< The servers we know.
|
||||||
StringList _network_ban_list; ///< The banned clients.
|
StringList _network_ban_list; ///< The banned clients.
|
||||||
|
@ -619,8 +621,6 @@ static void NetworkInitialize(bool close_admins = true)
|
||||||
|
|
||||||
_sync_frame = 0;
|
_sync_frame = 0;
|
||||||
_network_first_time = true;
|
_network_first_time = true;
|
||||||
|
|
||||||
_network_reconnect = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Non blocking connection to query servers for their game info. */
|
/** Non blocking connection to query servers for their game info. */
|
||||||
|
@ -738,7 +738,9 @@ public:
|
||||||
{
|
{
|
||||||
Debug(net, 9, "Client::OnFailure(): connection_string={}", this->connection_string);
|
Debug(net, 9, "Client::OnFailure(): connection_string={}", this->connection_string);
|
||||||
|
|
||||||
ShowNetworkError(STR_NETWORK_ERROR_NOCONNECTION);
|
if (_network_reconnect_attempts == 0) {
|
||||||
|
ShowNetworkError(STR_NETWORK_ERROR_NOCONNECTION);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnConnect(SOCKET s) override
|
void OnConnect(SOCKET s) override
|
||||||
|
|
|
@ -344,6 +344,8 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendJoin()
|
||||||
_network_join_status = NETWORK_JOIN_STATUS_AUTHORIZING;
|
_network_join_status = NETWORK_JOIN_STATUS_AUTHORIZING;
|
||||||
SetWindowDirty(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_JOIN);
|
SetWindowDirty(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_JOIN);
|
||||||
|
|
||||||
|
_network_reconnect_attempts = 0;
|
||||||
|
|
||||||
auto p = std::make_unique<Packet>(PACKET_CLIENT_JOIN);
|
auto p = std::make_unique<Packet>(PACKET_CLIENT_JOIN);
|
||||||
p->Send_string(GetNetworkRevisionString());
|
p->Send_string(GetNetworkRevisionString());
|
||||||
p->Send_uint32(_openttd_newgrf_version);
|
p->Send_uint32(_openttd_newgrf_version);
|
||||||
|
@ -1127,14 +1129,10 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_NEWGAME(Packet
|
||||||
{
|
{
|
||||||
Debug(net, 9, "Client::Receive_SERVER_NEWGAME()");
|
Debug(net, 9, "Client::Receive_SERVER_NEWGAME()");
|
||||||
|
|
||||||
/* Only when we're trying to join we really
|
|
||||||
* care about the server shutting down. */
|
|
||||||
if (this->status >= STATUS_JOIN) {
|
if (this->status >= STATUS_JOIN) {
|
||||||
/* To throttle the reconnects a bit, every clients waits its
|
_network_reconnect_attempts = NETWORK_RECONNECT_ATTEMPTS;
|
||||||
* Client ID modulo 16 + 1 (value 0 means no reconnect).
|
_network_reconnect_backoff = std::chrono::seconds(1);
|
||||||
* This way reconnects should be spread out a bit. */
|
_network_reconnect = std::chrono::steady_clock::now() + _network_reconnect_backoff;
|
||||||
_network_reconnect = _network_own_client_id % 16 + 1;
|
|
||||||
ShowErrorMessage(STR_NETWORK_MESSAGE_SERVER_REBOOT, INVALID_STRING_ID, WL_CRITICAL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->status == STATUS_ACTIVE) ClientNetworkEmergencySave();
|
if (this->status == STATUS_ACTIVE) ClientNetworkEmergencySave();
|
||||||
|
|
|
@ -28,7 +28,9 @@ extern NetworkCompanyState *_network_company_states;
|
||||||
|
|
||||||
extern ClientID _network_own_client_id;
|
extern ClientID _network_own_client_id;
|
||||||
extern ClientID _redirect_console_to_client;
|
extern ClientID _redirect_console_to_client;
|
||||||
extern uint8_t _network_reconnect;
|
extern uint32_t _network_reconnect_attempts;
|
||||||
|
extern std::chrono::seconds _network_reconnect_backoff;
|
||||||
|
extern std::chrono::steady_clock::time_point _network_reconnect;
|
||||||
extern StringList _network_bind_list;
|
extern StringList _network_bind_list;
|
||||||
extern StringList _network_host_list;
|
extern StringList _network_host_list;
|
||||||
extern StringList _network_ban_list;
|
extern StringList _network_ban_list;
|
||||||
|
|
|
@ -91,8 +91,6 @@ extern std::string _network_server_invite_code;
|
||||||
/* Variable available for clients. */
|
/* Variable available for clients. */
|
||||||
extern std::string _network_server_name;
|
extern std::string _network_server_name;
|
||||||
|
|
||||||
extern uint8_t _network_reconnect;
|
|
||||||
|
|
||||||
extern CompanyMask _network_company_passworded;
|
extern CompanyMask _network_company_passworded;
|
||||||
|
|
||||||
void NetworkQueryServer(const std::string &connection_string);
|
void NetworkQueryServer(const std::string &connection_string);
|
||||||
|
|
|
@ -1600,11 +1600,30 @@ void GameLoop()
|
||||||
/* Multiplayer */
|
/* Multiplayer */
|
||||||
NetworkGameLoop();
|
NetworkGameLoop();
|
||||||
} else {
|
} else {
|
||||||
if (_network_reconnect > 0 && --_network_reconnect == 0) {
|
if (_network_reconnect_attempts > 0 && std::chrono::steady_clock::now() > _network_reconnect) {
|
||||||
/* This means that we want to reconnect to the last host
|
Debug(net, 3, "Reconnect attempt #{}", _network_reconnect_attempts);
|
||||||
* We do this here, because it means that the network is really closed */
|
|
||||||
NetworkClientConnectGame(_settings_client.network.last_joined, COMPANY_SPECTATOR);
|
_network_reconnect_attempts--;
|
||||||
|
_network_reconnect_backoff = std::min(_network_reconnect_backoff * 2, std::chrono::seconds(30));
|
||||||
|
_network_reconnect = std::chrono::steady_clock::now() + _network_reconnect_backoff;
|
||||||
|
|
||||||
|
if (_network_reconnect_attempts == 0) {
|
||||||
|
ShowErrorMessage(STR_NETWORK_MESSAGE_SERVER_REBOOT_REJOIN_FAILED, INVALID_STRING_ID, WL_ERROR);
|
||||||
|
} else {
|
||||||
|
/* Show that we are reconnecting the first time we do an attempt.
|
||||||
|
* We have to do it this late, as switching to the main menu closes
|
||||||
|
* all errors (except critical, but this isn't critical). */
|
||||||
|
if (_network_reconnect_attempts == NETWORK_RECONNECT_ATTEMPTS - 1) {
|
||||||
|
ShowErrorMessage(STR_NETWORK_MESSAGE_SERVER_REBOOT, INVALID_STRING_ID, WL_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the AskRelay window is open, don't start a new connect. */
|
||||||
|
if (FindWindowByClass(WC_NETWORK_ASK_RELAY) == nullptr) {
|
||||||
|
NetworkClientConnectGame(_settings_client.network.last_joined, COMPANY_SPECTATOR);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Singleplayer */
|
/* Singleplayer */
|
||||||
StateGameLoop();
|
StateGameLoop();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue