Example #1
0
  /**
   * Handle a "setBuildQueue"-message.
   *
   * @param server The <code>FreeColServer</code> handling the message.
   * @param player The <code>Player</code> the message applies to.
   * @param connection The <code>Connection</code> message was received on.
   * @return An update containing the new queue or an error <code>Element</code> on failure.
   */
  public Element handle(FreeColServer server, Player player, Connection connection) {
    ServerPlayer serverPlayer = server.getPlayer(connection);
    Game game = server.getGame();
    Specification spec = game.getSpecification();

    Colony colony;
    try {
      colony = player.getOurFreeColGameObject(colonyId, Colony.class);
    } catch (Exception e) {
      return DOMMessage.clientError(e.getMessage());
    }

    if (queue == null) {
      return DOMMessage.clientError("Empty queue");
    }
    List<BuildableType> buildQueue = new ArrayList<BuildableType>();
    for (int i = 0; i < queue.length; i++) {
      try {
        buildQueue.add(i, spec.getType(queue[i], BuildableType.class));
      } catch (Exception cce) {
        return DOMMessage.clientError("Not a buildable type: " + queue[i]);
      }
    }

    // Proceed to set the build queue.
    return server.getInGameController().setBuildQueue(serverPlayer, colony, buildQueue);
  }
  public void testNoBuildingMaterialsProductionWhenBuildingNothing() {
    Game game = getGame();
    game.setMap(getTestMap(true));

    Colony colony = getStandardColony(4);
    Building carpenterHouse = colony.getBuilding(carpenterHouseType);
    Unit unit = colony.getFirstUnit();
    // necessary for work production
    int initialLumber = 100;
    int initialHammers = 0;
    colony.addGoods(lumberGoodsType, initialLumber);
    colony.setCurrentlyBuilding(null);

    assertEquals(
        "Wrong initial lumber quantity.", initialLumber, colony.getGoodsCount(lumberGoodsType));
    assertEquals(
        "Colony should not have initial hammers.",
        initialHammers,
        colony.getGoodsCount(hammerGoodsType));

    unit.setLocation(carpenterHouse);

    assertTrue(
        "Colony should be producing hammers.", colony.getTotalProductionOf(hammerGoodsType) > 0);

    ServerTestHelper.newTurn();

    assertEquals(
        "Colony should not have produced hammers.",
        initialHammers,
        colony.getGoodsCount(hammerGoodsType));
    assertEquals(
        "Wrong final lumber quantity.", initialLumber, colony.getGoodsCount(lumberGoodsType));
  }
Example #3
0
  /**
   * Handle a "buildColony"-message.
   *
   * @param server The <code>FreeColServer</code> handling the request.
   * @param player The <code>Player</code> building the colony.
   * @param connection The <code>Connection</code> the message is from.
   * @return An update <code>Element</code> defining the new colony and updating its surrounding
   *     tiles, or an error <code>Element</code> on failure.
   */
  public Element handle(FreeColServer server, Player player, Connection connection) {
    Game game = server.getGame();
    ServerPlayer serverPlayer = server.getPlayer(connection);

    Unit unit;
    try {
      unit = player.getFreeColGameObject(builderId, Unit.class);
    } catch (Exception e) {
      return DOMMessage.clientError(e.getMessage());
    }
    if (!unit.canBuildColony()) {
      return DOMMessage.clientError("Unit " + builderId + " can not build colony.");
    }

    if (colonyName == null) {
      return DOMMessage.clientError("Null colony name");
    } else if (Player.ASSIGN_SETTLEMENT_NAME.equals(colonyName)) {; // ok
    } else if (game.getSettlement(colonyName) != null) {
      return DOMMessage.clientError("Non-unique colony name " + colonyName);
    }

    Tile tile = unit.getTile();
    if (!player.canClaimToFoundSettlement(tile)) {
      return DOMMessage.clientError("Can not build colony on tile: " + tile);
    }

    // Build can proceed.
    return server.getInGameController().buildSettlement(serverPlayer, unit, colonyName);
  }
  public void testAssignDefendSettlementMission() {
    Game game = ServerTestHelper.startServerGame(getTestMap());
    Map map = game.getMap();
    AIMain aiMain = ServerTestHelper.getServer().getAIMain();

    // Create player and unit
    ServerPlayer dutch = (ServerPlayer) game.getPlayerByNationId("model.nation.dutch");

    Tile tile1 = map.getTile(2, 2);
    Unit soldier = new ServerUnit(game, tile1, dutch, veteranType);

    AIUnit aiUnit = aiMain.getAIUnit(soldier);
    assertNotNull(aiUnit);

    // Add nearby colony in need of defense
    Tile colonyTile = map.getTile(2, 3);
    assertTrue(colonyTile != null);
    colonyTile.setExplored(dutch, true);
    Colony colony =
        FreeColTestUtils.getColonyBuilder().player(dutch).colonyTile(colonyTile).build();

    assertTrue(colonyTile.getSettlement() == colony);
    assertTrue(colony.getOwner() == dutch);
    assertTrue(colony.getUnitCount() == 1);
    aiUnit.setMission(null);
    assertEquals(
        "DefendSettlementMission should be possible",
        null,
        DefendSettlementMission.invalidReason(aiUnit));
    assertEquals(
        "DefendSettlementMission should work with colony",
        null,
        DefendSettlementMission.invalidReason(aiUnit, colony));
  }
