diff --git a/Projekte/battleship/model/src/main/java/pp/battleship/game/server/ServerGameLogic.java b/Projekte/battleship/model/src/main/java/pp/battleship/game/server/ServerGameLogic.java index a5987fa..8959d04 100644 --- a/Projekte/battleship/model/src/main/java/pp/battleship/game/server/ServerGameLogic.java +++ b/Projekte/battleship/model/src/main/java/pp/battleship/game/server/ServerGameLogic.java @@ -9,6 +9,7 @@ package pp.battleship.game.server; import pp.battleship.BattleshipConfig; import pp.battleship.message.client.ClientInterpreter; +import pp.battleship.message.client.ClientMessage; import pp.battleship.message.client.MapMessage; import pp.battleship.message.client.ShootMessage; import pp.battleship.message.server.EffectMessage; @@ -134,6 +135,7 @@ public class ServerGameLogic implements ClientInterpreter { /** * Handles the reception of a MapMessage. + * Also tests if Map is in correct format * * @param msg the received MapMessage * @param from the ID of the sender client @@ -142,10 +144,59 @@ public class ServerGameLogic implements ClientInterpreter { public void received(MapMessage msg, int from) { if (state != ServerState.SET_UP) LOGGER.log(Level.ERROR, "playerReady not allowed in {0}", state); //NON-NLS - else - playerReady(getPlayerById(from), msg.getShips()); + + Player cp = getPlayerById(from); + List ships = msg.getShips(); + + if (!validateShips(ships)) { + LOGGER.log(Level.ERROR, "Invalid ship placement by player {0}", from); + return; + } + + playerReady(cp, ships); } + + /** + * Validates a list of ships. + * Validates the list, that no ships are out of bounds or overlap with each other + * + * @param ships list of ships to validate + * @return {@code true} if all ships positions are valid, {@code false} otherwise + */ + private boolean validateShips(List ships) { + Set occupiedPoints = new HashSet<>(); + + for (Battleship ship : ships) { + if (!isWithinBounds(ship)) { + return false; + } + + for (int x = ship.getMinX(); x <= ship.getMaxX(); x++) { + for (int y = ship.getMinY(); y <= ship.getMaxY(); y++) { + IntPoint point = new IntPoint(x, y); + if (!occupiedPoints.add(point)) { + return false; + } + } + } + } + + return true; + } + + + /** + * Test if a ship is inside the map + * @param ship the ship to validate + * @return {@code true} if a ship is within bounds, {@code false} otherwise + */ + private boolean isWithinBounds(Battleship ship) { + return ship.getMinX() >= 0 && ship.getMaxX() < config.getMapWidth() && + ship.getMinY() >= 0 && ship.getMaxY() < config.getMapHeight(); + } + + /** * Handles the reception of a ShootMessage. *