foxygit / doom Log in
commit a4567e04c7f90f12ae7e2bedf840d80e14409283
Author:     Simon Howard <fraggle@gmail.com>
AuthorDate: Wed Oct 19 18:10:11 2011 +0000
Commit:     Simon Howard <fraggle@gmail.com>
CommitDate: Wed Oct 19 18:10:11 2011 +0000

    Change MAXPLAYERS to NET_MAXPLAYERS and add back individual MAXPLAYERS
    defines for each game. Refactor "waiting screen" data code.

    Subversion-branch: /branches/v2-branch
    Subversion-revision: 2441
---
 src/d_loop.c          |  19 +++++----
 src/doom/doomdef.h    |   4 +-
 src/heretic/doomdef.h |   1 +
 src/hexen/g_game.c    |   1 +
 src/hexen/h2def.h     |   1 +
 src/net_client.c      | 104 +++++++------------------------------------------
 src/net_client.h      |  10 +----
 src/net_defs.h        |  34 +++++++++++++---
 src/net_gui.c         |  40 ++++++++++---------
 src/net_server.c      | 103 ++++++++++++++++++++++---------------------------
 src/net_structrw.c    | 105 +++++++++++++++++++++++++++++++++-----------------
 src/net_structrw.h    |   4 +-
 src/strife/doomdef.h  |   4 +-
 13 files changed, 200 insertions(+), 230 deletions(-)

diff --git a/src/d_loop.c b/src/d_loop.c
index 617302a5..0206e85a 100644
--- a/src/d_loop.c
+++ b/src/d_loop.c
@@ -52,8 +52,8 @@

 typedef struct
 {
-    ticcmd_t cmds[MAXPLAYERS];
-    boolean ingame[MAXPLAYERS];
+    ticcmd_t cmds[NET_MAXPLAYERS];
+    boolean ingame[NET_MAXPLAYERS];
 } ticcmd_set_t;

 //
@@ -113,7 +113,7 @@ static loop_interface_t *loop_interface = NULL;
 // This is distinct from playeringame[] used by the game code, which may
 // modify playeringame[] when playing back multiplayer demos.

-static boolean local_playeringame[MAXPLAYERS];
+static boolean local_playeringame[NET_MAXPLAYERS];


 // 35 fps clock adjusted by offsetms milliseconds
@@ -282,7 +282,7 @@ void D_ReceiveTic(ticcmd_t *ticcmds, boolean *players_mask)
         return;
     }

