shithub: choc

Download patch

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 */
+