From 9b156c1bd433fd231868a70dad719c6972858072 Mon Sep 17 00:00:00 2001 From: rubidium Date: Fri, 19 Jun 2009 20:26:18 +0000 Subject: [PATCH] (svn r16601) -Fix [FS#2880]: try 2... hopefully better this time --- src/network/core/core.h | 3 ++- src/network/core/tcp.cpp | 4 ++-- src/network/core/tcp.h | 2 +- src/network/core/tcp_game.cpp | 4 ++-- src/network/core/tcp_game.h | 2 +- src/network/core/udp.cpp | 4 ++-- src/network/core/udp.h | 2 +- src/network/network.cpp | 15 ++++++++------- src/network/network_internal.h | 2 +- src/network/network_server.cpp | 20 +++++++------------- 10 files changed, 27 insertions(+), 31 deletions(-) diff --git a/src/network/core/core.h b/src/network/core/core.h index 4fca89f542..89c3164024 100644 --- a/src/network/core/core.h +++ b/src/network/core/core.h @@ -50,9 +50,10 @@ public: /** * Close the current connection; for TCP this will be mostly equivalent * to Close(), but for UDP it just means the packet has to be dropped. + * @param error Whether we quit under an error condition or not. * @return new status of the connection. */ - virtual NetworkRecvStatus CloseConnection() { this->has_quit = true; return NETWORK_RECV_STATUS_OKAY; } + virtual NetworkRecvStatus CloseConnection(bool error = true) { this->has_quit = true; return NETWORK_RECV_STATUS_OKAY; } /** * Whether the current client connected to the socket has quit. diff --git a/src/network/core/tcp.cpp b/src/network/core/tcp.cpp index a80defb4c0..dd79edbb5c 100644 --- a/src/network/core/tcp.cpp +++ b/src/network/core/tcp.cpp @@ -27,10 +27,10 @@ NetworkTCPSocketHandler::~NetworkTCPSocketHandler() this->sock = INVALID_SOCKET; } -NetworkRecvStatus NetworkTCPSocketHandler::CloseConnection() +NetworkRecvStatus NetworkTCPSocketHandler::CloseConnection(bool error) { this->writable = false; - NetworkSocketHandler::CloseConnection(); + NetworkSocketHandler::CloseConnection(error); /* Free all pending and partially received packets */ while (this->packet_queue != NULL) { diff --git a/src/network/core/tcp.h b/src/network/core/tcp.h index 7e49648132..1ced4bd6eb 100644 --- a/src/network/core/tcp.h +++ b/src/network/core/tcp.h @@ -29,7 +29,7 @@ public: */ bool IsConnected() const { return this->sock != INVALID_SOCKET; } - virtual NetworkRecvStatus CloseConnection(); + virtual NetworkRecvStatus CloseConnection(bool error = true); void Send_Packet(Packet *packet); bool Send_Packets(); bool IsPacketQueueEmpty(); diff --git a/src/network/core/tcp_game.cpp b/src/network/core/tcp_game.cpp index b4bb52190a..58447ad68d 100644 --- a/src/network/core/tcp_game.cpp +++ b/src/network/core/tcp_game.cpp @@ -50,7 +50,7 @@ NetworkClientSocket::~NetworkClientSocket() * @return the new status * TODO: needs to be splitted when using client and server socket packets */ -NetworkRecvStatus NetworkClientSocket::CloseConnection() +NetworkRecvStatus NetworkClientSocket::CloseConnection(bool error) { /* Clients drop back to the main menu */ if (!_network_server && _networking) { @@ -62,7 +62,7 @@ NetworkRecvStatus NetworkClientSocket::CloseConnection() return NETWORK_RECV_STATUS_CONN_LOST; } - NetworkCloseClient(this); + NetworkCloseClient(this, error); return NETWORK_RECV_STATUS_OKAY; } diff --git a/src/network/core/tcp_game.h b/src/network/core/tcp_game.h index 1d29b5a02e..69412fcd24 100644 --- a/src/network/core/tcp_game.h +++ b/src/network/core/tcp_game.h @@ -96,7 +96,7 @@ public: CommandPacket *command_queue; ///< The command-queue awaiting delivery - NetworkRecvStatus CloseConnection(); + NetworkRecvStatus CloseConnection(bool error = true); NetworkClientSocket(ClientID client_id = INVALID_CLIENT_ID); ~NetworkClientSocket(); diff --git a/src/network/core/udp.cpp b/src/network/core/udp.cpp index fec5bfb59b..9dbf8dea46 100644 --- a/src/network/core/udp.cpp +++ b/src/network/core/udp.cpp @@ -62,9 +62,9 @@ void NetworkUDPSocketHandler::Close() this->sockets.Clear(); } -NetworkRecvStatus NetworkUDPSocketHandler::CloseConnection() +NetworkRecvStatus NetworkUDPSocketHandler::CloseConnection(bool error) { - NetworkSocketHandler::CloseConnection(); + NetworkSocketHandler::CloseConnection(error); return NETWORK_RECV_STATUS_OKAY; } diff --git a/src/network/core/udp.h b/src/network/core/udp.h index 6f68c213d7..226cbb0dfa 100644 --- a/src/network/core/udp.h +++ b/src/network/core/udp.h @@ -110,7 +110,7 @@ protected: /** The opened sockets. */ SocketList sockets; - NetworkRecvStatus CloseConnection(); + NetworkRecvStatus CloseConnection(bool error = true); /* Declare all possible packets here. If it can be received by the * a specific handler, it has to be implemented. */ diff --git a/src/network/network.cpp b/src/network/network.cpp index 09ae9b7ae2..cff0f456c0 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -278,7 +278,7 @@ static void NetworkClientError(NetworkRecvStatus res, NetworkClientSocket *cs) /* We just want to close the connection.. */ if (res == NETWORK_RECV_STATUS_CLOSE_QUERY) { cs->NetworkSocketHandler::CloseConnection(); - NetworkCloseClient(cs); + NetworkCloseClient(cs, true); _networking = false; DeleteWindowById(WC_NETWORK_STATUS_WINDOW, 0); @@ -291,6 +291,7 @@ static void NetworkClientError(NetworkRecvStatus res, NetworkClientSocket *cs) case NETWORK_RECV_STATUS_NEWGRF_MISMATCH: errorno = NETWORK_ERROR_NEWGRF_MISMATCH; break; default: errorno = NETWORK_ERROR_GENERAL; break; } + /* This means we fucked up and the server closed the connection */ if (res != NETWORK_RECV_STATUS_SERVER_ERROR && res != NETWORK_RECV_STATUS_SERVER_FULL && res != NETWORK_RECV_STATUS_SERVER_BANNED) { @@ -298,7 +299,7 @@ static void NetworkClientError(NetworkRecvStatus res, NetworkClientSocket *cs) } _switch_mode = SM_MENU; - NetworkCloseClient(cs); + NetworkCloseClient(cs, true); _networking = false; } @@ -437,7 +438,7 @@ static NetworkClientSocket *NetworkAllocClient(SOCKET s) } /* Close a connection */ -void NetworkCloseClient(NetworkClientSocket *cs) +void NetworkCloseClient(NetworkClientSocket *cs, bool error) { /* * Sending a message just before leaving the game calls cs->Send_Packets. @@ -448,9 +449,7 @@ void NetworkCloseClient(NetworkClientSocket *cs) */ if (cs->sock == INVALID_SOCKET) return; - DEBUG(net, 1, "Closed client connection %d", cs->client_id); - - if (!cs->HasClientQuit() && _network_server && cs->status > STATUS_INACTIVE) { + if (error && !cs->HasClientQuit() && _network_server && cs->status > STATUS_INACTIVE) { /* We did not receive a leave message from this client... */ char client_name[NETWORK_CLIENT_NAME_LENGTH]; NetworkClientSocket *new_cs; @@ -467,6 +466,8 @@ void NetworkCloseClient(NetworkClientSocket *cs) } } + DEBUG(net, 1, "Closed client connection %d", cs->client_id); + /* When the client was PRE_ACTIVE, the server was in pause mode, so unpause */ if (cs->status == STATUS_PRE_ACTIVE && (_pause_mode & PM_PAUSED_JOIN)) { DoCommandP(0, PM_PAUSED_JOIN, 0, CMD_PAUSE); @@ -579,7 +580,7 @@ static void NetworkClose() SEND_COMMAND(PACKET_CLIENT_QUIT)(); cs->Send_Packets(); } - NetworkCloseClient(cs); + NetworkCloseClient(cs, false); } if (_network_server) { diff --git a/src/network/network_internal.h b/src/network/network_internal.h index 2f743775de..091b32782d 100644 --- a/src/network/network_internal.h +++ b/src/network/network_internal.h @@ -148,7 +148,7 @@ void NetworkExecuteLocalCommandQueue(); void NetworkFreeLocalCommandQueue(); /* from network.c */ -void NetworkCloseClient(NetworkClientSocket *cs); +void NetworkCloseClient(NetworkClientSocket *cs, bool error); void NetworkTextMessage(NetworkAction action, ConsoleColour colour, bool self_send, const char *name, const char *str = "", int64 data = 0); void NetworkGetClientName(char *clientname, size_t size, const NetworkClientSocket *cs); uint NetworkCalculateLag(const NetworkClientSocket *cs); diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp index 1ed4031ce8..8898854824 100644 --- a/src/network/network_server.cpp +++ b/src/network/network_server.cpp @@ -167,13 +167,13 @@ DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_ERROR)(NetworkClientSocket *cs, Netw DEBUG(net, 1, "Client %d made an error and has been disconnected. Reason: '%s'", cs->client_id, str); } - cs->CloseConnection(); + cs->CloseConnection(false); /* Make sure the data get's there before we close the connection */ cs->Send_Packets(); /* The client made a mistake, so drop his connection now! */ - NetworkCloseClient(cs); + NetworkCloseClient(cs, false); } DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_CHECK_NEWGRFS)(NetworkClientSocket *cs) @@ -963,7 +963,7 @@ DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_ERROR) } } - cs->CloseConnection(); + cs->CloseConnection(false); } DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_QUIT) @@ -989,13 +989,7 @@ DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_QUIT) } } - /* First tell we already closed the connection... - * ... then start the generic code to close the actual connection. - * This to make sure the 'connection lost' message is only shown - * when the connection got really lost and not when the client - * told us it was going to disconnect. */ - cs->NetworkSocketHandler::CloseConnection(); - cs->CloseConnection(); + cs->CloseConnection(false); } DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_ACK) @@ -1610,7 +1604,7 @@ void NetworkServer_Tick(bool send_frame) /* Client did still not report in after 4 game-day, drop him * (that is, the 3 of above, + 1 before any lag is counted) */ IConsolePrintF(CC_ERROR,"Client #%d is dropped because the client did not respond for more than 4 game-days", cs->client_id); - NetworkCloseClient(cs); + NetworkCloseClient(cs, true); continue; } @@ -1626,13 +1620,13 @@ void NetworkServer_Tick(bool send_frame) int lag = NetworkCalculateLag(cs); if (lag > _settings_client.network.max_join_time) { IConsolePrintF(CC_ERROR,"Client #%d is dropped because it took longer than %d ticks for him to join", cs->client_id, _settings_client.network.max_join_time); - NetworkCloseClient(cs); + NetworkCloseClient(cs, true); } } else if (cs->status == STATUS_INACTIVE) { int lag = NetworkCalculateLag(cs); if (lag > 4 * DAY_TICKS) { IConsolePrintF(CC_ERROR,"Client #%d is dropped because it took longer than %d ticks to start the joining process", cs->client_id, 4 * DAY_TICKS); - NetworkCloseClient(cs); + NetworkCloseClient(cs, true); } }