diff options
-rw-r--r-- | src/console_cmds.cpp | 4 | ||||
-rw-r--r-- | src/economy.cpp | 2 | ||||
-rw-r--r-- | src/network/core/core.h | 52 | ||||
-rw-r--r-- | src/network/core/packet.cpp | 23 | ||||
-rw-r--r-- | src/network/core/packet.h | 23 | ||||
-rw-r--r-- | src/network/core/tcp.cpp | 67 | ||||
-rw-r--r-- | src/network/core/tcp.h | 52 | ||||
-rw-r--r-- | src/network/core/udp.cpp | 96 | ||||
-rw-r--r-- | src/network/core/udp.h | 12 | ||||
-rw-r--r-- | src/network/network.cpp | 66 | ||||
-rw-r--r-- | src/network/network_client.cpp | 2 | ||||
-rw-r--r-- | src/network/network_client.h | 2 | ||||
-rw-r--r-- | src/network/network_data.cpp | 4 | ||||
-rw-r--r-- | src/network/network_data.h | 72 | ||||
-rw-r--r-- | src/network/network_server.cpp | 60 | ||||
-rw-r--r-- | src/network/network_server.h | 8 | ||||
-rw-r--r-- | src/network/network_udp.cpp | 31 |
17 files changed, 306 insertions, 270 deletions
diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp index 8f495e32b..21012e458 100644 --- a/src/console_cmds.cpp +++ b/src/console_cmds.cpp @@ -550,7 +550,7 @@ DEF_CONSOLE_CMD(ConStatus) "active" }; - const NetworkClientState *cs; + NetworkTCPSocketHandler *cs; if (argc == 0) { IConsoleHelp("List the status of all clients connected to the server. Usage 'status'"); @@ -672,7 +672,7 @@ DEF_CONSOLE_CMD(ConKick) DEF_CONSOLE_CMD(ConResetCompany) { const Player *p; - const NetworkClientState *cs; + NetworkTCPSocketHandler *cs; const NetworkClientInfo *ci; PlayerID index; diff --git a/src/economy.cpp b/src/economy.cpp index 452ee746e..1e631e415 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -427,7 +427,7 @@ static void PlayersCheckBankrupt(Player *p) /* The server has to handle all administrative issues, for example * updating and notifying all clients of what has happened */ if (_network_server) { - const NetworkClientState *cs; + NetworkTCPSocketHandler *cs; NetworkClientInfo *ci = NetworkFindClientInfoFromIndex(NETWORK_SERVER_INDEX); /* The server has just gone belly-up, mark it as spectator */ diff --git a/src/network/core/core.h b/src/network/core/core.h index c6dc05591..f88fd0116 100644 --- a/src/network/core/core.h +++ b/src/network/core/core.h @@ -5,9 +5,61 @@ #ifdef ENABLE_NETWORK +#include "os_abstraction.h" + bool NetworkCoreInitialize(void); void NetworkCoreShutdown(void); +typedef enum { + NETWORK_RECV_STATUS_OKAY, ///< Everything is okay + NETWORK_RECV_STATUS_DESYNC, ///< A desync did occur + NETWORK_RECV_STATUS_SAVEGAME, ///< Something went wrong (down)loading the savegame + NETWORK_RECV_STATUS_CONN_LOST, ///< The conection is 'just' lost + 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_FULL, ///< The server is full + NETWORK_RECV_STATUS_SERVER_BANNED, ///< The server has banned us + NETWORK_RECV_STATUS_CLOSE_QUERY, ///< Done quering the server +} NetworkRecvStatus; + +/** + * SocketHandler for all network sockets in OpenTTD. + */ +class NetworkSocketHandler { +public: + /* TODO: make socket & has_quit protected once the TCP stuff + *is in a real class too */ + bool has_quit; ///< Whether the current client has quit/send a bad packet + SOCKET sock; ///< The socket currently connected to +public: + NetworkSocketHandler() { this->sock = INVALID_SOCKET; this->has_quit = false; } + virtual ~NetworkSocketHandler() { this->Close(); } + + /** Really close the socket */ + virtual void Close() {} + + /** + * 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. + * @return new status of the connection. + */ + virtual NetworkRecvStatus CloseConnection() { this->has_quit = true; return NETWORK_RECV_STATUS_OKAY; } + + /** + * Whether this socket is currently bound to a socket. + * @return true when the socket is bound, false otherwise + */ + bool IsConnected() { return this->sock != INVALID_SOCKET; } + + /** + * Whether the current client connected to the socket has quit. + * In the case of UDP, for example, once a client quits (send bad + * data), the socket in not closed; only the packet is dropped. + * @return true when the current client has quit, false otherwise + */ + bool HasClientQuit() { return this->has_quit; } +}; + #endif /* ENABLE_NETWORK */ #endif /* NETWORK_CORE_H */ diff --git a/src/network/core/packet.cpp b/src/network/core/packet.cpp index 511e0c675..fe10af48f 100644 --- a/src/network/core/packet.cpp +++ b/src/network/core/packet.cpp @@ -6,7 +6,6 @@ #include "../../macros.h" #include "../../string.h" #include "../../helpers.hpp" -#include "../network_data.h" #include "packet.h" @@ -111,17 +110,15 @@ void NetworkSend_string(Packet *packet, const char* data) */ -extern NetworkRecvStatus CloseConnection(NetworkClientState *cs); - /** Is it safe to read from the packet, i.e. didn't we run over the buffer ? */ -static inline bool CanReadFromPacket(NetworkClientState *cs, const Packet *packet, const uint bytes_to_read) +static inline bool CanReadFromPacket(NetworkSocketHandler *cs, const Packet *packet, const uint bytes_to_read) { - /* Don't allow reading from a closed socket */ - if (HasClientQuit(cs)) return false; + /* Don't allow reading from a quit client/client who send bad data */ + if (cs->HasClientQuit()) return false; /* Check if variable is within packet-size */ if (packet->pos + bytes_to_read > packet->size) { - CloseConnection(cs); + cs->CloseConnection(); return false; } @@ -138,7 +135,7 @@ void NetworkRecv_ReadPacketSize(Packet *packet) packet->size += (uint16)packet->buffer[1] << 8; } -uint8 NetworkRecv_uint8(NetworkClientState *cs, Packet *packet) +uint8 NetworkRecv_uint8(NetworkSocketHandler *cs, Packet *packet) { uint8 n; @@ -148,7 +145,7 @@ uint8 NetworkRecv_uint8(NetworkClientState *cs, Packet *packet) return n; } -uint16 NetworkRecv_uint16(NetworkClientState *cs, Packet *packet) +uint16 NetworkRecv_uint16(NetworkSocketHandler *cs, Packet *packet) { uint16 n; @@ -159,7 +156,7 @@ uint16 NetworkRecv_uint16(NetworkClientState *cs, Packet *packet) return n; } -uint32 NetworkRecv_uint32(NetworkClientState *cs, Packet *packet) +uint32 NetworkRecv_uint32(NetworkSocketHandler *cs, Packet *packet) { uint32 n; @@ -172,7 +169,7 @@ uint32 NetworkRecv_uint32(NetworkClientState *cs, Packet *packet) return n; } -uint64 NetworkRecv_uint64(NetworkClientState *cs, Packet *packet) +uint64 NetworkRecv_uint64(NetworkSocketHandler *cs, Packet *packet) { uint64 n; @@ -190,13 +187,13 @@ uint64 NetworkRecv_uint64(NetworkClientState *cs, Packet *packet) } /** Reads a string till it finds a '\0' in the stream */ -void NetworkRecv_string(NetworkClientState *cs, Packet *p, char *buffer, size_t size) +void NetworkRecv_string(NetworkSocketHandler *cs, Packet *p, char *buffer, size_t size) { PacketSize pos; char *bufp = buffer; /* Don't allow reading from a closed socket */ - if (HasClientQuit(cs)) return; + if (cs->HasClientQuit()) return; pos = p->pos; while (--size > 0 && pos < p->size && (*buffer++ = p->buffer[pos++]) != '\0') {} diff --git a/src/network/core/packet.h b/src/network/core/packet.h index e42c65d5c..65ddec72c 100644 --- a/src/network/core/packet.h +++ b/src/network/core/packet.h @@ -6,23 +6,12 @@ #ifdef ENABLE_NETWORK #include "config.h" +#include "core.h" /** * @file packet.h Basic functions to create, fill and read packets. */ -typedef struct NetworkClientState NetworkClientState; - -/** - * Queries the network client state struct to determine whether - * the client has quit. It indirectly also queries whether the - * packet is corrupt as the connection will be closed if it is - * reading beyond the boundary of the received packet. - * @param cs the state to query - * @param true if the connection should be considered dropped - */ -bool HasClientQuit(const NetworkClientState *cs); - typedef uint16 PacketSize; ///< Size of the whole packet. typedef uint8 PacketType; ///< Identifier for the packet @@ -58,11 +47,11 @@ void NetworkSend_uint64(Packet *packet, uint64 data); void NetworkSend_string(Packet *packet, const char* data); void NetworkRecv_ReadPacketSize(Packet *packet); -uint8 NetworkRecv_uint8 (NetworkClientState *cs, Packet *packet); -uint16 NetworkRecv_uint16(NetworkClientState *cs, Packet *packet); -uint32 NetworkRecv_uint32(NetworkClientState *cs, Packet *packet); -uint64 NetworkRecv_uint64(NetworkClientState *cs, Packet *packet); -void NetworkRecv_string(NetworkClientState *cs, Packet *packet, char* buffer, size_t size); +uint8 NetworkRecv_uint8 (NetworkSocketHandler *cs, Packet *packet); +uint16 NetworkRecv_uint16(NetworkSocketHandler *cs, Packet *packet); +uint32 NetworkRecv_uint32(NetworkSocketHandler *cs, Packet *packet); +uint64 NetworkRecv_uint64(NetworkSocketHandler *cs, Packet *packet); +void NetworkRecv_string(NetworkSocketHandler *cs, Packet *packet, char* buffer, size_t size); #endif /* ENABLE_NETWORK */ diff --git a/src/network/core/tcp.cpp b/src/network/core/tcp.cpp index 98b5d8d5d..54271de57 100644 --- a/src/network/core/tcp.cpp +++ b/src/network/core/tcp.cpp @@ -18,6 +18,26 @@ * @file tcp.c Basic functions to receive and send TCP packets. */ +/** Very ugly temporary hack !!! */ +void NetworkTCPSocketHandler::Initialize() +{ + this->sock = INVALID_SOCKET; + + this->index = 0; + this->last_frame = 0; + this->last_frame_server = 0; + this->lag_test = 0; + + this->status = STATUS_INACTIVE; + this->has_quit = false; + this->writable = false; + + this->packet_queue = NULL; + this->packet_recv = NULL; + + this->command_queue = NULL; +} + /** * Functions to help NetworkRecv_Packet/NetworkSend_Packet a bit * A socket can make errors. When that happens this handles what to do. @@ -25,10 +45,11 @@ * For servers: close connection and that is it * @param cs the client to close the connection of * @return the new status + * TODO: needs to be splitted when using client and server socket packets */ -NetworkRecvStatus CloseConnection(NetworkClientState *cs) +NetworkRecvStatus NetworkTCPSocketHandler::CloseConnection() { - NetworkCloseClient(cs); + NetworkCloseClient(this); /* Clients drop back to the main menu */ if (!_network_server && _networking) { @@ -43,23 +64,13 @@ NetworkRecvStatus CloseConnection(NetworkClientState *cs) } /** - * Whether the client has quit or not (used in packet.c) - * @param cs the client to check - * @return true if the client has quit - */ -bool HasClientQuit(const NetworkClientState *cs) -{ - return cs->has_quit; -} - -/** * This function puts the packet in the send-queue and it is send as * soon as possible. This is the next tick, or maybe one tick later * if the OS-network-buffer is full) * @param packet the packet to send * @param cs the client to send to */ -void NetworkSend_Packet(Packet *packet, NetworkClientState *cs) +void NetworkSend_Packet(Packet *packet, NetworkTCPSocketHandler *cs) { Packet *p; assert(packet != NULL); @@ -89,31 +100,31 @@ void NetworkSend_Packet(Packet *packet, NetworkClientState *cs) * 3) sending took too long * @param cs the client to send the packets for */ -bool NetworkSend_Packets(NetworkClientState *cs) +bool NetworkSend_Packets(NetworkTCPSocketHandler *cs) { ssize_t res; Packet *p; /* We can not write to this socket!! */ if (!cs->writable) return false; - if (cs->socket == INVALID_SOCKET) return false; + if (!cs->IsConnected()) return false; p = cs->packet_queue; while (p != NULL) { - res = send(cs->socket, (const char*)p->buffer + p->pos, p->size - p->pos, 0); + res = send(cs->sock, (const char*)p->buffer + p->pos, p->size - p->pos, 0); if (res == -1) { int err = GET_LAST_ERROR(); if (err != EWOULDBLOCK) { /* Something went wrong.. close client! */ DEBUG(net, 0, "send failed with error %d", err); - CloseConnection(cs); + cs->CloseConnection(); return false; } return true; } if (res == 0) { /* Client/server has left us :( */ - CloseConnection(cs); + cs->CloseConnection(); return false; } @@ -139,14 +150,14 @@ bool NetworkSend_Packets(NetworkClientState *cs) * @param status the variable to store the status into * @return the received packet (or NULL when it didn't receive one) */ -Packet *NetworkRecv_Packet(NetworkClientState *cs, NetworkRecvStatus *status) +Packet *NetworkRecv_Packet(NetworkTCPSocketHandler *cs, NetworkRecvStatus *status) { ssize_t res; Packet *p; *status = NETWORK_RECV_STATUS_OKAY; - if (cs->socket == INVALID_SOCKET) return NULL; + if (!cs->IsConnected()) return NULL; if (cs->packet_recv == NULL) { cs->packet_recv = MallocT<Packet>(1); @@ -161,14 +172,14 @@ Packet *NetworkRecv_Packet(NetworkClientState *cs, NetworkRecvStatus *status) /* Read packet size */ if (p->pos < sizeof(PacketSize)) { while (p->pos < sizeof(PacketSize)) { - /* Read the size of the packet */ - res = recv(cs->socket, (char*)p->buffer + p->pos, sizeof(PacketSize) - p->pos, 0); + /* Read the size of the packet */ + res = recv(cs->sock, (char*)p->buffer + p->pos, sizeof(PacketSize) - p->pos, 0); if (res == -1) { int err = GET_LAST_ERROR(); if (err != EWOULDBLOCK) { /* Something went wrong... (104 is connection reset by peer) */ if (err != 104) DEBUG(net, 0, "recv failed with error %d", err); - *status = CloseConnection(cs); + *status = cs->CloseConnection(); return NULL; } /* Connection would block, so stop for now */ @@ -176,7 +187,7 @@ Packet *NetworkRecv_Packet(NetworkClientState *cs, NetworkRecvStatus *status) } if (res == 0) { /* Client/server has left */ - *status = CloseConnection(cs); + *status = cs->CloseConnection(); return NULL; } p->pos += res; @@ -185,20 +196,20 @@ Packet *NetworkRecv_Packet(NetworkClientState *cs, NetworkRecvStatus *status) NetworkRecv_ReadPacketSize(p); if (p->size > SEND_MTU) { - *status = CloseConnection(cs); + *status = cs->CloseConnection(); return NULL; } } /* Read rest of packet */ while (p->pos < p->size) { - res = recv(cs->socket, (char*)p->buffer + p->pos, p->size - p->pos, 0); + res = recv(cs->sock, (char*)p->buffer + p->pos, p->size - p->pos, 0); if (res == -1) { int err = GET_LAST_ERROR(); if (err != EWOULDBLOCK) { /* Something went wrong... (104 is connection reset by peer) */ if (err != 104) DEBUG(net, 0, "recv failed with error %d", err); - *status = CloseConnection(cs); + *status = cs->CloseConnection(); return NULL; } /* Connection would block */ @@ -206,7 +217,7 @@ Packet *NetworkRecv_Packet(NetworkClientState *cs, NetworkRecvStatus *status) } if (res == 0) { /* Client/server has left */ - *status = CloseConnection(cs); + *status = cs->CloseConnection(); return NULL; } diff --git a/src/network/core/tcp.h b/src/network/core/tcp.h index ab5c9b8e0..c15f851aa 100644 --- a/src/network/core/tcp.h +++ b/src/network/core/tcp.h @@ -6,6 +6,7 @@ #ifdef ENABLE_NETWORK #include "os_abstraction.h" +#include "core.h" #include "packet.h" /** @@ -54,9 +55,54 @@ enum { PACKET_END ///< Must ALWAYS be on the end of this list!! (period) }; -void NetworkSend_Packet(Packet *packet, NetworkClientState *cs); -Packet *NetworkRecv_Packet(NetworkClientState *cs, NetworkRecvStatus *status); -bool NetworkSend_Packets(NetworkClientState *cs); +typedef struct CommandPacket { + struct CommandPacket *next; + PlayerByte player; ///< player that is executing the command + uint32 cmd; ///< command being executed + uint32 p1; ///< parameter p1 + uint32 p2; ///< parameter p2 + TileIndex tile; ///< tile command being executed on + char text[80]; + uint32 frame; ///< the frame in which this packet is executed + byte callback; ///< any callback function executed upon successful completion of the command +} CommandPacket; + +typedef enum { + STATUS_INACTIVE, ///< The client is not connected nor active + STATUS_AUTH, ///< The client is authorized + STATUS_MAP_WAIT, ///< The client is waiting as someone else is downloading the map + STATUS_MAP, ///< The client is downloading the map + STATUS_DONE_MAP, ///< The client has downloaded the map + STATUS_PRE_ACTIVE, ///< The client is catching up the delayed frames + STATUS_ACTIVE, ///< The client is an active player in the game +} ClientStatus; + +/** Base socket handler for all TCP sockets */ +class NetworkTCPSocketHandler : public NetworkSocketHandler { +/* TODO: rewrite into a proper class */ +public: + uint16 index; + uint32 last_frame; + uint32 last_frame_server; + byte lag_test; // This byte is used for lag-testing the client + + ClientStatus status; + bool writable; // is client ready to write to? + + Packet *packet_queue; // Packets that are awaiting delivery + Packet *packet_recv; // Partially received packet + + CommandPacket *command_queue; // The command-queue awaiting delivery + + NetworkRecvStatus CloseConnection(); + void Initialize(); +}; + + + +void NetworkSend_Packet(Packet *packet, NetworkTCPSocketHandler *cs); +Packet *NetworkRecv_Packet(NetworkTCPSocketHandler *cs, NetworkRecvStatus *status); +bool NetworkSend_Packets(NetworkTCPSocketHandler *cs); #endif /* ENABLE_NETWORK */ diff --git a/src/network/core/udp.cpp b/src/network/core/udp.cpp index ddc4cadfb..c3709aa10 100644 --- a/src/network/core/udp.cpp +++ b/src/network/core/udp.cpp @@ -13,12 +13,6 @@ * @file udp.c Basic functions to receive and send UDP packets. */ -/** Initialize the sockets with an INVALID_SOCKET */ -NetworkUDPSocketHandler::NetworkUDPSocketHandler() -{ - this->udp = INVALID_SOCKET; -} - /** * Start listening on the given host and port. * @param udp the place where the (references to the) UDP are stored @@ -34,8 +28,8 @@ bool NetworkUDPSocketHandler::Listen(const uint32 host, const uint16 port, const /* Make sure socket is closed */ this->Close(); - this->udp = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (this->udp == INVALID_SOCKET) { + this->sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (!this->IsConnected()) { DEBUG(net, 0, "[udp] failed to start UDP listener"); return false; } @@ -44,9 +38,9 @@ bool NetworkUDPSocketHandler::Listen(const uint32 host, const uint16 port, const { unsigned long blocking = 1; #ifndef BEOS_NET_SERVER - ioctlsocket(this->udp, FIONBIO, &blocking); + ioctlsocket(this->sock, FIONBIO, &blocking); #else - setsockopt(this->udp, SOL_SOCKET, SO_NONBLOCK, &blocking, NULL); + setsockopt(this->sock, SOL_SOCKET, SO_NONBLOCK, &blocking, NULL); #endif } @@ -55,7 +49,7 @@ bool NetworkUDPSocketHandler::Listen(const uint32 host, const uint16 port, const sin.sin_addr.s_addr = host; sin.sin_port = htons(port); - if (bind(this->udp, (struct sockaddr*)&sin, sizeof(sin)) != 0) { + if (bind(this->sock, (struct sockaddr*)&sin, sizeof(sin)) != 0) { DEBUG(net, 0, "[udp] bind failed on %s:%i", inet_ntoa(*(struct in_addr *)&host), port); return false; } @@ -64,7 +58,7 @@ bool NetworkUDPSocketHandler::Listen(const uint32 host, const uint16 port, const /* Enable broadcast */ unsigned long val = 1; #ifndef BEOS_NET_SERVER // will work around this, some day; maybe. - setsockopt(this->udp, SOL_SOCKET, SO_BROADCAST, (char *) &val , sizeof(val)); + setsockopt(this->sock, SOL_SOCKET, SO_BROADCAST, (char *) &val , sizeof(val)); #endif } @@ -79,12 +73,17 @@ bool NetworkUDPSocketHandler::Listen(const uint32 host, const uint16 port, const */ void NetworkUDPSocketHandler::Close() { - if (this->udp == INVALID_SOCKET) return; + if (!this->IsConnected()) return; - closesocket(this->udp); - this->udp = INVALID_SOCKET; + closesocket(this->sock); + this->sock = INVALID_SOCKET; } +NetworkRecvStatus NetworkUDPSocketHandler::CloseConnection() +{ + this->has_quit = true; + return NETWORK_RECV_STATUS_OKAY; +} /** * Send a packet over UDP @@ -99,7 +98,7 @@ void NetworkUDPSocketHandler::SendPacket(Packet *p, const struct sockaddr_in *re NetworkSend_FillPacketSize(p); /* Send the buffer */ - res = sendto(this->udp, (const char*)p->buffer, p->size, 0, (struct sockaddr *)recv, sizeof(*recv)); + res = sendto(this->sock, (const char*)p->buffer, p->size, 0, (struct sockaddr *)recv, sizeof(*recv)); /* Check for any errors, but ignore it otherwise */ if (res == -1) DEBUG(net, 1, "[udp] sendto failed with: %i", GET_LAST_ERROR()); @@ -117,13 +116,13 @@ void NetworkUDPSocketHandler::ReceivePackets() Packet p; int packet_len; - if (this->udp == INVALID_SOCKET) return; + if (!this->IsConnected()) return; packet_len = sizeof(p.buffer); client_len = sizeof(client_addr); /* Try to receive anything */ - nbytes = recvfrom(this->udp, (char*)p.buffer, packet_len, 0, (struct sockaddr *)&client_addr, &client_len); + nbytes = recvfrom(this->sock, (char*)p.buffer, packet_len, 0, (struct sockaddr *)&client_addr, &client_len); /* We got some bytes for the base header of the packet. */ if (nbytes > 2) { @@ -170,9 +169,9 @@ void NetworkUDPSocketHandler::Send_GRFIdentifier(Packet *p, const GRFConfig *c) void NetworkUDPSocketHandler::Recv_GRFIdentifier(Packet *p, GRFConfig *c) { uint j; - c->grfid = NetworkRecv_uint32(&this->cs, p); + c->grfid = NetworkRecv_uint32(this, p); for (j = 0; j < sizeof(c->md5sum); j++) { - c->md5sum[j] = NetworkRecv_uint8(&this->cs, p); + c->md5sum[j] = NetworkRecv_uint8(this, p); } } @@ -246,7 +245,7 @@ void NetworkUDPSocketHandler::Send_NetworkGameInfo(Packet *p, const NetworkGameI */ void NetworkUDPSocketHandler::Recv_NetworkGameInfo(Packet *p, NetworkGameInfo *info) { - info->game_info_version = NetworkRecv_uint8(&this->cs, p); + info->game_info_version = NetworkRecv_uint8(this, p); /* * Please observe the order. @@ -260,7 +259,7 @@ void NetworkUDPSocketHandler::Recv_NetworkGameInfo(Packet *p, NetworkGameInfo *i case 4: { GRFConfig **dst = &info->grfconfig; uint i; - uint num_grfs = NetworkRecv_uint8(&this->cs, p); + uint num_grfs = NetworkRecv_uint8(this, p); for (i = 0; i < num_grfs; i++) { GRFConfig *c = CallocT<GRFConfig>(1); @@ -273,31 +272,31 @@ void NetworkUDPSocketHandler::Recv_NetworkGameInfo(Packet *p, NetworkGameInfo *i } } /* Fallthrough */ case 3: - info->game_date = NetworkRecv_uint32(&this->cs, p); - info->start_date = NetworkRecv_uint32(&this->cs, p); + info->game_date = NetworkRecv_uint32(this, p); + info->start_date = NetworkRecv_uint32(this, p); /* Fallthrough */ case 2: - info->companies_max = NetworkRecv_uint8 (&this->cs, p); - info->companies_on = NetworkRecv_uint8 (&this->cs, p); - info->spectators_max = NetworkRecv_uint8 (&this->cs, p); + info->companies_max = NetworkRecv_uint8 (this, p); + info->companies_on = NetworkRecv_uint8 (this, p); + info->spectators_max = NetworkRecv_uint8 (this, p); /* Fallthrough */ case 1: - NetworkRecv_string(&this->cs, p, info->server_name, sizeof(info->server_name)); - NetworkRecv_string(&this->cs, p, info->server_revision, sizeof(info->server_revision)); - info->server_lang = NetworkRecv_uint8 (&this->cs, p); - info->use_password = NetworkRecv_uint8 (&this->cs, p); - info->clients_max = NetworkRecv_uint8 (&this->cs, p); - info->clients_on = NetworkRecv_uint8 (&this->cs, p); - info->spectators_on = NetworkRecv_uint8 (&this->cs, p); + NetworkRecv_string(this, p, info->server_name, sizeof(info->server_name)); + NetworkRecv_string(this, p, info->server_revision, sizeof(info->server_revision)); + info->server_lang = NetworkRecv_uint8 (this, p); + info->use_password = NetworkRecv_uint8 (this, p); + info->clients_max = NetworkRecv_uint8 (this, p); + info->clients_on = NetworkRecv_uint8 (this, p); + info->spectators_on = NetworkRecv_uint8 (this, p); if (info->game_info_version < 3) { // 16 bits dates got scrapped and are read earlier - info->game_date = NetworkRecv_uint16(&this->cs, p) + DAYS_TILL_ORIGINAL_BASE_YEAR; - info->start_date = NetworkRecv_uint16(&this->cs, p) + DAYS_TILL_ORIGINAL_BASE_YEAR; + info->game_date = NetworkRecv_uint16(this, p) + DAYS_TILL_ORIGINAL_BASE_YEAR; + info->start_date = NetworkRecv_uint16(this, p) + DAYS_TILL_ORIGINAL_BASE_YEAR; } - NetworkRecv_string(&this->cs, p, info->map_name, sizeof(info->map_name)); - info->map_width = NetworkRecv_uint16(&this->cs, p); - info->map_height = NetworkRecv_uint16(&this->cs, p); - info->map_set = NetworkRecv_uint8 (&this->cs, p); - info->dedicated = (NetworkRecv_uint8(&this->cs, p) != 0); + NetworkRecv_string(this, p, info->map_name, sizeof(info->map_name)); + info->map_width = NetworkRecv_uint16(this, p); + info->map_height = NetworkRecv_uint16(this, p); + info->map_set = NetworkRecv_uint8 (this, p); + info->dedicated = (NetworkRecv_uint8(this, p) != 0); } } @@ -313,13 +312,12 @@ void NetworkUDPSocketHandler::HandleUDPPacket(Packet *p, const struct sockaddr_i { PacketUDPType type; - /* Fake a client, so we can see when there is an illegal packet */ - this->cs.socket = INVALID_SOCKET; - this->cs.has_quit = false; + /* New packet == new client, which has not quit yet */ + this->has_quit = false; - type = (PacketUDPType)NetworkRecv_uint8(&this->cs, p); + type = (PacketUDPType)NetworkRecv_uint8(this, p); - switch (this->cs.has_quit ? PACKET_UDP_END : type) { + switch (this->HasClientQuit() ? PACKET_UDP_END : type) { UDP_COMMAND(PACKET_UDP_CLIENT_FIND_SERVER); UDP_COMMAND(PACKET_UDP_SERVER_RESPONSE); UDP_COMMAND(PACKET_UDP_CLIENT_DETAIL_INFO); @@ -333,7 +331,7 @@ void NetworkUDPSocketHandler::HandleUDPPacket(Packet *p, const struct sockaddr_i UDP_COMMAND(PACKET_UDP_SERVER_NEWGRFS); default: - if (!this->cs.has_quit) { + if (this->HasClientQuit()) { DEBUG(net, 0, "[udp] received invalid packet type %d from %s:%d", type, inet_ntoa(client_addr->sin_addr), ntohs(client_addr->sin_port)); } else { DEBUG(net, 0, "[udp] received illegal packet from %s:%d", inet_ntoa(client_addr->sin_addr), ntohs(client_addr->sin_port)); @@ -351,8 +349,8 @@ void NetworkUDPSocketHandler::HandleUDPPacket(Packet *p, const struct sockaddr_i #define DEFINE_UNAVAILABLE_UDP_RECEIVE_COMMAND(type) \ void NetworkUDPSocketHandler::NetworkPacketReceive_## type ##_command(\ Packet *p, const struct sockaddr_in *client_addr) { \ - DEBUG(net, 0, "[udp] received packet on wrong port from %s:%d", \ - inet_ntoa(client_addr->sin_addr), ntohs(client_addr->sin_port)); \ + DEBUG(net, 0, "[udp] received packet type %d on wrong port from %s:%d", \ + type, inet_ntoa(client_addr->sin_addr), ntohs(client_addr->sin_port)); \ } DEFINE_UNAVAILABLE_UDP_RECEIVE_COMMAND(PACKET_UDP_CLIENT_FIND_SERVER); diff --git a/src/network/core/udp.h b/src/network/core/udp.h index 755829600..9bb743841 100644 --- a/src/network/core/udp.h +++ b/src/network/core/udp.h @@ -6,11 +6,11 @@ #ifdef ENABLE_NETWORK #include "os_abstraction.h" +#include "core.h" #include "game.h" #include "packet.h" #include "../../newgrf_config.h" #include "../../debug.h" -#include "../network_data.h" /** * @file udp.h Basic functions to receive and send UDP packets. @@ -91,11 +91,11 @@ enum PacketUDPType { #define DECLARE_UDP_RECEIVE_COMMAND(type) virtual void NetworkPacketReceive_## type ##_command(Packet *p, const struct sockaddr_in *) -class NetworkUDPSocketHandler { -private: - SOCKET udp; +/** Base socket handler for all UDP sockets */ +class NetworkUDPSocketHandler : public NetworkSocketHandler { protected: - NetworkClientState cs; + NetworkRecvStatus CloseConnection(); + /* Declare all possible packets here. If it can be received by the * a specific handler, it has to be implemented. */ DECLARE_UDP_RECEIVE_COMMAND(PACKET_UDP_CLIENT_FIND_SERVER); @@ -121,10 +121,8 @@ protected: */ virtual void HandleIncomingNetworkGameInfoGRFConfig(GRFConfig *config) { NOT_REACHED(); } public: - NetworkUDPSocketHandler(); virtual ~NetworkUDPSocketHandler() { this->Close(); } - bool IsListening() { return this->udp != INVALID_SOCKET; } bool Listen(uint32 host, uint16 port, bool broadcast); void Close(); diff --git a/src/network/network.cpp b/src/network/network.cpp index 14a7ee0b0..124409e3d 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -47,7 +47,7 @@ extern NetworkUDPSocketHandler *_udp_master_socket; ///< udp master socket // Here we keep track of the clients // (and the client uses [0] for his own communication) -NetworkClientState _clients[MAX_CLIENTS]; +NetworkTCPSocketHandler _clients[MAX_CLIENTS]; @@ -90,9 +90,9 @@ NetworkClientInfo *NetworkFindClientInfoFromIP(const char *ip) } // Function that looks up the CS for a given client-index -NetworkClientState *NetworkFindClientStateFromIndex(uint16 client_index) +NetworkTCPSocketHandler *NetworkFindClientStateFromIndex(uint16 client_index) { - NetworkClientState *cs; + NetworkTCPSocketHandler *cs; for (cs = _clients; cs != endof(_clients); cs++) { if (cs->index == client_index) return cs; @@ -103,7 +103,7 @@ NetworkClientState *NetworkFindClientStateFromIndex(uint16 client_index) // NetworkGetClientName is a server-safe function to get the name of the client // if the user did not send it yet, Client #<no> is used. -void NetworkGetClientName(char *client_name, size_t size, const NetworkClientState *cs) +void NetworkGetClientName(char *client_name, size_t size, const NetworkTCPSocketHandler *cs) { const NetworkClientInfo *ci = DEREF_CLIENT_INFO(cs); @@ -116,7 +116,7 @@ void NetworkGetClientName(char *client_name, size_t size, const NetworkClientSta byte NetworkSpectatorCount(void) { - const NetworkClientState *cs; + NetworkTCPSocketHandler *cs; byte count = 0; FOR_ALL_CLIENTS(cs) { @@ -197,7 +197,7 @@ void CDECL NetworkTextMessage(NetworkAction action, uint16 color, bool self_send } // Calculate the frame-lag of a client -uint NetworkCalculateLag(const NetworkClientState *cs) +uint NetworkCalculateLag(const NetworkTCPSocketHandler *cs) { int lag = cs->last_frame_server - cs->last_frame; // This client has missed his ACK packet after 1 DAY_TICKS.. @@ -230,7 +230,7 @@ static void ServerStartError(const char *error) NetworkError(STR_NETWORK_ERR_SERVER_START); } -static void NetworkClientError(NetworkRecvStatus res, NetworkClientState* cs) +static void NetworkClientError(NetworkRecvStatus res, NetworkTCPSocketHandler* cs) { // First, send a CLIENT_ERROR to the server, so he knows we are // disconnection (and why!) @@ -298,7 +298,7 @@ char* GetNetworkErrorMsg(char* buf, NetworkErrorCode err, const char* last) /* Count the number of active clients connected */ static uint NetworkCountPlayers(void) { - const NetworkClientState *cs; + NetworkTCPSocketHandler *cs; uint count = 0; FOR_ALL_CLIENTS(cs) { @@ -549,9 +549,9 @@ void ParseConnectionString(const char **player, const char **port, char *connect // Creates a new client from a socket // Used both by the server and the client -static NetworkClientState *NetworkAllocClient(SOCKET s) +static NetworkTCPSocketHandler *NetworkAllocClient(SOCKET s) { - NetworkClientState *cs; + NetworkTCPSocketHandler *cs; byte client_no = 0; if (_network_server) { @@ -564,11 +564,8 @@ static NetworkClientState *NetworkAllocClient(SOCKET s) } cs = DEREF_CLIENT(client_no); - memset(cs, 0, sizeof(*cs)); - cs->socket = s; - cs->last_frame = 0; - cs->has_quit = false; - + cs->Initialize(); + cs->sock = s; cs->last_frame = _frame_counter; cs->last_frame_server = _frame_counter; @@ -588,11 +585,11 @@ static NetworkClientState *NetworkAllocClient(SOCKET s) } // Close a connection -void NetworkCloseClient(NetworkClientState *cs) +void NetworkCloseClient(NetworkTCPSocketHandler *cs) { NetworkClientInfo *ci; // Socket is already dead - if (cs->socket == INVALID_SOCKET) { + if (cs->sock == INVALID_SOCKET) { cs->has_quit = true; return; } @@ -604,7 +601,7 @@ void NetworkCloseClient(NetworkClientState *cs) NetworkErrorCode errorno = NETWORK_ERROR_CONNECTION_LOST; char str[100]; char client_name[NETWORK_CLIENT_NAME_LENGTH]; - NetworkClientState *new_cs; + NetworkTCPSocketHandler *new_cs; NetworkGetClientName(client_name, sizeof(client_name), cs); @@ -626,7 +623,7 @@ void NetworkCloseClient(NetworkClientState *cs) NetworkServer_HandleChat(NETWORK_ACTION_SERVER_MESSAGE, DESTTYPE_BROADCAST, 0, "Game unpaused", NETWORK_SERVER_INDEX); } - closesocket(cs->socket); + closesocket(cs->sock); cs->writable = false; cs->has_quit = true; @@ -653,7 +650,7 @@ void NetworkCloseClient(NetworkClientState *cs) if (cs->status > STATUS_INACTIVE) _network_game_info.clients_on--; _network_clients_connected--; - while ((cs + 1) != DEREF_CLIENT(MAX_CLIENTS) && (cs + 1)->socket != INVALID_SOCKET) { + while ((cs + 1) != DEREF_CLIENT(MAX_CLIENTS) && (cs + 1)->sock != INVALID_SOCKET) { *cs = *(cs + 1); *ci = *(ci + 1); cs++; @@ -664,7 +661,7 @@ void NetworkCloseClient(NetworkClientState *cs) } // Reset the status of the last socket - cs->socket = INVALID_SOCKET; + cs->sock = INVALID_SOCKET; cs->status = STATUS_INACTIVE; cs->index = NETWORK_EMPTY_INDEX; ci->client_index = NETWORK_EMPTY_INDEX; @@ -711,7 +708,7 @@ static bool NetworkConnect(const char *hostname, int port) static void NetworkAcceptClients(void) { struct sockaddr_in sin; - NetworkClientState *cs; + NetworkTCPSocketHandler *cs; uint i; bool banned; @@ -827,7 +824,7 @@ static bool NetworkListen(void) // Close all current connections static void NetworkClose(void) { - NetworkClientState *cs; + NetworkTCPSocketHandler *cs; FOR_ALL_CLIENTS(cs) { if (!_network_server) { @@ -849,16 +846,13 @@ static void NetworkClose(void) // Inits the network (cleans sockets and stuff) static void NetworkInitialize(void) { - NetworkClientState *cs; + NetworkTCPSocketHandler *cs; _local_command_queue = NULL; // Clean all client-sockets - memset(_clients, 0, sizeof(_clients)); for (cs = _clients; cs != &_clients[MAX_CLIENTS]; cs++) { - cs->socket = INVALID_SOCKET; - cs->status = STATUS_INACTIVE; - cs->command_queue = NULL; + cs->Initialize(); } // Clean the client_info memory @@ -1071,7 +1065,7 @@ bool NetworkServerStart(void) void NetworkReboot(void) { if (_network_server) { - NetworkClientState *cs; + NetworkTCPSocketHandler *cs; FOR_ALL_CLIENTS(cs) { SEND_COMMAND(PACKET_SERVER_NEWGAME)(cs); NetworkSend_Packets(cs); @@ -1095,7 +1089,7 @@ void NetworkReboot(void) void NetworkDisconnect(void) { if (_network_server) { - NetworkClientState *cs; + NetworkTCPSocketHandler *cs; FOR_ALL_CLIENTS(cs) { SEND_COMMAND(PACKET_SERVER_SHUTDOWN)(cs); NetworkSend_Packets(cs); @@ -1122,7 +1116,7 @@ void NetworkDisconnect(void) // Receives something from the network static bool NetworkReceive(void) { - NetworkClientState *cs; + NetworkTCPSocketHandler *cs; int n; fd_set read_fd, write_fd; struct timeval tv; @@ -1131,8 +1125,8 @@ static bool NetworkReceive(void) FD_ZERO(&write_fd); FOR_ALL_CLIENTS(cs) { - FD_SET(cs->socket, &read_fd); - FD_SET(cs->socket, &write_fd); + FD_SET(cs->sock, &read_fd); + FD_SET(cs->sock, &write_fd); } // take care of listener port @@ -1151,8 +1145,8 @@ static bool NetworkReceive(void) // read stuff from clients FOR_ALL_CLIENTS(cs) { - cs->writable = !!FD_ISSET(cs->socket, &write_fd); - if (FD_ISSET(cs->socket, &read_fd)) { + cs->writable = !!FD_ISSET(cs->sock, &write_fd); + if (FD_ISSET(cs->sock, &read_fd)) { if (_network_server) { NetworkServer_ReadPackets(cs); } else { @@ -1177,7 +1171,7 @@ static bool NetworkReceive(void) // This sends all buffered commands (if possible) static void NetworkSend(void) { - NetworkClientState *cs; + NetworkTCPSocketHandler *cs; FOR_ALL_CLIENTS(cs) { if (cs->writable) { NetworkSend_Packets(cs); diff --git a/src/network/network_client.cpp b/src/network/network_client.cpp index 9e9b5969c..47bb952f2 100644 --- a/src/network/network_client.cpp +++ b/src/network/network_client.cpp @@ -796,7 +796,7 @@ void NetworkClient_Connected(void) } // Reads the packets from the socket-stream, if available -NetworkRecvStatus NetworkClient_ReadPackets(NetworkClientState *cs) +NetworkRecvStatus NetworkClient_ReadPackets(NetworkTCPSocketHandler *cs) { Packet *p; NetworkRecvStatus res = NETWORK_RECV_STATUS_OKAY; diff --git a/src/network/network_client.h b/src/network/network_client.h index 2dd776ac1..7d50b1edd 100644 --- a/src/network/network_client.h +++ b/src/network/network_client.h @@ -17,7 +17,7 @@ DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_SET_NAME)(const char *name); DEF_CLIENT_SEND_COMMAND(PACKET_CLIENT_ACK); DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_RCON)(const char *pass, const char *command); -NetworkRecvStatus NetworkClient_ReadPackets(NetworkClientState *cs); +NetworkRecvStatus NetworkClient_ReadPackets(NetworkTCPSocketHandler *cs); void NetworkClient_Connected(void); #endif /* ENABLE_NETWORK */ diff --git a/src/network/network_data.cpp b/src/network/network_data.cpp index 4b0166c9a..7cb27adf7 100644 --- a/src/network/network_data.cpp +++ b/src/network/network_data.cpp @@ -12,7 +12,7 @@ #include "../helpers.hpp" // Add a command to the local command queue -void NetworkAddCommandQueue(NetworkClientState *cs, CommandPacket *cp) +void NetworkAddCommandQueue(NetworkTCPSocketHandler *cs, CommandPacket *cp) { CommandPacket* new_cp = MallocT<CommandPacket>(1); @@ -65,7 +65,7 @@ void NetworkSend_Command(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, Comma // client on the server can do everything 1 tick faster than others. // So to keep the game fair, we delay the command with 1 tick // which gives about the same speed as most clients. - NetworkClientState *cs; + NetworkTCPSocketHandler *cs; // And we queue it for delivery to the clients FOR_ALL_CLIENTS(cs) { diff --git a/src/network/network_data.h b/src/network/network_data.h index 057a78f27..46561c51f 100644 --- a/src/network/network_data.h +++ b/src/network/network_data.h @@ -9,8 +9,10 @@ #include "../openttd.h" #include "network.h" #include "core/os_abstraction.h" +#include "core/core.h" #include "core/config.h" #include "core/packet.h" +#include "core/tcp.h" #define MAX_TEXT_MSG_LEN 1024 /* long long long long sentences :-) */ @@ -18,28 +20,6 @@ #define NETWORK_SERVER_INDEX 1 #define NETWORK_EMPTY_INDEX 0 -typedef struct CommandPacket { - struct CommandPacket *next; - PlayerByte player; /// player that is executing the command - uint32 cmd; /// command being executed - uint32 p1; /// parameter p1 - uint32 p2; /// parameter p2 - TileIndex tile; /// tile command being executed on - char text[80]; - uint32 frame; /// the frame in which this packet is executed - byte callback; /// any callback function executed upon successful completion of the command -} CommandPacket; - -typedef enum { - STATUS_INACTIVE, - STATUS_AUTH, // This means that the client is authorized - STATUS_MAP_WAIT, // This means that the client is put on hold because someone else is getting the map - STATUS_MAP, - STATUS_DONE_MAP, - STATUS_PRE_ACTIVE, - STATUS_ACTIVE, -} ClientStatus; - typedef enum { MAP_PACKET_START, MAP_PACKET_NORMAL, @@ -47,18 +27,6 @@ typedef enum { } MapPacket; typedef enum { - NETWORK_RECV_STATUS_OKAY, - NETWORK_RECV_STATUS_DESYNC, - NETWORK_RECV_STATUS_SAVEGAME, - NETWORK_RECV_STATUS_CONN_LOST, - NETWORK_RECV_STATUS_MALFORMED_PACKET, - NETWORK_RECV_STATUS_SERVER_ERROR, // The server told us we made an error - NETWORK_RECV_STATUS_SERVER_FULL, - NETWORK_RECV_STATUS_SERVER_BANNED, - NETWORK_RECV_STATUS_CLOSE_QUERY, // Done quering the server -} NetworkRecvStatus; - -typedef enum { NETWORK_ERROR_GENERAL, // Try to use thisone like never // Signals from clients @@ -96,24 +64,6 @@ typedef enum { NETWORK_COMPANY_PASSWORD, } NetworkPasswordType; -// To keep the clients all together -struct NetworkClientState { // Typedeffed in network_core/packet.h - SOCKET socket; - uint16 index; - uint32 last_frame; - uint32 last_frame_server; - byte lag_test; // This byte is used for lag-testing the client - - ClientStatus status; - bool writable; // is client ready to write to? - bool has_quit; - - Packet *packet_queue; // Packets that are awaiting delivery - Packet *packet_recv; // Partially received packet - - CommandPacket *command_queue; // The command-queue awaiting delivery -}; - typedef enum { DESTTYPE_BROADCAST, ///< Send message/notice to all players (All) DESTTYPE_TEAM, ///< Send message/notice to everyone playing the same company (Team) @@ -125,7 +75,7 @@ extern CommandPacket *_local_command_queue; // Here we keep track of the clients // (and the client uses [0] for his own communication) -extern NetworkClientState _clients[MAX_CLIENTS]; +extern NetworkTCPSocketHandler _clients[MAX_CLIENTS]; #define DEREF_CLIENT(i) (&_clients[i]) // This returns the NetworkClientInfo from a NetworkClientState @@ -135,28 +85,28 @@ extern NetworkClientState _clients[MAX_CLIENTS]; #define DEF_CLIENT_RECEIVE_COMMAND(type) NetworkRecvStatus NetworkPacketReceive_ ## type ## _command(Packet *p) #define DEF_CLIENT_SEND_COMMAND(type) void NetworkPacketSend_ ## type ## _command(void) #define DEF_CLIENT_SEND_COMMAND_PARAM(type) void NetworkPacketSend_ ## type ## _command -#define DEF_SERVER_RECEIVE_COMMAND(type) void NetworkPacketReceive_ ## type ## _command(NetworkClientState *cs, Packet *p) -#define DEF_SERVER_SEND_COMMAND(type) void NetworkPacketSend_ ## type ## _command(NetworkClientState *cs) +#define DEF_SERVER_RECEIVE_COMMAND(type) void NetworkPacketReceive_ ## type ## _command(NetworkTCPSocketHandler *cs, Packet *p) +#define DEF_SERVER_SEND_COMMAND(type) void NetworkPacketSend_ ## type ## _command(NetworkTCPSocketHandler *cs) #define DEF_SERVER_SEND_COMMAND_PARAM(type) void NetworkPacketSend_ ## type ## _command #define SEND_COMMAND(type) NetworkPacketSend_ ## type ## _command #define RECEIVE_COMMAND(type) NetworkPacketReceive_ ## type ## _command -#define FOR_ALL_CLIENTS(cs) for (cs = _clients; cs != endof(_clients) && cs->socket != INVALID_SOCKET; cs++) +#define FOR_ALL_CLIENTS(cs) for (cs = _clients; cs != endof(_clients) && cs->IsConnected(); cs++) #define FOR_ALL_ACTIVE_CLIENT_INFOS(ci) for (ci = _network_client_info; ci != endof(_network_client_info); ci++) if (ci->client_index != NETWORK_EMPTY_INDEX) void NetworkExecuteCommand(CommandPacket *cp); -void NetworkAddCommandQueue(NetworkClientState *cs, CommandPacket *cp); +void NetworkAddCommandQueue(NetworkTCPSocketHandler *cs, CommandPacket *cp); // from network.c -void NetworkCloseClient(NetworkClientState *cs); +void NetworkCloseClient(NetworkTCPSocketHandler *cs); void CDECL NetworkTextMessage(NetworkAction action, uint16 color, bool self_send, const char *name, const char *str, ...); -void NetworkGetClientName(char *clientname, size_t size, const NetworkClientState *cs); -uint NetworkCalculateLag(const NetworkClientState *cs); +void NetworkGetClientName(char *clientname, size_t size, const NetworkTCPSocketHandler *cs); +uint NetworkCalculateLag(const NetworkTCPSocketHandler *cs); byte NetworkGetCurrentLanguageIndex(void); NetworkClientInfo *NetworkFindClientInfoFromIndex(uint16 client_index); NetworkClientInfo *NetworkFindClientInfoFromIP(const char *ip); -NetworkClientState *NetworkFindClientStateFromIndex(uint16 client_index); +NetworkTCPSocketHandler *NetworkFindClientStateFromIndex(uint16 client_index); unsigned long NetworkResolveHost(const char *hostname); char* GetNetworkErrorMsg(char* buf, NetworkErrorCode err, const char* last); diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp index ed7951c41..59696c940 100644 --- a/src/network/network_server.cpp +++ b/src/network/network_server.cpp @@ -26,14 +26,14 @@ // This file handles all the server-commands -static void NetworkHandleCommandQueue(NetworkClientState* cs); +static void NetworkHandleCommandQueue(NetworkTCPSocketHandler* cs); // ********** // Sending functions -// DEF_SERVER_SEND_COMMAND has parameter: NetworkClientState *cs +// DEF_SERVER_SEND_COMMAND has parameter: NetworkTCPSocketHandler *cs // ********** -DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_CLIENT_INFO)(NetworkClientState *cs, NetworkClientInfo *ci) +DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_CLIENT_INFO)(NetworkTCPSocketHandler *cs, NetworkClientInfo *ci) { // // Packet: SERVER_CLIENT_INFO @@ -131,7 +131,7 @@ DEF_SERVER_SEND_COMMAND(PACKET_SERVER_COMPANY_INFO) NetworkSend_Packet(p, cs); } -DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_ERROR)(NetworkClientState *cs, NetworkErrorCode error) +DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_ERROR)(NetworkTCPSocketHandler *cs, NetworkErrorCode error) { // // Packet: SERVER_ERROR @@ -150,7 +150,7 @@ DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_ERROR)(NetworkClientState *cs, Netwo // Only send when the current client was in game if (cs->status > STATUS_AUTH) { - NetworkClientState *new_cs; + NetworkTCPSocketHandler *new_cs; char client_name[NETWORK_CLIENT_NAME_LENGTH]; NetworkGetClientName(client_name, sizeof(client_name), cs); @@ -182,7 +182,7 @@ DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_ERROR)(NetworkClientState *cs, Netwo NetworkCloseClient(cs); } -DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_NEED_PASSWORD)(NetworkClientState *cs, NetworkPasswordType type) +DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_NEED_PASSWORD)(NetworkTCPSocketHandler *cs, NetworkPasswordType type) { // // Packet: SERVER_NEED_PASSWORD @@ -206,7 +206,7 @@ DEF_SERVER_SEND_COMMAND(PACKET_SERVER_WELCOME) // Packet *p; - const NetworkClientState *new_cs; + NetworkTCPSocketHandler *new_cs; // Invalid packet when status is AUTH or higher if (cs->status >= STATUS_AUTH) return; @@ -237,7 +237,7 @@ DEF_SERVER_SEND_COMMAND(PACKET_SERVER_WAIT) // uint8: Clients awaiting map // int waiting = 0; - NetworkClientState *new_cs; + NetworkTCPSocketHandler *new_cs; Packet *p; // Count how many players are waiting in the queue @@ -330,7 +330,7 @@ DEF_SERVER_SEND_COMMAND(PACKET_SERVER_MAP) fclose(file_pointer); { - NetworkClientState *new_cs; + NetworkTCPSocketHandler *new_cs; bool new_map_client = false; // Check if there is a client waiting for receiving the map // and start sending him the map @@ -367,7 +367,7 @@ DEF_SERVER_SEND_COMMAND(PACKET_SERVER_MAP) } } -DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_JOIN)(NetworkClientState *cs, uint16 client_index) +DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_JOIN)(NetworkTCPSocketHandler *cs, uint16 client_index) { // // Packet: SERVER_JOIN @@ -433,7 +433,7 @@ DEF_SERVER_SEND_COMMAND(PACKET_SERVER_SYNC) NetworkSend_Packet(p, cs); } -DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_COMMAND)(NetworkClientState *cs, CommandPacket *cp) +DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_COMMAND)(NetworkTCPSocketHandler *cs, CommandPacket *cp) { // // Packet: SERVER_COMMAND @@ -463,7 +463,7 @@ DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_COMMAND)(NetworkClientState *cs, Com NetworkSend_Packet(p, cs); } -DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_CHAT)(NetworkClientState *cs, NetworkAction action, uint16 client_index, bool self_send, const char *msg) +DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_CHAT)(NetworkTCPSocketHandler *cs, NetworkAction action, uint16 client_index, bool self_send, const char *msg) { // // Packet: SERVER_CHAT @@ -484,7 +484,7 @@ DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_CHAT)(NetworkClientState *cs, Networ NetworkSend_Packet(p, cs); } -DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_ERROR_QUIT)(NetworkClientState *cs, uint16 client_index, NetworkErrorCode errorno) +DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_ERROR_QUIT)(NetworkTCPSocketHandler *cs, uint16 client_index, NetworkErrorCode errorno) { // // Packet: SERVER_ERROR_QUIT @@ -503,7 +503,7 @@ DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_ERROR_QUIT)(NetworkClientState *cs, NetworkSend_Packet(p, cs); } -DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_QUIT)(NetworkClientState *cs, uint16 client_index, const char *leavemsg) +DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_QUIT)(NetworkTCPSocketHandler *cs, uint16 client_index, const char *leavemsg) { // // Packet: SERVER_ERROR_QUIT @@ -548,7 +548,7 @@ DEF_SERVER_SEND_COMMAND(PACKET_SERVER_NEWGAME) NetworkSend_Packet(p, cs); } -DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_RCON)(NetworkClientState *cs, uint16 color, const char *command) +DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_RCON)(NetworkTCPSocketHandler *cs, uint16 color, const char *command) { Packet *p = NetworkSend_Init(PACKET_SERVER_RCON); @@ -559,7 +559,7 @@ DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_RCON)(NetworkClientState *cs, uint16 // ********** // Receiving functions -// DEF_SERVER_RECEIVE_COMMAND has parameter: NetworkClientState *cs, Packet *p +// DEF_SERVER_RECEIVE_COMMAND has parameter: NetworkTCPSocketHandler *cs, Packet *p // ********** DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_COMPANY_INFO) @@ -696,7 +696,7 @@ DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_PASSWORD) DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_GETMAP) { - const NetworkClientState *new_cs; + NetworkTCPSocketHandler *new_cs; // The client was never joined.. so this is impossible, right? // Ignore the packet, give the client a warning, and close his connection @@ -724,7 +724,7 @@ DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_MAP_OK) // Client has the map, now start syncing if (cs->status == STATUS_DONE_MAP && !cs->has_quit) { char client_name[NETWORK_CLIENT_NAME_LENGTH]; - NetworkClientState *new_cs; + NetworkTCPSocketHandler *new_cs; NetworkGetClientName(client_name, sizeof(client_name), cs); @@ -789,7 +789,7 @@ static bool CheckCommandFlags(const CommandPacket *cp, const NetworkClientInfo * */ DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_COMMAND) { - NetworkClientState *new_cs; + NetworkTCPSocketHandler *new_cs; const NetworkClientInfo *ci; byte callback; @@ -888,7 +888,7 @@ DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_ERROR) { // This packets means a client noticed an error and is reporting this // to us. Display the error and report it to the other clients - NetworkClientState *new_cs; + NetworkTCPSocketHandler *new_cs; char str[100]; char client_name[NETWORK_CLIENT_NAME_LENGTH]; NetworkErrorCode errorno = (NetworkErrorCode)NetworkRecv_uint8(cs, p); @@ -920,7 +920,7 @@ DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_QUIT) { // The client wants to leave. Display this and report it to the other // clients. - NetworkClientState *new_cs; + NetworkTCPSocketHandler *new_cs; char str[100]; char client_name[NETWORK_CLIENT_NAME_LENGTH]; @@ -978,7 +978,7 @@ DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_ACK) void NetworkServer_HandleChat(NetworkAction action, DestType desttype, int dest, const char *msg, uint16 from_index) { - NetworkClientState *cs; + NetworkTCPSocketHandler *cs; const NetworkClientInfo *ci, *ci_own, *ci_to; switch (desttype) { @@ -1141,7 +1141,7 @@ DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_RCON) } // The layout for the receive-functions by the server -typedef void NetworkServerPacket(NetworkClientState *cs, Packet *p); +typedef void NetworkServerPacket(NetworkTCPSocketHandler *cs, Packet *p); // This array matches PacketType. At an incoming @@ -1193,7 +1193,7 @@ void NetworkPopulateCompanyInfo(void) const Player *p; const Vehicle *v; const Station *s; - const NetworkClientState *cs; + NetworkTCPSocketHandler *cs; const NetworkClientInfo *ci; uint i; uint16 months_empty; @@ -1302,7 +1302,7 @@ void NetworkPopulateCompanyInfo(void) // Send a packet to all clients with updated info about this client_index void NetworkUpdateClientInfo(uint16 client_index) { - NetworkClientState *cs; + NetworkTCPSocketHandler *cs; NetworkClientInfo *ci = NetworkFindClientInfoFromIndex(client_index); if (ci == NULL) return; @@ -1329,7 +1329,7 @@ static void NetworkCheckRestartMap(void) (and item 1. happens a year later) */ static void NetworkAutoCleanCompanies(void) { - const NetworkClientState *cs; + NetworkTCPSocketHandler *cs; const NetworkClientInfo *ci; const Player *p; bool clients_in_company[MAX_PLAYERS]; @@ -1382,7 +1382,7 @@ static void NetworkAutoCleanCompanies(void) // and it returns true if that succeeded. bool NetworkFindName(char new_name[NETWORK_CLIENT_NAME_LENGTH]) { - NetworkClientState *new_cs; + NetworkTCPSocketHandler *new_cs; bool found_name = false; byte number = 0; char original_name[NETWORK_CLIENT_NAME_LENGTH]; @@ -1421,7 +1421,7 @@ bool NetworkFindName(char new_name[NETWORK_CLIENT_NAME_LENGTH]) } // Reads a packet from the stream -bool NetworkServer_ReadPackets(NetworkClientState *cs) +bool NetworkServer_ReadPackets(NetworkTCPSocketHandler *cs) { Packet *p; NetworkRecvStatus res; @@ -1439,7 +1439,7 @@ bool NetworkServer_ReadPackets(NetworkClientState *cs) } // Handle the local command-queue -static void NetworkHandleCommandQueue(NetworkClientState* cs) +static void NetworkHandleCommandQueue(NetworkTCPSocketHandler* cs) { CommandPacket *cp; @@ -1454,7 +1454,7 @@ static void NetworkHandleCommandQueue(NetworkClientState* cs) // This is called every tick if this is a _network_server void NetworkServer_Tick(bool send_frame) { - NetworkClientState *cs; + NetworkTCPSocketHandler *cs; #ifndef ENABLE_NETWORK_SYNC_EVERY_FRAME bool send_sync = false; #endif diff --git a/src/network/network_server.h b/src/network/network_server.h index c5b2baade..3924a6062 100644 --- a/src/network/network_server.h +++ b/src/network/network_server.h @@ -6,16 +6,16 @@ #ifdef ENABLE_NETWORK DEF_SERVER_SEND_COMMAND(PACKET_SERVER_MAP); -DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_ERROR_QUIT)(NetworkClientState *cs, uint16 client_index, NetworkErrorCode errorno); -DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_ERROR)(NetworkClientState *cs, NetworkErrorCode error); +DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_ERROR_QUIT)(NetworkTCPSocketHandler *cs, uint16 client_index, NetworkErrorCode errorno); +DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_ERROR)(NetworkTCPSocketHandler *cs, NetworkErrorCode error); DEF_SERVER_SEND_COMMAND(PACKET_SERVER_SHUTDOWN); DEF_SERVER_SEND_COMMAND(PACKET_SERVER_NEWGAME); -DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_RCON)(NetworkClientState *cs, uint16 color, const char *command); +DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_RCON)(NetworkTCPSocketHandler *cs, uint16 color, const char *command); bool NetworkFindName(char new_name[NETWORK_CLIENT_NAME_LENGTH]); void NetworkServer_HandleChat(NetworkAction action, DestType type, int dest, const char *msg, uint16 from_index); -bool NetworkServer_ReadPackets(NetworkClientState *cs); +bool NetworkServer_ReadPackets(NetworkTCPSocketHandler *cs); void NetworkServer_Tick(bool send_frame); void NetworkServerMonthlyLoop(void); void NetworkServerYearlyLoop(void); diff --git a/src/network/network_udp.cpp b/src/network/network_udp.cpp index 6e0ee8edc..f6ef19fe3 100644 --- a/src/network/network_udp.cpp +++ b/src/network/network_udp.cpp @@ -93,7 +93,7 @@ DEF_UDP_RECEIVE_COMMAND(Server, PACKET_UDP_CLIENT_FIND_SERVER) DEF_UDP_RECEIVE_COMMAND(Server, PACKET_UDP_CLIENT_DETAIL_INFO) { - NetworkClientState *cs; + NetworkTCPSocketHandler *cs; NetworkClientInfo *ci; Packet *packet; Player *player; @@ -221,7 +221,7 @@ DEF_UDP_RECEIVE_COMMAND(Server, PACKET_UDP_CLIENT_GET_NEWGRFS) DEBUG(net, 6, "[udp] newgrf data request from %s:%d", inet_ntoa(client_addr->sin_addr), ntohs(client_addr->sin_port)); - num_grfs = NetworkRecv_uint8 (&this->cs, p); + num_grfs = NetworkRecv_uint8 (this, p); if (num_grfs > NETWORK_MAX_GRF_COUNT) return; for (i = 0; i < num_grfs; i++) { @@ -360,14 +360,15 @@ DEF_UDP_RECEIVE_COMMAND(Client, PACKET_UDP_MASTER_RESPONSE_LIST) * an uint32 (ip) and an uint16 (port) for each pair */ - ver = NetworkRecv_uint8(&this->cs, p); - - if (this->cs.has_quit) return; + ver = NetworkRecv_uint8(this, p); if (ver == 1) { - for (i = NetworkRecv_uint16(&this->cs, p); i != 0 ; i--) { - ip.s_addr = TO_LE32(NetworkRecv_uint32(&this->cs, p)); - port = NetworkRecv_uint16(&this->cs, p); + for (i = NetworkRecv_uint16(this, p); i != 0 ; i--) { + ip.s_addr = TO_LE32(NetworkRecv_uint32(this, p)); + port = NetworkRecv_uint16(this, p); + + /* Somehow we reached the end of the packet */ + if (this->HasClientQuit()) return; NetworkUDPQueryServer(inet_ntoa(ip), port); } } @@ -381,7 +382,7 @@ DEF_UDP_RECEIVE_COMMAND(Client, PACKET_UDP_SERVER_NEWGRFS) DEBUG(net, 6, "[udp] newgrf data reply from %s:%d", inet_ntoa(client_addr->sin_addr), ntohs(client_addr->sin_port)); - num_grfs = NetworkRecv_uint8 (&this->cs, p); + num_grfs = NetworkRecv_uint8 (this, p); if (num_grfs > NETWORK_MAX_GRF_COUNT) return; for (i = 0; i < num_grfs; i++) { @@ -390,7 +391,7 @@ DEF_UDP_RECEIVE_COMMAND(Client, PACKET_UDP_SERVER_NEWGRFS) GRFConfig c; this->Recv_GRFIdentifier(p, &c); - NetworkRecv_string(&this->cs, p, name, sizeof(name)); + NetworkRecv_string(this, p, name, sizeof(name)); /* An empty name is not possible under normal circumstances * and causes problems when showing the NewGRF list. */ @@ -465,7 +466,7 @@ void NetworkUDPQueryMasterServer(void) struct sockaddr_in out_addr; Packet *p; - if (!_udp_client_socket->IsListening()) { + if (!_udp_client_socket->IsConnected()) { if (!_udp_client_socket->Listen(0, 0, true)) return; } @@ -492,7 +493,7 @@ void NetworkUDPSearchGame(void) if (_network_udp_broadcast > 0) return; // No UDP-socket yet.. - if (!_udp_client_socket->IsListening()) { + if (!_udp_client_socket->IsConnected()) { if (!_udp_client_socket->Listen(0, 0, true)) return; } @@ -509,7 +510,7 @@ NetworkGameList *NetworkUDPQueryServer(const char* host, unsigned short port) NetworkGameList *item; // No UDP-socket yet.. - if (!_udp_client_socket->IsListening()) { + if (!_udp_client_socket->IsConnected()) { if (!_udp_client_socket->Listen(0, 0, true)) return NULL; } @@ -545,7 +546,7 @@ void NetworkUDPRemoveAdvertise(void) if (!_networking || !_network_server || !_network_udp_server) return; /* check for socket */ - if (!_udp_master_socket->IsListening()) { + if (!_udp_master_socket->IsConnected()) { if (!_udp_master_socket->Listen(0, 0, false)) return; } @@ -578,7 +579,7 @@ void NetworkUDPAdvertise(void) return; /* check for socket */ - if (!_udp_master_socket->IsListening()) { + if (!_udp_master_socket->IsConnected()) { if (!_udp_master_socket->Listen(0, 0, false)) return; } |