Author: sveinung Date: Sun Jan 17 19:04:27 2016 New Revision: 31476 URL: http://svn.gna.org/viewcvs/freeciv?rev=31476&view=rev Log: Detect spaceship part autoplace failure.
Stop spaceship part autoplace when placing a spaceship part fails. This avoids an eternal loop where placing the same part fails again and again. The eternal loop was triggered when a player launched his space ship without placing all the space ship parts built that turn. The bundled clients placed the space ship components before the player had a chance to launch the space ship. Freeciv-web didn't. Reported by: Andreas Røsdal <andreasr> See bug #24309 Modified: trunk/server/advisors/advspace.c trunk/server/spacerace.c trunk/server/spacerace.h Modified: trunk/server/advisors/advspace.c URL: http://svn.gna.org/viewcvs/freeciv/trunk/server/advisors/advspace.c?rev=31476&r1=31475&r2=31476&view=diff ============================================================================== --- trunk/server/advisors/advspace.c (original) +++ trunk/server/advisors/advspace.c Sun Jan 17 19:04:27 2016 @@ -27,6 +27,8 @@ /**************************************************************************** Place all available spaceship components. + + Returns TRUE iff at least one part was placed. ****************************************************************************/ bool adv_spaceship_autoplace(struct player *pplayer, struct player_spaceship *ship) @@ -39,8 +41,15 @@ placed = next_spaceship_component(pplayer, ship, &place); if (placed) { - handle_spaceship_place(pplayer, place.type, place.num); - retval = TRUE; + if (do_spaceship_place(pplayer, ACT_REQ_SS_AGENT, + place.type, place.num)) { + /* A part was placed. It was placed even if the placement of future + * parts will fail. */ + retval = TRUE; + } else { + /* Unable to place this part. Don't try to place it again. */ + break; + } } } while (placed); Modified: trunk/server/spacerace.c URL: http://svn.gna.org/viewcvs/freeciv/trunk/server/spacerace.c?rev=31476&r1=31475&r2=31476&view=diff ============================================================================== --- trunk/server/spacerace.c (original) +++ trunk/server/spacerace.c Sun Jan 17 19:04:27 2016 @@ -204,148 +204,214 @@ Handle spaceship part placement request **************************************************************************/ void handle_spaceship_place(struct player *pplayer, - enum spaceship_place_type type, int num) + enum spaceship_place_type type, int num) +{ + (void) do_spaceship_place(pplayer, ACT_REQ_PLAYER, type, num); +} + +/************************************************************************** + Place a spaceship part +**************************************************************************/ +bool do_spaceship_place(struct player *pplayer, enum action_requester from, + enum spaceship_place_type type, int num) { struct player_spaceship *ship = &pplayer->spaceship; if (ship->state == SSHIP_NONE) { - notify_player(pplayer, NULL, E_SPACESHIP, ftc_server, - _("Spaceship action received," - " but you don't have a spaceship!")); - return; - } + if (from == ACT_REQ_PLAYER) { + notify_player(pplayer, NULL, E_SPACESHIP, ftc_server, + _("Spaceship action received," + " but you don't have a spaceship!")); + } + + return FALSE; + } + if (ship->state >= SSHIP_LAUNCHED) { - notify_player(pplayer, NULL, E_SPACESHIP, ftc_server, - _("You can't modify your spaceship after launch!")); - return; - } + if (from == ACT_REQ_PLAYER) { + notify_player(pplayer, NULL, E_SPACESHIP, ftc_server, + _("You can't modify your spaceship after launch!")); + } + + return FALSE; + } + if (type == SSHIP_PLACE_STRUCTURAL) { if (num < 0 || num >= NUM_SS_STRUCTURALS || BV_ISSET(ship->structure, num)) { - return; + return FALSE; } if (num_spaceship_structurals_placed(ship) >= ship->structurals) { - notify_player(pplayer, NULL, E_SPACESHIP, ftc_server, - _("You don't have any unplaced Space Structurals!")); - return; + if (from == ACT_REQ_PLAYER) { + notify_player(pplayer, NULL, E_SPACESHIP, ftc_server, + _("You don't have any unplaced Space Structurals!")); + } + + return FALSE; } if (num != 0 && !BV_ISSET(ship->structure, structurals_info[num].required)) { - notify_player(pplayer, NULL, E_SPACESHIP, ftc_server, - _("That Space Structural would not be connected!")); - return; - } + if (from == ACT_REQ_PLAYER) { + notify_player(pplayer, NULL, E_SPACESHIP, ftc_server, + _("That Space Structural would not be connected!")); + } + + return FALSE; + } + BV_SET(ship->structure, num); spaceship_calc_derived(ship); send_spaceship_info(pplayer, NULL); - return; - } + return TRUE; + } + if (type == SSHIP_PLACE_FUEL) { - if (ship->fuel != num-1) { - return; + if (ship->fuel != num - 1) { + return FALSE; } if (ship->fuel + ship->propulsion >= ship->components) { - notify_player(pplayer, NULL, E_SPACESHIP, ftc_server, - _("You don't have any unplaced Space Components!")); - return; + if (from == ACT_REQ_PLAYER) { + notify_player(pplayer, NULL, E_SPACESHIP, ftc_server, + _("You don't have any unplaced Space Components!")); + } + + return FALSE; } if (num > NUM_SS_COMPONENTS/2) { - notify_player(pplayer, NULL, E_SPACESHIP, ftc_server, - _("Your spaceship already has" - " the maximum number of Fuel Components!")); - return; - } + if (from == ACT_REQ_PLAYER) { + notify_player(pplayer, NULL, E_SPACESHIP, ftc_server, + _("Your spaceship already has" + " the maximum number of Fuel Components!")); + } + + return FALSE; + } + ship->fuel++; spaceship_calc_derived(ship); send_spaceship_info(pplayer, NULL); - return; - } + return TRUE; + } + if (type == SSHIP_PLACE_PROPULSION) { - if (ship->propulsion != num-1) { - return; + if (ship->propulsion != num - 1) { + return FALSE; } if (ship->fuel + ship->propulsion >= ship->components) { - notify_player(pplayer, NULL, E_SPACESHIP, ftc_server, - _("You don't have any unplaced" - " Space Components!")); - return; + if (from == ACT_REQ_PLAYER) { + notify_player(pplayer, NULL, E_SPACESHIP, ftc_server, + _("You don't have any unplaced" + " Space Components!")); + } + + return FALSE; } if (num > NUM_SS_COMPONENTS/2) { - notify_player(pplayer, NULL, E_SPACESHIP, ftc_server, - _("Your spaceship already has the" - " maximum number of Propulsion Components!")); - return; - } + if (from == ACT_REQ_PLAYER) { + notify_player(pplayer, NULL, E_SPACESHIP, ftc_server, + _("Your spaceship already has the" + " maximum number of Propulsion Components!")); + } + + return FALSE; + } + ship->propulsion++; spaceship_calc_derived(ship); send_spaceship_info(pplayer, NULL); - return; - } + return TRUE; + } + if (type == SSHIP_PLACE_HABITATION) { - if (ship->habitation != num-1) { - return; + if (ship->habitation != num - 1) { + return FALSE; } if (ship->habitation + ship->life_support + ship->solar_panels >= ship->modules) { - notify_player(pplayer, NULL, E_SPACESHIP, ftc_server, - _("You don't have any unplaced Space Modules!")); - return; + if (from == ACT_REQ_PLAYER) { + notify_player(pplayer, NULL, E_SPACESHIP, ftc_server, + _("You don't have any unplaced Space Modules!")); + } + + return FALSE; } if (num > NUM_SS_MODULES / 3) { - notify_player(pplayer, NULL, E_SPACESHIP, ftc_server, - _("Your spaceship already has the" - " maximum number of Habitation Modules!")); - return; - } + if (from == ACT_REQ_PLAYER) { + notify_player(pplayer, NULL, E_SPACESHIP, ftc_server, + _("Your spaceship already has the" + " maximum number of Habitation Modules!")); + } + + return FALSE; + } + ship->habitation++; spaceship_calc_derived(ship); send_spaceship_info(pplayer, NULL); - return; - } + return TRUE; + } + if (type == SSHIP_PLACE_LIFE_SUPPORT) { - if (ship->life_support != num-1) { - return; + if (ship->life_support != num - 1) { + return FALSE; } if (ship->habitation + ship->life_support + ship->solar_panels >= ship->modules) { - notify_player(pplayer, NULL, E_SPACESHIP, ftc_server, - _("You don't have any unplaced Space Modules!")); - return; + if (from == ACT_REQ_PLAYER) { + notify_player(pplayer, NULL, E_SPACESHIP, ftc_server, + _("You don't have any unplaced Space Modules!")); + } + + return FALSE; } if (num > NUM_SS_MODULES / 3) { - notify_player(pplayer, NULL, E_SPACESHIP, ftc_server, - _("Your spaceship already has the" - " maximum number of Life Support Modules!")); - return; - } + if (from == ACT_REQ_PLAYER) { + notify_player(pplayer, NULL, E_SPACESHIP, ftc_server, + _("Your spaceship already has the" + " maximum number of Life Support Modules!")); + } + + return FALSE; + } + ship->life_support++; spaceship_calc_derived(ship); send_spaceship_info(pplayer, NULL); - return; - } + return TRUE; + } + if (type == SSHIP_PLACE_SOLAR_PANELS) { - if (ship->solar_panels != num-1) { - return; + if (ship->solar_panels != num - 1) { + return FALSE; } if (ship->habitation + ship->life_support + ship->solar_panels >= ship->modules) { - notify_player(pplayer, NULL, E_SPACESHIP, ftc_server, - _("You don't have any unplaced Space Modules!")); - return; + if (from == ACT_REQ_PLAYER) { + notify_player(pplayer, NULL, E_SPACESHIP, ftc_server, + _("You don't have any unplaced Space Modules!")); + } + + return FALSE; } if (num > NUM_SS_MODULES / 3) { - notify_player(pplayer, NULL, E_SPACESHIP, ftc_server, - _("Your spaceship already has the" - " maximum number of Solar Panel Modules!")); - return; - } + if (from == ACT_REQ_PLAYER) { + notify_player(pplayer, NULL, E_SPACESHIP, ftc_server, + _("Your spaceship already has the" + " maximum number of Solar Panel Modules!")); + } + + return FALSE; + } + ship->solar_panels++; spaceship_calc_derived(ship); send_spaceship_info(pplayer, NULL); - return; - } + return TRUE; + } + log_error("Received unknown spaceship place type %d from %s", type, player_name(pplayer)); + return FALSE; } /************************************************************************** Modified: trunk/server/spacerace.h URL: http://svn.gna.org/viewcvs/freeciv/trunk/server/spacerace.h?rev=31476&r1=31475&r2=31476&view=diff ============================================================================== --- trunk/server/spacerace.h (original) +++ trunk/server/spacerace.h Sun Jan 17 19:04:27 2016 @@ -28,4 +28,7 @@ void spaceship_lost(struct player *pplayer); struct player *check_spaceship_arrival(void); +bool do_spaceship_place(struct player *pplayer, enum action_requester from, + enum spaceship_place_type type, int num); + #endif /* FC__SPACERACE_H */ _______________________________________________ Freeciv-commits mailing list Freeciv-commits@gna.org https://mail.gna.org/listinfo/freeciv-commits