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;