diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/Client.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/Client.java index 8b10afa..613cd8b 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/Client.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/Client.java @@ -2,12 +2,11 @@ package ch.unibas.dmi.dbis.cs108.multiplayer.client; import ch.unibas.dmi.dbis.cs108.multiplayer.helpers.ClientPinger; -import ch.unibas.dmi.dbis.cs108.multiplayer.server.MessageFormatter; import java.net.Socket; import java.io.*; import java.net.UnknownHostException; import java.util.Scanner; -//import org.apache.logging.log4j.message.Message; + public class Client { @@ -23,8 +22,7 @@ public class Client { this.out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); this.in = new BufferedReader((new InputStreamReader((socket.getInputStream())))); - //TODO: add the system based generated username here. - //TODO: hide connecting logic (next 4 lines) + //TODO hide connecting logik(next 4 lines) this.userName = userName; this.out.write(getUsername()); this.out.newLine(); @@ -36,6 +34,10 @@ public class Client { } } + /** + * + */ + public void sendMessage() { try { Scanner sc = new Scanner(System.in); @@ -59,7 +61,7 @@ public class Client { */ public void chatListener() { /*TODO: what type of decoding has to be done - TODO: how shall input be logged? + TODO how shall input be logged? */ new Thread(new Runnable() { @Override @@ -105,8 +107,8 @@ public class Client { } public void closeEverything(Socket socket, BufferedReader in, BufferedWriter out) { - //TODO: Correctly closing a clients connection - //TODO: the server should be notified in a way so it can handle it cleanly + //TODO Correctly closing a clients connection + //TODO the server should be notified in a way so he can handle it cleanly try { if (in != null) { in.close(); @@ -132,7 +134,8 @@ public class Client { } else { hostname = args[0]; } - System.out.println("Choose a nickname: "); + String systemName = System.getProperty("user.name"); + System.out.println("Choose a nickname (Suggestion: " + systemName + "): "); String username = sc.next(); Socket socket; try { diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/MessageFormatter.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/MessageFormatter.java similarity index 70% rename from src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/MessageFormatter.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/MessageFormatter.java index b2c7984..0913fa4 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/MessageFormatter.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/MessageFormatter.java @@ -1,6 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.multiplayer.server; - -import java.io.StringBufferInputStream; +package ch.unibas.dmi.dbis.cs108.multiplayer.client; public class MessageFormatter { @@ -9,7 +7,7 @@ public class MessageFormatter { * handle it. May need to be redesigned one the games uses a GUI * * @param msg the Messaged to be reformatted - * @return the reformatted message + * @return the reformatted message in the form HEADR$msg */ public static String formatMsg(String msg) { @@ -23,15 +21,17 @@ public class MessageFormatter { } switch (header) { case "/c": - stringBuilder.append("CHATA"); - s = msg.substring(2); + stringBuilder.append("CHATA$"); + s = msg.substring(3); break; case "/q": - stringBuilder.append("QUITS"); - s = msg.substring(2); + stringBuilder.append("QUITS$"); + s = msg.substring(3); break; case "/n": - stringBuilder.append("NAMEC"); + stringBuilder.append("NAMEC$"); + s = msg.substring(3); + break; default: s = msg; } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/AllClientNames.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/AllClientNames.java new file mode 100644 index 0000000..aea8c71 --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/AllClientNames.java @@ -0,0 +1,14 @@ +package ch.unibas.dmi.dbis.cs108.multiplayer.server; + +/* This class is built to contain the usernames of all players in a single string. +* This allows a duplicate check (--> ClientHandler) when a new player chooses +* a name: does the string with all the previous names contain the new player's +* desired username? If yes, he is being assigned a random name. If no, he can keep +* his desired name. */ + +public class AllClientNames { + static StringBuilder names = new StringBuilder(); + public static String allNames(String currentName) { + return names.append(currentName).toString(); + } +} 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 6b204bf..b64ebe7 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 @@ -29,6 +29,12 @@ public class ClientHandler implements Runnable { this.out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); this.in = new BufferedReader((new InputStreamReader((socket.getInputStream())))); this.clientUserName = in.readLine(); + // duplicate handling: if username already taken, assign random name to client + if (AllClientNames.allNames("").contains(clientUserName)) { + clientUserName = NameGenerator.randomName(clientUserName); + } + // add username to list of all client names for future duplicate checking + AllClientNames.allNames(clientUserName); connectedClients.add(this); serverPinger = new ServerPinger(out, socket); Thread sP = new Thread(serverPinger); @@ -73,7 +79,7 @@ public class ClientHandler implements Runnable { * The main logic of the client handler. * Since every client is put on a string this is where * most interactions between client and server are held - */ + **/ public void run() { String msg; while (socket.isConnected()) { @@ -92,6 +98,16 @@ public class ClientHandler implements Runnable { return clientUserName; } + public void changeUsername(String newName) { + if (AllClientNames.allNames("").contains(newName)) { + newName = NameGenerator.randomName(newName); + } + String h = this.clientUserName; //just a friendly little helper + this.clientUserName = newName; + AllClientNames.allNames(newName); + broadcastMessage(h +" have changed their nickname to " + clientUserName); + } + public void broadcastMessage(String msg) { for (ClientHandler client : connectedClients) { client.sendMsgToClient("CHATM:" + clientUserName + ": \"" + msg + "\""); 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 85971a9..29fff16 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 @@ -21,6 +21,9 @@ public class JServerProtocolParser { case "CHATA": h.broadcastMessage(msg.substring(6)); break; + case "NAMEC": + h.changeUsername(msg.substring(6)); + break; case "CPING": h.sendMsgToClient("PINGB"); break; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/NameGenerator.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/NameGenerator.java new file mode 100644 index 0000000..b080320 --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/NameGenerator.java @@ -0,0 +1,25 @@ +package ch.unibas.dmi.dbis.cs108.multiplayer.server; + +import java.util.Random; + +// Creates a String beginning with "player_" followed by 4 random letters + +public class NameGenerator { + static String randomName(String username) { + StringBuilder name; + while (true) { + + name = new StringBuilder(); + Random r = new Random(); + for (int i = 0; i < 4; i++) { + int c = r.nextInt(10); + name.append(c); + } + if (!AllClientNames.allNames("").contains(username + name)) { + break; + } + } + return username + name; + } + +} diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/Server.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/Server.java index 31b72ba..534e936 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/Server.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/Server.java @@ -26,6 +26,12 @@ public class Server { Thread th = new Thread(nextClient); connectedClients.add(nextClient); th.start(); + // close socket + remove client if client is disconnected + if (socket.getInputStream().read() == -1) { + System.out.println("client disconnected. closing socket"); + socket.close(); + connectedClients.remove(nextClient); + } } } catch (IOException e) {