1
0
Fork 0

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.
pull/8766/head
Patric Stout 2021-02-27 10:50:41 +01:00 committed by Patric Stout
parent 3677418225
commit 8d199b1bbc
2 changed files with 40 additions and 21 deletions

View File

@ -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); NetworkAdminClientError(this->client_id, NETWORK_ERROR_CONNECTION_LOST);
DEBUG(net, 1, "Closed client connection %d", this->client_id); DEBUG(net, 1, "Closed client connection %d", this->client_id);
@ -565,6 +575,33 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendWait()
return NETWORK_RECV_STATUS_OKAY; 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 */ /** This sends the map to the client */
NetworkRecvStatus ServerNetworkGameSocketHandler::SendMap() NetworkRecvStatus ServerNetworkGameSocketHandler::SendMap()
{ {
@ -620,27 +657,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendMap()
* to send it is ready (maybe that happens like never ;)) */ * to send it is ready (maybe that happens like never ;)) */
this->status = STATUS_DONE_MAP; this->status = STATUS_DONE_MAP;
/* Find the best candidate for joining, i.e. the first joiner. */ this->CheckNextClientToSendMap();
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();
}
}
} }
switch (this->SendPackets()) { switch (this->SendPackets()) {

View File

@ -80,6 +80,8 @@ public:
NetworkRecvStatus CloseConnection(NetworkRecvStatus status) override; NetworkRecvStatus CloseConnection(NetworkRecvStatus status) override;
void GetClientName(char *client_name, const char *last) const; void GetClientName(char *client_name, const char *last) const;
void CheckNextClientToSendMap(NetworkClientSocket *ignore_cs = nullptr);
NetworkRecvStatus SendMap(); NetworkRecvStatus SendMap();
NetworkRecvStatus SendErrorQuit(ClientID client_id, NetworkErrorCode errorno); NetworkRecvStatus SendErrorQuit(ClientID client_id, NetworkErrorCode errorno);
NetworkRecvStatus SendQuit(ClientID client_id); NetworkRecvStatus SendQuit(ClientID client_id);