<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
[email protected]
https://mail.gna.org/listinfo/freeciv-dev