summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/network/core/tcp_game.cpp3
-rw-r--r--src/network/core/tcp_game.h1
-rw-r--r--src/network/network.cpp56
-rw-r--r--src/network/network_client.cpp22
-rw-r--r--src/network/network_client.h2
-rw-r--r--src/network/network_internal.h1
-rw-r--r--src/network/network_server.cpp71
-rw-r--r--src/network/network_server.h2
8 files changed, 88 insertions, 70 deletions
diff --git a/src/network/core/tcp_game.cpp b/src/network/core/tcp_game.cpp
index b0db78eb7..037cb42fc 100644
--- a/src/network/core/tcp_game.cpp
+++ b/src/network/core/tcp_game.cpp
@@ -47,7 +47,6 @@ NetworkGameSocketHandler::NetworkGameSocketHandler(SOCKET s)
* For clients: close connection and drop back to main-menu
* For servers: close connection and that is it
* @return the new status
- * TODO: needs to be splitted when using client and server socket packets
*/
NetworkRecvStatus NetworkGameSocketHandler::CloseConnection(bool error)
{
@@ -61,7 +60,7 @@ NetworkRecvStatus NetworkGameSocketHandler::CloseConnection(bool error)
return NETWORK_RECV_STATUS_CONN_LOST;
}
- return NetworkCloseClient(this, error ? NETWORK_RECV_STATUS_SERVER_ERROR : NETWORK_RECV_STATUS_CONN_LOST);
+ return this->CloseConnection(error ? NETWORK_RECV_STATUS_SERVER_ERROR : NETWORK_RECV_STATUS_CONN_LOST);
}
diff --git a/src/network/core/tcp_game.h b/src/network/core/tcp_game.h
index f083396e8..5ab814bae 100644
--- a/src/network/core/tcp_game.h
+++ b/src/network/core/tcp_game.h
@@ -179,6 +179,7 @@ public:
CommandQueue outgoing_queue; ///< The command-queue awaiting delivery
NetworkRecvStatus CloseConnection(bool error = true);
+ virtual NetworkRecvStatus CloseConnection(NetworkRecvStatus status) = 0;
virtual ~NetworkGameSocketHandler() {}
inline void SetInfo(NetworkClientInfo *info) { assert(info != NULL && this->info == NULL); this->info = info; }
diff --git a/src/network/network.cpp b/src/network/network.cpp
index f874be3e9..6d19dc738 100644
--- a/src/network/network.cpp
+++ b/src/network/network.cpp
@@ -91,7 +91,7 @@ extern NetworkUDPSocketHandler *_udp_master_socket; ///< udp master socket
static SocketList _listensockets;
/* The amount of clients connected */
-static byte _network_clients_connected = 0;
+byte _network_clients_connected = 0;
/* Some externs / forwards */
extern void StateGameLoop();
@@ -262,7 +262,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, res);
+ cs->CloseConnection(res);
_networking = false;
DeleteWindowById(WC_NETWORK_STATUS_WINDOW, 0);
@@ -283,7 +283,7 @@ static void NetworkClientError(NetworkRecvStatus res, NetworkClientSocket *cs)
}
_switch_mode = SM_MENU;
- NetworkCloseClient(cs, res);
+ cs->CloseConnection(res);
_networking = false;
}
@@ -494,54 +494,6 @@ static NetworkClientSocket *NetworkAllocClient(SOCKET s)
return new ServerNetworkGameSocketHandler(s);
}
-/* Close a connection */
-NetworkRecvStatus NetworkCloseClient(NetworkClientSocket *cs, NetworkRecvStatus status)
-{
- assert(status != NETWORK_RECV_STATUS_OKAY);
- /*
- * Sending a message just before leaving the game calls cs->Send_Packets.
- * This might invoke this function, which means that when we close the
- * connection after cs->Send_Packets we will close an already closed
- * connection. This handles that case gracefully without having to make
- * that code any more complex or more aware of the validity of the socket.
- */
- if (cs->sock == INVALID_SOCKET) return status;
-
- if (status != NETWORK_RECV_STATUS_CONN_LOST && !cs->HasClientQuit() && _network_server && cs->status >= STATUS_AUTHORIZED) {
- /* We did not receive a leave message from this client... */
- char client_name[NETWORK_CLIENT_NAME_LENGTH];
- NetworkClientSocket *new_cs;
-
- NetworkGetClientName(client_name, sizeof(client_name), cs);
-
- NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, NULL, STR_NETWORK_ERROR_CLIENT_CONNECTION_LOST);
-
- /* Inform other clients of this... strange leaving ;) */
- FOR_ALL_CLIENT_SOCKETS(new_cs) {
- if (new_cs->status > STATUS_AUTHORIZED && cs != new_cs) {
- SEND_COMMAND(PACKET_SERVER_ERROR_QUIT)(new_cs, cs->client_id, NETWORK_ERROR_CONNECTION_LOST);
- }
- }
- }
-
- DEBUG(net, 1, "Closed client connection %d", cs->client_id);
-
- if (_network_server) {
- /* We just lost one client :( */
- if (cs->status >= STATUS_AUTHORIZED) _network_game_info.clients_on--;
- _network_clients_connected--;
-
- SetWindowDirty(WC_CLIENT_LIST, 0);
- }
-
- cs->Send_Packets(true);
-
- delete cs->GetInfo();
- delete cs;
-
- return status;
-}
-
/* For the server, to accept new clients */
static void NetworkAcceptClients(SOCKET ls)
{
@@ -636,7 +588,7 @@ static void NetworkClose()
MyClient::SendQuit();
cs->Send_Packets();
}
- NetworkCloseClient(cs, NETWORK_RECV_STATUS_CONN_LOST);
+ cs->CloseConnection(NETWORK_RECV_STATUS_CONN_LOST);
}
if (_network_server) {
diff --git a/src/network/network_client.cpp b/src/network/network_client.cpp
index 619a43ebf..929d58763 100644
--- a/src/network/network_client.cpp
+++ b/src/network/network_client.cpp
@@ -51,6 +51,28 @@ ClientNetworkGameSocketHandler::~ClientNetworkGameSocketHandler()
ClientNetworkGameSocketHandler::my_client = NULL;
}
+NetworkRecvStatus ClientNetworkGameSocketHandler::CloseConnection(NetworkRecvStatus status)
+{
+ assert(status != NETWORK_RECV_STATUS_OKAY);
+ /*
+ * Sending a message just before leaving the game calls cs->Send_Packets.
+ * This might invoke this function, which means that when we close the
+ * connection after cs->Send_Packets we will close an already closed
+ * connection. This handles that case gracefully without having to make
+ * that code any more complex or more aware of the validity of the socket.
+ */
+ if (this->sock == INVALID_SOCKET) return status;
+
+ DEBUG(net, 1, "Closed client connection %d", this->client_id);
+
+ this->Send_Packets(true);
+
+ delete this->GetInfo();
+ delete this;
+
+ return status;
+}
+
/** Our client's connection. */
ClientNetworkGameSocketHandler * ClientNetworkGameSocketHandler::my_client = NULL;
diff --git a/src/network/network_client.h b/src/network/network_client.h
index 4e9934cce..5b00aba0f 100644
--- a/src/network/network_client.h
+++ b/src/network/network_client.h
@@ -53,6 +53,8 @@ public:
ClientNetworkGameSocketHandler(SOCKET s);
~ClientNetworkGameSocketHandler();
+ NetworkRecvStatus CloseConnection(NetworkRecvStatus status);
+
static NetworkRecvStatus SendCompanyInformationQuery();
static NetworkRecvStatus SendJoin();
diff --git a/src/network/network_internal.h b/src/network/network_internal.h
index b492e61c3..c4ef68dda 100644
--- a/src/network/network_internal.h
+++ b/src/network/network_internal.h
@@ -166,7 +166,6 @@ void NetworkFreeLocalCommandQueue();
void NetworkSyncCommandQueue(NetworkClientSocket *cs);
/* from network.c */
-NetworkRecvStatus NetworkCloseClient(NetworkClientSocket *cs, NetworkRecvStatus status);
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 5f7601fb7..b5189da0e 100644
--- a/src/network/network_server.cpp
+++ b/src/network/network_server.cpp
@@ -63,6 +63,51 @@ ServerNetworkGameSocketHandler::~ServerNetworkGameSocketHandler()
OrderBackup::ResetUser(this->client_id);
}
+NetworkRecvStatus ServerNetworkGameSocketHandler::CloseConnection(NetworkRecvStatus status)
+{
+ assert(status != NETWORK_RECV_STATUS_OKAY);
+ /*
+ * Sending a message just before leaving the game calls cs->Send_Packets.
+ * This might invoke this function, which means that when we close the
+ * connection after cs->Send_Packets we will close an already closed
+ * connection. This handles that case gracefully without having to make
+ * that code any more complex or more aware of the validity of the socket.
+ */
+ if (this->sock == INVALID_SOCKET) return status;
+
+ if (status != NETWORK_RECV_STATUS_CONN_LOST && !this->HasClientQuit() && this->status >= STATUS_AUTHORIZED) {
+ /* We did not receive a leave message from this client... */
+ char client_name[NETWORK_CLIENT_NAME_LENGTH];
+ NetworkClientSocket *new_cs;
+
+ NetworkGetClientName(client_name, sizeof(client_name), this);
+
+ NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, NULL, STR_NETWORK_ERROR_CLIENT_CONNECTION_LOST);
+
+ /* Inform other clients of this... strange leaving ;) */
+ FOR_ALL_CLIENT_SOCKETS(new_cs) {
+ if (new_cs->status > STATUS_AUTHORIZED && this != new_cs) {
+ SEND_COMMAND(PACKET_SERVER_ERROR_QUIT)(new_cs, this->client_id, NETWORK_ERROR_CONNECTION_LOST);
+ }
+ }
+ }
+
+ DEBUG(net, 1, "Closed client connection %d", this->client_id);
+
+ /* We just lost one client :( */
+ if (this->status >= STATUS_AUTHORIZED) _network_game_info.clients_on--;
+ extern byte _network_clients_connected;
+ _network_clients_connected--;
+
+ SetWindowDirty(WC_CLIENT_LIST, 0);
+
+ this->Send_Packets(true);
+
+ delete this->GetInfo();
+ delete this;
+
+ return status;
+}
static void NetworkHandleCommandQueue(NetworkClientSocket *cs);
@@ -205,7 +250,7 @@ DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_ERROR)(NetworkClientSocket *cs, Netw
}
/* The client made a mistake, so drop his connection now! */
- return NetworkCloseClient(cs, NETWORK_RECV_STATUS_SERVER_ERROR);
+ return cs->CloseConnection(NETWORK_RECV_STATUS_SERVER_ERROR);
}
DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_CHECK_NEWGRFS)(NetworkClientSocket *cs)
@@ -245,7 +290,7 @@ DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_NEED_GAME_PASSWORD)(NetworkClientSoc
*/
/* Invalid packet when status is STATUS_AUTH_GAME or higher */
- if (cs->status >= STATUS_AUTH_GAME) return NetworkCloseClient(cs, NETWORK_RECV_STATUS_MALFORMED_PACKET);
+ if (cs->status >= STATUS_AUTH_GAME) return cs->CloseConnection(NETWORK_RECV_STATUS_MALFORMED_PACKET);
cs->status = STATUS_AUTH_GAME;
@@ -265,7 +310,7 @@ DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_NEED_COMPANY_PASSWORD)(NetworkClient
*/
/* Invalid packet when status is STATUS_AUTH_COMPANY or higher */
- if (cs->status >= STATUS_AUTH_COMPANY) return NetworkCloseClient(cs, NETWORK_RECV_STATUS_MALFORMED_PACKET);
+ if (cs->status >= STATUS_AUTH_COMPANY) return cs->CloseConnection(NETWORK_RECV_STATUS_MALFORMED_PACKET);
cs->status = STATUS_AUTH_COMPANY;
@@ -289,7 +334,7 @@ DEF_SERVER_SEND_COMMAND(PACKET_SERVER_WELCOME)
NetworkClientSocket *new_cs;
/* Invalid packet when status is AUTH or higher */
- if (cs->status >= STATUS_AUTHORIZED) return NetworkCloseClient(cs, NETWORK_RECV_STATUS_MALFORMED_PACKET);
+ if (cs->status >= STATUS_AUTHORIZED) return cs->CloseConnection(NETWORK_RECV_STATUS_MALFORMED_PACKET);
cs->status = STATUS_AUTHORIZED;
_network_game_info.clients_on++;
@@ -991,8 +1036,7 @@ DEF_GAME_RECEIVE_COMMAND(Server, PACKET_CLIENT_ERROR)
/* The client was never joined.. thank the client for the packet, but ignore it */
if (this->status < STATUS_DONE_MAP || this->HasClientQuit()) {
- this->CloseConnection();
- return NETWORK_RECV_STATUS_CONN_LOST;
+ return this->CloseConnection(NETWORK_RECV_STATUS_CONN_LOST);
}
NetworkGetClientName(client_name, sizeof(client_name), this);
@@ -1010,8 +1054,7 @@ DEF_GAME_RECEIVE_COMMAND(Server, PACKET_CLIENT_ERROR)
}
}
- this->CloseConnection(false);
- return NETWORK_RECV_STATUS_CONN_LOST;
+ return this->CloseConnection(NETWORK_RECV_STATUS_CONN_LOST);
}
DEF_GAME_RECEIVE_COMMAND(Server, PACKET_CLIENT_QUIT)
@@ -1023,8 +1066,7 @@ DEF_GAME_RECEIVE_COMMAND(Server, PACKET_CLIENT_QUIT)
/* The client was never joined.. thank the client for the packet, but ignore it */
if (this->status < STATUS_DONE_MAP || this->HasClientQuit()) {
- this->CloseConnection();
- return NETWORK_RECV_STATUS_CONN_LOST;
+ return this->CloseConnection(NETWORK_RECV_STATUS_CONN_LOST);
}
NetworkGetClientName(client_name, sizeof(client_name), this);
@@ -1037,8 +1079,7 @@ DEF_GAME_RECEIVE_COMMAND(Server, PACKET_CLIENT_QUIT)
}
}
- this->CloseConnection(false);
- return NETWORK_RECV_STATUS_CONN_LOST;
+ return this->CloseConnection(NETWORK_RECV_STATUS_CONN_LOST);
}
DEF_GAME_RECEIVE_COMMAND(Server, PACKET_CLIENT_ACK)
@@ -1579,7 +1620,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, NETWORK_RECV_STATUS_SERVER_ERROR);
+ cs->CloseConnection(NETWORK_RECV_STATUS_SERVER_ERROR);
continue;
}
@@ -1595,13 +1636,13 @@ void NetworkServer_Tick(bool send_frame)
uint 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, NETWORK_RECV_STATUS_SERVER_ERROR);
+ cs->CloseConnection(NETWORK_RECV_STATUS_SERVER_ERROR);
}
} else if (cs->status == STATUS_INACTIVE) {
uint 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, NETWORK_RECV_STATUS_SERVER_ERROR);
+ cs->CloseConnection(NETWORK_RECV_STATUS_SERVER_ERROR);
}
}
diff --git a/src/network/network_server.h b/src/network/network_server.h
index 037f22a71..2e5e3fc49 100644
--- a/src/network/network_server.h
+++ b/src/network/network_server.h
@@ -38,6 +38,8 @@ protected:
public:
ServerNetworkGameSocketHandler(SOCKET s);
~ServerNetworkGameSocketHandler();
+
+ NetworkRecvStatus CloseConnection(NetworkRecvStatus status);
};
DEF_SERVER_SEND_COMMAND(PACKET_SERVER_MAP);