Example #5
0
  /**
   * Updates and starts the new game.
   *
   * <p>Called in response to a requestLaunch message arriving at the PreGameInputHandler.
   *
   * <ol>
   *   <li>Creates the game.
   *   <li>Sends updated game information to the clients.
   *   <li>Changes the game state to {@link net.sf.freecol.server.FreeColServer.GameState#IN_GAME}.
   *   <li>Sends the "startGame"-message to the clients.
   * </ol>
   */
  public void startGame() throws FreeColException {
    final FreeColServer freeColServer = getFreeColServer();
    Game game = freeColServer.buildGame();

    // Inform the clients.
    for (Player player : new ArrayList<Player>(game.getPlayers())) {
      if (!player.isAI()) {
        player.invalidateCanSeeTiles(); // Send clean copy of the game
        Connection conn = ((ServerPlayer) player).getConnection();
        Element update = DOMMessage.createMessage("updateGame");
        update.appendChild(game.toXMLElement(update.getOwnerDocument(), player));
        try {
          conn.askDumping(update);
        } catch (IOException e) {
          logger.log(Level.WARNING, "Unable to updateGame", e);
        }
      }
    }

    // Start the game:
    freeColServer.setGameState(FreeColServer.GameState.IN_GAME);
    try {
      freeColServer.updateMetaServer();
    } catch (NoRouteToServerException e) {
    }

    freeColServer.getServer().sendToAll(DOMMessage.createMessage("startGame"));
    freeColServer
        .getServer()
        .setMessageHandlerToAllConnections(freeColServer.getInGameInputHandler());
  }
  public void testIsTargetValidForSeekAndDestroy() {
    Game game = ServerTestHelper.startServerGame(getTestMap());
    Map map = game.getMap();
    AIMain aiMain = ServerTestHelper.getServer().getAIMain();

    // Create player and unit
    ServerPlayer incaPlayer = (ServerPlayer) game.getPlayerByNationId("model.nation.inca");
    NativeAIPlayer aiInca = (NativeAIPlayer) aiMain.getAIPlayer(incaPlayer);
    ServerPlayer dutchPlayer = (ServerPlayer) game.getPlayerByNationId("model.nation.dutch");

    Tile dutchUnitTile = map.getTile(9, 9);
    Tile braveUnitTile = map.getTile(9, 8);
    ;

    Unit brave = new ServerUnit(game, braveUnitTile, incaPlayer, braveType);
    Unit soldier = new ServerUnit(game, dutchUnitTile, dutchPlayer, veteranType);

    Player.makeContact(incaPlayer, dutchPlayer);

    assertFalse(
        "Target should NOT be valid for UnitSeekAndDestroyMission",
        aiInca.isTargetValidForSeekAndDestroy(brave, soldier.getTile()));

    incaPlayer.setTension(dutchPlayer, new Tension(Tension.Level.HATEFUL.getLimit()));
    assertTrue(
        "Target should be valid for UnitSeekAndDestroyMission",
        aiInca.isTargetValidForSeekAndDestroy(brave, soldier.getTile()));

    incaPlayer.setStance(dutchPlayer, Stance.WAR);
    dutchPlayer.setStance(incaPlayer, Stance.WAR);
    assertTrue(
        "Target should be valid for UnitSeekAndDestroyMission",
        aiInca.isTargetValidForSeekAndDestroy(brave, soldier.getTile()));
  }
  /**
   * When searching for threats to a settlement, the indian player should ignore naval threats, as
   * he does not have naval power
   */
  public void testSecureIndianSettlementMissionIgnoreNavalThreat() {
    Game game = ServerTestHelper.startServerGame(getCoastTestMap(plainsType));
    Map map = game.getMap();
    AIMain aiMain = ServerTestHelper.getServer().getAIMain();
    InGameController igc = ServerTestHelper.getInGameController();

    // Create player and unit
    ServerPlayer inca = (ServerPlayer) game.getPlayerByNationId("model.nation.inca");
    NativeAIPlayer aiInca = (NativeAIPlayer) aiMain.getAIPlayer(inca);
    ServerPlayer dutch = (ServerPlayer) game.getPlayerByNationId("model.nation.dutch");

    Tile settlementTile = map.getTile(9, 9);
    Tile seaTile = map.getTile(10, 9);
    assertTrue("Settlement tile should be land", settlementTile.isLand());
    assertFalse("Galleon tile should be ocean", seaTile.isLand());
    FreeColTestCase.IndianSettlementBuilder builder =
        new FreeColTestCase.IndianSettlementBuilder(game);
    IndianSettlement camp =
        builder.player(inca).settlementTile(settlementTile).initialBravesInCamp(10).build();
    ServerUnit galleon = new ServerUnit(game, seaTile, dutch, galleonType);
    int unitsInGalleon = 6;
    for (int i = 0; i < unitsInGalleon; i++) {
      ServerUnit artillery = new ServerUnit(game, settlementTile, dutch, artilleryType);
      igc.embarkUnit(dutch, artillery, galleon);
    }
    assertEquals("Wrong number of units onboard galleon", unitsInGalleon, galleon.getUnitCount());
    assertEquals("Galleon should be full", 0, galleon.getSpaceLeft());

    for (Unit brave : camp.getUnitList()) {
      AIUnit aiUnit = aiMain.getAIUnit(brave);
      assertNotNull(aiUnit);
      new UnitWanderHostileMission(aiMain, aiUnit);

      assertTrue("No enemy units present", aiUnit.hasMission(UnitWanderHostileMission.class));
    }

    inca.setStance(dutch, Stance.WAR);
    inca.setTension(dutch, new Tension(Tension.Level.HATEFUL.getLimit()));
    assertTrue("Indian player should be at war with dutch", inca.getStance(dutch) == Stance.WAR);
    assertEquals(
        "Wrong Indian player tension towards dutch",
        Tension.Level.HATEFUL.getLimit(),
        inca.getTension(dutch).getValue());

    aiInca.abortInvalidMissions();
    aiInca.secureIndianSettlement(camp, lb);
    boolean seeking = false;
    for (Unit brave : inca.getUnits()) {
      AIUnit aiUnit = aiMain.getAIUnit(brave);
      assertNotNull(aiUnit);
      if (aiUnit.hasMission(UnitSeekAndDestroyMission.class)) {
        seeking = true;
        break;
      }
    }
    assertFalse("Braves should not pursue naval units", seeking);
  }
  /**
   * Find a new location from a stream attribute. This is necessary because <code>Location</code> is
   * an interface.
   *
   * @param game The <code>Game</code> to look in.
   * @param attributeName The attribute to check.
   * @param make If true, try to make the location if it is not found.
   * @return The <code>Location</code> found.
   */
  public Location getLocationAttribute(Game game, String attributeName, boolean make)
      throws XMLStreamException {

    if (attributeName == null) return null;

    final String attrib =
        // @compat 0.10.7
        (FreeColObject.ID_ATTRIBUTE_TAG.equals(attributeName))
            ? readId()
            :
            // end @compat
            getAttribute(attributeName, (String) null);

    if (attrib != null) {
      FreeColObject fco = lookup(game, attrib);
      if (fco == null && make) {
        Class<? extends FreeColGameObject> c = game.getLocationClass(attrib);
        if (c != null) {
          fco = makeFreeColGameObject(game, attributeName, c, getReadScope() == ReadScope.SERVER);
        }
      }
      if (fco instanceof Location) return (Location) fco;
      logger.warning("Not a location: " + attrib);
    }
    return null;
  }
  public void testImpossibleConditionsForTargetSelection() {
    Game game = ServerTestHelper.startServerGame(getCoastTestMap(plainsType));
    Map map = game.getMap();
    AIMain aiMain = ServerTestHelper.getServer().getAIMain();

    // Create attacking player and units
    ServerPlayer dutch = (ServerPlayer) game.getPlayerByNationId("model.nation.dutch");

    Tile tile1 = map.getTile(2, 2);
    Tile tile2 = map.getTile(2, 1);
    Unit soldier = new ServerUnit(game, tile1, dutch, veteranType);
    Unit friendlyColonist = new ServerUnit(game, tile2, dutch, colonistType);

    AIUnit aiUnit = aiMain.getAIUnit(soldier);
    assertNotNull(aiUnit);

    // Create defending player and unit
    ServerPlayer french = (ServerPlayer) game.getPlayerByNationId("model.nation.french");

    Tile tile3 = map.getTile(1, 2);
    Unit enemyColonist = new ServerUnit(game, tile3, french, colonistType);

    Tile tile4 = map.getTile(12, 12); // in the water
    assertFalse("Tle should be water", tile4.isLand());

    Unit enemyGalleon = new ServerUnit(game, tile4, french, galleonType);
    // Make tests

    assertNotNull(
        "Cannot attack own unit",
        UnitSeekAndDestroyMission.invalidReason(aiUnit, friendlyColonist));
    assertNotNull(
        "Players are not at war", UnitSeekAndDestroyMission.invalidReason(aiUnit, enemyColonist));

    dutch.setStance(french, Stance.WAR);
    french.setStance(dutch, Stance.WAR);

    assertEquals(
        "Unit should be able to attack land unit",
        null,
        UnitSeekAndDestroyMission.invalidReason(aiUnit, enemyColonist));
    assertNotNull(
        "Land unit cannot attack naval unit",
        UnitSeekAndDestroyMission.invalidReason(aiUnit, enemyGalleon));
  }
  public void testFoodConsumption() {
    Game game = ServerTestHelper.startServerGame(getTestMap(plains));
    ServerPlayer dutch = (ServerPlayer) game.getPlayerByNationId("model.nation.dutch");
    // Setting test colony and colonist
    Colony colony =
        FreeColTestUtils.getColonyBuilder().colonyTile(game.getMap().getTile(5, 8)).build();
    new ServerUnit(game, colony.getWorkLocationForProducing(bellsType), dutch, colonistType);
    assertEquals(0, colony.getGoodsCount(foodType));

    int quantity = colony.getFoodConsumption() * 2;
    colony.addGoods(foodGoodsType, quantity);
    int foodStored = colony.getGoodsCount(foodGoodsType);
    assertEquals(quantity, foodStored);
    int foodExpected = foodStored - colony.getFoodConsumption() + colony.getFoodProduction();

    ServerTestHelper.newTurn();
    assertEquals(
        "Unexpected value for remaining food, ", foodExpected, colony.getGoodsCount(foodGoodsType));
  }
  /**
   * Start a new server game, using a *copy* of a supplied map.
   *
   * @param map The <code>Map</code> to copy.
   * @param spec The <code>Specification</code> to use.
   * @return The new running server game.
   */
  public static Game startServerGame(Map map, Specification spec) {
    stopServerGame();
    FreeColServer serv = startServer(false, true, spec);
    serv.setMapGenerator(new MockMapGenerator(serv.getGame(), map));
    PreGameController pgc = (PreGameController) serv.getController();
    try {
      pgc.startGame();
    } catch (FreeColException e) {
      fail("Failed to start game: " + e.getMessage());
    }

    Game game = serv.getGame();
    FreeColTestCase.setGame(game);
    if (game.getCurrentPlayer() == null) {
      game.setCurrentPlayer(game.getFirstPlayer());
    }
    random = new Random();
    return game;
  }
  public void testEqualFoodProductionConsumptionCase() {
    Game game = ServerTestHelper.startServerGame(getTestMap(desert));

    // Setting test colony
    Tile colonyTile = game.getMap().getTile(5, 8);
    Colony colony =
        FreeColTestUtils.getColonyBuilder().colonyTile(colonyTile).initialColonists(1).build();

    // Set the food production of the center tile of the colony to 2
    // This will be the only food production of the colony
    List<AbstractGoods> colonyTileProduction = colonyTile.getType().getPossibleProduction(true);
    for (int i = 0; i < colonyTileProduction.size(); i++) {
      AbstractGoods production = colonyTileProduction.get(i);
      if (production.getType() == foodGoodsType) {
        production.setAmount(2);
        break;
      }
    }
    Unit unit = colony.getUnitList().get(0);
    unit.setLocation(colony.getWorkLocationFor(unit, bellsType));

    // Verify that there is enough food stored
    colony.addGoods(foodGoodsType, colony.getFoodConsumption() * 2);

    assertEquals(
        "Production not equal to consumption",
        colony.getFoodConsumption(),
        colony.getFoodProduction());

    int colonists = colony.getUnitCount();
    assertEquals("Unexpected change of colonists in colony", colonists, colony.getUnitCount());

    assertEquals(
        "Unexpected change of production/consumption ratio",
        colony.getFoodProduction(),
        colony.getFoodConsumption());
  }
  /**
   * Do a special non-interning read of a <code>FreeColObject</code>.
   *
   * @param game The <code>Game</code> to look in.
   * @param returnClass The class to expect.
   * @return The <code>FreeColObject</code> found, or null there was no ID_ATTRIBUTE_TAG present.
   * @exception XMLStreamException if there is problem reading the stream.
   */
  private <T extends FreeColObject> T uninternedRead(Game game, Class<T> returnClass)
      throws XMLStreamException {

    T ret;
    try {
      ret = game.newInstance(returnClass, false);
    } catch (IOException e) {
      throw new XMLStreamException(e);
    }
    String id = readId();
    if (id == null) {
      throw new XMLStreamException("Object identifier not found.");
    }
    uninterned.put(id, ret);
    ret.readFromXML(this);
    return ret;
  }
  /**
   * Either get an existing <code>FreeColGameObject</code> from a stream attribute or create it if
   * it does not exist.
   *
   * <p>Use this routine when the object may not necessarily already be present in the game, but is
   * expected to be defined eventually.
   *
   * @param game The <code>Game</code> to look in.
   * @param attributeName The required attribute name.
   * @param returnClass The class of object.
   * @param required If true a null result should throw an exception.
   * @return The <code>FreeColGameObject</code> found or made, or null if the attribute was not
   *     present.
   */
  public <T extends FreeColGameObject> T makeFreeColGameObject(
      Game game, String attributeName, Class<T> returnClass, boolean required)
      throws XMLStreamException {
    final String id =
        // @compat 0.10.7
        (FreeColObject.ID_ATTRIBUTE_TAG.equals(attributeName))
            ? readId()
            :
            // end @compat
            getAttribute(attributeName, (String) null);

    if (id == null) {
      if (required) {
        throw new XMLStreamException(
            "Missing " + attributeName + " for " + returnClass.getName() + ": " + currentTag());
      }
    } else {
      FreeColObject fco = lookup(game, id);
      if (fco == null) {
        try {
          T ret = game.newInstance(returnClass, getReadScope() == ReadScope.SERVER);
          if (shouldIntern()) {
            ret.internId(id);
          } else {
            uninterned.put(id, ret);
          }
          return ret;
        } catch (IOException e) {
          if (required) {
            throw new XMLStreamException(e);
          } else {
            logger.log(Level.WARNING, "Failed to create FCGO: " + id, e);
          }
        }
      } else {
        try {
          return returnClass.cast(fco);
        } catch (ClassCastException cce) {
          throw new XMLStreamException(cce);
        }
      }
    }
    return null;
  }
 /**
  * Look up an identifier in an enclosing game. If not interning prefer an non-interned result.
  *
  * @param game The <code>Game</code> to consult.
  * @param id The object identifier.
  * @return The <code>FreeColObject</code> found, or null if none.
  */
 private FreeColObject lookup(Game game, String id) {
   FreeColObject fco = (shouldIntern()) ? null : uninterned.get(id);
   return (fco != null) ? fco : game.getFreeColGameObject(id);
 }
  public void testSecureIndianSettlementMission() {
    Game game = ServerTestHelper.startServerGame(getTestMap());
    Map map = game.getMap();
    AIMain aiMain = ServerTestHelper.getServer().getAIMain();

    // Create player and unit
    ServerPlayer inca = (ServerPlayer) game.getPlayerByNationId("model.nation.inca");
    NativeAIPlayer aiInca = (NativeAIPlayer) aiMain.getAIPlayer(inca);
    ServerPlayer dutch = (ServerPlayer) game.getPlayerByNationId("model.nation.dutch");

    Tile settlementTile = map.getTile(9, 9);
    Tile adjacentTile = settlementTile.getNeighbourOrNull(Direction.N);
    assertTrue("Settlement tile should be land", settlementTile.isLand());
    assertTrue("Adjacent tile should be land", adjacentTile != null && adjacentTile.isLand());
    FreeColTestCase.IndianSettlementBuilder builder =
        new FreeColTestCase.IndianSettlementBuilder(game);
    IndianSettlement camp =
        builder.player(inca).settlementTile(settlementTile).initialBravesInCamp(8).build();
    assertEquals("One camp", 1, inca.getNumberOfSettlements());

    // Put one brave outside the camp, but in the settlement tile,
    // so that he may defend the settlement
    Unit braveOutside = new ServerUnit(game, settlementTile, inca, braveType);
    braveOutside.setHomeIndianSettlement(camp);

    // Setup enemy units
    int enemyUnits = camp.getUnitCount() + 1;
    for (int i = 0; i < enemyUnits; i++) {
      new ServerUnit(game, adjacentTile, dutch, veteranType);
    }

    Iterator<Unit> campUnitIter = camp.getOwnedUnitsIterator();
    while (campUnitIter.hasNext()) {
      Unit brave = campUnitIter.next();
      assertNotNull("Got null while getting the camps units", brave);
      AIUnit aiUnit = aiMain.getAIUnit(brave);
      assertNotNull("Couldnt get the ai object for the brave", aiUnit);
      new UnitWanderHostileMission(aiMain, aiUnit);
      assertTrue(
          "Should be UnitWanderHostileMission", aiUnit.hasMission(UnitWanderHostileMission.class));
      assertEquals(
          "Unit should be candidate for seek+destroy",
          null,
          UnitSeekAndDestroyMission.invalidReason(aiUnit));
      assertEquals(
          "Unit should be candidate for defend",
          null,
          DefendSettlementMission.invalidReason(aiUnit));
    }

    inca.setStance(dutch, Stance.WAR);
    inca.setTension(dutch, new Tension(Tension.Level.HATEFUL.getLimit()));
    camp.setAlarm(dutch, inca.getTension(dutch));
    assertTrue("Indian player should be at war with dutch", inca.getStance(dutch) == Stance.WAR);
    assertEquals(
        "Wrong Indian player tension towards dutch",
        Tension.Level.HATEFUL.getLimit(),
        inca.getTension(dutch).getValue());
    aiInca.secureIndianSettlement(camp, lb);

    // Verify if a unit was assigned a UnitSeekAndDestroyMission
    boolean isSeekAndDestroyMission = false;
    for (Unit brave : inca.getUnits()) {
      AIUnit aiUnit = aiMain.getAIUnit(brave);
      assertNotNull("Couldnt get aiUnit for players brave", aiUnit);
      assertNotNull("Unit missing mission", aiUnit.getMission());
      isSeekAndDestroyMission = aiUnit.hasMission(UnitSeekAndDestroyMission.class);
      if (isSeekAndDestroyMission) break;
    }
    assertTrue("A brave should have a UnitSeekAndDestroyMission", isSeekAndDestroyMission);
  }