ref: 37f611e199bd7a300def37c84f7fdb205534ca19
parent: 68e5d0979584d614868f790e2dcf4e5e186415b0
author: Simon Howard <[email protected]>
date: Thu Dec 29 12:48:25 EST 2005
Add initial client/server connect code. Reorganise sources list in Makefile.am. Subversion-branch: /trunk/chocolate-doom Subversion-revision: 232
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -7,33 +7,104 @@
chocolate_doom_LDADD = ../textscreen/libtextscreen.a @LDFLAGS@ @SDL_LIBS@ @SDLMIXER_LIBS@ @SDLNET_LIBS@
SOURCE_FILES=\
-am_map.c d_think.h i_video.c p_floor.c p_tick.c r_things.h \
-am_map.h d_ticcmd.h i_video.h p_inter.c p_tick.h sounds.c \
-d_englsh.h f_finale.c m_argv.c p_inter.h p_user.c sounds.h \
-d_event.h f_finale.h m_argv.h p_lights.c r_bsp.c s_sound.c \
-d_french.h f_wipe.c m_bbox.c p_local.h r_bsp.h s_sound.h \
-d_items.c f_wipe.h m_bbox.h p_map.c r_data.c st_lib.c \
-d_items.h g_game.c m_cheat.c p_maputl.c r_data.h st_lib.h \
-d_main.c g_game.h m_cheat.h p_mobj.c r_defs.h st_stuff.c \
-d_main.h hu_lib.c m_fixed.c p_mobj.h r_draw.c st_stuff.h \
-d_net.c hu_lib.h m_fixed.h p_plats.c r_draw.h tables.c \
-d_net.h hu_stuff.c m_menu.c p_pspr.c r_local.h tables.h \
-doomdata.h hu_stuff.h m_menu.h p_pspr.h r_main.c v_video.c \
-doomdef.c i_main.c m_misc.c p_saveg.c r_main.h v_video.h \
-doomdef.h i_net.c m_misc.h p_saveg.h r_plane.c wi_stuff.c \
-doomstat.c i_net.h m_random.c p_setup.c r_plane.h wi_stuff.h \
-doomstat.h info.c m_random.h p_setup.h r_segs.c w_wad.c \
-doomtype.h info.h m_swap.c p_sight.c r_segs.h w_wad.h \
-d_player.h i_sound.c m_swap.h p_spec.c r_sky.c z_zone.c \
-dstrings.c i_sound.h p_ceilng.c p_spec.h r_sky.h z_zone.h \
-dstrings.h i_system.c p_doors.c p_switch.c r_state.h mmus2mid.c \
-d_textur.h i_system.h p_enemy.c p_telept.c r_things.c mmus2mid.h \
-deh_defs.h deh_frame.c deh_main.c deh_ptr.c deh_text.c deh_thing.c \
-deh_io.c deh_io.h deh_ammo.c deh_cheat.c deh_weapon.c \
-deh_misc.c deh_misc.h deh_sound.c deh_main.h doomfeatures.h \
-w_merge.c w_merge.h deh_mapping.c deh_mapping.h \
-net_defs.h net_io.h net_loop.h net_packet.h net_sdl.h \
-net_io.c net_loop.c net_packet.c net_sdl.c
+am_map.c am_map.h \
+deh_ammo.c \
+deh_cheat.c \
+deh_defs.h \
+deh_frame.c \
+deh_io.c deh_io.h \
+deh_main.c deh_main.h \
+deh_mapping.c deh_mapping.h \
+deh_misc.c deh_misc.h \
+deh_ptr.c \
+deh_sound.c \
+deh_text.c \
+deh_thing.c \
+deh_weapon.c \
+d_englsh.h \
+d_event.h \
+d_french.h \
+d_items.c d_items.h \
+d_main.c d_main.h \
+d_net.c d_net.h \
+doomdata.h \
+doomdef.c doomdef.h \
+doomfeatures.h \
+doomstat.c doomstat.h \
+doomtype.h \
+d_player.h \
+dstrings.c dstrings.h \
+d_textur.h \
+d_think.h \
+d_ticcmd.h \
+f_finale.c f_finale.h \
+f_wipe.c f_wipe.h \
+g_game.c g_game.h \
+hu_lib.c hu_lib.h \
+hu_stuff.c hu_stuff.h \
+i_main.c \
+i_net.c i_net.h \
+info.c info.h \
+i_sound.c i_sound.h \
+i_system.c i_system.h \
+i_video.c i_video.h \
+m_argv.c m_argv.h \
+m_bbox.c m_bbox.h \
+m_cheat.c m_cheat.h \
+m_fixed.c m_fixed.h \
+m_menu.c m_menu.h \
+m_misc.c m_misc.h \
+mmus2mid.c mmus2mid.h \
+m_random.c m_random.h \
+m_swap.c m_swap.h \
+net_client.c \
+net_defs.h \
+net_io.c net_io.h \
+net_loop.c net_loop.h \
+net_packet.c net_packet.h \
+net_sdl.c net_sdl.h \
+net_server.c net_server.h \
+p_ceilng.c \
+p_doors.c \
+p_enemy.c \
+p_floor.c \
+p_inter.c p_inter.h \
+p_lights.c \
+p_local.h \
+p_map.c \
+p_maputl.c \
+p_mobj.c p_mobj.h \
+p_plats.c \
+p_pspr.c p_pspr.h \
+p_saveg.c p_saveg.h \
+p_setup.c p_setup.h \
+p_sight.c \
+p_spec.c p_spec.h \
+p_switch.c \
+p_telept.c \
+p_tick.c p_tick.h \
+p_user.c \
+r_bsp.c r_bsp.h \
+r_data.c r_data.h \
+r_defs.h \
+r_draw.c r_draw.h \
+r_local.h \
+r_main.c r_main.h \
+r_plane.c r_plane.h \
+r_segs.c r_segs.h \
+r_sky.c r_sky.h \
+r_state.h \
+r_things.c r_things.h \
+sounds.c sounds.h \
+s_sound.c s_sound.h \
+st_lib.c st_lib.h \
+st_stuff.c st_stuff.h \
+tables.c tables.h \
+v_video.c v_video.h \
+wi_stuff.c wi_stuff.h \
+w_merge.c w_merge.h \
+w_wad.c w_wad.h \
+z_zone.c z_zone.h
if HAVE_WINDRES
chocolate_doom_SOURCES=$(SOURCE_FILES) chocolate-doom-res.rc
--- /dev/null
+++ b/src/net_client.c
@@ -1,0 +1,98 @@
+// Emacs style mode select -*- C++ -*-
+//-----------------------------------------------------------------------------
+//
+// $Id: net_client.c 232 2005-12-29 17:48:25Z fraggle $
+//
+// Copyright(C) 2005 Simon Howard
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+// 02111-1307, USA.
+//
+// $Log$
+// Revision 1.1 2005/12/29 17:48:25 fraggle
+// Add initial client/server connect code. Reorganise sources list in
+// Makefile.am.
+//
+//
+// Network client code
+//
+
+#include "doomdef.h"
+#include "doomstat.h"
+#include "i_system.h"
+#include "net_client.h"
+#include "net_defs.h"
+#include "net_io.h"
+#include "net_packet.h"
+#include "net_server.h"
+
+static net_addr_t *server_addr;
+static net_context_t *client_context;
+
+// connect to a server
+
+boolean NET_ClientConnect(net_addr_t *addr)
+{
+ net_packet_t *packet;
+ int last_send_time = -1;
+
+ server_addr = addr;
+
+ // create a new network I/O context and add just the
+ // necessary module
+
+ client_context = NET_NewContext();
+
+ // initialise module for client mode
+
+ if (!addr->module->InitClient())
+ {
+ return false;
+ }
+
+ NET_AddModule(client_context, addr->module);
+
+ // try to connect
+
+ // construct a SYN packet
+
+ packet = NET_NewPacket(10);
+
+ // packet type
+
+ NET_WriteInt16(packet, NET_PACKET_TYPE_SYN);
+
+ // magic number
+
+ NET_WriteInt32(packet, NET_MAGIC_NUMBER);
+
+ while (true)
+ {
+ if (I_GetTime() - last_send_time > 35)
+ {
+ // resend packet
+
+ NET_SendPacket(addr, packet);
+ last_send_time = I_GetTime();
+ }
+
+ // run the server, just incase we are doing a loopback
+ // connect
+
+ NET_ServerRun();
+ }
+}
+
+
--- /dev/null
+++ b/src/net_client.h
@@ -1,0 +1,40 @@
+// Emacs style mode select -*- C++ -*-
+//-----------------------------------------------------------------------------
+//
+// $Id: net_client.h 232 2005-12-29 17:48:25Z fraggle $
+//
+// Copyright(C) 2005 Simon Howard
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+// 02111-1307, USA.
+//
+// $Log$
+// Revision 1.1 2005/12/29 17:48:25 fraggle
+// Add initial client/server connect code. Reorganise sources list in
+// Makefile.am.
+//
+//
+// Network client code
+//
+
+#ifndef NET_CLIENT_H
+#define NET_CLIENT_H
+
+#include "net_defs.h"
+
+boolean NET_ClietConnect(net_addr_t *addr);
+
+#endif /* #ifndef NET_CLIENT_H */
+
--- a/src/net_defs.h
+++ b/src/net_defs.h
@@ -1,7 +1,7 @@
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
-// $Id: net_defs.h 229 2005-10-30 19:56:15Z fraggle $
+// $Id: net_defs.h 232 2005-12-29 17:48:25Z fraggle $
//
// Copyright(C) 2005 Simon Howard
//
@@ -21,6 +21,10 @@
// 02111-1307, USA.
//
// $Log$
+// Revision 1.2 2005/12/29 17:48:25 fraggle
+// Add initial client/server connect code. Reorganise sources list in
+// Makefile.am.
+//
// Revision 1.1 2005/10/30 19:56:15 fraggle
// Add foundation code for the new networking system
//
@@ -88,6 +92,20 @@
net_module_t *module;
void *handle;
};
+
+// magic number sent when connecting to check this is a valid client
+
+#define NET_MAGIC_NUMBER 3436803284U
+
+// packet types
+
+typedef enum
+{
+ NET_PACKET_TYPE_SYN,
+ NET_PACKET_TYPE_ACK,
+ NET_PACKET_TYPE_GAMESTART,
+ NET_PACKET_TYPE_GAMEDATA,
+} net_packet_type_t;
#endif /* #ifndef NET_DEFS_H */
--- /dev/null
+++ b/src/net_server.c
@@ -1,0 +1,286 @@
+// Emacs style mode select -*- C++ -*-
+//-----------------------------------------------------------------------------
+//
+// $Id: net_server.c 232 2005-12-29 17:48:25Z fraggle $
+//
+// Copyright(C) 2005 Simon Howard
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+// 02111-1307, USA.
+//
+// $Log$
+// Revision 1.1 2005/12/29 17:48:25 fraggle
+// Add initial client/server connect code. Reorganise sources list in
+// Makefile.am.
+//
+//
+// Network server code
+//
+
+#include "doomdef.h"
+#include "doomstat.h"
+#include "i_system.h"
+#include "net_defs.h"
+#include "net_io.h"
+#include "net_loop.h"
+#include "net_packet.h"
+#include "net_server.h"
+
+typedef enum
+{
+ // received a syn, sent an ack, waiting for an ack reply
+
+ CLIENT_STATE_WAITING_ACK,
+
+ // waiting for a game to start
+
+ CLIENT_STATE_WAITING_START,
+
+ // in game
+
+ CLIENT_STATE_IN_GAME,
+
+} net_clientstate_t;
+
+#define MAX_RETRIES 5
+
+typedef struct
+{
+ boolean active;
+ net_clientstate_t state;
+ net_addr_t *addr;
+ int last_send_time;
+ int num_retries;
+} net_client_t;
+
+static boolean server_initialised = false;
+static net_client_t clients[MAXNETNODES];
+static net_context_t *server_context;
+
+// parse a SYN from a client(initiating a connection)
+
+static void NET_ServerParseSYN(net_packet_t *packet,
+ net_client_t *client,
+ net_addr_t *addr)
+{
+ unsigned int magic;
+ int i;
+
+ // read the magic number
+
+ if (!NET_ReadInt16(packet, &magic))
+ {
+ return;
+ }
+
+ if (magic != NET_MAGIC_NUMBER)
+ {
+ // invalid magic number
+
+ return;
+ }
+
+ // received a valid SYN
+
+ // allocate a client slot if there isn't one already
+
+ if (client == NULL)
+ {
+ // find a slot, or return if none found
+
+ for (i=0; i<MAXNETNODES; ++i)
+ {
+ if (!clients[i].active)
+ {
+ clients[i].active = true;
+ clients[i].addr = addr;
+ clients[i].state = CLIENT_STATE_WAITING_ACK;
+ clients[i].num_retries = 0;
+ client = &clients[i];
+ break;
+ }
+ }
+
+ if (client == NULL)
+ {
+ return;
+ }
+ }
+
+ if (client->state == CLIENT_STATE_WAITING_ACK)
+ {
+ // force an acknowledgement
+
+ client->last_send_time = -1;
+ }
+}
+
+// parse an ACK packet from a client
+
+static void NET_ServerParseACK(net_packet_t *packet, net_client_t *client)
+{
+ if (client == NULL)
+ {
+ return;
+ }
+
+ if (client->state == CLIENT_STATE_WAITING_ACK)
+ {
+ // now waiting for the game to start
+
+ client->state = CLIENT_STATE_WAITING_START;
+ }
+}
+
+// Process a packet received by the server
+
+static void NET_ServerPacket(net_packet_t *packet, net_addr_t *addr)
+{
+ net_client_t *client;
+ unsigned int packet_type;
+ int i;
+
+ // find which client this packet came from
+
+ client = NULL;
+
+ for (i=0; i<MAXNETNODES; ++i)
+ {
+ if (clients[i].active && client[i].addr == addr)
+ {
+ // found the client
+
+ client = &clients[i];
+ break;
+ }
+ }
+
+ if (!NET_ReadInt16(packet, &packet_type))
+ {
+ // no packet type
+
+ return;
+ }
+
+ switch (packet_type)
+ {
+ case NET_PACKET_TYPE_SYN:
+ NET_ServerParseSYN(packet, client, addr);
+ break;
+ case NET_PACKET_TYPE_ACK:
+ NET_ServerParseACK(packet, client);
+ break;
+ case NET_PACKET_TYPE_GAMESTART:
+ break;
+ case NET_PACKET_TYPE_GAMEDATA:
+ break;
+ default:
+ // unknown packet type
+
+ break;
+ }
+}
+
+// Perform any needed action on a client
+
+void NET_ServerRunClient(net_client_t *client)
+{
+ net_packet_t *packet;
+
+ if (client->state == CLIENT_STATE_WAITING_ACK)
+ {
+ if (client->last_send_time < 0
+ || I_GetTime() - client->last_send_time > 35)
+ {
+ // it has been a second since the last ACK was sent, and
+ // still no reply.
+
+ if (client->num_retries < MAX_RETRIES)
+ {
+ // send another ACK
+
+ packet = NET_NewPacket(10);
+ NET_WriteInt16(packet, NET_PACKET_TYPE_ACK);
+ NET_SendPacket(client->addr, packet);
+ NET_FreePacket(packet);
+ client->last_send_time = I_GetTime();
+
+ ++client->num_retries;
+ }
+ else
+ {
+ // no more retries allowed.
+
+ NET_FreeAddress(client->addr);
+
+ client->active = false;
+ }
+ }
+ }
+}
+
+// Initialise server and wait for connections
+
+void NET_ServerInit(void)
+{
+ int i;
+
+ // initialise send/receive context, with loopback send/recv
+
+ server_context = NET_NewContext();
+ NET_AddModule(server_context, &net_loop_server_module);
+ net_loop_server_module.InitServer();
+
+ // no clients yet
+
+ for (i=0; i<MAXNETNODES; ++i)
+ {
+ clients[i].active = false;
+ }
+
+ server_initialised = true;
+}
+
+// Run server code to check for new packets/send packets as the server
+// requires
+
+void NET_ServerRun(void)
+{
+ net_addr_t *addr;
+ net_packet_t *packet;
+ int i;
+
+ if (!server_initialised)
+ {
+ return;
+ }
+
+ while (NET_RecvPacket(server_context, &addr, &packet))
+ {
+ NET_ServerPacket(packet, addr);
+ }
+
+ // "Run" any clients that may have things to do, independent of responses
+ // to received packets
+
+ for (i=0; i<MAXNETNODES; ++i)
+ {
+ if (clients[i].active)
+ {
+ NET_ServerRunClient(&clients[i]);
+ }
+ }
+}
+
--- /dev/null
+++ b/src/net_server.h
@@ -1,0 +1,44 @@
+// Emacs style mode select -*- C++ -*-
+//-----------------------------------------------------------------------------
+//
+// $Id: net_server.h 232 2005-12-29 17:48:25Z fraggle $
+//
+// Copyright(C) 2005 Simon Howard
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+// 02111-1307, USA.
+//
+// $Log$
+// Revision 1.1 2005/12/29 17:48:25 fraggle
+// Add initial client/server connect code. Reorganise sources list in
+// Makefile.am.
+//
+//
+// Network server code
+//
+
+#ifndef NET_SERVER_H
+#define NET_SERVER_H
+
+// initialise server and wait for connections
+
+void NET_ServerInit(void);
+
+// run server: check for new packets received etc.
+
+void NET_ServerRun(void);
+
+#endif /* #ifndef NET_SERVER_H */
+