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

Reply via email to