shithub: choc

Download patch

ref: 48b1728d9145baf1912aa6566d8e64abea65f83b
parent: 609e5d2928561b35fc16749e063dbfd61c9a17e1
author: Simon Howard <fraggle@gmail.com>
date: Tue Apr 2 16:44:26 EDT 2013

Split game start sequence into two-stage process. This is the first
stage in refactoring the way that network startup works.

Subversion-branch: /branches/v2-branch
Subversion-revision: 2580

--- a/src/d_loop.c
+++ b/src/d_loop.c
@@ -309,6 +309,24 @@
     lasttime = GetAdjustedTime() / ticdup;
 }
 
+//
+// Block until the game start message is received from the server.
+//
+
+void D_BlockUntilStart(net_gamesettings_t *settings)
+{
+    while (!NET_CL_GetSettings(settings))
+    {
+        NET_CL_Run();
+        NET_SV_Run();
+
+        if (!net_client_connected)
+        {
+            I_Error("Lost connection to server");
+        }
+    }
+}
+
 boolean D_InitNetGame(net_connect_data_t *connect_data,
                       net_gamesettings_t *settings)
 {
@@ -440,9 +458,15 @@
 
         printf("D_CheckNetGame: Connected to %s\n", NET_AddrToString(addr));
 
-        // Wait for game start message received from server.
+        // Wait for launch message received from server.
 
-        NET_WaitForStart(settings);
+        NET_WaitForLaunch();
+
+        // Send our game settings and block until game start is received
+        // from the server.
+
+        NET_CL_StartGame(settings);
+        D_BlockUntilStart(settings);
 
         // Read the game settings that were received.
 
--- a/src/net_client.c
+++ b/src/net_client.c
@@ -51,6 +51,10 @@
 
 typedef enum
 {
+    // waiting for the game to launch
+
+    CLIENT_STATE_WAITING_LAUNCH,
+
     // waiting for the game to start
 
     CLIENT_STATE_WAITING_START,
@@ -73,10 +77,10 @@
 
     unsigned int resend_time;
 
-    // Tic data from server 
+    // Tic data from server
 
     net_full_ticcmd_t cmd;
-    
+
 } net_server_recv_t;
 
 // Type of structure used in the send window
@@ -115,15 +119,15 @@
 
 boolean net_client_connected;
 
-// true if we have received waiting data from the server
+// true if we have received waiting data from the server,
+// and the wait data that was received.
 
 boolean net_client_received_wait_data;
-
 net_waitdata_t net_client_wait_data;
 
-// Waiting for the game to start?
+// Waiting at the initial wait screen for the game to be launched?
 
-boolean net_waiting_for_start = false;
+boolean net_waiting_for_launch = false;
 
 // Name that we send to the server
 
@@ -306,6 +310,11 @@
     }
 }
 
+void NET_CL_LaunchGame(void)
+{
+    NET_Conn_NewReliable(&client_connection, NET_PACKET_TYPE_LAUNCH);
+}
+
 void NET_CL_StartGame(net_gamesettings_t *settings)
 {
     net_packet_t *packet;
@@ -457,6 +466,16 @@
     net_client_received_wait_data = true;
 }
 
+static void NET_CL_ParseLaunch(net_packet_t *packet)
+{
+    if (client_state != CLIENT_STATE_WAITING_LAUNCH)
+    {
+        return;
+    }
+
+    client_state = CLIENT_STATE_WAITING_START;
+}
+
 static void NET_CL_ParseGameStart(net_packet_t *packet)
 {
     if (!NET_ReadSettings(packet, &settings))
@@ -805,6 +824,10 @@
                 NET_CL_ParseWaitingData(packet);
                 break;
 
+            case NET_PACKET_TYPE_LAUNCH:
+                NET_CL_ParseLaunch(packet);
+                break;
+
             case NET_PACKET_TYPE_GAMESTART:
                 NET_CL_ParseGameStart(packet);
                 break;
@@ -864,13 +887,14 @@
      || client_connection.state == NET_CONN_STATE_DISCONNECTED_SLEEP)
     {
         NET_CL_Disconnected();
-    
+
         NET_CL_Shutdown();
     }
-    
-    net_waiting_for_start = client_connection.state == NET_CONN_STATE_CONNECTED
-                         && client_state == CLIENT_STATE_WAITING_START;
 
+    net_waiting_for_launch =
+            client_connection.state == NET_CONN_STATE_CONNECTED
+         && client_state == CLIENT_STATE_WAITING_LAUNCH;
+
     if (client_state == CLIENT_STATE_IN_GAME)
     {
         // Possibly advance the receive window
@@ -932,7 +956,7 @@
     NET_Conn_InitClient(&client_connection, addr);
 
     // try to connect
- 
+
     start_time = I_GetTimeMS();
     last_send_time = -1;
 
@@ -947,9 +971,9 @@
             NET_CL_SendSYN(data);
             last_send_time = nowtime;
         }
