diff options
author | Patric Stout <truebrain@openttd.org> | 2021-02-27 10:50:41 +0100 |
---|---|---|
committer | Patric Stout <github@truebrain.nl> | 2021-02-28 12:27:04 +0100 |
commit | 8d199b1bbc2f7f0db98b47b709b75ff97b23e730 (patch) | |
tree | 29c578948f8d26f0a1d34e7cb4f641b5fb0c80a2 | |
parent | 3677418225c069b7b6b16f3d0855a772f0e47c0a (diff) | |
download | openttd-8d199b1bbc2f7f0db98b47b709b75ff97b23e730.tar.xz |
Fix: [Network] send map to next client if current client disconnects
Also terminate creating of the savegame, as the client is gone,
there really is no need for that anymore.
-rw-r--r-- | src/network/network_server.cpp | 59 | ||||
-rw-r--r-- | src/network/network_server.h | 2 |
2 files changed, 40 insertions, 21 deletions
diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp index 9a0c6a3bb..bef5a5350 100644 --- a/src/network/network_server.cpp +++ b/src/network/network_server.cpp @@ -281,6 +281,16 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::CloseConnection(NetworkRecvSta } } + /* If we were transfering a map to this client, stop the savegame creation + * process and queue the next client to receive the map. */ + if (this->status == STATUS_MAP) { + /* Ensure the saving of the game is stopped too. */ + this->savegame->Destroy(); + this->savegame = nullptr; + + this->CheckNextClientToSendMap(this); + } + NetworkAdminClientError(this->client_id, NETWORK_ERROR_CONNECTION_LOST); DEBUG(net, 1, "Closed client connection %d", this->client_id); @@ -565,6 +575,33 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendWait() return NETWORK_RECV_STATUS_OKAY; } +void ServerNetworkGameSocketHandler::CheckNextClientToSendMap(NetworkClientSocket *ignore_cs) +{ + /* Find the best candidate for joining, i.e. the first joiner. */ + NetworkClientSocket *best = nullptr; + for (NetworkClientSocket *new_cs : NetworkClientSocket::Iterate()) { + if (ignore_cs == new_cs) continue; + + if (new_cs->status == STATUS_MAP_WAIT) { + if (best == nullptr || best->GetInfo()->join_date > new_cs->GetInfo()->join_date || (best->GetInfo()->join_date == new_cs->GetInfo()->join_date && best->client_id > new_cs->client_id)) { + best = new_cs; + } + } + } + + /* Is there someone else to join? */ + if (best != nullptr) { + /* Let the first start joining. */ + best->status = STATUS_AUTHORIZED; + best->SendMap(); + + /* And update the rest. */ + for (NetworkClientSocket *new_cs : NetworkClientSocket::Iterate()) { + if (new_cs->status == STATUS_MAP_WAIT) new_cs->SendWait(); + } + } +} + /** This sends the map to the client */ NetworkRecvStatus ServerNetworkGameSocketHandler::SendMap() { @@ -620,27 +657,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendMap() * to send it is ready (maybe that happens like never ;)) */ this->status = STATUS_DONE_MAP; - /* Find the best candidate for joining, i.e. the first joiner. */ - NetworkClientSocket *best = nullptr; - for (NetworkClientSocket *new_cs : NetworkClientSocket::Iterate()) { - if (new_cs->status == STATUS_MAP_WAIT) { - if (best == nullptr || best->GetInfo()->join_date > new_cs->GetInfo()->join_date || (best->GetInfo()->join_date == new_cs->GetInfo()->join_date && best->client_id > new_cs->client_id)) { - best = new_cs; - } - } - } - - /* Is there someone else to join? */ - if (best != nullptr) { - /* Let the first start joining. */ - best->status = STATUS_AUTHORIZED; - best->SendMap(); - - /* And update the rest. */ - for (NetworkClientSocket *new_cs : NetworkClientSocket::Iterate()) { - if (new_cs->status == STATUS_MAP_WAIT) new_cs->SendWait(); - } - } + this->CheckNextClientToSendMap(); } switch (this->SendPackets()) { diff --git a/src/network/network_server.h b/src/network/network_server.h index 3dfcf5594..4e099a7fa 100644 --- a/src/network/network_server.h +++ b/src/network/network_server.h @@ -80,6 +80,8 @@ public: NetworkRecvStatus CloseConnection(NetworkRecvStatus status) override; void GetClientName(char *client_name, const char *last) const; + void CheckNextClientToSendMap(NetworkClientSocket *ignore_cs = nullptr); + NetworkRecvStatus SendMap(); NetworkRecvStatus SendErrorQuit(ClientID client_id, NetworkErrorCode errorno); NetworkRecvStatus SendQuit(ClientID client_id); |