(svn r15079) -Codechange: split tcp 'backend' and in-game handling like it is for UDP.

pull/155/head
rubidium 16 years ago
parent 9724a986c8
commit 850a2735cc

@ -3231,6 +3231,14 @@
RelativePath=".\..\src\network\core\tcp.h"
>
</File>
<File
RelativePath=".\..\src\network\core\tcp_game.cpp"
>
</File>
<File
RelativePath=".\..\src\network\core\tcp_game.h"
>
</File>
<File
RelativePath=".\..\src\network\core\udp.cpp"
>

@ -3228,6 +3228,14 @@
RelativePath=".\..\src\network\core\tcp.h"
>
</File>
<File
RelativePath=".\..\src\network\core\tcp_game.cpp"
>
</File>
<File
RelativePath=".\..\src\network\core\tcp_game.h"
>
</File>
<File
RelativePath=".\..\src\network\core\udp.cpp"
>

@ -776,6 +776,8 @@ network/core/packet.cpp
network/core/packet.h
network/core/tcp.cpp
network/core/tcp.h
network/core/tcp_game.cpp
network/core/tcp_game.h
network/core/udp.cpp
network/core/udp.h

@ -43,7 +43,7 @@ public:
SOCKET sock; ///< The socket currently connected to
public:
/** Create a new unbound socket */
NetworkSocketHandler() { this->sock = INVALID_SOCKET; this->has_quit = false; }
NetworkSocketHandler(SOCKET s = INVALID_SOCKET) { this->sock = s; this->has_quit = false; }
/** Close the socket when distructing the socket handler */
virtual ~NetworkSocketHandler() { this->Close(); }

