From ce739933cb95d20d4a5e4c84cfad5b84cca344ca Mon Sep 17 00:00:00 2001 From: Alexander Hirmer Date: Mon, 29 Nov 2021 15:56:32 +0100 Subject: [PATCH] #14 --- .../eu/jonahbauer/wizard/server/Session.java | 41 ++++++++++++++++--- .../wizard/server/machine/Player.java | 9 +++- .../server/machine/states/LobbyState.java | 1 + .../server/machine/states/SessionState.java | 8 +++- 4 files changed, 52 insertions(+), 7 deletions(-) diff --git a/wizard-server/src/main/java/eu/jonahbauer/wizard/server/Session.java b/wizard-server/src/main/java/eu/jonahbauer/wizard/server/Session.java index 296bbdf..648775c 100644 --- a/wizard-server/src/main/java/eu/jonahbauer/wizard/server/Session.java +++ b/wizard-server/src/main/java/eu/jonahbauer/wizard/server/Session.java @@ -2,8 +2,14 @@ package eu.jonahbauer.wizard.server; import eu.jonahbauer.wizard.common.messages.data.PlayerData; import eu.jonahbauer.wizard.common.messages.data.SessionData; +import eu.jonahbauer.wizard.common.messages.observer.ObserverMessage; +import eu.jonahbauer.wizard.common.messages.player.PlayerMessage; import eu.jonahbauer.wizard.common.messages.server.*; import eu.jonahbauer.wizard.common.model.Configuration; +import eu.jonahbauer.wizard.core.machine.Game; +import eu.jonahbauer.wizard.core.messages.Observer; +import eu.jonahbauer.wizard.core.model.Configurations; +import eu.jonahbauer.wizard.core.model.GameConfiguration; import eu.jonahbauer.wizard.server.machine.Player; import lombok.AccessLevel; import lombok.Data; @@ -17,7 +23,7 @@ import java.util.concurrent.ThreadLocalRandom; @Getter @EqualsAndHashCode(of = "uuid") -public class Session { +public class Session implements Observer { private static final int MIN_PLAYERS = 3; private static final int MAX_PLAYERS = 6; @@ -29,6 +35,8 @@ public class Session { @Getter(AccessLevel.NONE) private final Map players = new HashMap<>(); + private Game game; + public Session(UUID uuid, String name, long timeout, Configuration configuration) { this.uuid = uuid; @@ -48,9 +56,9 @@ public class Session { */ public synchronized UUID join(Player player, String name) { if (players.size() == MAX_PLAYERS) { - throw new NackException(NackMessage.BAD_REQUEST, "Session is full."); + throw new NackException(NackMessage.SESSION_FULL, "Session is full."); } else if (players.values().stream().anyMatch(p -> p.getName().equalsIgnoreCase(name))) { - throw new NackException(NackMessage.BAD_REQUEST, "Name is already taken."); + throw new NackException(NackMessage.NAME_TAKEN, "Name is already taken."); } Lobby.getInstance().leave(player); @@ -80,16 +88,19 @@ public class Session { public synchronized void ready(UUID player, boolean ready) { var sessionPlayer = players.get(player); if (sessionPlayer == null) { - throw new NackException(NackMessage.BAD_REQUEST, "Who are you?"); + throw new NackException(NackMessage.PLAYER_NOT_FOUND, "Who are you?"); } if (sessionPlayer.isReady() != ready) { sessionPlayer.setReady(ready); + sessionPlayer.getPlayer().send(new AckMessage()); notifyPlayers(new PlayerModifiedMessage(sessionPlayer.toData())); } if (players.size() >= MIN_PLAYERS && players.values().stream().allMatch(SessionPlayer::isReady)) { - // TODO start game + game = new Game(Configurations.get(configuration), this); + notifyPlayers(new StartingGameMessage()); + game.start(players.keySet().stream().toList()); } } @@ -119,6 +130,26 @@ public class Session { return new SessionData(uuid, name, players.size(), configuration); } + /** + * Forwards the message sent by the player to the game. + * + * @param player the player + * @param message the players message + */ + public void handlePlayerMessage(UUID player, PlayerMessage message) { + game.onMessage(player, message); + } + + @Override + public void notify(ObserverMessage message) { + notifyPlayers(new GameMessage(message)); + } + + @Override + public void notify(UUID player, ObserverMessage message) { + players.get(player).getPlayer().send(new GameMessage(message)); + } + @Data @EqualsAndHashCode(of = "uuid") private static class SessionPlayer { diff --git a/wizard-server/src/main/java/eu/jonahbauer/wizard/server/machine/Player.java b/wizard-server/src/main/java/eu/jonahbauer/wizard/server/machine/Player.java index c732945..382ce0a 100644 --- a/wizard-server/src/main/java/eu/jonahbauer/wizard/server/machine/Player.java +++ b/wizard-server/src/main/java/eu/jonahbauer/wizard/server/machine/Player.java @@ -2,7 +2,9 @@ package eu.jonahbauer.wizard.server.machine; import eu.jonahbauer.wizard.common.machine.Context; import eu.jonahbauer.wizard.common.messages.client.ClientMessage; +import eu.jonahbauer.wizard.common.messages.server.NackMessage; import eu.jonahbauer.wizard.common.messages.server.ServerMessage; +import eu.jonahbauer.wizard.server.NackException; import eu.jonahbauer.wizard.server.machine.states.CreatedState; import lombok.SneakyThrows; import org.springframework.web.socket.CloseStatus; @@ -27,7 +29,12 @@ public class Player extends Context { } public void onMessage(ClientMessage message) { - execute(s -> s.onMessage(this, message)); + + try { + execute(s -> s.onMessage(this, message)); + } catch (NackException e) { + send(new NackMessage(e.getCode(), e.getMessage())); + } } public void onClose(CloseStatus status) { diff --git a/wizard-server/src/main/java/eu/jonahbauer/wizard/server/machine/states/LobbyState.java b/wizard-server/src/main/java/eu/jonahbauer/wizard/server/machine/states/LobbyState.java index fd0879b..09e3bfc 100644 --- a/wizard-server/src/main/java/eu/jonahbauer/wizard/server/machine/states/LobbyState.java +++ b/wizard-server/src/main/java/eu/jonahbauer/wizard/server/machine/states/LobbyState.java @@ -41,6 +41,7 @@ public class LobbyState implements ClientState { @Override public Optional onClose(Player player, CloseStatus status) { + Lobby.getInstance().leave(player); return Optional.of(new Closed()); } diff --git a/wizard-server/src/main/java/eu/jonahbauer/wizard/server/machine/states/SessionState.java b/wizard-server/src/main/java/eu/jonahbauer/wizard/server/machine/states/SessionState.java index bf9b328..95edd69 100644 --- a/wizard-server/src/main/java/eu/jonahbauer/wizard/server/machine/states/SessionState.java +++ b/wizard-server/src/main/java/eu/jonahbauer/wizard/server/machine/states/SessionState.java @@ -1,6 +1,7 @@ package eu.jonahbauer.wizard.server.machine.states; import eu.jonahbauer.wizard.common.messages.client.ClientMessage; +import eu.jonahbauer.wizard.common.messages.client.InteractionMessage; import eu.jonahbauer.wizard.common.messages.client.LeaveSessionMessage; import eu.jonahbauer.wizard.common.messages.client.ReadyMessage; import eu.jonahbauer.wizard.common.messages.server.NackMessage; @@ -36,14 +37,19 @@ public class SessionState implements ClientState { } else if (message instanceof LeaveSessionMessage) { Lobby.getInstance().getSession(session).leave(self); return Optional.of(new LobbyState()); + } else if (message instanceof InteractionMessage interactionMessage) { + var playerMessage = interactionMessage.getPlayerMessage(); + Lobby.getInstance().getSession(session).handlePlayerMessage(self, playerMessage); + return Optional.empty(); } else { - player.send(new NackMessage(0, "Error: Invalid Message!")); + player.send(new NackMessage(NackMessage.UNEXPECTED_MESSAGE, "Invalid Message!")); return Optional.empty(); } } @Override public Optional onClose(Player player, CloseStatus status) { + Lobby.getInstance().getSession(session).leave(self); return Optional.of(new Closed()); }