mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-03-08 23:19:40 +00:00
Fix: [Network] clients leaving because of broken connections was not broadcasted (#9238)
The code mixed up "client has quit but we already told everyone" with "client lost connection, handle this". Split up those two signals: - CLIENT_QUIT means we told everyone and the connection is now dead - CONNECTION_LIST means we should tell everyone we lost a client
This commit is contained in:
parent
2e429ee485
commit
36e22f3a7b
@ -20,16 +20,17 @@ void NetworkCoreShutdown();
|
|||||||
|
|
||||||
/** Status of a network client; reasons why a client has quit */
|
/** Status of a network client; reasons why a client has quit */
|
||||||
enum NetworkRecvStatus {
|
enum NetworkRecvStatus {
|
||||||
NETWORK_RECV_STATUS_OKAY, ///< Everything is okay
|
NETWORK_RECV_STATUS_OKAY, ///< Everything is okay.
|
||||||
NETWORK_RECV_STATUS_DESYNC, ///< A desync did occur
|
NETWORK_RECV_STATUS_DESYNC, ///< A desync did occur.
|
||||||
NETWORK_RECV_STATUS_NEWGRF_MISMATCH, ///< We did not have the required NewGRFs
|
NETWORK_RECV_STATUS_NEWGRF_MISMATCH, ///< We did not have the required NewGRFs.
|
||||||
NETWORK_RECV_STATUS_SAVEGAME, ///< Something went wrong (down)loading the savegame
|
NETWORK_RECV_STATUS_SAVEGAME, ///< Something went wrong (down)loading the savegame.
|
||||||
NETWORK_RECV_STATUS_CONN_LOST, ///< The connection is 'just' lost
|
NETWORK_RECV_STATUS_CLIENT_QUIT, ///< The connection is lost gracefully. Other clients are already informed of this leaving client.
|
||||||
NETWORK_RECV_STATUS_MALFORMED_PACKET, ///< We apparently send a malformed packet
|
NETWORK_RECV_STATUS_MALFORMED_PACKET, ///< We apparently send a malformed packet.
|
||||||
NETWORK_RECV_STATUS_SERVER_ERROR, ///< The server told us we made an error
|
NETWORK_RECV_STATUS_SERVER_ERROR, ///< The server told us we made an error.
|
||||||
NETWORK_RECV_STATUS_SERVER_FULL, ///< The server is full
|
NETWORK_RECV_STATUS_SERVER_FULL, ///< The server is full.
|
||||||
NETWORK_RECV_STATUS_SERVER_BANNED, ///< The server has banned us
|
NETWORK_RECV_STATUS_SERVER_BANNED, ///< The server has banned us.
|
||||||
NETWORK_RECV_STATUS_CLOSE_QUERY, ///< Done querying the server
|
NETWORK_RECV_STATUS_CLOSE_QUERY, ///< Done querying the server.
|
||||||
|
NETWORK_RECV_STATUS_CONNECTION_LOST, ///< The connection is lost unexpectedly.
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Forward declaration due to circular dependencies */
|
/** Forward declaration due to circular dependencies */
|
||||||
|
@ -41,7 +41,7 @@ NetworkAdminSocketHandler::~NetworkAdminSocketHandler()
|
|||||||
NetworkRecvStatus NetworkAdminSocketHandler::CloseConnection(bool error)
|
NetworkRecvStatus NetworkAdminSocketHandler::CloseConnection(bool error)
|
||||||
{
|
{
|
||||||
delete this;
|
delete this;
|
||||||
return NETWORK_RECV_STATUS_CONN_LOST;
|
return NETWORK_RECV_STATUS_CLIENT_QUIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -48,10 +48,10 @@ NetworkRecvStatus NetworkGameSocketHandler::CloseConnection(bool error)
|
|||||||
_networking = false;
|
_networking = false;
|
||||||
ShowErrorMessage(STR_NETWORK_ERROR_LOSTCONNECTION, INVALID_STRING_ID, WL_CRITICAL);
|
ShowErrorMessage(STR_NETWORK_ERROR_LOSTCONNECTION, INVALID_STRING_ID, WL_CRITICAL);
|
||||||
|
|
||||||
return NETWORK_RECV_STATUS_CONN_LOST;
|
return NETWORK_RECV_STATUS_CLIENT_QUIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this->CloseConnection(error ? NETWORK_RECV_STATUS_SERVER_ERROR : NETWORK_RECV_STATUS_CONN_LOST);
|
return this->CloseConnection(NETWORK_RECV_STATUS_CONNECTION_LOST);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -585,13 +585,13 @@ void NetworkClose(bool close_admins)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) {
|
for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) {
|
||||||
cs->CloseConnection(NETWORK_RECV_STATUS_CONN_LOST);
|
cs->CloseConnection(NETWORK_RECV_STATUS_CLIENT_QUIT);
|
||||||
}
|
}
|
||||||
ServerNetworkGameSocketHandler::CloseListeners();
|
ServerNetworkGameSocketHandler::CloseListeners();
|
||||||
ServerNetworkAdminSocketHandler::CloseListeners();
|
ServerNetworkAdminSocketHandler::CloseListeners();
|
||||||
} else if (MyClient::my_client != nullptr) {
|
} else if (MyClient::my_client != nullptr) {
|
||||||
MyClient::SendQuit();
|
MyClient::SendQuit();
|
||||||
MyClient::my_client->CloseConnection(NETWORK_RECV_STATUS_CONN_LOST);
|
MyClient::my_client->CloseConnection(NETWORK_RECV_STATUS_CLIENT_QUIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
TCPConnecter::KillAll();
|
TCPConnecter::KillAll();
|
||||||
|
@ -656,7 +656,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_CLIENT_INFO(Pac
|
|||||||
p->Recv_string(name, sizeof(name));
|
p->Recv_string(name, sizeof(name));
|
||||||
|
|
||||||
if (this->status < STATUS_AUTHORIZED) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
|
if (this->status < STATUS_AUTHORIZED) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
|
||||||
if (this->HasClientQuit()) return NETWORK_RECV_STATUS_CONN_LOST;
|
if (this->HasClientQuit()) return NETWORK_RECV_STATUS_CLIENT_QUIT;
|
||||||
/* The server validates the name when receiving it from clients, so when it is wrong
|
/* The server validates the name when receiving it from clients, so when it is wrong
|
||||||
* here something went really wrong. In the best case the packet got malformed on its
|
* here something went really wrong. In the best case the packet got malformed on its
|
||||||
* way too us, in the worst case the server is broken or compromised. */
|
* way too us, in the worst case the server is broken or compromised. */
|
||||||
|
@ -256,7 +256,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::CloseConnection(NetworkRecvSta
|
|||||||
*/
|
*/
|
||||||
if (this->sock == INVALID_SOCKET) return status;
|
if (this->sock == INVALID_SOCKET) return status;
|
||||||
|
|
||||||
if (status != NETWORK_RECV_STATUS_CONN_LOST && status != NETWORK_RECV_STATUS_SERVER_ERROR && !this->HasClientQuit() && this->status >= STATUS_AUTHORIZED) {
|
if (status != NETWORK_RECV_STATUS_CLIENT_QUIT && status != NETWORK_RECV_STATUS_SERVER_ERROR && !this->HasClientQuit() && this->status >= STATUS_AUTHORIZED) {
|
||||||
/* We did not receive a leave message from this client... */
|
/* We did not receive a leave message from this client... */
|
||||||
char client_name[NETWORK_CLIENT_NAME_LENGTH];
|
char client_name[NETWORK_CLIENT_NAME_LENGTH];
|
||||||
|
|
||||||
@ -893,7 +893,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_JOIN(Packet *p)
|
|||||||
p->Recv_string(name, sizeof(name));
|
p->Recv_string(name, sizeof(name));
|
||||||
playas = (Owner)p->Recv_uint8();
|
playas = (Owner)p->Recv_uint8();
|
||||||
|
|
||||||
if (this->HasClientQuit()) return NETWORK_RECV_STATUS_CONN_LOST;
|
if (this->HasClientQuit()) return NETWORK_RECV_STATUS_CLIENT_QUIT;
|
||||||
|
|
||||||
/* join another company does not affect these values */
|
/* join another company does not affect these values */
|
||||||
switch (playas) {
|
switch (playas) {
|
||||||
@ -1077,7 +1077,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_COMMAND(Packet
|
|||||||
CommandPacket cp;
|
CommandPacket cp;
|
||||||
const char *err = this->ReceiveCommand(p, &cp);
|
const char *err = this->ReceiveCommand(p, &cp);
|
||||||
|
|
||||||
if (this->HasClientQuit()) return NETWORK_RECV_STATUS_CONN_LOST;
|
if (this->HasClientQuit()) return NETWORK_RECV_STATUS_CLIENT_QUIT;
|
||||||
|
|
||||||
NetworkClientInfo *ci = this->GetInfo();
|
NetworkClientInfo *ci = this->GetInfo();
|
||||||
|
|
||||||
@ -1136,7 +1136,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_ERROR(Packet *p
|
|||||||
|
|
||||||
/* The client was never joined.. thank the client for the packet, but ignore it */
|
/* The client was never joined.. thank the client for the packet, but ignore it */
|
||||||
if (this->status < STATUS_DONE_MAP || this->HasClientQuit()) {
|
if (this->status < STATUS_DONE_MAP || this->HasClientQuit()) {
|
||||||
return this->CloseConnection(NETWORK_RECV_STATUS_CONN_LOST);
|
return this->CloseConnection(NETWORK_RECV_STATUS_CLIENT_QUIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
this->GetClientName(client_name, lastof(client_name));
|
this->GetClientName(client_name, lastof(client_name));
|
||||||
@ -1156,7 +1156,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_ERROR(Packet *p
|
|||||||
|
|
||||||
NetworkAdminClientError(this->client_id, errorno);
|
NetworkAdminClientError(this->client_id, errorno);
|
||||||
|
|
||||||
return this->CloseConnection(NETWORK_RECV_STATUS_CONN_LOST);
|
return this->CloseConnection(NETWORK_RECV_STATUS_CLIENT_QUIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_QUIT(Packet *p)
|
NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_QUIT(Packet *p)
|
||||||
@ -1167,7 +1167,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_QUIT(Packet *p)
|
|||||||
|
|
||||||
/* The client was never joined.. thank the client for the packet, but ignore it */
|
/* The client was never joined.. thank the client for the packet, but ignore it */
|
||||||
if (this->status < STATUS_DONE_MAP || this->HasClientQuit()) {
|
if (this->status < STATUS_DONE_MAP || this->HasClientQuit()) {
|
||||||
return this->CloseConnection(NETWORK_RECV_STATUS_CONN_LOST);
|
return this->CloseConnection(NETWORK_RECV_STATUS_CLIENT_QUIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
this->GetClientName(client_name, lastof(client_name));
|
this->GetClientName(client_name, lastof(client_name));
|
||||||
@ -1182,7 +1182,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_QUIT(Packet *p)
|
|||||||
|
|
||||||
NetworkAdminClientQuit(this->client_id);
|
NetworkAdminClientQuit(this->client_id);
|
||||||
|
|
||||||
return this->CloseConnection(NETWORK_RECV_STATUS_CONN_LOST);
|
return this->CloseConnection(NETWORK_RECV_STATUS_CLIENT_QUIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_ACK(Packet *p)
|
NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_ACK(Packet *p)
|
||||||
@ -1412,7 +1412,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_SET_NAME(Packet
|
|||||||
p->Recv_string(client_name, sizeof(client_name));
|
p->Recv_string(client_name, sizeof(client_name));
|
||||||
ci = this->GetInfo();
|
ci = this->GetInfo();
|
||||||
|
|
||||||
if (this->HasClientQuit()) return NETWORK_RECV_STATUS_CONN_LOST;
|
if (this->HasClientQuit()) return NETWORK_RECV_STATUS_CLIENT_QUIT;
|
||||||
|
|
||||||
if (ci != nullptr) {
|
if (ci != nullptr) {
|
||||||
if (!NetworkIsValidClientName(client_name)) {
|
if (!NetworkIsValidClientName(client_name)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user