@ -8,31 +8,17 @@
#include "../../stdafx.h"
#include "../../debug.h"
#include "../../openttd.h"
#include "../../variables.h"
#include "../network_internal.h"
#include "packet.h"
#include "tcp.h"
#include "table/strings.h"
#include "../../oldpool_func.h"
/** Make very sure the preconditions given in network_type.h are actually followed */
assert_compile(MAX_CLIENT_SLOTS == (MAX_CLIENT_SLOTS >> NCI_BITS_PER_POOL_BLOCK) << NCI_BITS_PER_POOL_BLOCK);
assert_compile(MAX_CLIENT_SLOTS > MAX_CLIENTS);
typedef ClientIndex NetworkClientSocketID;
DEFINE_OLD_POOL_GENERIC(NetworkClientSocket, NetworkClientSocket);
NetworkClientSocket::NetworkClientSocket(ClientID client_id)
NetworkTCPSocketHandler::NetworkTCPSocketHandler(SOCKET s) :
NetworkSocketHandler(s),
packet_queue(NULL), packet_recv(NULL), writable(false)
{
this->sock = INVALID_SOCKET;
this->client_id = client_id;
this->status = STATUS_INACTIVE;
}
NetworkClientSocket::~NetworkClientSocket()
NetworkTCPSocketHandler::~NetworkTCPSocketHandler()
{
if (this->sock != INVALID_SOCKET) closesocket(this->sock);
this->writable = false;
@ -47,39 +33,7 @@ NetworkClientSocket::~NetworkClientSocket()
delete this->packet_recv;
this->packet_recv = NULL;
while (this->command_queue != NULL) {
CommandPacket *p = this->command_queue->next;
free(this->command_queue);
this->command_queue = p;
}
this->sock = INVALID_SOCKET;
this->client_id = INVALID_CLIENT_ID;
this->status = STATUS_INACTIVE;
}
/**
* Functions to help NetworkRecv_Packet/NetworkSend_Packet a bit
* A socket can make errors. When that happens this handles what to do.
* 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 NetworkClientSocket::CloseConnection()
{
/* Clients drop back to the main menu */
if (!_network_server && _networking) {
_switch_mode = SM_MENU;
_networking = false;
extern StringID _switch_mode_errorstr;
_switch_mode_errorstr = STR_NETWORK_ERR_LOSTCONNECTION;
return NETWORK_RECV_STATUS_CONN_LOST;
}
NetworkCloseClient(this);
return NETWORK_RECV_STATUS_OKAY;
}
/**
@ -88,7 +42,7 @@ NetworkRecvStatus NetworkClientSocket::CloseConnection()
* if the OS-network-buffer is full)
* @param packet the packet to send
*/
void NetworkClientSocket::Send_Packet(Packet *packet)
void NetworkTCPSocketHandler::Send_Packet(Packet *packet)
{
Packet *p;
assert(packet != NULL);
@ -114,7 +68,7 @@ void NetworkClientSocket::Send_Packet(Packet *packet)
* data right now (full network-buffer, it happens ;))
* 3) sending took too long
*/
bool NetworkClientSocket::Send_Packets()
bool NetworkTCPSocketHandler::Send_Packets()
{
ssize_t res;
Packet *p;
@ -163,7 +117,7 @@ bool NetworkClientSocket::Send_Packets()
* @param status the variable to store the status into
* @return the received packet (or NULL when it didn't receive one)
*/
Packet *NetworkClientSocket::Recv_Packet(NetworkRecvStatus *status)
Packet *NetworkTCPSocketHandler::Recv_Packet(NetworkRecvStatus *status)
{
ssize_t res;
Packet *p;
@ -242,7 +196,7 @@ Packet *NetworkClientSocket::Recv_Packet(NetworkRecvStatus *status)
return p;
}
bool NetworkClientSocket::IsPacketQueueEmpty()
bool NetworkTCPSocketHandler::IsPacketQueueEmpty()
{
return this->packet_queue == NULL;
}

@ -13,114 +13,24 @@
#include "core.h"
#include "packet.h"
/**
* Enum with all types of UDP packets.
* The order of the first 4 packets MUST not be changed, as
* it protects old clients from joining newer servers
* (because SERVER_ERROR is the respond to a wrong revision)
*/
enum {
PACKET_SERVER_FULL,
PACKET_SERVER_BANNED,
PACKET_CLIENT_JOIN,
PACKET_SERVER_ERROR,
PACKET_CLIENT_COMPANY_INFO,
PACKET_SERVER_COMPANY_INFO,
PACKET_SERVER_CLIENT_INFO,
PACKET_SERVER_NEED_PASSWORD,
PACKET_CLIENT_PASSWORD,
PACKET_SERVER_WELCOME,
PACKET_CLIENT_GETMAP,
PACKET_SERVER_WAIT,
PACKET_SERVER_MAP,
PACKET_CLIENT_MAP_OK,
PACKET_SERVER_JOIN,
PACKET_SERVER_FRAME,
PACKET_SERVER_SYNC,
PACKET_CLIENT_ACK,
PACKET_CLIENT_COMMAND,
PACKET_SERVER_COMMAND,
PACKET_CLIENT_CHAT,
PACKET_SERVER_CHAT,
PACKET_CLIENT_SET_PASSWORD,
PACKET_CLIENT_SET_NAME,
PACKET_CLIENT_QUIT,
PACKET_CLIENT_ERROR,
PACKET_SERVER_QUIT,
PACKET_SERVER_ERROR_QUIT,
PACKET_SERVER_SHUTDOWN,
PACKET_SERVER_NEWGAME,
PACKET_SERVER_RCON,
PACKET_CLIENT_RCON,
PACKET_SERVER_CHECK_NEWGRFS,
PACKET_CLIENT_NEWGRFS_CHECKED,
PACKET_END ///< Must ALWAYS be on the end of this list!! (period)
};
/** Packet that wraps a command */
struct CommandPacket;
/** Status of a client */
enum ClientStatus {
STATUS_INACTIVE, ///< The client is not connected nor active
STATUS_AUTHORIZING,///< The client is authorizing
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 active within in the game
};
class NetworkClientSocket;
DECLARE_OLD_POOL(NetworkClientSocket, NetworkClientSocket, NCI_BITS_PER_POOL_BLOCK, MAX_CLIENT_SLOTS >> NCI_BITS_PER_POOL_BLOCK);
/** Base socket handler for all TCP sockets */
class NetworkClientSocket : public PoolItem<NetworkClientSocket, ClientIndex, &_NetworkClientSocket_pool>, public NetworkSocketHandler {
/* TODO: rewrite into a proper class */
class NetworkTCPSocketHandler : public NetworkSocketHandler {
private:
Packet *packet_queue; ///< Packets that are awaiting delivery
Packet *packet_recv; ///< Partially received packet
NetworkClientInfo *info; ///< Client info related to this socket
public:
ClientID client_id; ///< Client identifier
uint32 last_frame; ///< Last frame we have executed
uint32 last_frame_server; ///< Last frame the server has executed
byte lag_test; ///< Byte used for lag-testing the client
ClientStatus status; ///< Status of this client
bool writable; ///< Can we write to this socket?
CommandPacket *command_queue; ///< The command-queue awaiting delivery
NetworkRecvStatus CloseConnection();
void Send_Packet(Packet *packet);
bool Send_Packets();
bool IsPacketQueueEmpty();
Packet *Recv_Packet(NetworkRecvStatus *status);
NetworkClientSocket(ClientID client_id = INVALID_CLIENT_ID);
~NetworkClientSocket();
inline bool IsValid() const { return this->IsConnected(); }
inline void SetInfo(NetworkClientInfo *info) { assert(info != NULL && this->info == NULL); this->info = info; }
inline NetworkClientInfo *GetInfo() const { return this->info; }
const char *Recv_Command(Packet *p, CommandPacket *cp);
void Send_Command(Packet *p, const CommandPacket *cp);
NetworkTCPSocketHandler(SOCKET s = INVALID_SOCKET);
~NetworkTCPSocketHandler();
};
static inline bool IsValidNetworkClientSocketIndex(ClientIndex index)
{
return (uint)index < GetNetworkClientSocketPoolSize() && GetNetworkClientSocket(index)->IsValid();
}
#define FOR_ALL_CLIENT_SOCKETS_FROM(d, start) for (d = GetNetworkClientSocket(start); d != NULL; d = (d->index + 1U < GetNetworkClientSocketPoolSize()) ? GetNetworkClientSocket(d->index + 1U) : NULL) if (d->IsValid())
#define FOR_ALL_CLIENT_SOCKETS(d) FOR_ALL_CLIENT_SOCKETS_FROM(d, 0)
#endif /* ENABLE_NETWORK */
#endif /* NETWORK_CORE_TCP_H */

@ -0,0 +1,69 @@
/* $Id$ */
/**
* @file tcp_game.cpp Basic functions to receive and send TCP packets for game purposes.
*/
#ifdef ENABLE_NETWORK
#include "../../stdafx.h"
#include "../../openttd.h"
#include "../../variables.h"
#include "../network_internal.h"
#include "packet.h"
#include "tcp_game.h"
#include "table/strings.h"
#include "../../oldpool_func.h"
/** Make very sure the preconditions given in network_type.h are actually followed */
assert_compile(MAX_CLIENT_SLOTS == (MAX_CLIENT_SLOTS >> NCI_BITS_PER_POOL_BLOCK) << NCI_BITS_PER_POOL_BLOCK);
assert_compile(MAX_CLIENT_SLOTS > MAX_CLIENTS);
typedef ClientIndex NetworkClientSocketID;
DEFINE_OLD_POOL_GENERIC(NetworkClientSocket, NetworkClientSocket);
NetworkClientSocket::NetworkClientSocket(ClientID client_id)
{
this->client_id = client_id;
this->status = STATUS_INACTIVE;
}
NetworkClientSocket::~NetworkClientSocket()
{
while (this->command_queue != NULL) {
CommandPacket *p = this->command_queue->next;
free(this->command_queue);
this->command_queue = p;
}
this->client_id = INVALID_CLIENT_ID;
this->status = STATUS_INACTIVE;
}
/**
* Functions to help NetworkRecv_Packet/NetworkSend_Packet a bit
* A socket can make errors. When that happens this handles what to do.
* 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 NetworkClientSocket::CloseConnection()
{
/* Clients drop back to the main menu */
if (!_network_server && _networking) {
_switch_mode = SM_MENU;
_networking = false;
extern StringID _switch_mode_errorstr;
_switch_mode_errorstr = STR_NETWORK_ERR_LOSTCONNECTION;
return NETWORK_RECV_STATUS_CONN_LOST;
}
NetworkCloseClient(this);
return NETWORK_RECV_STATUS_OKAY;
}
#endif /* ENABLE_NETWORK */

@ -0,0 +1,117 @@
/* $Id$ */
/**
* @file tcp_game.h Basic functions to receive and send TCP packets for game purposes.
*/
#ifndef NETWORK_CORE_TCP_GAME_H
#define NETWORK_CORE_TCP_GAME_H
#ifdef ENABLE_NETWORK
#include "os_abstraction.h"
#include "tcp.h"
#include "packet.h"
/**
* Enum with all types of UDP packets.
* The order of the first 4 packets MUST not be changed, as
* it protects old clients from joining newer servers
* (because SERVER_ERROR is the respond to a wrong revision)
*/
enum {
PACKET_SERVER_FULL,
PACKET_SERVER_BANNED,
PACKET_CLIENT_JOIN,
PACKET_SERVER_ERROR,
PACKET_CLIENT_COMPANY_INFO,
PACKET_SERVER_COMPANY_INFO,
PACKET_SERVER_CLIENT_INFO,
PACKET_SERVER_NEED_PASSWORD,
PACKET_CLIENT_PASSWORD,
PACKET_SERVER_WELCOME,
PACKET_CLIENT_GETMAP,
PACKET_SERVER_WAIT,
PACKET_SERVER_MAP,
PACKET_CLIENT_MAP_OK,
PACKET_SERVER_JOIN,
PACKET_SERVER_FRAME,
PACKET_SERVER_SYNC,
PACKET_CLIENT_ACK,
PACKET_CLIENT_COMMAND,
PACKET_SERVER_COMMAND,
PACKET_CLIENT_CHAT,
PACKET_SERVER_CHAT,
PACKET_CLIENT_SET_PASSWORD,
PACKET_CLIENT_SET_NAME,
PACKET_CLIENT_QUIT,
PACKET_CLIENT_ERROR,
PACKET_SERVER_QUIT,
PACKET_SERVER_ERROR_QUIT,
PACKET_SERVER_SHUTDOWN,
PACKET_SERVER_NEWGAME,
PACKET_SERVER_RCON,
PACKET_CLIENT_RCON,
PACKET_SERVER_CHECK_NEWGRFS,
PACKET_CLIENT_NEWGRFS_CHECKED,
PACKET_END ///< Must ALWAYS be on the end of this list!! (period)
};
/** Packet that wraps a command */
struct CommandPacket;
/** Status of a client */
enum ClientStatus {
STATUS_INACTIVE, ///< The client is not connected nor active
STATUS_AUTHORIZING,///< The client is authorizing
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 active within in the game
};
class NetworkClientSocket;
DECLARE_OLD_POOL(NetworkClientSocket, NetworkClientSocket, NCI_BITS_PER_POOL_BLOCK, MAX_CLIENT_SLOTS >> NCI_BITS_PER_POOL_BLOCK);
/** Base socket handler for all TCP sockets */
class NetworkClientSocket : public PoolItem<NetworkClientSocket, ClientIndex, &_NetworkClientSocket_pool>, public NetworkTCPSocketHandler {
/* TODO: rewrite into a proper class */
private:
NetworkClientInfo *info; ///< Client info related to this socket
public:
ClientID client_id; ///< Client identifier
uint32 last_frame; ///< Last frame we have executed
uint32 last_frame_server; ///< Last frame the server has executed
byte lag_test; ///< Byte used for lag-testing the client
ClientStatus status; ///< Status of this client
CommandPacket *command_queue; ///< The command-queue awaiting delivery
NetworkRecvStatus CloseConnection();
NetworkClientSocket(ClientID client_id = INVALID_CLIENT_ID);
~NetworkClientSocket();
inline bool IsValid() const { return this->IsConnected(); }
inline void SetInfo(NetworkClientInfo *info) { assert(info != NULL && this->info == NULL); this->info = info; }
inline NetworkClientInfo *GetInfo() const { return this->info; }
const char *Recv_Command(Packet *p, CommandPacket *cp);
void Send_Command(Packet *p, const CommandPacket *cp);
};
static inline bool IsValidNetworkClientSocketIndex(ClientIndex index)
{
return (uint)index < GetNetworkClientSocketPoolSize() && GetNetworkClientSocket(index)->IsValid();
}
#define FOR_ALL_CLIENT_SOCKETS_FROM(d, start) for (d = GetNetworkClientSocket(start); d != NULL; d = (d->index + 1U < GetNetworkClientSocketPoolSize()) ? GetNetworkClientSocket(d->index + 1U) : NULL) if (d->IsValid())
#define FOR_ALL_CLIENT_SOCKETS(d) FOR_ALL_CLIENT_SOCKETS_FROM(d, 0)
#endif /* ENABLE_NETWORK */
#endif /* NETWORK_CORE_TCP_GAME_H */

@ -14,7 +14,7 @@
#include "core/core.h"
#include "core/config.h"
#include "core/packet.h"
#include "core/tcp.h"
#include "core/tcp_game.h"
#include "../command_type.h"

Loading…
Cancel
Save