- 
-        // time out after 5 seconds 
 
+        // time out after 5 seconds
+
         if (nowtime - start_time > 5000)
         {
             break;
@@ -973,7 +997,7 @@
     {
         // connected ok!
 
-        client_state = CLIENT_STATE_WAITING_START;
+        client_state = CLIENT_STATE_WAITING_LAUNCH;
         drone = data->drone;
 
         return true;
--- a/src/net_client.h
+++ b/src/net_client.h
@@ -33,6 +33,7 @@
 void NET_CL_Disconnect(void);
 void NET_CL_Run(void);
 void NET_CL_Init(void);
+void NET_CL_LaunchGame(void);
 void NET_CL_StartGame(net_gamesettings_t *settings);
 void NET_CL_SendTiccmd(ticcmd_t *ticcmd, int maketic);
 boolean NET_CL_GetSettings(net_gamesettings_t *_settings);
@@ -43,7 +44,7 @@
 extern boolean net_client_connected;
 extern boolean net_client_received_wait_data;
 extern net_waitdata_t net_client_wait_data;
-extern boolean net_waiting_for_start;
+extern boolean net_waiting_for_launch;
 extern char *net_player_name;
 
 extern sha1_digest_t net_server_wad_sha1sum;
--- a/src/net_defs.h
+++ b/src/net_defs.h
@@ -116,7 +116,7 @@
 
 // packet types
 
-typedef enum 
+typedef enum
 {
     NET_PACKET_TYPE_SYN,
     NET_PACKET_TYPE_ACK,
@@ -133,6 +133,7 @@
     NET_PACKET_TYPE_CONSOLE_MESSAGE,
     NET_PACKET_TYPE_QUERY,
     NET_PACKET_TYPE_QUERY_RESPONSE,
+    NET_PACKET_TYPE_LAUNCH,
 } net_packet_type_t;
 
 typedef enum
--- a/src/net_gui.c
+++ b/src/net_gui.c
@@ -54,11 +54,9 @@
     I_Quit();
 }
 
-static void StartGame(TXT_UNCAST_ARG(widget), TXT_UNCAST_ARG(settings))
+static void StartGame(TXT_UNCAST_ARG(widget), TXT_UNCAST_ARG(unused))
 {
-    TXT_CAST_ARG(net_gamesettings_t, settings);
-
-    NET_CL_StartGame(settings);
+    NET_CL_LaunchGame();
 }
 
 static void OpenWaitDialog(void)
@@ -112,7 +110,7 @@
     TXT_AddWidget(window, drone_label);
 }
 
