diff options
author | jbion <joffrey.bion@amadeus.com> | 2016-12-18 01:22:47 +0100 |
---|---|---|
committer | jbion <joffrey.bion@amadeus.com> | 2016-12-18 01:22:47 +0100 |
commit | deff1187c52191f211cd66c917b1ee94c9499dfc (patch) | |
tree | 5670ad2d389c8d810f6f963aa099d36d0d846423 /src/main/java/org/luxons | |
parent | Add proper logging and validation (diff) | |
download | seven-wonders-deff1187c52191f211cd66c917b1ee94c9499dfc.tar.gz seven-wonders-deff1187c52191f211cd66c917b1ee94c9499dfc.tar.bz2 seven-wonders-deff1187c52191f211cd66c917b1ee94c9499dfc.zip |
Improve LobbyController errors and logs
Diffstat (limited to 'src/main/java/org/luxons')
-rw-r--r-- | src/main/java/org/luxons/sevenwonders/actions/JoinOrCreateGameAction.java (renamed from src/main/java/org/luxons/sevenwonders/actions/JoinGameAction.java) | 12 | ||||
-rw-r--r-- | src/main/java/org/luxons/sevenwonders/controllers/LobbyController.java | 98 | ||||
-rw-r--r-- | src/main/java/org/luxons/sevenwonders/controllers/UniqueIdAlreadyUsedException.java | 15 | ||||
-rw-r--r-- | src/main/java/org/luxons/sevenwonders/game/Lobby.java | 32 | ||||
-rw-r--r-- | src/main/java/org/luxons/sevenwonders/game/Player.java | 19 |
5 files changed, 138 insertions, 38 deletions
diff --git a/src/main/java/org/luxons/sevenwonders/actions/JoinGameAction.java b/src/main/java/org/luxons/sevenwonders/actions/JoinOrCreateGameAction.java index fc2e11d2..cf5596da 100644 --- a/src/main/java/org/luxons/sevenwonders/actions/JoinGameAction.java +++ b/src/main/java/org/luxons/sevenwonders/actions/JoinOrCreateGameAction.java @@ -3,22 +3,22 @@ package org.luxons.sevenwonders.actions; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; -public class JoinGameAction { +public class JoinOrCreateGameAction { @NotNull @Size(min=2, max=30) - private String gameId; + private String gameName; @NotNull @Size(min=2, max=20) private String playerName; - public String getGameId() { - return gameId; + public String getGameName() { + return gameName; } - public void setGameId(String gameId) { - this.gameId = gameId; + public void setGameName(String gameName) { + this.gameName = gameName; } public String getPlayerName() { diff --git a/src/main/java/org/luxons/sevenwonders/controllers/LobbyController.java b/src/main/java/org/luxons/sevenwonders/controllers/LobbyController.java index 312214d6..ea262c4e 100644 --- a/src/main/java/org/luxons/sevenwonders/controllers/LobbyController.java +++ b/src/main/java/org/luxons/sevenwonders/controllers/LobbyController.java @@ -4,7 +4,7 @@ import java.security.Principal; import java.util.HashMap; import java.util.Map; -import org.luxons.sevenwonders.actions.JoinGameAction; +import org.luxons.sevenwonders.actions.JoinOrCreateGameAction; import org.luxons.sevenwonders.game.Game; import org.luxons.sevenwonders.game.Lobby; import org.luxons.sevenwonders.game.Player; @@ -12,9 +12,11 @@ import org.luxons.sevenwonders.game.data.GameDefinitionLoader; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.messaging.handler.annotation.MessageExceptionHandler; import org.springframework.messaging.handler.annotation.MessageMapping; import org.springframework.messaging.handler.annotation.SendTo; import org.springframework.messaging.simp.SimpMessageHeaderAccessor; +import org.springframework.messaging.simp.annotation.SendToUser; import org.springframework.stereotype.Controller; import org.springframework.validation.annotation.Validated; @@ -24,6 +26,8 @@ public class LobbyController { private static final Logger logger = LoggerFactory.getLogger(LobbyController.class); + public static final String ATTR_LOBBY = "lobby"; + private final GameDefinitionLoader gameDefinitionLoader; private long lastGameId = 0; @@ -37,39 +41,87 @@ public class LobbyController { this.gameDefinitionLoader = gameDefinitionLoader; } + @MessageExceptionHandler + @SendToUser("/queue/errors") + public String handleException(Throwable exception) { + logger.error("An error occured during message handling", exception); + return exception.getClass().getSimpleName() + ": " + exception.getMessage(); + } + @MessageMapping("/create-game") @SendTo("/topic/games") - public String createGame(SimpMessageHeaderAccessor headerAccessor, Principal principal) { - long newId = lastGameId++; - String id = String.valueOf(newId); - - Lobby lobby = new Lobby(newId, gameDefinitionLoader.getGameDefinition()); - lobbies.put(id, lobby); - logger.info("Game {} created by {}", id, principal.getName()); - return id; + public Lobby createGame(SimpMessageHeaderAccessor headerAccessor, @Validated JoinOrCreateGameAction action, + Principal principal) { + Lobby lobby = (Lobby)headerAccessor.getSessionAttributes().get(ATTR_LOBBY); + if (lobby != null) { + logger.warn("Client already in game '{}', cannot create a new game", lobby.getName()); + return lobby; + } + + Player player = createPlayer(action.getPlayerName(), principal); + lobby = createGame(action.getGameName(), player); + + headerAccessor.getSessionAttributes().put(ATTR_LOBBY, lobby); + + logger.info("Game '{}' (id={}) created by {} ({})", lobby.getName(), lobby.getId(), player.getDisplayName(), + player.getUserName()); + return lobby; } @MessageMapping("/join-game") - @SendTo("/topic/players") - public Player joinGame(SimpMessageHeaderAccessor headerAccessor, @Validated JoinGameAction action, + @SendToUser("/queue/join-game") + public Lobby joinGame(SimpMessageHeaderAccessor headerAccessor, @Validated JoinOrCreateGameAction action, Principal principal) { - Player player = (Player)headerAccessor.getSessionAttributes().get("player"); - Lobby lobby = (Lobby)headerAccessor.getSessionAttributes().get("lobby"); - if (player != null && lobby != null) { - logger.warn("Client has already joined game {} under the name {}", lobby.getId(), player.getName()); - return player; + Lobby lobby = (Lobby)headerAccessor.getSessionAttributes().get(ATTR_LOBBY); + if (lobby != null) { + logger.warn("Client already in game '{}', cannot join a different game", lobby.getName()); + return lobby; + } + + lobby = lobbies.get(action.getGameName()); + if (lobby == null) { + throw new GameNotFoundException(action.getGameName()); } - lobby = lobbies.get(action.getGameId()); - Player newPlayer = new Player(action.getPlayerName()); - newPlayer.setUserName(principal.getName()); + Player newPlayer = createPlayer(action.getPlayerName(), principal); lobby.addPlayer(newPlayer); - headerAccessor.getSessionAttributes().put("player", newPlayer); - headerAccessor.getSessionAttributes().put("lobby", lobby); + headerAccessor.getSessionAttributes().put(ATTR_LOBBY, lobby); - logger.warn("Player {} joined game {}", action.getPlayerName(), action.getGameId()); + logger.warn("Player {} joined game {}", action.getPlayerName(), action.getGameName()); - return newPlayer; + return lobby; } + + private Player createPlayer(String name, Principal principal) { + Player player = new Player(name); + player.setUserName(principal.getName()); + return player; + } + + private Lobby createGame(String name, Player owner) { + if (lobbies.containsKey(name)) { + throw new GameNameAlreadyUsedException(name); + } + long id = lastGameId++; + Lobby lobby = new Lobby(id, name, owner, gameDefinitionLoader.getGameDefinition()); + lobbies.put(name, lobby); + return lobby; + } + + private class GameNotFoundException extends RuntimeException { + + public GameNotFoundException(String name) { + super(name); + } + + } + + private class GameNameAlreadyUsedException extends UniqueIdAlreadyUsedException { + + public GameNameAlreadyUsedException(String name) { + super(name); + } + } + } diff --git a/src/main/java/org/luxons/sevenwonders/controllers/UniqueIdAlreadyUsedException.java b/src/main/java/org/luxons/sevenwonders/controllers/UniqueIdAlreadyUsedException.java new file mode 100644 index 00000000..56c22655 --- /dev/null +++ b/src/main/java/org/luxons/sevenwonders/controllers/UniqueIdAlreadyUsedException.java @@ -0,0 +1,15 @@ +package org.luxons.sevenwonders.controllers; + +public class UniqueIdAlreadyUsedException extends RuntimeException { + + private String id; + + public UniqueIdAlreadyUsedException(String id) { + super("'" + id + "'"); + this.id = id; + } + + public String getUsedId() { + return id; + } +} diff --git a/src/main/java/org/luxons/sevenwonders/game/Lobby.java b/src/main/java/org/luxons/sevenwonders/game/Lobby.java index 24055c75..7256936c 100644 --- a/src/main/java/org/luxons/sevenwonders/game/Lobby.java +++ b/src/main/java/org/luxons/sevenwonders/game/Lobby.java @@ -3,28 +3,37 @@ package org.luxons.sevenwonders.game; import java.util.ArrayList; import java.util.List; +import org.luxons.sevenwonders.controllers.UniqueIdAlreadyUsedException; import org.luxons.sevenwonders.game.data.GameDefinition; public class Lobby { private final long id; + private final String name; + private final List<Player> players; private final GameDefinition gameDefinition; private State state = State.LOBBY; - public Lobby(long id, GameDefinition gameDefinition) { + public Lobby(long id, String name, Player owner, GameDefinition gameDefinition) { this.id = id; + this.name = name; this.gameDefinition = gameDefinition; - this.players = new ArrayList<>(3); + this.players = new ArrayList<>(gameDefinition.getMinPlayers()); + players.add(owner); } public long getId() { return id; } + public String getName() { + return name; + } + public synchronized int addPlayer(Player player) throws GameAlreadyStartedException, PlayerOverflowException { if (hasStarted()) { throw new GameAlreadyStartedException(); @@ -32,6 +41,9 @@ public class Lobby { if (maxPlayersReached()) { throw new PlayerOverflowException(); } + if (playerNameAlreadyUsed(player.getDisplayName())) { + throw new PlayerNameAlreadyUsedException(player.getDisplayName()); + } int playerId = players.size(); players.add(player); return playerId; @@ -45,6 +57,10 @@ public class Lobby { return players.size() >= gameDefinition.getMaxPlayers(); } + private boolean playerNameAlreadyUsed(String name) { + return players.stream().anyMatch(p -> p.getDisplayName().equals(name)); + } + public synchronized Game startGame(Settings settings) throws PlayerUnderflowException { if (!hasEnoughPlayers()) { throw new PlayerUnderflowException(); @@ -58,6 +74,11 @@ public class Lobby { return players.size() >= gameDefinition.getMinPlayers(); } + @Override + public String toString() { + return "Lobby{" + "id=" + id + ", name='" + name + '\'' + ", state=" + state + '}'; + } + public class GameAlreadyStartedException extends IllegalStateException { } @@ -66,4 +87,11 @@ public class Lobby { public class PlayerUnderflowException extends IllegalStateException { } + + public class PlayerNameAlreadyUsedException extends UniqueIdAlreadyUsedException { + + public PlayerNameAlreadyUsedException(String name) { + super(name); + } + } } diff --git a/src/main/java/org/luxons/sevenwonders/game/Player.java b/src/main/java/org/luxons/sevenwonders/game/Player.java index eafabf4a..fd2f254b 100644 --- a/src/main/java/org/luxons/sevenwonders/game/Player.java +++ b/src/main/java/org/luxons/sevenwonders/game/Player.java @@ -2,20 +2,20 @@ package org.luxons.sevenwonders.game; public class Player { - private String name; + private String displayName; private String userName; - public Player(String name) { - this.name = name; + public Player(String displayName) { + this.displayName = displayName; } - public String getName() { - return name; + public String getDisplayName() { + return displayName; } - public void setName(String name) { - this.name = name; + public void setDisplayName(String displayName) { + this.displayName = displayName; } public String getUserName() { @@ -25,4 +25,9 @@ public class Player { public void setUserName(String userName) { this.userName = userName; } + + @Override + public String toString() { + return "Player{" + "name='" + displayName + '\'' + ", userName='" + userName + '\'' + '}'; + } } |