Implemented (almost) all required Lobby functionality. Also added Client_01 and CLient_02 for testing inside intelliJ
This commit is contained in:
parent
33cbb4e57d
commit
01b08e41b8
@ -0,0 +1,8 @@
|
|||||||
|
package ch.unibas.dmi.dbis.cs108.multiplayer.client;
|
||||||
|
|
||||||
|
public class Client_01 {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Client.main(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
package ch.unibas.dmi.dbis.cs108.multiplayer.client;
|
||||||
|
|
||||||
|
public class Client_02 {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Client.main(args);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -83,13 +83,15 @@ public class Protocol {
|
|||||||
public static final String createNewLobby = "CRTLB";
|
public static final String createNewLobby = "CRTLB";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: implement in {@link ch.unibas.dmi.dbis.cs108.multiplayer.client.MessageFormatter}
|
|
||||||
* TODO: imlement in {@link ch.unibas.dmi.dbis.cs108.multiplayer.server.JServerProtocolParser}
|
|
||||||
* TODO: add the Servers reaction, i.e. sending a list of lobbies.
|
|
||||||
* Represents a clients' request for a list of lobbies
|
* Represents a clients' request for a list of lobbies
|
||||||
*/
|
*/
|
||||||
public static final String listLobbies = "LISTL";
|
public static final String listLobbies = "LISTL";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a clients' request for a list of all players within the lobby.
|
||||||
|
*/
|
||||||
|
public static final String listPlayersInLobby = "LISTP";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Client requests to join the Lobby with the given number, for example,
|
* Client requests to join the Lobby with the given number, for example,
|
||||||
* {@code JOINL$2} means the client wants to join lobby 2.
|
* {@code JOINL$2} means the client wants to join lobby 2.
|
||||||
@ -97,6 +99,12 @@ public class Protocol {
|
|||||||
*/
|
*/
|
||||||
public static final String joinLobby = "JOINL";
|
public static final String joinLobby = "JOINL";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Client requests to leave whatever lobby they're in.
|
||||||
|
*/
|
||||||
|
public static final String leaveLobby = "LEAVL";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//SERVER TO CLIENT COMMANDS
|
//SERVER TO CLIENT COMMANDS
|
||||||
|
|
||||||
|
|||||||
@ -37,7 +37,6 @@ public class ClientHandler implements Runnable {
|
|||||||
public ServerPinger serverPinger;
|
public ServerPinger serverPinger;
|
||||||
public static HashSet<ClientHandler> connectedClients = new HashSet<>();
|
public static HashSet<ClientHandler> connectedClients = new HashSet<>();
|
||||||
public static HashSet<ClientHandler> disconnectedClients = new HashSet<>(); //todo: implement re-connection
|
public static HashSet<ClientHandler> disconnectedClients = new HashSet<>(); //todo: implement re-connection
|
||||||
public static HashSet<ClientHandler> lobby = new HashSet<>();
|
|
||||||
public static HashSet<ClientHandler> ghostClients = new HashSet<>();
|
public static HashSet<ClientHandler> ghostClients = new HashSet<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -81,10 +80,6 @@ public class ClientHandler implements Runnable {
|
|||||||
return connectedClients;
|
return connectedClients;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static HashSet<ClientHandler> getLobby() {
|
|
||||||
return lobby;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static HashSet<ClientHandler> getGhostClients() {
|
public static HashSet<ClientHandler> getGhostClients() {
|
||||||
return ghostClients;
|
return ghostClients;
|
||||||
}
|
}
|
||||||
@ -130,7 +125,7 @@ public class ClientHandler implements Runnable {
|
|||||||
public void changeUsername(String newName) {
|
public void changeUsername(String newName) {
|
||||||
String helper = this.getClientUserName();
|
String helper = this.getClientUserName();
|
||||||
this.clientUserName = nameDuplicateChecker.checkName(newName);
|
this.clientUserName = nameDuplicateChecker.checkName(newName);
|
||||||
broadcastAnnouncement(helper + " has changed their nickname to " + clientUserName);
|
broadcastAnnouncementToAll(helper + " has changed their nickname to " + clientUserName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -142,15 +137,53 @@ public class ClientHandler implements Runnable {
|
|||||||
*/
|
*/
|
||||||
public void setUsernameOnLogin(String name) {
|
public void setUsernameOnLogin(String name) {
|
||||||
this.clientUserName = nameDuplicateChecker.checkName(name);
|
this.clientUserName = nameDuplicateChecker.checkName(name);
|
||||||
broadcastAnnouncement(clientUserName + " has joined the Server");
|
broadcastAnnouncementToAll(clientUserName + " has joined the Server");
|
||||||
|
|
||||||
|
/* The following lines could be un-commented to provide Lobby information on login
|
||||||
|
sendAnnouncementToClient("Welcome, " + clientUserName + "!");
|
||||||
|
sendAnnouncementToClient("Here are the currently open Lobbies:");
|
||||||
|
listLobbies();
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Broadcasts a chat Message to all active clients in the form "Username: @msg"
|
* Returns the Lobby this ClientHandler is in. If this ClientHandler is not in a Lobby,
|
||||||
*
|
* it returns null.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Lobby getLobby() {
|
||||||
|
try {
|
||||||
|
Lobby l = Lobby.getLobbyFromID(Lobby.clientIsInLobby(this));
|
||||||
|
return l;
|
||||||
|
} catch (Exception e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Broadcasts a chat Message to all clients in the same lobby in the form "Username: @msg"
|
||||||
|
* If this client isn't in a lobby, it instead defers the message to broadcastChatMessageToAll
|
||||||
* @param msg the Message to be broadcast
|
* @param msg the Message to be broadcast
|
||||||
*/
|
*/
|
||||||
public void broadcastChatMessage(String msg) {
|
public void broadcastChatMessageToLobby(String msg) {
|
||||||
|
Lobby l = getLobby();
|
||||||
|
if (l != null) {
|
||||||
|
for (ClientHandler client : l.getLobbyClients()) {
|
||||||
|
client.sendMsgToClient(Protocol.printToClientChat + "$" + clientUserName + ": " + msg);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LOGGER.debug("Could not send chat message; probably client isn't in a lobby."
|
||||||
|
+ "Will broadcast across all lobbies now.");
|
||||||
|
broadcastChatMessageToAll(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Broadcasts a chat Message to all clients across all lobbies & clients who are not in a lobby
|
||||||
|
* in the form "Username: @msg"
|
||||||
|
* @param msg the Message to be broadcast
|
||||||
|
*/
|
||||||
|
public void broadcastChatMessageToAll(String msg) {
|
||||||
for (ClientHandler client : connectedClients) {
|
for (ClientHandler client : connectedClients) {
|
||||||
client.sendMsgToClient(Protocol.printToClientChat + "$" + clientUserName + ": " + msg);
|
client.sendMsgToClient(Protocol.printToClientChat + "$" + clientUserName + ": " + msg);
|
||||||
}
|
}
|
||||||
@ -159,18 +192,38 @@ public class ClientHandler implements Runnable {
|
|||||||
/**
|
/**
|
||||||
* Broadcasts a non-chat Message to all active clients. This can be used for server messages /
|
* Broadcasts a non-chat Message to all active clients. This can be used for server messages /
|
||||||
* announcements rather than chat messages. The message will be printed to the user exactly as it
|
* 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
|
* is given to this method. Unlike eg. broadcastChatMessageToLobby, it will also be printed onto the server
|
||||||
* console.
|
* console.
|
||||||
* todo: this could be static!
|
* @param msg the Message to be broadcast. Does not have to be protocol-formatted, this method will take care of that.
|
||||||
* @param msg the Message to be broadcast
|
|
||||||
*/
|
*/
|
||||||
public void broadcastAnnouncement(String msg) {
|
public static void broadcastAnnouncementToAll(String msg) {
|
||||||
System.out.println(msg);
|
System.out.println(msg);
|
||||||
for (ClientHandler client : connectedClients) {
|
for (ClientHandler client : connectedClients) {
|
||||||
client.sendMsgToClient(Protocol.printToClientConsole + "$" + msg);
|
client.sendMsgToClient(Protocol.printToClientConsole + "$" + msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Broadcasts a non-chat Message to all clients in the same lobby. This can be used for server messages /
|
||||||
|
* announcements rather than chat messages. The message will be printed to the user exactly as it
|
||||||
|
* is given to this method. The announcement will not be printed on the server console.
|
||||||
|
*
|
||||||
|
* @param msg the Message to be broadcast. Does not have to be protocol-formatted, this method will take care of that.
|
||||||
|
*/
|
||||||
|
public void broadcastAnnouncementToLobby(String msg) {
|
||||||
|
Lobby l = getLobby();
|
||||||
|
if (l != null) {
|
||||||
|
//System.out.println(msg); we can-comment this if you want lobby-announcements to print on the server console as well.
|
||||||
|
for (ClientHandler client : l.getLobbyClients()) {
|
||||||
|
client.sendMsgToClient(Protocol.printToClientConsole + "$" + msg);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LOGGER.debug("Could not send announcements; probably client isn't in a lobby."
|
||||||
|
+ "Will broadcast across all lobbies now.");
|
||||||
|
broadcastAnnouncementToAll(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a given message to client. The message has to already be protocol-formatted. ALL
|
* Sends a given message to client. The message has to already be protocol-formatted. ALL
|
||||||
* communication with the client has to happen via this method!
|
* communication with the client has to happen via this method!
|
||||||
@ -190,6 +243,10 @@ public class ClientHandler implements Runnable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void sendAnnouncementToClient(String msg) {
|
||||||
|
sendMsgToClient(Protocol.printToClientConsole + "$" + msg);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes & disconnects the client. To be used if a severe connection loss is detected (i.e. if
|
* Removes & disconnects the client. To be used if a severe connection loss is detected (i.e. if
|
||||||
* trying to send / receive a message throws an exception, not just if ping-pong detects a
|
* trying to send / receive a message throws an exception, not just if ping-pong detects a
|
||||||
@ -200,7 +257,9 @@ public class ClientHandler implements Runnable {
|
|||||||
public void removeClientOnConnectionLoss() {
|
public void removeClientOnConnectionLoss() {
|
||||||
connectedClients.remove(this);
|
connectedClients.remove(this);
|
||||||
disconnectClient();
|
disconnectClient();
|
||||||
broadcastAnnouncement(getClientUserName() + " has left the server due to a connection loss.");
|
serverData.removeClientFromSetOfAllClients(this); //todo: delete?
|
||||||
|
serverData.removeClientFromLobby(this); //todo: do this via Lobby class directly.
|
||||||
|
broadcastAnnouncementToAll(getClientUserName() + " has left the server due to a connection loss.");
|
||||||
disconnectedClients.add(this);
|
disconnectedClients.add(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,9 +269,11 @@ public class ClientHandler implements Runnable {
|
|||||||
* removeClientOnConnectionLoss() if the client has to be removed due to a connection loss.
|
* removeClientOnConnectionLoss() if the client has to be removed due to a connection loss.
|
||||||
*/
|
*/
|
||||||
public void removeClientOnLogout() {
|
public void removeClientOnLogout() {
|
||||||
broadcastAnnouncement(getClientUserName() + " has left the server.");
|
broadcastAnnouncementToAll(getClientUserName() + " has left the server.");
|
||||||
sendMsgToClient(Protocol.serverConfirmQuit); //todo: protocol
|
sendMsgToClient(Protocol.serverConfirmQuit);
|
||||||
connectedClients.remove(this);
|
connectedClients.remove(this);
|
||||||
|
serverData.removeClientFromSetOfAllClients(this); //todo: delete?
|
||||||
|
serverData.removeClientFromLobby(this); //todo: do this via Lobby class directly.
|
||||||
disconnectClient();
|
disconnectClient();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,11 +285,8 @@ public class ClientHandler implements Runnable {
|
|||||||
if (Lobby.clientIsInLobby(this) == -1) {
|
if (Lobby.clientIsInLobby(this) == -1) {
|
||||||
Lobby newGame = new Lobby(this);
|
Lobby newGame = new Lobby(this);
|
||||||
serverData.addLobbyToListOfAllLobbies(newGame);
|
serverData.addLobbyToListOfAllLobbies(newGame);
|
||||||
broadcastAnnouncement("New lobby with ID: " + newGame.getLobbyID()
|
|
||||||
+ " created by " + this.getClientUserName());
|
|
||||||
} else {
|
} else {
|
||||||
sendMsgToClient(Protocol.printToClientConsole +
|
sendAnnouncementToClient("You are already in lobby nr. " + Lobby.clientIsInLobby(this));
|
||||||
"$You are already in lobby nr. " + Lobby.clientIsInLobby(this));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,42 +300,69 @@ public class ClientHandler implements Runnable {
|
|||||||
if (l != null) {
|
if (l != null) {
|
||||||
l.addPlayer(this);
|
l.addPlayer(this);
|
||||||
} else {
|
} else {
|
||||||
LOGGER.debug(getClientUserName() + " tried to join Lobby nr. "
|
sendAnnouncementToClient("Invalid Lobby nr.");
|
||||||
+ i + " but that doesn't exist.");
|
sendAnnouncementToClient("use LISTL to list lobbies");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void leaveLobby() {
|
||||||
|
for (Lobby l : Lobby.lobbies) {
|
||||||
|
boolean b = l.removePlayer(this);
|
||||||
|
if (b) broadcastAnnouncementToAll(this.getClientUserName() + " has left lobby nr. " + l.getLobbyID());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a list of all lobbies to send to client after LISTL command. Uses
|
* Lists all lobbies and their members, along with players outside lobbies
|
||||||
* Lobby.getIdAndAdminForList() to build a formated list for the client. used in
|
* to this clientHandler's client as an announcement.
|
||||||
* JServerProtocolParser.
|
|
||||||
* //TODO Still does not work properly!
|
|
||||||
*/
|
*/
|
||||||
public void listAllLobbiesToClient() {
|
public void listLobbies() {
|
||||||
StringBuilder response = new StringBuilder();
|
if (Lobby.lobbies.isEmpty()) {
|
||||||
response.append(Protocol.listLobbies);
|
sendAnnouncementToClient("No open Lobbies.");
|
||||||
response.append("$");
|
|
||||||
if (serverData.getAllLobbies().isEmpty()) {
|
|
||||||
response.append("There are currently no open lobbies");
|
|
||||||
LOGGER.debug("No open lobbies");
|
|
||||||
} else {
|
} else {
|
||||||
for (Lobby l : serverData.getAllLobbies()) {
|
for (Lobby l : Lobby.lobbies) {
|
||||||
response.append(l.getIdAndAdminAndFormat());
|
sendAnnouncementToClient("Lobby nr. " + l.getLobbyID() + ":");
|
||||||
|
for (ClientHandler c : l.getLobbyClients()) {
|
||||||
|
if (c.equals(l.getAdmin())) {
|
||||||
|
sendAnnouncementToClient(" -" + c.getClientUserName() + " (admin)");
|
||||||
|
} else {
|
||||||
|
sendAnnouncementToClient(" -" + c.getClientUserName());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LOGGER.debug(
|
boolean helper = false; //used to print "Clients not in lobbies" only once, if needed.
|
||||||
"RESPONSE TO LISTL: " + response.toString() + " requested by: " + this.clientUserName);
|
for (ClientHandler c: connectedClients) {
|
||||||
try {
|
if (Lobby.clientIsInLobby(c) == -1) {
|
||||||
out.write(response.toString());
|
if (!helper) {
|
||||||
out.newLine();
|
helper = true;
|
||||||
out.flush();
|
sendAnnouncementToClient("Clients not in lobbies:");
|
||||||
} catch (IOException e) {
|
}
|
||||||
LOGGER.debug(e.getMessage());
|
sendAnnouncementToClient(" -" + c.getClientUserName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!helper) {
|
||||||
|
sendAnnouncementToClient("No clients outside of lobbies");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void listPlayersInLobby() {
|
||||||
|
Lobby l = getLobby();
|
||||||
|
if (l != null) {
|
||||||
|
sendAnnouncementToClient("Players in lobby nr. " + l.getLobbyID() + ":");
|
||||||
|
for (ClientHandler c : l.getLobbyClients()) {
|
||||||
|
if (c.equals(l.getAdmin())) {
|
||||||
|
sendAnnouncementToClient(" -" + c.getClientUserName() + " (admin)");
|
||||||
|
} else {
|
||||||
|
sendAnnouncementToClient(" -" + c.getClientUserName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sendAnnouncementToClient("You are not in a Lobby.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Closes the client's socket, in, and out. and removes from global list of clients.
|
* Closes the client's socket, in, and out. and removes from global list of clients.
|
||||||
@ -286,8 +371,6 @@ public class ClientHandler implements Runnable {
|
|||||||
socket = this.getSocket();
|
socket = this.getSocket();
|
||||||
in = this.getIn();
|
in = this.getIn();
|
||||||
out = this.getOut();
|
out = this.getOut();
|
||||||
serverData.removeClientFromSetOfAllClients(this);
|
|
||||||
serverData.removeClientFromLobby(this);
|
|
||||||
try {
|
try {
|
||||||
Thread.sleep(100);
|
Thread.sleep(100);
|
||||||
if (in != null) {
|
if (in != null) {
|
||||||
|
|||||||
@ -2,7 +2,6 @@ package ch.unibas.dmi.dbis.cs108.multiplayer.server;
|
|||||||
|
|
||||||
|
|
||||||
import ch.unibas.dmi.dbis.cs108.BudaLogConfig;
|
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.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import ch.unibas.dmi.dbis.cs108.multiplayer.helpers.Protocol;
|
import ch.unibas.dmi.dbis.cs108.multiplayer.helpers.Protocol;
|
||||||
@ -36,7 +35,7 @@ public class JServerProtocolParser {
|
|||||||
}
|
}
|
||||||
switch (header) {
|
switch (header) {
|
||||||
case Protocol.chatMsgToAll:
|
case Protocol.chatMsgToAll:
|
||||||
h.broadcastChatMessage(msg.substring(6));
|
h.broadcastChatMessageToLobby(msg.substring(6));
|
||||||
break;
|
break;
|
||||||
case Protocol.clientLogin:
|
case Protocol.clientLogin:
|
||||||
h.setLoggedIn(true);
|
h.setLoggedIn(true);
|
||||||
@ -71,8 +70,13 @@ public class JServerProtocolParser {
|
|||||||
h.createNewLobby();
|
h.createNewLobby();
|
||||||
break;
|
break;
|
||||||
case Protocol.listLobbies:
|
case Protocol.listLobbies:
|
||||||
h.listAllLobbiesToClient();
|
h.listLobbies();
|
||||||
LOGGER.debug(Protocol.listLobbies + " command received from: " + h.getClientUserName());
|
break;
|
||||||
|
case Protocol.listPlayersInLobby:
|
||||||
|
h.listPlayersInLobby();
|
||||||
|
break;
|
||||||
|
case Protocol.leaveLobby:
|
||||||
|
h.leaveLobby();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
System.out.println("Received unknown command");
|
System.out.println("Received unknown command");
|
||||||
|
|||||||
@ -13,6 +13,9 @@ import org.apache.logging.log4j.LogManager;
|
|||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* todo: this class is not meaningfully used now, we could probably delete it?
|
||||||
|
*
|
||||||
|
*
|
||||||
* This Class Represents an Object containing different Maps, Lists and Sets wherein a server object
|
* This Class Represents an Object containing different Maps, Lists and Sets wherein a server object
|
||||||
* can find all needed data. An instance of this object can also be passed to other class-objects if
|
* can find all needed data. An instance of this object can also be passed to other class-objects if
|
||||||
* they need the same data. This Class is used to query for information in collections.
|
* they need the same data. This Class is used to query for information in collections.
|
||||||
|
|||||||
@ -1,16 +1,15 @@
|
|||||||
package ch.unibas.dmi.dbis.cs108.sebaschi;
|
package ch.unibas.dmi.dbis.cs108.sebaschi;
|
||||||
|
|
||||||
import ch.unibas.dmi.dbis.cs108.BudaLogConfig;
|
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 ch.unibas.dmi.dbis.cs108.multiplayer.server.ClientHandler;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use: If a client sends a CRTGM command the server should create a lobby with the client as admin.
|
* Use: If a client sends a CRTLB command the server should create a lobby with the client as admin.
|
||||||
* In this state, up to 5 other clients (so 6 in total) are able to join this lobby. Once the admin
|
* In this state, up to 5 other clients (so 6 in total) are able to join this lobby. Once the admin
|
||||||
* feels like it, he can start a game.
|
* feels like it, they can start a game.
|
||||||
* TODO: is all data in here or should GameSessionData be used to collect all relevant data?
|
* TODO: is all data in here or should GameSessionData be used to collect all relevant data?
|
||||||
*/
|
*/
|
||||||
public class Lobby {
|
public class Lobby {
|
||||||
@ -22,7 +21,7 @@ public class Lobby {
|
|||||||
private static final int MAX_NO_OF_CLIENTS = 6;
|
private static final int MAX_NO_OF_CLIENTS = 6;
|
||||||
|
|
||||||
//TODO
|
//TODO
|
||||||
CentralServerData serverData;
|
CentralServerData serverData; //todo: do we need this?
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Person who created the game and can configure it and decide to start once enough lobbyClients
|
* The Person who created the game and can configure it and decide to start once enough lobbyClients
|
||||||
@ -48,8 +47,12 @@ public class Lobby {
|
|||||||
this.admin = admin;
|
this.admin = admin;
|
||||||
this.lobbyClients.add(admin);
|
this.lobbyClients.add(admin);
|
||||||
lobbies.add(this);
|
lobbies.add(this);
|
||||||
this.lobbyID = lobbies.size();
|
int helper = 1;
|
||||||
admin.broadcastAnnouncement("New Lobby created by " + admin.getClientUserName() +
|
while (getLobbyFromID(helper) != null) {
|
||||||
|
helper++;
|
||||||
|
}
|
||||||
|
this.lobbyID = helper;
|
||||||
|
admin.broadcastAnnouncementToAll("New Lobby created by " + admin.getClientUserName() +
|
||||||
". This lobby's ID: " + this.lobbyID);
|
". This lobby's ID: " + this.lobbyID);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,22 +83,6 @@ public class Lobby {
|
|||||||
return this.lobbyClients;
|
return this.lobbyClients;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Builds a message for the LISTL command.
|
|
||||||
*
|
|
||||||
* @return a string formatted for the clients convenients.
|
|
||||||
*/
|
|
||||||
public String getIdAndAdminAndFormat() {
|
|
||||||
StringBuilder response = new StringBuilder();
|
|
||||||
response.append("Lobby ID: ");
|
|
||||||
response.append(this.lobbyID);
|
|
||||||
response.append(" Admin Username: ");
|
|
||||||
response.append(getAdmin().getClientUserName());
|
|
||||||
response.append(System.lineSeparator());
|
|
||||||
LOGGER.info(response.toString());
|
|
||||||
return response.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the lobby with the desired LobbyID.
|
* Returns the lobby with the desired LobbyID.
|
||||||
* For example, getLobbyFromID(5) returns the lobby whose LobbyID is 5.
|
* For example, getLobbyFromID(5) returns the lobby whose LobbyID is 5.
|
||||||
@ -134,17 +121,15 @@ public class Lobby {
|
|||||||
if (lobbyClients.size() < MAX_NO_OF_CLIENTS) {
|
if (lobbyClients.size() < MAX_NO_OF_CLIENTS) {
|
||||||
if (clientIsInLobby(client) == -1) {
|
if (clientIsInLobby(client) == -1) {
|
||||||
lobbyClients.add(client);
|
lobbyClients.add(client);
|
||||||
client.broadcastAnnouncement(client.getClientUserName() + " has joined lobby " + this.getLobbyID());
|
client.broadcastAnnouncementToAll(client.getClientUserName() + " has joined lobby " + this.getLobbyID());
|
||||||
LOGGER.debug(client.getClientUserName() + " has been added to Lobby with ID: " + lobbyID
|
//LOGGER.debug(client.getClientUserName() + " has been added to Lobby with ID: " + lobbyID
|
||||||
+ ". Current number of lobbyClients in this lobby: " + lobbyClients.size());
|
// + ". Current number of lobbyClients in this lobby: " + lobbyClients.size());
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
client.sendMsgToClient(Protocol.printToClientConsole + "$You are already in lobby nr. "
|
client.sendAnnouncementToClient("You are already in lobby nr. " + clientIsInLobby(client));
|
||||||
+ clientIsInLobby(client));
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
client.sendMsgToClient(Protocol.printToClientConsole +
|
client.sendAnnouncementToClient("This lobby is full. Please try joining a different lobby or create a new lobby");
|
||||||
"$This lobby is full. Please try joining a different lobby or create a new lobby");
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -158,14 +143,28 @@ public class Lobby {
|
|||||||
* @return true if a player was found and removed. Used for debugging.
|
* @return true if a player was found and removed. Used for debugging.
|
||||||
*/
|
*/
|
||||||
public synchronized boolean removePlayer(ClientHandler player) {
|
public synchronized boolean removePlayer(ClientHandler player) {
|
||||||
|
//if the player who leaves the lobby is the admin, the lobby is closed.
|
||||||
|
if (player.equals(getAdmin())) {
|
||||||
|
closeLobby();
|
||||||
|
}
|
||||||
return this.getLobbyClients().remove(player);
|
return this.getLobbyClients().remove(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
//todo: this here?
|
/**
|
||||||
public void broadcastToLounge(String msg) {
|
* Closes the lobby.
|
||||||
for (ClientHandler lounger : this.getLobbyClients()) {
|
*
|
||||||
|
*/
|
||||||
}
|
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
|
||||||
|
since if the lobby is removed from the lobbies
|
||||||
|
hash set then e.g. clientIsInLobby will not be able to tell that these clients
|
||||||
|
are theoretically still in this lobby. However, in the future we might implement
|
||||||
|
removing the clients anyways.
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user