From 8df3eb7ce027ec1a73c8fce879ee0d59ac4e49c9 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sun, 8 Jan 2006 04:52:26 +0000 Subject: Allow the server to reject clients Subversion-branch: /trunk/chocolate-doom Subversion-revision: 268 --- src/net_client.c | 32 ++++++++++++++++++++++++++++-- src/net_common.c | 47 ++++++++++++++++++-------------------------- src/net_defs.h | 6 +++++- src/net_server.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 113 insertions(+), 32 deletions(-) diff --git a/src/net_client.c b/src/net_client.c index b2fef28a..bb2a60f9 100644 --- a/src/net_client.c +++ b/src/net_client.c @@ -1,7 +1,7 @@ // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // -// $Id: net_client.c 267 2006-01-08 03:36:40Z fraggle $ +// $Id: net_client.c 268 2006-01-08 04:52:26Z fraggle $ // // Copyright(C) 2005 Simon Howard // @@ -21,6 +21,9 @@ // 02111-1307, USA. // // $Log$ +// Revision 1.13 2006/01/08 04:52:26 fraggle +// Allow the server to reject clients +// // Revision 1.12 2006/01/08 03:36:40 fraggle // Fix double free of addresses // @@ -262,11 +265,25 @@ void NET_CL_Run(void) && client_state == CLIENT_STATE_WAITING_START; } +static void NET_CL_SendSYN(void) +{ + net_packet_t *packet; + + packet = NET_NewPacket(10); + NET_WriteInt16(packet, NET_PACKET_TYPE_SYN); + NET_WriteInt32(packet, NET_MAGIC_NUMBER); + NET_WriteInt16(packet, gamemode); + NET_WriteInt16(packet, gamemission); + NET_Conn_SendPacket(&client_connection, packet); + NET_FreePacket(packet); +} + // connect to a server boolean NET_CL_Connect(net_addr_t *addr) { int start_time; + int last_send_time; server_addr = addr; @@ -293,12 +310,23 @@ boolean NET_CL_Connect(net_addr_t *addr) // try to connect start_time = I_GetTimeMS(); + last_send_time = -1; while (client_connection.state == NET_CONN_STATE_CONNECTING) { + int nowtime = I_GetTimeMS(); + + // Send a SYN packet every second. + + if (nowtime - last_send_time > 1000 || last_send_time < 0) + { + NET_CL_SendSYN(); + last_send_time = nowtime; + } + // time out after 5 seconds - if (I_GetTimeMS() - start_time > 5000) + if (nowtime - start_time > 5000) { break; } diff --git a/src/net_common.c b/src/net_common.c index 8af6b8d6..a89b1bba 100644 --- a/src/net_common.c +++ b/src/net_common.c @@ -1,7 +1,7 @@ // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // -// $Id: net_common.c 264 2006-01-08 02:53:05Z fraggle $ +// $Id: net_common.c 268 2006-01-08 04:52:26Z fraggle $ // // Copyright(C) 2005 Simon Howard // @@ -21,6 +21,9 @@ // 02111-1307, USA. // // $Log$ +// Revision 1.3 2006/01/08 04:52:26 fraggle +// Allow the server to reject clients +// // Revision 1.2 2006/01/08 02:53:05 fraggle // Send keepalives if the connection is not doing anything else. // Send all packets using a new NET_Conn_SendPacket to support this. @@ -143,6 +146,18 @@ static void NET_Conn_ParseDisconnectACK(net_connection_t *conn, } } +static void NET_Conn_ParseReject(net_connection_t *conn, net_packet_t *packet) +{ + if (conn->state == NET_CONN_STATE_CONNECTING) + { + // rejected by server + + conn->state = NET_CONN_STATE_DISCONNECTED; + + // there is a rejection message here, but it is unused at the moment. + } +} + // Process a packet received by the server // // Returns true if eaten by common code @@ -166,6 +181,9 @@ boolean NET_Conn_Packet(net_connection_t *conn, net_packet_t *packet, case NET_PACKET_TYPE_KEEPALIVE: // No special action needed. break; + case NET_PACKET_TYPE_REJECTED: + NET_Conn_ParseReject(conn, packet); + break; default: // Not a common packet @@ -219,33 +237,6 @@ void NET_Conn_Run(net_connection_t *conn) NET_FreePacket(packet); } } - else if (conn->state == NET_CONN_STATE_CONNECTING) - { - if (conn->last_send_time < 0 - || nowtime - conn->last_send_time > 1000) - { - // It has been a second since the last SYN was sent, and no - // reply. - - if (conn->num_retries < MAX_RETRIES) - { - // send another SYN - - packet = NET_NewPacket(10); - NET_WriteInt16(packet, NET_PACKET_TYPE_SYN); - NET_WriteInt32(packet, NET_MAGIC_NUMBER); - NET_Conn_SendPacket(conn, packet); - NET_FreePacket(packet); - conn->last_send_time = nowtime; - - ++conn->num_retries; - } - else - { - conn->state = NET_CONN_STATE_DISCONNECTED; - } - } - } else if (conn->state == NET_CONN_STATE_WAITING_ACK) { if (conn->last_send_time < 0 diff --git a/src/net_defs.h b/src/net_defs.h index cc5658bf..ccaa3a08 100644 --- a/src/net_defs.h +++ b/src/net_defs.h @@ -1,7 +1,7 @@ // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // -// $Id: net_defs.h 264 2006-01-08 02:53:05Z fraggle $ +// $Id: net_defs.h 268 2006-01-08 04:52:26Z fraggle $ // // Copyright(C) 2005 Simon Howard // @@ -21,6 +21,9 @@ // 02111-1307, USA. // // $Log$ +// Revision 1.6 2006/01/08 04:52:26 fraggle +// Allow the server to reject clients +// // Revision 1.5 2006/01/08 02:53:05 fraggle // Send keepalives if the connection is not doing anything else. // Send all packets using a new NET_Conn_SendPacket to support this. @@ -115,6 +118,7 @@ typedef enum { NET_PACKET_TYPE_SYN, NET_PACKET_TYPE_ACK, + NET_PACKET_TYPE_REJECTED, NET_PACKET_TYPE_KEEPALIVE, NET_PACKET_TYPE_WAITING_DATA, NET_PACKET_TYPE_GAMESTART, diff --git a/src/net_server.c b/src/net_server.c index 90e3e87a..d1cdfc82 100644 --- a/src/net_server.c +++ b/src/net_server.c @@ -1,7 +1,7 @@ // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // -// $Id: net_server.c 266 2006-01-08 03:36:17Z fraggle $ +// $Id: net_server.c 268 2006-01-08 04:52:26Z fraggle $ // // Copyright(C) 2005 Simon Howard // @@ -21,6 +21,9 @@ // 02111-1307, USA. // // $Log$ +// Revision 1.15 2006/01/08 04:52:26 fraggle +// Allow the server to reject clients +// // Revision 1.14 2006/01/08 03:36:17 fraggle // Fix packet send // @@ -113,6 +116,8 @@ static net_server_state_t server_state; static boolean server_initialised = false; static net_client_t clients[MAXNETNODES]; static net_context_t *server_context; +static int sv_gamemode; +static int sv_gamemission; static void NET_SV_DisconnectClient(net_client_t *client) { @@ -189,6 +194,19 @@ static net_client_t *NET_SV_FindClient(net_addr_t *addr) return NULL; } +// send a rejection packet to a client + +static void NET_SV_SendReject(net_addr_t *addr, char *msg) +{ + net_packet_t *packet; + + packet = NET_NewPacket(10); + NET_WriteInt16(packet, NET_PACKET_TYPE_REJECTED); + NET_WriteString(packet, msg); + NET_SendPacket(addr, packet); + NET_FreePacket(packet); +} + // parse a SYN from a client(initiating a connection) static void NET_SV_ParseSYN(net_packet_t *packet, @@ -196,6 +214,7 @@ static void NET_SV_ParseSYN(net_packet_t *packet, net_addr_t *addr) { unsigned int magic; + unsigned int cl_gamemode, cl_gamemission; int i; // read the magic number @@ -212,6 +231,14 @@ static void NET_SV_ParseSYN(net_packet_t *packet, return; } + // read the game mode and mission + + if (!NET_ReadInt16(packet, &cl_gamemode) + || !NET_ReadInt16(packet, &cl_gamemission)) + { + return; + } + // received a valid SYN // allocate a client slot if there isn't one already @@ -249,7 +276,38 @@ static void NET_SV_ParseSYN(net_packet_t *packet, if (!client->active) { + int num_clients; + + // Before accepting a new client, check that there is a slot + // free + + num_clients = NET_SV_NumClients(); + + if (num_clients >= MAXPLAYERS) + { + NET_SV_SendReject(addr, "Server is full!"); + return; + } + + // Adopt the game mode and mission of the first connecting client + + if (num_clients == 0) + { + sv_gamemode = cl_gamemode; + sv_gamemission = cl_gamemission; + } + + // Check the connecting client is playing the same game as all + // the other clients + + if (cl_gamemode != sv_gamemode || cl_gamemission != sv_gamemission) + { + NET_SV_SendReject(addr, "You are playing the wrong game!"); + return; + } + // Activate, initialise connection + client->active = true; NET_Conn_InitServer(&client->connection, addr); client->addr = addr; -- cgit v1.2.3