summaryrefslogtreecommitdiff
path: root/src/main/java/org
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org')
-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.java98
-rw-r--r--src/main/java/org/luxons/sevenwonders/controllers/UniqueIdAlreadyUsedException.java15
-rw-r--r--src/main/java/org/luxons/sevenwonders/game/Lobby.java32
-rw-r--r--src/main/java/org/luxons/sevenwonders/game/Player.java19
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 + '\'' + '}';
+ }
}
bgstack15