diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/helpers/Protocol.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/helpers/Protocol.java index c9ff718..202e210 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/helpers/Protocol.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/helpers/Protocol.java @@ -70,6 +70,13 @@ public class Protocol { */ public static final String listLobbies = "LISTL"; + /** + * Client requests to join the Lobby with the given number, for example, + * {@code JOINL$2} means the client wants to join lobby 2. + * todo: document handling when lobby is already full + */ + public static final String joinLobby = "JOINL"; + //SERVER TO CLIENT COMMANDS /** @@ -106,4 +113,6 @@ public class Protocol { public static final String serverDeliversLobbyList = "LLIST"; + + } 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 c6a7fe1..89e0c5f 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 @@ -18,7 +18,7 @@ public class ClientHandler implements Runnable { public static final Logger LOGGER = LogManager.getLogger(); public static final BudaLogConfig l = new BudaLogConfig(LOGGER); - CentralServerData serverData; + CentralServerData serverData; //todo: does this really need to be instantiated? private String clientUserName; private BufferedWriter out; @@ -161,7 +161,7 @@ public class ClientHandler implements Runnable { * announcements rather than chat messages. The message will be printed to the user exactly as it * is given to this method. Unlike broadcastChatMessage, it will also be printed onto the server * console. - * + * todo: this could be static! * @param msg the Message to be broadcast */ public void broadcastAnnouncement(String msg) { @@ -179,7 +179,7 @@ public class ClientHandler implements Runnable { */ public void sendMsgToClient(String msg) { try { - if(!msg.equals("SPING"))LOGGER.debug("Message sent to client: " + msg); + //if(!msg.equals("SPING"))LOGGER.debug("Message sent to client: " + msg); out.write(msg); out.newLine(); out.flush(); diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/JServerProtocolParser.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/JServerProtocolParser.java index ac4add4..b2d9978 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/JServerProtocolParser.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/JServerProtocolParser.java @@ -2,6 +2,7 @@ package ch.unibas.dmi.dbis.cs108.multiplayer.server; import ch.unibas.dmi.dbis.cs108.BudaLogConfig; +import ch.unibas.dmi.dbis.cs108.sebaschi.Lobby; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import ch.unibas.dmi.dbis.cs108.multiplayer.helpers.Protocol; @@ -57,6 +58,18 @@ public class JServerProtocolParser { case Protocol.clientQuitRequest: h.removeClientOnLogout(); break; + case Protocol.joinLobby: + //todo: have this be a method of clientHandler. + int i = Integer.parseInt(msg.substring(6, 7)); + Lobby l = Lobby.getLobbyFromID(i); + if (l != null) { + l.addPlayer(h); + h.broadcastAnnouncement(h.getClientUserName() + " joined Lobby nr. " + l.getLobbyID()); + } else { + LOGGER.debug(h.getClientUserName() + " tried to join Lobby nr. " + + i + " but that doesn't exist."); + } + break; case Protocol.createNewGame: h.createNewLobby(); LOGGER.debug(Protocol.createNewGame @@ -65,7 +78,7 @@ public class JServerProtocolParser { break; case Protocol.listLobbies: h.listAllLobbiesToClient(); - LOGGER.debug(Protocol.listLobbies + " command recieved from: " + h.getClientUserName()); + LOGGER.debug(Protocol.listLobbies + " command received from: " + h.getClientUserName()); break; default: System.out.println("Received unknown command"); diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/sebaschi/GameSessionData.java b/src/main/java/ch/unibas/dmi/dbis/cs108/sebaschi/GameSessionData.java index fe2b850..7ee113f 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/sebaschi/GameSessionData.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/sebaschi/GameSessionData.java @@ -9,7 +9,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; /** - * Class that shall contain all non-game logik information relevant to a game session needed for + * Class that shall contain all non-game logic information relevant to a game session needed for * client-server and client-client communication. */ public class GameSessionData { diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/sebaschi/Lobby.java b/src/main/java/ch/unibas/dmi/dbis/cs108/sebaschi/Lobby.java index 2920e4b..16af8f8 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/sebaschi/Lobby.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/sebaschi/Lobby.java @@ -3,8 +3,7 @@ package ch.unibas.dmi.dbis.cs108.sebaschi; import ch.unibas.dmi.dbis.cs108.BudaLogConfig; import ch.unibas.dmi.dbis.cs108.multiplayer.helpers.Protocol; import ch.unibas.dmi.dbis.cs108.multiplayer.server.ClientHandler; -import java.util.ArrayList; -import java.util.List; +import java.util.HashSet; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -18,15 +17,15 @@ public class Lobby { public static final Logger LOGGER = LogManager.getLogger(); public static final BudaLogConfig l = new BudaLogConfig(LOGGER); + public static HashSet lobbies = new HashSet<>(); private static final int MAX_NO_OF_CLIENTS = 6; - public static int lobbies; //TODO CentralServerData serverData; /** - * The Person who created the game and can configure it and decide to start once enough players + * The Person who created the game and can configure it and decide to start once enough lobbyClients * have entered the lobby. */ private final ClientHandler admin; @@ -34,31 +33,28 @@ public class Lobby { /** * Everyone who's in the lobby. */ - private List players = new ArrayList<>(6); + private HashSet lobbyClients = new HashSet<>(6); private int numberOfPlayersInLobby; - //TODO maybe it makes sense to have LobbyID Class? - private final int lobbyID = lobbies++; - - static { - lobbies = 0; - } + private final int lobbyID; /** - * Constructor. Sets the admin to who created the lobby. Adds the admin to the list of players. - * Increases the number of players from 0 to 1. + * Constructor. Sets the admin to who created the lobby. Adds the admin to the list of lobbyClients. + * Increases the number of lobbyClients from 0 to 1. * * @param admin the Client who called CRTGM */ public Lobby(ClientHandler admin) { this.admin = admin; - this.players.add(admin); + this.lobbyClients.add(admin); this.numberOfPlayersInLobby = 1; - LOGGER.debug("New Lobby created by " + admin.getClientUserName() + ". This lobby's ID: " - + this.lobbyID); + lobbies.add(this); + this.lobbyID = lobbies.size(); + admin.broadcastAnnouncement("New Lobby created by " + admin.getClientUserName() + + ". This lobby's ID: " + this.lobbyID); } /** @@ -80,12 +76,12 @@ public class Lobby { } /** - * Returns the list containing players currently in the lobby + * Returns the list containing lobbyClients currently in the lobby * - * @return list of players + * @return list of lobbyClients */ - public List getPlayers() { - return this.players; + public HashSet getLobbyClients() { + return this.lobbyClients; } /** @@ -104,22 +100,47 @@ public class Lobby { return response.toString(); } + /** + * Returns the lobby with the desired LobbyID. + * For example, getLobbyFromID(5) returns the lobby whose LobbyID is 5. + * If no such lobby exists, it returns null. + */ + public static Lobby getLobbyFromID(int i) { + for (Lobby l: lobbies) { + if (l.getLobbyID() == i) { + return l; + } + } + return null; + } + + public static boolean clientIsInALobby(ClientHandler h) { + for (Lobby l: lobbies) { + for (ClientHandler clientHandler: l.getLobbyClients()) { + if (h.equals(clientHandler)) { + return true; + } + } + } + return false; + } + /** * Adds a player to the lobby. * TODO: add an appropriate response. Currently hardcoded. * TODO: Does this method need to be implemented somewhere else, e.g. in the ClientHandler? - * + * //todo: Client can only join one Lobby. * @param player who wants to join the lobby. */ public synchronized void addPlayer(ClientHandler player) { - if (players.size() <= MAX_NO_OF_CLIENTS) { - players.add(player); + if (lobbyClients.size() < MAX_NO_OF_CLIENTS) { + lobbyClients.add(player); numberOfPlayersInLobby++; LOGGER.debug(player.getClientUserName() + " has been added to Lobby with ID: " + lobbyID - + ". Current number of players in this lobby: " + players.size()); + + ". Current number of lobbyClients in this lobby: " + lobbyClients.size()); } else { LOGGER.debug( - player.getClientUserName() + " could not be added to lobby. Number of players in lobby: " + player.getClientUserName() + " could not be added to lobby. Number of lobbyClients in lobby: " + numberOfPlayersInLobby); //TODO: does this have to be formatted in any way to conform to protocol? player.sendMsgToClient(Protocol.printToClientConsole + @@ -136,11 +157,11 @@ public class Lobby { * @return true if a player was found and removed. Used for debugging. */ public synchronized boolean removePlayer(ClientHandler player) { - return this.getPlayers().remove(player); + return this.getLobbyClients().remove(player); } public void broadcastToLounge(String msg) { - for (ClientHandler lounger : this.getPlayers()) { + for (ClientHandler lounger : this.getLobbyClients()) { } }