shithub: choc

Download patch

ref: 126e7b235274aafdb5edfb636561a6443a543cb3
parent: 2a6a4f36231cccd5b95029ee3f287657031552f5
author: Simon Howard <[email protected]>
date: Fri Apr 5 21:36:07 EDT 2013

Handle client disconnects when waiting for the game to start. Abort game
startup if a player disconnects, or continue gracefully if a drone
disconnects.

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

--- a/src/net_server.c
+++ b/src/net_server.c
@@ -903,6 +903,16 @@
     return true;
 }
 
+// Check if the game should start, and if so, start it.
+
+static void CheckStartGame(void)
+{
+    if (AllNodesReady())
+    {
+        StartGame();
+    }
+}
+
 // Send waiting data with current status to all nodes that are ready to
 // start the game.
 
@@ -953,13 +963,8 @@
 
     client->ready = true;
 
-    // Start the game once all clients are ready.
+    CheckStartGame();
 
-    if (AllNodesReady())
-    {
-        StartGame();
-    }
-
     // Update all ready clients with the current state (number of players
     // ready, etc.). This is used by games that show startup progress
     // (eg. Hexen's spinal loading)
@@ -1664,9 +1669,19 @@
 
     if (client->connection.state == NET_CONN_STATE_DISCONNECTED)
     {
-        // deactivate and free back 
-
         client->active = false;
+
+        // If we were about to start a game, any player disconnecting
+        // should cause an abort.
+
+        if (server_state == SERVER_WAITING_START && !client->drone)
+        {
+            NET_SV_BroadcastMessage("Game startup aborted because "
+                                    "player '%s' disconnected.",
+                                    client->name);
+            NET_SV_GameEnded();
+        }
+
         free(client->name);
         NET_FreeAddress(client->addr);
 
@@ -1680,7 +1695,7 @@
             NET_SV_GameEnded();
         }
     }
-    
+
     if (!ClientConnected(client))
     {
         // client has not yet finished connecting
@@ -1753,7 +1768,6 @@
     if (now - master_resolve_time > MASTER_RESOLVE_PERIOD * 1000)
     {
         net_addr_t *new_addr;
-        printf("Re-resolve master server\n");
 
         new_addr = NET_Query_ResolveMaster(server_context);
 
@@ -1841,17 +1855,26 @@
         }
     }
 
-    if (server_state == SERVER_IN_GAME)
+    switch (server_state)
     {
-        NET_SV_AdvanceWindow();
+        case SERVER_WAITING_LAUNCH:
+            break;
 
-        for (i=0; i<NET_MAXPLAYERS; ++i)
-        {
-            if (sv_players[i] != NULL && ClientConnected(sv_players[i]))
+        case SERVER_WAITING_START:
+            CheckStartGame();
+            break;
+
+        case SERVER_IN_GAME:
+            NET_SV_AdvanceWindow();
+
+            for (i = 0; i < NET_MAXPLAYERS; ++i)
             {
-                NET_SV_CheckResends(sv_players[i]);
+                if (sv_players[i] != NULL && ClientConnected(sv_players[i]))
+                {
+                    NET_SV_CheckResends(sv_players[i]);
+                }
             }
-        }
+            break;
     }
 }