-static void UpdateGUI(net_gamesettings_t *settings)
+static void UpdateGUI(void)
 {
     txt_window_action_t *startgame;
     char buf[50];
@@ -174,7 +172,7 @@
     if (net_client_wait_data.is_controller)
     {
         startgame = TXT_NewWindowAction(' ', "Start game");
-        TXT_SignalConnect(startgame, "pressed", StartGame, settings);
+        TXT_SignalConnect(startgame, "pressed", StartGame, NULL);
     }
     else
     {
@@ -287,11 +285,11 @@
 
     TXT_AddWidget(window, TXT_NewLabel
             ("If you continue, this may cause your game to desync."));
-    
+
     had_warning = true;
 }
 
-void NET_WaitForStart(net_gamesettings_t *settings)
+void NET_WaitForLaunch(void)
 {
     if (!TXT_Init())
     {
@@ -305,9 +303,9 @@
     OpenWaitDialog();
     had_warning = false;
 
-    while (net_waiting_for_start)
+    while (net_waiting_for_launch)
     {
-        UpdateGUI(settings);
+        UpdateGUI();
         CheckSHA1Sums();
 
         TXT_DispatchEvents();
@@ -323,6 +321,6 @@
 
         TXT_Sleep(100);
     }
-    
+
     TXT_Shutdown();
 }
--- a/src/net_gui.h
+++ b/src/net_gui.h
@@ -22,15 +22,15 @@
 //
 //  * The client waiting screen when we are waiting for the server to
 //    start the game.
-//   
+//
 
 
-#ifndef NET_GUI_H 
+#ifndef NET_GUI_H
 #define NET_GUI_H
 
 #include "doomtype.h"
 
-extern void NET_WaitForStart(net_gamesettings_t *settings);
+extern void NET_WaitForLaunch(void);
 
 #endif /* #ifndef NET_GUI_H */
 
--- a/src/net_server.c
+++ b/src/net_server.c
@@ -56,8 +56,14 @@
 
 typedef enum
 {
-    // waiting for the game to start
+    // waiting for the game to be "launched" (key player to press the start
+    // button)
 
+    SERVER_WAITING_LAUNCH,
+
+    // game has been launched, we are waiting for all players to be ready
+    // so the game can start.
+
     SERVER_WAITING_START,
 
     // in a game
@@ -65,7 +71,7 @@
     SERVER_IN_GAME,
 } net_server_state_t;
 
-typedef struct 
+typedef struct
 {
     boolean active;
     int player_number;
@@ -80,7 +86,7 @@
     unsigned int connect_time;
 
     // Last time new gamedata was received from this client
-    
+
     int last_gamedata_time;
 
     // recording a demo without -longtics
@@ -542,7 +548,7 @@
         // will simply not function at all.
         //
 
-        if (M_CheckParm("-ignoreversion") == 0) 
+        if (M_CheckParm("-ignoreversion") == 0)
         {
             NET_SV_SendReject(addr,
                               "Version mismatch: server version is: "
@@ -578,17 +584,17 @@
     {
         return;
     }
-    
+
     // received a valid SYN
 
     // not accepting new connections?
-    
-    if (server_state != SERVER_WAITING_START)
+
+    if (server_state != SERVER_WAITING_LAUNCH)
     {
         NET_SV_SendReject(addr, "Server is not currently accepting connections");
         return;
     }
-    
+
     // allocate a client slot if there isn't one already
 
     if (client == NULL)
@@ -683,6 +689,43 @@
     }
 }
 
+// Parse a launch packet. This is sent by the key player when the "start"
+// button is pressed, and causes the startup process to continue.
+
+static void NET_SV_ParseLaunch(net_packet_t *packet, net_client_t *client)
+{
+    unsigned int i;
+
+    // Only the controller can launch the game.
+
+    if (client != NET_SV_Controller())
+    {
+        return;
+    }
+
+    // Can only launch when we are in the waiting state.
+
+    if (server_state != SERVER_WAITING_LAUNCH)
+    {
+        return;
+    }
+
+    // Forward launch on to all clients.
+
+    for (i=0; i<MAXNETNODES; ++i)
+    {
+        if (!ClientConnected(&clients[i]))
+            continue;
+
+        NET_Conn_NewReliable(&clients[i].connection,
+                             NET_PACKET_TYPE_LAUNCH);
+    }
+
+    // Now in launch state.
+
+    server_state = SERVER_WAITING_START;
+}
+
 // Parse a game start packet
 
 static void NET_SV_ParseGameStart(net_packet_t *packet, net_client_t *client)
@@ -691,7 +734,7 @@
     net_packet_t *startpacket;
     int nowtime;
     int i;
-    
+
     if (client != NET_SV_Controller())
     {
         // Only the controller can start a new game
@@ -713,10 +756,10 @@
         return;
     }
 
+    // Can only start a game if we are in the waiting start state.
+
     if (server_state != SERVER_WAITING_START)
     {
-        // Can only start a game if we are in the waiting start state.
-
         return;
     }
 
@@ -1232,7 +1275,7 @@
         // Packet was eaten by the common connection code
     }
     else
-    { 
+    {
         //printf("SV: %s: %i\n", NET_AddrToString(addr), packet_type);
 
         switch (packet_type)
@@ -1240,6 +1283,9 @@
             case NET_PACKET_TYPE_GAMESTART:
                 NET_SV_ParseGameStart(packet, client);
                 break;
+            case NET_PACKET_TYPE_LAUNCH:
+                NET_SV_ParseLaunch(packet, client);
+                break;
             case NET_PACKET_TYPE_GAMEDATA:
                 NET_SV_ParseGameData(packet, client);
                 break;
@@ -1502,7 +1548,7 @@
 {
     int i;
 
-    server_state = SERVER_WAITING_START;
+    server_state = SERVER_WAITING_LAUNCH;
     sv_gamemode = indetermined;
 
     for (i=0; i<MAXNETNODES; ++i)
@@ -1557,7 +1603,7 @@
         return;
     }
 
-    if (server_state == SERVER_WAITING_START)
+    if (server_state == SERVER_WAITING_LAUNCH)
     {
         // Waiting for the game to start
 
@@ -1605,7 +1651,7 @@
 
     NET_SV_AssignPlayers();
 
-    server_state = SERVER_WAITING_START;
+    server_state = SERVER_WAITING_LAUNCH;
     sv_gamemode = indetermined;
     server_initialized = true;
 }