shithub: choc

Download patch

ref: 8df3eb7ce027ec1a73c8fce879ee0d59ac4e49c9
parent: 0a55e76dc58993267abb4b0cde944f1babecc242
author: Simon Howard <[email protected]>
date: Sat Jan 7 23:52:26 EST 2006

Allow the server to reject clients

Subversion-branch: /trunk/chocolate-doom
Subversion-revision: 268

--- 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 @@
                          && 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 @@
     // 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;
         }
--- 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_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 @@
         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
 
@@ -217,33 +235,6 @@
             NET_WriteInt16(packet, NET_PACKET_TYPE_KEEPALIVE);
             NET_Conn_SendPacket(conn, packet);
             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)
--- 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 @@
 {
     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,
--- 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 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 @@
     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 @@
                             net_addr_t *addr)
 {
     unsigned int magic;
+    unsigned int cl_gamemode, cl_gamemission;
     int i;
 
     // read the magic number
@@ -212,6 +231,14 @@
         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 @@
 
     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;