-    for (i = 0; i < MAXPLAYERS; ++i)
+    for (i = 0; i < NET_MAXPLAYERS; ++i)
     {
         if (!drone && i == localplayer)
         {
@@ -457,7 +457,7 @@ boolean D_InitNetGame(net_connect_data_t *connect_data,

     localplayer = settings->consoleplayer;

-    for (i = 0; i < MAXPLAYERS; ++i)
+    for (i = 0; i < NET_MAXPLAYERS; ++i)
     {
         local_playeringame[i] = i < settings->num_players;
     }
@@ -524,7 +524,7 @@ static void OldNetSync(void)
     // ideally maketic should be 1 - 3 tics above lowtic
     // if we are consistantly slower, speed up time

-    for (i=0 ; i<MAXPLAYERS ; i++)
+    for (i=0 ; i<NET_MAXPLAYERS ; i++)
     {
         if (local_playeringame[i])
         {
@@ -575,7 +575,7 @@ static boolean PlayersInGame(void)

     if (net_client_connected)
     {
-        for (i = 0; i < MAXPLAYERS; ++i)
+        for (i = 0; i < NET_MAXPLAYERS; ++i)
         {
             result = result || local_playeringame[i];
         }
@@ -600,7 +600,7 @@ static void TicdupSquash(ticcmd_set_t *set)
     ticcmd_t *cmd;
     unsigned int i;

-    for (i = 0; i < MAXPLAYERS ; ++i)
+    for (i = 0; i < NET_MAXPLAYERS ; ++i)
     {
         cmd = &set->cmds[i];
         cmd->chatchar = 0;
@@ -616,7 +616,7 @@ static void SinglePlayerClear(ticcmd_set_t *set)
 {
     unsigned int i;

-    for (i = 0; i < MAXPLAYERS; ++i)
+    for (i = 0; i < NET_MAXPLAYERS; ++i)
     {
         if (i != localplayer)
         {
@@ -750,4 +750,3 @@ void D_RegisterLoopCallbacks(loop_interface_t *i)
 {
     loop_interface = i;
 }
-
diff --git a/src/doom/doomdef.h b/src/doom/doomdef.h
index e911f886..049ba9e3 100644
--- a/src/doom/doomdef.h
+++ b/src/doom/doomdef.h
@@ -49,6 +49,9 @@
 // most parameter validation debugging code will not be compiled
 #define RANGECHECK

+// The maximum number of players, multiplayer/networking.
+#define MAXPLAYERS 4
+
 // The current state of the game: whether we are
 // playing, gazing at the intermission screen,
 // the game final animation, or a demo.
@@ -171,4 +174,3 @@ typedef enum
 } powerduration_t;

 #endif          // __DOOMDEF__
-
diff --git a/src/heretic/doomdef.h b/src/heretic/doomdef.h
index 5d3e67d3..3209cbe4 100644
--- a/src/heretic/doomdef.h
+++ b/src/heretic/doomdef.h
@@ -78,6 +78,7 @@
 */

 #define NUMARTIFCTS	28
+#define MAXPLAYERS	4

 #define	BT_ATTACK		1
 #define	BT_USE			2
diff --git a/src/hexen/g_game.c b/src/hexen/g_game.c
index 0118cd6b..a638e65e 100644
--- a/src/hexen/g_game.c
+++ b/src/hexen/g_game.c
@@ -1815,6 +1815,7 @@ void G_DoPlayDemo(void)
         playeringame[i] = *demo_p++;
         PlayerClass[i] = *demo_p++;
     }
+    demo_p += 8;

     // Initialize world info, etc.
     G_StartNewInit();
diff --git a/src/hexen/h2def.h b/src/hexen/h2def.h
index 9b8b33f9..5960743c 100644
--- a/src/hexen/h2def.h
+++ b/src/hexen/h2def.h
@@ -98,6 +98,7 @@
 */

 //#define NUMARTIFCTS   28
+#define MAXPLAYERS	8

 #define	BT_ATTACK		1
 #define	BT_USE			2
diff --git a/src/net_client.c b/src/net_client.c
index e151a773..083dca8b 100644
--- a/src/net_client.c
+++ b/src/net_client.c
@@ -118,36 +118,7 @@ boolean net_client_connected;

 boolean net_client_received_wait_data;

-// if true, this client is the controller of the game
-
-boolean net_client_controller = false;
-
-// Number of clients currently connected to the server
-
-unsigned int net_clients_in_game;
-
-// Number of drone players connected to the server
-
-unsigned int net_drones_in_game;
-
-// Names of all players
-
-char net_player_addresses[MAXPLAYERS][MAXPLAYERNAME];
-char net_player_names[MAXPLAYERS][MAXPLAYERNAME];
-
-// MD5 checksums of the wad directory and dehacked data that the server
-// has sent to us.
-
-md5_digest_t net_server_wad_md5sum;
-md5_digest_t net_server_deh_md5sum;
-
-// Is the server a freedoom game?
-
-unsigned int net_server_is_freedoom;
-
-// Player number
-
-int net_player_number;
+net_waitdata_t net_client_wait_data;

 // Waiting for the game to start?

@@ -171,7 +142,7 @@ static net_server_send_t send_queue[BACKUPTICS];

 // Receive window

-static ticcmd_t recvwindow_cmd_base[MAXPLAYERS];
+static ticcmd_t recvwindow_cmd_base[NET_MAXPLAYERS];
 static int recvwindow_start;
 static net_server_recv_t recvwindow[BACKUPTICS];

@@ -269,7 +240,7 @@ static void NET_CL_ExpandFullTiccmd(net_full_ticcmd_t *cmd, unsigned int seq,

     // Expand tic diffs for all players

-    for (i=0; i<MAXPLAYERS; ++i)
+    for (i=0; i<NET_MAXPLAYERS; ++i)
     {
         if (i == settings.consoleplayer && !drone)
         {
@@ -298,7 +269,7 @@ static void NET_CL_ExpandFullTiccmd(net_full_ticcmd_t *cmd, unsigned int seq,

 static void NET_CL_AdvanceWindow(void)
 {
-    ticcmd_t ticcmds[MAXPLAYERS];
+    ticcmd_t ticcmds[NET_MAXPLAYERS];

     while (recvwindow[0].active)
     {
@@ -456,79 +427,32 @@ void NET_CL_SendTiccmd(ticcmd_t *ticcmd, int maketic)

 static void NET_CL_ParseWaitingData(net_packet_t *packet)
 {
-    unsigned int num_players;
-    unsigned int num_drones;
-    unsigned int is_controller;
-    signed int player_number;
-    char *player_names[MAXPLAYERS];
-    char *player_addr[MAXPLAYERS];
-    md5_digest_t wad_md5sum, deh_md5sum;
-    unsigned int server_is_freedoom;
-    size_t i;
+    net_waitdata_t wait_data;

-    if (!NET_ReadInt8(packet, &num_players)
-     || !NET_ReadInt8(packet, &num_drones)
-     || !NET_ReadInt8(packet, &is_controller)
-     || !NET_ReadSInt8(packet, &player_number))
+    if (!NET_ReadWaitData(packet, &wait_data))
     {
-        // invalid packet
-
+        // Invalid packet?
         return;
     }

-    if (num_players > MAXPLAYERS)
+    if (wait_data.num_players > wait_data.max_players
+     || wait_data.max_players > NET_MAXPLAYERS)
     {
         // insane data

         return;
     }

-    if ((player_number >= 0 && drone)
-     || (player_number < 0 && !drone)
-     || (player_number >= (signed int) num_players))
+    if ((wait_data.consoleplayer >= 0 && drone)
+     || (wait_data.consoleplayer < 0 && !drone)
+     || (wait_data.consoleplayer >= wait_data.num_players))
     {
         // Invalid player number

         return;
     }
-
-    // Read the player names
-
-    for (i=0; i<num_players; ++i)
-    {
-        player_names[i] = NET_ReadString(packet);
-        player_addr[i] = NET_ReadString(packet);
-
-        if (player_names[i] == NULL || player_addr[i] == NULL)
-        {
-            return;
-        }
-    }
-
-    if (!NET_ReadMD5Sum(packet, wad_md5sum)
-     || !NET_ReadMD5Sum(packet, deh_md5sum)
-     || !NET_ReadInt8(packet, &server_is_freedoom))
-    {
-        return;
-    }
-
-    net_clients_in_game = num_players;
-    net_drones_in_game = num_drones;
-    net_client_controller = is_controller != 0;
-    net_player_number = player_number;
-
-    for (i=0; i<num_players; ++i)
-    {
-        strncpy(net_player_names[i], player_names[i], MAXPLAYERNAME);
-        net_player_names[i][MAXPLAYERNAME-1] = '\0';
-        strncpy(net_player_addresses[i], player_addr[i], MAXPLAYERNAME);
-        net_player_addresses[i][MAXPLAYERNAME-1] = '\0';
-    }
-
-    memcpy(net_server_wad_md5sum, wad_md5sum, sizeof(md5_digest_t));
-    memcpy(net_server_deh_md5sum, deh_md5sum, sizeof(md5_digest_t));
-    net_server_is_freedoom = server_is_freedoom;

+    memcpy(&net_client_wait_data, &wait_data, sizeof(net_waitdata_t));
     net_client_received_wait_data = true;
 }

@@ -544,7 +468,7 @@ static void NET_CL_ParseGameStart(net_packet_t *packet)
         return;
     }

-    if (settings.num_players > MAXPLAYERS
+    if (settings.num_players > NET_MAXPLAYERS
      || settings.consoleplayer >= (signed int) settings.num_players)
     {
         // insane values
diff --git a/src/net_client.h b/src/net_client.h
index b071d32a..242bf958 100644
--- a/src/net_client.h
+++ b/src/net_client.h
@@ -29,8 +29,6 @@
 #include "md5.h"
 #include "net_defs.h"

-#define MAXPLAYERNAME 30
-
 boolean NET_CL_Connect(net_addr_t *addr, net_connect_data_t *data);
 void NET_CL_Disconnect(void);
 void NET_CL_Run(void);
@@ -44,13 +42,8 @@ void NET_BindVariables(void);

 extern boolean net_client_connected;
 extern boolean net_client_received_wait_data;
-extern boolean net_client_controller;
-extern unsigned int net_clients_in_game;
-extern unsigned int net_drones_in_game;
+extern net_waitdata_t net_client_wait_data;
 extern boolean net_waiting_for_start;
-extern char net_player_names[MAXPLAYERS][MAXPLAYERNAME];
-extern char net_player_addresses[MAXPLAYERS][MAXPLAYERNAME];
-extern int net_player_number;
 extern char *net_player_name;

 extern md5_digest_t net_server_wad_md5sum;
@@ -63,4 +56,3 @@ extern unsigned int net_local_is_freedoom;
 extern boolean drone;

 #endif /* #ifndef NET_CLIENT_H */
-
diff --git a/src/net_defs.h b/src/net_defs.h
index 808fd2ff..84e82d28 100644
--- a/src/net_defs.h
+++ b/src/net_defs.h
@@ -33,18 +33,24 @@
 #include "md5.h"

 // Absolute maximum number of "nodes" in the game.  This is different to
-// MAXPLAYERS, as there may be observers that are not participating
+// NET_MAXPLAYERS, as there may be observers that are not participating
 // (eg. left/right monitors)

 #define MAXNETNODES 16

 // The maximum number of players, multiplayer/networking.
+// This is the maximum supported by the networking code; individual games
+// have their own values for MAXPLAYERS that can be smaller.

-#define MAXPLAYERS		4
+#define NET_MAXPLAYERS 8
+
+// Maximum length of a player's name.
+
+#define MAXPLAYERNAME 30

 // Networking and tick handling related.

-#define BACKUPTICS		128
+#define BACKUPTICS 128

 typedef struct _net_module_s net_module_t;
 typedef struct _net_packet_s net_packet_t;
@@ -179,7 +185,7 @@ typedef struct

     // Hexen player classes:

-    int player_classes[MAXPLAYERS];
+    int player_classes[NET_MAXPLAYERS];

 } net_gamesettings_t;

@@ -204,8 +210,8 @@ typedef struct
 {
     signed int latency;
     unsigned int seq;
-    boolean playeringame[MAXPLAYERS];
-    net_ticdiff_t cmds[MAXPLAYERS];
+    boolean playeringame[NET_MAXPLAYERS];
+    net_ticdiff_t cmds[NET_MAXPLAYERS];
 } net_full_ticcmd_t;

 // Data sent in response to server queries
@@ -221,4 +227,20 @@ typedef struct
     char *description;
 } net_querydata_t;

+// Data sent by the server while waiting for the game to start.
+
+typedef struct
+{
+    int num_players;
+    int num_drones;
+    int max_players;
+    int is_controller;
+    int consoleplayer;
+    char player_names[NET_MAXPLAYERS][MAXPLAYERNAME];
+    char player_addrs[NET_MAXPLAYERS][MAXPLAYERNAME];
+    md5_digest_t wad_md5sum;
+    md5_digest_t deh_md5sum;
+    int is_freedoom;
+} net_waitdata_t;
+
 #endif /* #ifndef NET_DEFS_H */
diff --git a/src/net_gui.c b/src/net_gui.c
index f2c4f1e5..781d27c6 100644
--- a/src/net_gui.c
+++ b/src/net_gui.c
@@ -42,8 +42,8 @@
 #include "textscreen.h"

 static txt_window_t *window;
-static txt_label_t *player_labels[MAXPLAYERS];
-static txt_label_t *ip_labels[MAXPLAYERS];
+static txt_label_t *player_labels[NET_MAXPLAYERS];
+static txt_label_t *ip_labels[NET_MAXPLAYERS];
 static txt_label_t *drone_label;
 static boolean had_warning;

@@ -83,7 +83,7 @@ static void BuildGUI(void)

     // Player labels

-    for (i=0; i<MAXPLAYERS; ++i)
+    for (i=0; i<NET_MAXPLAYERS; ++i)
     {
         sprintf(buf, " %i. ", i + 1);
         TXT_AddWidget(table, TXT_NewLabel(buf));
@@ -109,11 +109,11 @@ static void UpdateGUI(net_gamesettings_t *settings)
     char buf[50];
     unsigned int i;

-    for (i=0; i<MAXPLAYERS; ++i)
+    for (i=0; i<NET_MAXPLAYERS; ++i)
     {
         txt_color_t color = TXT_COLOR_BRIGHT_WHITE;

-        if ((signed) i == net_player_number)
+        if ((signed) i == net_client_wait_data.consoleplayer)
         {
             color = TXT_COLOR_YELLOW;
         }
@@ -121,10 +121,12 @@ static void UpdateGUI(net_gamesettings_t *settings)
         TXT_SetFGColor(player_labels[i], color);
         TXT_SetFGColor(ip_labels[i], color);

-        if (i < net_clients_in_game)
+        if (i < net_client_wait_data.num_players)
         {
-            TXT_SetLabel(player_labels[i], net_player_names[i]);
-            TXT_SetLabel(ip_labels[i], net_player_addresses[i]);
+            TXT_SetLabel(player_labels[i],
+                         net_client_wait_data.player_names[i]);
+            TXT_SetLabel(ip_labels[i],
+                         net_client_wait_data.player_addrs[i]);
         }
         else
         {
@@ -133,9 +135,10 @@ static void UpdateGUI(net_gamesettings_t *settings)
         }
     }

-    if (net_drones_in_game > 0)
+    if (net_client_wait_data.num_drones > 0)
     {
-        sprintf(buf, " (+%i observer clients)", net_drones_in_game);
+        sprintf(buf, " (+%i observer clients)",
+                     net_client_wait_data.num_drones);
         TXT_SetLabel(drone_label, buf);
     }
     else
@@ -143,7 +146,7 @@ static void UpdateGUI(net_gamesettings_t *settings)
         TXT_SetLabel(drone_label, "");
     }

-    if (net_client_controller)
+    if (net_client_wait_data.is_controller)
     {
         startgame = TXT_NewWindowAction(' ', "Start game");
         TXT_SignalConnect(startgame, "pressed", StartGame, settings);
@@ -181,11 +184,13 @@ static void CheckMD5Sums(void)
         return;
     }

-    correct_wad = memcmp(net_local_wad_md5sum, net_server_wad_md5sum,
+    correct_wad = memcmp(net_local_wad_md5sum,
+                         net_client_wait_data.wad_md5sum,
                          sizeof(md5_digest_t)) == 0;
-    correct_deh = memcmp(net_local_deh_md5sum, net_server_deh_md5sum,
+    correct_deh = memcmp(net_local_deh_md5sum,
+                         net_client_wait_data.deh_md5sum,
                          sizeof(md5_digest_t)) == 0;
-    same_freedoom = net_server_is_freedoom == net_local_is_freedoom;
+    same_freedoom = net_client_wait_data.is_freedoom == net_local_is_freedoom;

     if (correct_wad && correct_deh && same_freedoom)
     {
@@ -196,7 +201,7 @@ static void CheckMD5Sums(void)
     {
         printf("Warning: WAD MD5 does not match server:\n");
         PrintMD5Digest("Local", net_local_wad_md5sum);
-        PrintMD5Digest("Server", net_server_wad_md5sum);
+        PrintMD5Digest("Server", net_client_wait_data.wad_md5sum);
     }

     if (!same_freedoom)
@@ -204,14 +209,14 @@ static void CheckMD5Sums(void)
         printf("Warning: Mixing Freedoom with non-Freedoom\n");
         printf("Local: %i  Server: %i\n",
                net_local_is_freedoom,
-               net_server_is_freedoom);
+               net_client_wait_data.is_freedoom);
     }

     if (!correct_deh)
     {
         printf("Warning: Dehacked MD5 does not match server:\n");
         PrintMD5Digest("Local", net_local_deh_md5sum);
-        PrintMD5Digest("Server", net_server_deh_md5sum);
+        PrintMD5Digest("Server", net_client_wait_data.deh_md5sum);
     }

     window = TXT_NewWindow("WARNING");
@@ -295,4 +300,3 @@ void NET_WaitForStart(net_gamesettings_t *settings)

     TXT_Shutdown();
 }
-
diff --git a/src/net_server.c b/src/net_server.c
index fcece975..5fec5de1 100644
--- a/src/net_server.c
+++ b/src/net_server.c
@@ -136,7 +136,7 @@ typedef struct
 static net_server_state_t server_state;
 static boolean server_initialized = false;
 static net_client_t clients[MAXNETNODES];
-static net_client_t *sv_players[MAXPLAYERS];
+static net_client_t *sv_players[NET_MAXPLAYERS];
 static net_context_t *server_context;
 static unsigned int sv_gamemode;
 static unsigned int sv_gamemission;
@@ -150,7 +150,7 @@ static unsigned int master_refresh_time;
 // receive window

 static unsigned int recvwindow_start;
-static net_client_recv_t recvwindow[BACKUPTICS][MAXPLAYERS];
+static net_client_recv_t recvwindow[BACKUPTICS][NET_MAXPLAYERS];

 #define NET_SV_ExpandTicNum(b) NET_ExpandTicNum(recvwindow_start, (b))

@@ -239,7 +239,7 @@ static void NET_SV_AssignPlayers(void)
         }
     }

-    for (; pl<MAXPLAYERS; ++pl)
+    for (; pl<NET_MAXPLAYERS; ++pl)
     {
         sv_players[pl] = NULL;
     }
@@ -254,7 +254,7 @@ static int NET_SV_NumPlayers(void)

     result = 0;

-    for (i=0; i<MAXPLAYERS; ++i)
+    for (i=0; i<NET_MAXPLAYERS; ++i)
     {
         if (sv_players[i] != NULL && ClientConnected(sv_players[i]))
         {
@@ -354,7 +354,7 @@ static void NET_SV_AdvanceWindow(void)

         should_advance = true;

-        for (i=0; i<MAXPLAYERS; ++i)
+        for (i=0; i<NET_MAXPLAYERS; ++i)
         {
             if (sv_players[i] == NULL || !ClientConnected(sv_players[i]))
             {
@@ -599,7 +599,7 @@ static void NET_SV_ParseSYN(net_packet_t *packet,
         NET_SV_AssignPlayers();
         num_players = NET_SV_NumPlayers();

-        if ((!data.drone && num_players >= MAXPLAYERS)
+        if ((!data.drone && num_players >= NET_MAXPLAYERS)
          || NET_SV_NumClients() >= MAXNETNODES)
         {
             NET_SV_SendReject(addr, "Server is full!");
@@ -694,7 +694,7 @@ static void NET_SV_ParseGameStart(net_packet_t *packet, net_client_t *client)

     settings.lowres_turn = false;

-    for (i=0; i<MAXPLAYERS; ++i)
+    for (i=0; i<NET_MAXPLAYERS; ++i)
     {
         if (sv_players[i] != NULL && sv_players[i]->recording_lowres)
         {
@@ -706,7 +706,7 @@ static void NET_SV_ParseGameStart(net_packet_t *packet, net_client_t *client)

     // Copy player classes:

-    for (i = 0; i < MAXPLAYERS; ++i)
+    for (i = 0; i < NET_MAXPLAYERS; ++i)
     {
         if (sv_players[i] != NULL)
         {
@@ -1120,7 +1120,7 @@ void NET_SV_SendQueryResponse(net_addr_t *addr)
     // Number of players/maximum players

     querydata.num_players = NET_SV_NumPlayers();
-    querydata.max_players = MAXPLAYERS;
+    querydata.max_players = NET_MAXPLAYERS;

     // Game mode/mission

@@ -1234,71 +1234,58 @@ static void NET_SV_Packet(net_packet_t *packet, net_addr_t *addr)

 static void NET_SV_SendWaitingData(net_client_t *client)
 {
+    net_waitdata_t wait_data;
     net_packet_t *packet;
     net_client_t *controller;
-    int num_players;
     int i;

     NET_SV_AssignPlayers();

     controller = NET_SV_Controller();

-    num_players = NET_SV_NumPlayers();
-
-    // time to send the client another status packet
-
-    packet = NET_NewPacket(10);
-    NET_WriteInt16(packet, NET_PACKET_TYPE_WAITING_DATA);
-
-    // include the number of players waiting
-
-    NET_WriteInt8(packet, num_players);
+    wait_data.num_players = NET_SV_NumPlayers();
+    wait_data.num_drones = NET_SV_NumDrones();
+    wait_data.max_players = NET_MAXPLAYERS;
+    wait_data.is_controller = (client == controller);
+    wait_data.consoleplayer = client->player_number;

-    // send the number of drone clients
-
-    NET_WriteInt8(packet, NET_SV_NumDrones());
-
-    // indicate whether the client is the controller
-
-    NET_WriteInt8(packet, client == controller);
-
-    // send the player number of this client
-
-    NET_WriteInt8(packet, client->player_number);
-
-    // send the addresses of all players
+    // Send the WAD and dehacked checksums of the controlling client.
+    // If no controller found (?), send the details that the client
+    // is expecting anyway.

-    for (i=0; i<num_players; ++i)
+    if (controller != NULL)
     {
-        char *addr;
-
-        // name
+        controller = client;
+    }

-        NET_WriteString(packet, sv_players[i]->name);
+    memcpy(&wait_data.wad_md5sum, &controller->wad_md5sum,
+           sizeof(md5_digest_t));
+    memcpy(&wait_data.deh_md5sum, &controller->deh_md5sum,
+           sizeof(md5_digest_t));
+    wait_data.is_freedoom = controller->is_freedoom;

-        // address
+    // set name and address of each player:

-        addr = NET_AddrToString(sv_players[i]->addr);
+    for (i = 0; i < wait_data.num_players; ++i)
+    {
+        strncpy(wait_data.player_names[i],
+                sv_players[i]->name,
+                MAXPLAYERNAME);
+        wait_data.player_names[i][MAXPLAYERNAME-1] = '\0';

-        NET_WriteString(packet, addr);
+        strncpy(wait_data.player_addrs[i],
+                NET_AddrToString(sv_players[i]->addr),
+                MAXPLAYERNAME);
+        wait_data.player_addrs[i][MAXPLAYERNAME-1] = '\0';
     }

-    // Send the WAD and dehacked checksums of the controlling client.
+    // Construct packet:

-    if (controller != NULL)
-    {
-        NET_WriteMD5Sum(packet, controller->wad_md5sum);
-        NET_WriteMD5Sum(packet, controller->deh_md5sum);
-        NET_WriteInt8(packet, controller->is_freedoom);
-    }
-    else
-    {
-        NET_WriteMD5Sum(packet, client->wad_md5sum);
-        NET_WriteMD5Sum(packet, client->deh_md5sum);
-        NET_WriteInt8(packet, client->is_freedoom);
-    }
+    packet = NET_NewPacket(10);
+    NET_WriteInt16(packet, NET_PACKET_TYPE_WAITING_DATA);
+    NET_WriteWaitData(packet, &wait_data);

-    // send packet to client and free
+    // Send packet to client and free

     NET_Conn_SendPacket(&client->connection, packet);
     NET_FreePacket(packet);
@@ -1334,7 +1321,7 @@ static void NET_SV_PumpSendQueue(net_client_t *client)

     num_players = 0;

-    for (i=0; i<MAXPLAYERS; ++i)
+    for (i=0; i<NET_MAXPLAYERS; ++i)
     {
         if (sv_players[i] == client)
         {
@@ -1380,7 +1367,7 @@ static void NET_SV_PumpSendQueue(net_client_t *client)

     cmd.latency = 0;

-    for (i=0; i<MAXPLAYERS; ++i)
+    for (i=0; i<NET_MAXPLAYERS; ++i)
     {
         net_client_recv_t *recvobj;

@@ -1660,7 +1647,7 @@ void NET_SV_Run(void)
     {
         NET_SV_AdvanceWindow();

-        for (i=0; i<MAXPLAYERS; ++i)
+        for (i=0; i<NET_MAXPLAYERS; ++i)
         {
             if (sv_players[i] != NULL && ClientConnected(sv_players[i]))
             {
diff --git a/src/net_structrw.c b/src/net_structrw.c
index 47513269..9e7593f4 100644
--- a/src/net_structrw.c
+++ b/src/net_structrw.c
@@ -31,34 +31,6 @@
 #include "net_packet.h"
 #include "net_structrw.h"

-static void NET_WriteMD5(net_packet_t *packet, md5_digest_t digest)
-{
-    int i;
-
-    for (i = 0; i < sizeof(md5_digest_t); ++i)
-    {
-        NET_WriteInt8(packet, digest[i]);
-    }
-}
-
-static boolean NET_ReadMD5(net_packet_t *packet, md5_digest_t digest)
-{
-    unsigned int val;
-    int i;
-
-    for (i = 0; i < sizeof(md5_digest_t); ++i)
-    {
-        if (!NET_ReadInt8(packet, &val))
-        {
-            return false;
-        }
-
-        digest[i] = (uint8_t) val;
-    }
-
-    return true;
-}
-
 void NET_WriteConnectData(net_packet_t *packet, net_connect_data_t *data)
 {
     NET_WriteInt8(packet, data->gamemode);
@@ -66,8 +38,8 @@ void NET_WriteConnectData(net_packet_t *packet, net_connect_data_t *data)
     NET_WriteInt8(packet, data->lowres_turn);
     NET_WriteInt8(packet, data->drone);
     NET_WriteInt8(packet, data->is_freedoom);
-    NET_WriteMD5(packet, data->wad_md5sum);
-    NET_WriteMD5(packet, data->deh_md5sum);
+    NET_WriteMD5Sum(packet, data->wad_md5sum);
+    NET_WriteMD5Sum(packet, data->deh_md5sum);
     NET_WriteInt8(packet, data->player_class);
 }

@@ -78,8 +50,8 @@ boolean NET_ReadConnectData(net_packet_t *packet, net_connect_data_t *data)
         && NET_ReadInt8(packet, (unsigned int *) &data->lowres_turn)
         && NET_ReadInt8(packet, (unsigned int *) &data->drone)
         && NET_ReadInt8(packet, (unsigned int *) &data->is_freedoom)
-        && NET_ReadMD5(packet, data->wad_md5sum)
-        && NET_ReadMD5(packet, data->deh_md5sum)
+        && NET_ReadMD5Sum(packet, data->wad_md5sum)
+        && NET_ReadMD5Sum(packet, data->deh_md5sum)
         && NET_ReadInt8(packet, (unsigned int *) &data->player_class);
 }

@@ -415,14 +387,14 @@ boolean NET_ReadFullTiccmd(net_packet_t *packet, net_full_ticcmd_t *cmd, boolean
         return false;
     }

-    for (i=0; i<MAXPLAYERS; ++i)
+    for (i=0; i<NET_MAXPLAYERS; ++i)
     {
         cmd->playeringame[i] = (bitfield & (1 << i)) != 0;
     }

     // Read cmds

-    for (i=0; i<MAXPLAYERS; ++i)
+    for (i=0; i<NET_MAXPLAYERS; ++i)
     {
         if (cmd->playeringame[i])
         {
@@ -450,7 +422,7 @@ void NET_WriteFullTiccmd(net_packet_t *packet, net_full_ticcmd_t *cmd, boolean l

     bitfield = 0;

-    for (i=0; i<MAXPLAYERS; ++i)
+    for (i=0; i<NET_MAXPLAYERS; ++i)
     {
         if (cmd->playeringame[i])
         {
@@ -462,7 +434,7 @@ void NET_WriteFullTiccmd(net_packet_t *packet, net_full_ticcmd_t *cmd, boolean l

     // Write player ticcmds

-    for (i=0; i<MAXPLAYERS; ++i)
+    for (i=0; i<NET_MAXPLAYERS; ++i)
     {
         if (cmd->playeringame[i])
         {
@@ -471,6 +443,67 @@ void NET_WriteFullTiccmd(net_packet_t *packet, net_full_ticcmd_t *cmd, boolean l
     }
 }

+void NET_WriteWaitData(net_packet_t *packet, net_waitdata_t *data)
+{
+    int i;
+
+    NET_WriteInt8(packet, data->num_players);
+    NET_WriteInt8(packet, data->num_drones);
+    NET_WriteInt8(packet, data->max_players);
+    NET_WriteInt8(packet, data->is_controller);
+    NET_WriteInt8(packet, data->consoleplayer);
+
+    for (i = 0; i < data->num_players && i < NET_MAXPLAYERS; ++i)
+    {
+        NET_WriteString(packet, data->player_names[i]);
+        NET_WriteString(packet, data->player_addrs[i]);
+    }
+
+    NET_WriteMD5Sum(packet, data->wad_md5sum);
+    NET_WriteMD5Sum(packet, data->deh_md5sum);
+    NET_WriteInt8(packet, data->is_freedoom);
+}
+
+boolean NET_ReadWaitData(net_packet_t *packet, net_waitdata_t *data)
+{
+    int i;
+    char *s;
+
+    if (!NET_ReadInt8(packet, (unsigned int *) &data->num_players)
+     || !NET_ReadInt8(packet, (unsigned int *) &data->num_drones)
+     || !NET_ReadInt8(packet, (unsigned int *) &data->max_players)
+     || !NET_ReadInt8(packet, (unsigned int *) &data->is_controller)
+     || !NET_ReadSInt8(packet, (unsigned int *) &data->consoleplayer))
+    {
+        return false;
+    }
+
+    for (i = 0; i < data->num_players && i < NET_MAXPLAYERS; ++i)
+    {
+        s = NET_ReadString(packet);
+
+        if (s == NULL || strlen(s) >= MAXPLAYERNAME)
+        {
+            return false;
+        }
+
+        strcpy(data->player_names[i], s);
+
+        s = NET_ReadString(packet);
+
+        if (s == NULL || strlen(s) >= MAXPLAYERNAME)
+        {
+            return false;
+        }
+
+        strcpy(data->player_addrs[i], s);
+    }
+
+    return NET_ReadMD5Sum(packet, data->wad_md5sum)
+        && NET_ReadMD5Sum(packet, data->deh_md5sum)
+        && NET_ReadInt8(packet, (unsigned int *) &data->is_freedoom);
+}
+
 boolean NET_ReadMD5Sum(net_packet_t *packet, md5_digest_t digest)
 {
     unsigned int b;
diff --git a/src/net_structrw.h b/src/net_structrw.h
index 9f62176a..e894e170 100644
--- a/src/net_structrw.h
+++ b/src/net_structrw.h
@@ -46,7 +46,9 @@ void NET_WriteFullTiccmd(net_packet_t *packet, net_full_ticcmd_t *cmd, boolean l
 boolean NET_ReadMD5Sum(net_packet_t *packet, md5_digest_t digest);
 void NET_WriteMD5Sum(net_packet_t *packet, md5_digest_t digest);

+void NET_WriteWaitData(net_packet_t *packet, net_waitdata_t *data);
+boolean NET_ReadWaitData(net_packet_t *packet, net_waitdata_t *data);
+
 void NET_SafePuts(char *msg);

 #endif /* #ifndef NET_STRUCTRW_H */
-
diff --git a/src/strife/doomdef.h b/src/strife/doomdef.h
index 459c43dd..3c289808 100644
--- a/src/strife/doomdef.h
+++ b/src/strife/doomdef.h
@@ -47,6 +47,9 @@
 #define DOOM_191_VERSION 111


+// Maximum players for Strife:
+#define MAXPLAYERS 8
+
 // If rangecheck is undefined,
 // most parameter validation debugging code will not be compiled
 #define RANGECHECK
@@ -294,4 +297,3 @@ typedef enum
 } powerduration_t;

 #endif          // __DOOMDEF__
-