<URL: http://bugs.freeciv.org/Ticket/Display.html?id=40194 >

On 07/04/2008, Marko Lindqvist  wrote:
>
>   start_game() is called from two distinct places.
>
>   1) Command /start
>   2) All human players indicate that they are ready by using Start -button
>
>   There is some functionality in first that is never executed for case
>  two. Number of players is not checked against minplayers setting
>  (making it totally useless), there's no scenario sanity checking.

 S2_1 version of the fix.

 Updated S2_2/TRUNK version.


 - ML

diff -Nurd -X.diff_ignore freeciv/server/srv_main.c freeciv/server/srv_main.c
--- freeciv/server/srv_main.c	2008-04-05 00:59:42.000000000 +0300
+++ freeciv/server/srv_main.c	2008-04-15 10:43:53.000000000 +0300
@@ -1532,9 +1532,8 @@
 		    "are ready to start."),
 		  num_ready, num_ready + num_unready);
     } else {
-      notify_conn(NULL, NULL, E_SETTING,
-		  _("All players are ready; starting game."));
-      start_game();
+      /* Check minplayers etc. and then start */
+      start_command(NULL, FALSE, TRUE);
     }
   }
 }
diff -Nurd -X.diff_ignore freeciv/server/stdinhand.c freeciv/server/stdinhand.c
--- freeciv/server/stdinhand.c	2008-04-02 22:48:51.000000000 +0300
+++ freeciv/server/stdinhand.c	2008-04-15 10:54:34.000000000 +0300
@@ -92,7 +92,6 @@
 static bool observe_command(struct connection *caller, char *name, bool check);
 static bool take_command(struct connection *caller, char *name, bool check);
 static bool detach_command(struct connection *caller, char *name, bool check);
-static bool start_command(struct connection *caller, char *name, bool check);
 static bool end_command(struct connection *caller, char *str, bool check);
 static bool surrender_command(struct connection *caller, char *str, bool check);
 
@@ -3687,7 +3686,7 @@
   case CMD_TIMEOUT:
     return timeout_command(caller, allargs, check);
   case CMD_START_GAME:
-    return start_command(caller, arg, check);
+    return start_command(caller, check, FALSE);
   case CMD_END_GAME:
     return end_command(caller, arg, check);
   case CMD_SURRENDER:
@@ -3748,9 +3747,20 @@
 }
 
 /**************************************************************************
-...
+ Send start command related message
 **************************************************************************/
-static bool start_command(struct connection *caller, char *name, bool check)
+static void start_cmd_reply(struct connection *caller, bool notify, char *msg)
+{
+    cmd_reply(CMD_START_GAME, caller, C_FAIL, msg);
+    if (notify) {
+      notify_conn(NULL, NULL, E_SETTING, msg);
+    }
+}
+
+/**************************************************************************
+ Handle start command. Notify all players about errors if notify set.
+**************************************************************************/
+bool start_command(struct connection *caller, bool check, bool notify)
 {
   switch (server_state()) {
   case S_S_INITIAL:
@@ -3787,12 +3797,18 @@
 
     /* check min_players */
     if (game.info.nplayers < game.info.min_players) {
-      cmd_reply(CMD_START_GAME, caller, C_FAIL,
-		_("Not enough players, game will not start."));
+      start_cmd_reply(caller, notify,
+                      _("Not enough players, game will not start."));
       return FALSE;
     } else if (check) {
       return TRUE;
     } else if (!caller) {
+      if (notify) {
+        /* Called from handle_player_ready()
+         * Last player just toggled ready-status. */
+        notify_conn(NULL, NULL, E_SETTING,
+                    _("All players are ready; starting game."));
+      }
       start_game();
       return TRUE;
     } else if (!caller->player || !caller->player->is_connected) {
@@ -3804,15 +3820,15 @@
     }
   case S_S_OVER:
     /* TRANS: given when /start is invoked during gameover. */
-    cmd_reply(CMD_START_GAME, caller, C_FAIL,
-              _("Cannot start the game: the game is waiting for all clients "
-              "to disconnect."));
+    start_cmd_reply(caller, notify,
+                    _("Cannot start the game: the game is waiting for all clients "
+                      "to disconnect."));
     return FALSE;
   case S_S_RUNNING:
   case S_S_GENERATING_WAITING:
     /* TRANS: given when /start is invoked while the game is running. */
-    cmd_reply(CMD_START_GAME, caller, C_FAIL,
-              _("Cannot start the game: it is already running."));
+    start_cmd_reply(caller, notify,
+                    _("Cannot start the game: it is already running."));
     return FALSE;
   }
   assert(FALSE);
diff -Nurd -X.diff_ignore freeciv/server/stdinhand.h freeciv/server/stdinhand.h
--- freeciv/server/stdinhand.h	2007-03-05 19:13:46.000000000 +0200
+++ freeciv/server/stdinhand.h	2008-04-15 10:43:53.000000000 +0300
@@ -33,7 +33,7 @@
 void show_players(struct connection *caller);
 
 bool load_command(struct connection *caller, char *arg, bool check);
-
+bool start_command(struct connection *caller, bool check, bool notify);
 
 void toggle_ai_player_direct(struct connection *caller,
 			     struct player *pplayer);
diff -Nurd -X.diff_ignore freeciv/server/srv_main.c freeciv/server/srv_main.c
--- freeciv/server/srv_main.c	2008-04-01 22:40:44.000000000 +0300
+++ freeciv/server/srv_main.c	2008-04-15 10:38:00.000000000 +0300
@@ -1578,9 +1578,8 @@
 		    "are ready to start."),
 		  num_ready, num_ready + num_unready);
     } else {
-      notify_conn(NULL, NULL, E_SETTING,
-		  _("All players are ready; starting game."));
-      start_game();
+      /* Check minplayers etc. and then start */
+      start_command(NULL, FALSE, TRUE);
     }
   }
 }
