From 33cbb4e57df321ceb88ffec2b36021f185f217fa Mon Sep 17 00:00:00 2001 From: Jonas Date: Mon, 11 Apr 2022 18:08:39 +0200 Subject: [PATCH] Client Login into Lobby as well as creating a lobby now works and client can only be in one lobby at the same time. --- .../client/JClientProtocolParser.java | 4 ++ .../multiplayer/client/MessageFormatter.java | 2 +- .../cs108/multiplayer/helpers/Protocol.java | 20 +++++--- .../multiplayer/server/ClientHandler.java | 39 ++++++++++++---- .../server/JServerProtocolParser.java | 20 +++----- .../unibas/dmi/dbis/cs108/sebaschi/Lobby.java | 46 ++++++++++--------- 6 files changed, 78 insertions(+), 53 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/JClientProtocolParser.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/JClientProtocolParser.java index 3d02c69..043b610 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/JClientProtocolParser.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/JClientProtocolParser.java @@ -39,6 +39,10 @@ public class JClientProtocolParser { case Protocol.printToClientConsole: System.out.println(msg.substring(6)); break; + case Protocol.printToClientChat: + //todo: handle chat separately from console. + System.out.println(msg.substring(6)); + break; case Protocol.serverConfirmQuit: c.disconnectFromServer(); break; 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 5758e17..c72cd7a 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 @@ -50,7 +50,7 @@ public class MessageFormatter { break; case "/g": //CRTGM command - stringBuilder.append(Protocol.createNewGame + "$"); + stringBuilder.append(Protocol.createNewLobby + "$"); s = ""; //command has no parameters //TODO add LOGGER msg. Find out if .info or .debug. break; 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 bd1772a..5538819 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 @@ -75,14 +75,12 @@ public class Protocol { public static final String clientQuitRequest = "QUITR"; /** - * TODO: enable for client - * TODO: add sever response - * Client sends this message when he wants to create a new game. + * Client sends this message when they want to create a new game. * Client issues this command in {@link ch.unibas.dmi.dbis.cs108.multiplayer.client.MessageFormatter} * using "/g". * First a lobby {@link ch.unibas.dmi.dbis.cs108.sebaschi.Lobby} is created of which the requesting client is the admin of. */ - public static final String createNewGame = "CRTGM"; + public static final String createNewLobby = "CRTLB"; /** * TODO: implement in {@link ch.unibas.dmi.dbis.cs108.multiplayer.client.MessageFormatter} @@ -111,11 +109,19 @@ public class Protocol { public static final String pingFromServer = "SPING"; /** - * prints out incoming chat messages / announcements into the user's console. any string that + * prints out incoming announcements into the user's console. any string that + * follows CONSM$ is printed as is, so the message that follows already has to be formatted the + * way it should be shown to the client. + */ + public static final String printToClientConsole = "CONSM"; + + /** + * prints out incoming chat messages into the user's chat. any string that * follows CHATM$ is printed as is, so the message that follows already has to be formatted the * way it should be shown to the client. */ - public static final String printToClientConsole = "CHATM"; + public static final String printToClientChat = "CHATM"; + /** * Server confirms the client's quit request, meaning that the client can now close its @@ -137,7 +143,7 @@ public class Protocol { /** * todo: doc */ - public static final String serverDeliversLobbyList = "LLIST"; + public static final String serverDeliversLobbyList = "LLIST"; //todo: do we need this? 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 89e0c5f..7071a51 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 @@ -152,7 +152,7 @@ public class ClientHandler implements Runnable { */ public void broadcastChatMessage(String msg) { for (ClientHandler client : connectedClients) { - client.sendMsgToClient(Protocol.printToClientConsole + "$" + clientUserName + ": " + msg); + client.sendMsgToClient(Protocol.printToClientChat + "$" + clientUserName + ": " + msg); } } @@ -217,17 +217,35 @@ public class ClientHandler implements Runnable { } /** - * Invoked by CRTGM. Creates a new lobby with the ClientHandler as admin and adds the lobby to the - * server data. + * Invoked by Protocol.createNewLobby. Creates a new lobby with the ClientHandler as admin and + * adds the lobby to the server data. */ public void createNewLobby() { - Lobby newGame = new Lobby(this); - serverData.addLobbyToListOfAllLobbies(newGame); - LOGGER.debug( - this.getClientUserName() + " created a new lobby with ID: " + newGame.getLobbyID()); - //TODO add server response. Here a possibility: - sendMsgToClient(Protocol.printToClientConsole + "$New lobby with ID: " + newGame.getLobbyID() - + " created."); + if (Lobby.clientIsInLobby(this) == -1) { + Lobby newGame = new Lobby(this); + serverData.addLobbyToListOfAllLobbies(newGame); + broadcastAnnouncement("New lobby with ID: " + newGame.getLobbyID() + + " created by " + this.getClientUserName()); + } else { + sendMsgToClient(Protocol.printToClientConsole + + "$You are already in lobby nr. " + Lobby.clientIsInLobby(this)); + } + } + + /** + * The client wants to join the lobby with the index i. + * //todo: needs more doc. + * @param i + */ + public void joinLobby(int i) { + Lobby l = Lobby.getLobbyFromID(i); + if (l != null) { + l.addPlayer(this); + } else { + LOGGER.debug(getClientUserName() + " tried to join Lobby nr. " + + i + " but that doesn't exist."); + } + } /** @@ -260,6 +278,7 @@ public class ClientHandler implements Runnable { } + /** * Closes the client's socket, in, and out. and removes from global list of clients. */ 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 b2d9978..19df647 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 @@ -59,22 +59,16 @@ public class JServerProtocolParser { 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."); + try { + int i = Integer.parseInt(msg.substring(6, 7)); + h.joinLobby(i); + } catch (Exception e) { + h.sendMsgToClient(Protocol.printToClientConsole + + "$Invalid input. Please use JOINL$1 to join Lobby 1, for example."); } break; - case Protocol.createNewGame: + case Protocol.createNewLobby: h.createNewLobby(); - LOGGER.debug(Protocol.createNewGame - + " command reached in JServerProtocolParser. Command issued by: " - + h.getClientUserName()); break; case Protocol.listLobbies: h.listAllLobbiesToClient(); 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 16af8f8..5ee9a07 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 @@ -35,9 +35,6 @@ public class Lobby { */ private HashSet lobbyClients = new HashSet<>(6); - - private int numberOfPlayersInLobby; - private final int lobbyID; @@ -50,7 +47,6 @@ public class Lobby { public Lobby(ClientHandler admin) { this.admin = admin; this.lobbyClients.add(admin); - this.numberOfPlayersInLobby = 1; lobbies.add(this); this.lobbyID = lobbies.size(); admin.broadcastAnnouncement("New Lobby created by " + admin.getClientUserName() + @@ -114,38 +110,43 @@ public class Lobby { return null; } - public static boolean clientIsInALobby(ClientHandler h) { + /** + * 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()) { if (h.equals(clientHandler)) { - return true; + return l.getLobbyID(); } } } - return false; + return -1; } /** - * Adds a player to the lobby. + * Adds a player to the lobby. Returns true if successful. * 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. + * @param client who wants to join the lobby. */ - public synchronized void addPlayer(ClientHandler player) { + public synchronized boolean addPlayer(ClientHandler client) { 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 lobbyClients in this lobby: " + lobbyClients.size()); + if (clientIsInLobby(client) == -1) { + lobbyClients.add(client); + client.broadcastAnnouncement(client.getClientUserName() + " has joined lobby " + this.getLobbyID()); + LOGGER.debug(client.getClientUserName() + " has been added to Lobby with ID: " + lobbyID + + ". Current number of lobbyClients in this lobby: " + lobbyClients.size()); + return true; + } else { + client.sendMsgToClient(Protocol.printToClientConsole + "$You are already in lobby nr. " + + clientIsInLobby(client)); + } } else { - LOGGER.debug( - 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 + - "$The lobby is full. Please try joining a different lobby or create a new game"); + client.sendMsgToClient(Protocol.printToClientConsole + + "$This lobby is full. Please try joining a different lobby or create a new lobby"); } + return false; } /** @@ -160,6 +161,7 @@ public class Lobby { return this.getLobbyClients().remove(player); } + //todo: this here? public void broadcastToLounge(String msg) { for (ClientHandler lounger : this.getLobbyClients()) {