diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java index 4fddc93..c29fb1d 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java @@ -131,7 +131,10 @@ public class Game implements Runnable { } if (gameOverCheck.equals(ClientGameInfoHandler.gameOverGhostsWin) || gameOverCheck.equals( ClientGameInfoHandler.gameOverHumansWin)) { - lobby.getAdmin().broadcastAnnouncementToLobby(gameOverCheck); //ToDo(Seraina): adjust for lobby + lobby.getAdmin().broadcastAnnouncementToLobby(gameOverCheck); + lobby.removeGameFromRunningGames(this); + lobby.addGameToFinishedGames(this); + lobby.setLobbyIsOpen(true); return; } } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/MessageFormatter.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/MessageFormatter.java index 948e35f..185cb78 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/MessageFormatter.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/MessageFormatter.java @@ -90,6 +90,10 @@ public class MessageFormatter { System.out.println("invalid vote"); } stringBuilder.append(Protocol.votedFor + "$" + position + "$"); + break; + case "/s": + stringBuilder.append(Protocol.startANewGame); + break; default: s = msg; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/ClientHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/ClientHandler.java index f2e0574..a475f9f 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/ClientHandler.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/ClientHandler.java @@ -135,7 +135,6 @@ public class ClientHandler implements Runnable { try { getLobby().getGame().getGameState().changeUsername(helper,newName); } catch (NullPointerException e) { - LOGGER.warn("No game has been started yet in this lobby"); } } @@ -306,15 +305,27 @@ public class ClientHandler implements Runnable { } /** - * Initializes a new Game instance and starts its run method in a new thread + * Initializes a new Game instance and starts its run method in a new thread. + * Puts the game in the corresponding lobby. Only the admin of this lobby can start a new + * game. */ public void startNewGame() { try { Lobby l = getLobby(); - Game game = new Game(6,1, l.getLobbyClients().size(), l); - l.setGame(game); - Thread t = new Thread(game); - t.start(); + if (l.getLobbyIsOpen()) { + if (l.getAdmin().equals(this)) { + Game game = new Game(6, 1, l.getLobbyClients().size(), l); + l.setGame(game); + Thread t = new Thread(game); + t.start(); + l.addGameToRunningGames(game); + l.setLobbyIsOpen(false); + } else { + sendAnnouncementToClient("Only the admin can start the game"); + } + } else { + sendAnnouncementToClient("The game has already started"); + } } catch (TrainOverflow e) { LOGGER.warn(e.getMessage()); } catch (NullPointerException e) { @@ -379,7 +390,11 @@ public class ClientHandler implements Runnable { public void joinLobby(int i) { Lobby l = Lobby.getLobbyFromID(i); if (l != null) { - l.addPlayer(this); + if (l.getLobbyIsOpen()) { + l.addPlayer(this); + } else { + sendAnnouncementToClient("The game in Lobby " + l.getLobbyID() + " has already started"); + } } else { sendAnnouncementToClient("Invalid Lobby nr."); sendAnnouncementToClient("use LISTL to list lobbies"); @@ -411,7 +426,11 @@ public class ClientHandler implements Runnable { sendAnnouncementToClient("No open Lobbies."); } else { for (Lobby l : Lobby.lobbies) { - sendAnnouncementToClient("Lobby nr. " + l.getLobbyID() + ":"); + String lobbyStatus = "closed"; + if(l.getLobbyIsOpen()) { + lobbyStatus = "open"; + } + sendAnnouncementToClient("Lobby nr. " + l.getLobbyID() + ": (" + lobbyStatus + ")"); for (ClientHandler c : l.getLobbyClients()) { if (c.equals(l.getAdmin())) { sendAnnouncementToClient(" -" + c.getClientUserName() + " (admin)"); diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/Lobby.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/Lobby.java index 0c073f1..21bc958 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/Lobby.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/Lobby.java @@ -17,8 +17,20 @@ public class Lobby { public static final Logger LOGGER = LogManager.getLogger(); public static final BudaLogConfig l = new BudaLogConfig(LOGGER); public static HashSet lobbies = new HashSet<>(); - public Game game; - public boolean gameIsOngoing; //TODO(Seraina): getter and setter + public static HashSet runningGames = new HashSet<>(); + public static HashSet finishedGames = new HashSet<>(); + /** + * The currently ongoing game, is set, when a game is started + */ + private Game game; + /** + * true by default + * true if game has not started yet, false if game has. If true, potential players can still join the game. + * Should be set to true again, after a game is finished. + * Games can only be started if Lobby is open. + */ + private boolean lobbyIsOpen = true; + private static final int MAX_NO_OF_CLIENTS = 6; @@ -96,6 +108,14 @@ public class Lobby { return null; } + public static HashSet getFinishedGames() { + return finishedGames; + } + + public static HashSet getRunningGames() { + return runningGames; + } + /** * Returns the game that the clients in this lobby are in * @@ -105,6 +125,10 @@ public class Lobby { return game; } + public boolean getLobbyIsOpen() { + return lobbyIsOpen; + } + /** * Sets the game of this lobby to a certain game * @@ -114,10 +138,16 @@ public class Lobby { this.game = game; } + public void setLobbyIsOpen(boolean lobbyIsOpen) { + this.lobbyIsOpen = lobbyIsOpen; + } + /** * Returns the ID of the lobby that the client is in. If the client is not in any * lobby, it returns -1. */ + + public static int clientIsInLobby(ClientHandler h) { for (Lobby l: lobbies) { for (ClientHandler clientHandler: l.getLobbyClients()) { @@ -172,6 +202,18 @@ public class Lobby { return false; } + public void addGameToRunningGames(Game game) { + runningGames.add(game); + } + + public void removeGameFromRunningGames(Game game) { + runningGames.remove(game); + } + + public void addGameToFinishedGames(Game game) { + finishedGames.add(game); + } + /** * Closes the lobby. * @@ -179,6 +221,7 @@ public class Lobby { public void closeLobby() { lobbies.remove(this); ClientHandler.broadcastAnnouncementToAll("Lobby nr. " + this.getLobbyID() + " has been closed."); + /* Todo: theoretically, this is enough to close a lobby. ClientHandlers dont have to manually be removed from the lobby