diff -Nurd -X.diff_ignore freeciv/server/stdinhand.c freeciv/server/stdinhand.c
--- freeciv/server/stdinhand.c	2008-04-06 11:24:53.000000000 +0300
+++ freeciv/server/stdinhand.c	2008-04-15 10:52:22.000000000 +0300
@@ -93,7 +93,6 @@
 static bool observe_command(struct connection *caller, char *name, bool check);
 static bool take_command(struct connection *caller, char *name, bool check);
 static bool detach_command(struct connection *caller, char *name, bool check);
-static bool start_command(struct connection *caller, char *name, bool check);
 static bool end_command(struct connection *caller, char *str, bool check);
 static bool surrender_command(struct connection *caller, char *str, bool check);
 
@@ -3695,7 +3694,7 @@
   case CMD_TIMEOUT:
     return timeout_command(caller, allargs, check);
   case CMD_START_GAME:
-    return start_command(caller, arg, check);
+    return start_command(caller, check, FALSE);
   case CMD_END_GAME:
     return end_command(caller, arg, check);
   case CMD_SURRENDER:
@@ -3756,9 +3755,20 @@
 }
 
 /**************************************************************************
-...
+ Send start command related message
 **************************************************************************/
-static bool start_command(struct connection *caller, char *name, bool check)
+static void start_cmd_reply(struct connection *caller, bool notify, char *msg)
+{
+    cmd_reply(CMD_START_GAME, caller, C_FAIL, msg);
+    if (notify) {
+      notify_conn(NULL, NULL, E_SETTING, msg);
+    }
+}
+
+/**************************************************************************
+ Handle start command. Notify all players about errors if notify set.
+**************************************************************************/
+bool start_command(struct connection *caller, bool check, bool notify)
 {
   switch (server_state()) {
   case S_S_INITIAL:
@@ -3795,32 +3805,40 @@
 
     /* check min_players */
     if (game.info.nplayers < game.info.min_players) {
-      cmd_reply(CMD_START_GAME, caller, C_FAIL,
-		_("Not enough players, game will not start."));
+      start_cmd_reply(caller, notify,
+                      _("Not enough players, game will not start."));
       return FALSE;
     } else if (check) {
       return TRUE;
     } else if (!caller) {
+      if (notify) {
+        /* Called from handle_player_ready()
+         * Last player just toggled ready-status. */
+        notify_conn(NULL, NULL, E_SETTING,
+                    _("All players are ready; starting game."));
+      }
       start_game();
       return TRUE;
     } else if (NULL == caller->playing || !caller->playing->is_connected) {
       /* A detached or observer player can't do /start. */
       return TRUE;
     } else {
+      /* This might trigger recursive call to start_command() if this is
+       * last player who gets ready. In that case caller is NULL. */
       handle_player_ready(caller->playing, player_number(caller->playing), TRUE);
       return TRUE;
     }
   case S_S_OVER:
     /* TRANS: given when /start is invoked during gameover. */
-    cmd_reply(CMD_START_GAME, caller, C_FAIL,
-              _("Cannot start the game: the game is waiting for all clients "
-              "to disconnect."));
+    start_cmd_reply(caller, notify,
+                    _("Cannot start the game: the game is waiting for all clients "
+                      "to disconnect."));
     return FALSE;
   case S_S_RUNNING:
   case S_S_GENERATING_WAITING:
     /* TRANS: given when /start is invoked while the game is running. */
-    cmd_reply(CMD_START_GAME, caller, C_FAIL,
-              _("Cannot start the game: it is already running."));
+    start_cmd_reply(caller, notify,
+                    _("Cannot start the game: it is already running."));
     return FALSE;
   }
   assert(FALSE);
diff -Nurd -X.diff_ignore freeciv/server/stdinhand.h freeciv/server/stdinhand.h
--- freeciv/server/stdinhand.h	2007-09-14 14:44:25.000000000 +0300
+++ freeciv/server/stdinhand.h	2008-04-15 10:38:00.000000000 +0300
@@ -33,7 +33,7 @@
 void show_players(struct connection *caller);
 
 bool load_command(struct connection *caller, char *arg, bool check);
-
+bool start_command(struct connection *caller, bool check, bool notify);
 
 void toggle_ai_player_direct(struct connection *caller,
 			     struct player *pplayer);
_______________________________________________
Freeciv-dev mailing list
Freeciv-dev@gna.org
https://mail.gna.org/listinfo/freeciv-dev

Reply via email to