Merge remote-tracking branch 'origin/Jonas_Stuff' into Jonas_Stuff

# Conflicts:
#	src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/Client.java
This commit is contained in:
Jonas 2022-03-27 17:09:44 +02:00
commit b344e59b23
7 changed files with 85 additions and 18 deletions

View File

@ -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.helpers.ClientPinger;
import ch.unibas.dmi.dbis.cs108.multiplayer.server.MessageFormatter;
import java.net.Socket; import java.net.Socket;
import java.io.*; import java.io.*;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.util.Scanner; import java.util.Scanner;
//import org.apache.logging.log4j.message.Message;
public class Client { public class Client {
@ -23,8 +22,7 @@ public class Client {
this.out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); this.out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
this.in = new BufferedReader((new InputStreamReader((socket.getInputStream())))); this.in = new BufferedReader((new InputStreamReader((socket.getInputStream()))));
//TODO: add the system based generated username here. //TODO hide connecting logik(next 4 lines)
//TODO: hide connecting logic (next 4 lines)
this.userName = userName; this.userName = userName;
this.out.write(getUsername()); this.out.write(getUsername());
this.out.newLine(); this.out.newLine();
@ -36,6 +34,10 @@ public class Client {
} }
} }
/**
*
*/
public void sendMessage() { public void sendMessage() {
try { try {
Scanner sc = new Scanner(System.in); Scanner sc = new Scanner(System.in);
@ -59,7 +61,7 @@ public class Client {
*/ */
public void chatListener() { public void chatListener() {
/*TODO: what type of decoding has to be done /*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() { new Thread(new Runnable() {
@Override @Override
@ -105,8 +107,8 @@ public class Client {
} }
public void closeEverything(Socket socket, BufferedReader in, BufferedWriter out) { public void closeEverything(Socket socket, BufferedReader in, BufferedWriter out) {
//TODO: Correctly closing a clients connection //TODO Correctly closing a clients connection
//TODO: the server should be notified in a way so it can handle it cleanly //TODO the server should be notified in a way so he can handle it cleanly
try { try {
if (in != null) { if (in != null) {
in.close(); in.close();
@ -132,7 +134,8 @@ public class Client {
} else { } else {
hostname = args[0]; 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(); String username = sc.next();
Socket socket; Socket socket;
try { try {

View File

@ -1,6 +1,4 @@
package ch.unibas.dmi.dbis.cs108.multiplayer.server; package ch.unibas.dmi.dbis.cs108.multiplayer.client;
import java.io.StringBufferInputStream;
public class MessageFormatter { public class MessageFormatter {
@ -9,7 +7,7 @@ public class MessageFormatter {
* handle it. May need to be redesigned one the games uses a GUI * handle it. May need to be redesigned one the games uses a GUI
* *
* @param msg the Messaged to be reformatted * @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) { public static String formatMsg(String msg) {
@ -23,15 +21,17 @@ public class MessageFormatter {
} }
switch (header) { switch (header) {
case "/c": case "/c":
stringBuilder.append("CHATA"); stringBuilder.append("CHATA$");
s = msg.substring(2); s = msg.substring(3);
break; break;
case "/q": case "/q":
stringBuilder.append("QUITS"); stringBuilder.append("QUITS$");
s = msg.substring(2); s = msg.substring(3);
break; break;
case "/n": case "/n":
stringBuilder.append("NAMEC"); stringBuilder.append("NAMEC$");
s = msg.substring(3);
break;
default: default:
s = msg; s = msg;
} }

View File

@ -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();
}
}

View File

@ -29,6 +29,12 @@ public class ClientHandler implements Runnable {
this.out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); this.out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
this.in = new BufferedReader((new InputStreamReader((socket.getInputStream())))); this.in = new BufferedReader((new InputStreamReader((socket.getInputStream()))));
this.clientUserName = in.readLine(); 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); connectedClients.add(this);
serverPinger = new ServerPinger(out, socket); serverPinger = new ServerPinger(out, socket);
Thread sP = new Thread(serverPinger); Thread sP = new Thread(serverPinger);
@ -73,7 +79,7 @@ public class ClientHandler implements Runnable {
* The main logic of the client handler. * The main logic of the client handler.
* Since every client is put on a string this is where * Since every client is put on a string this is where
* most interactions between client and server are held * most interactions between client and server are held
*/ **/
public void run() { public void run() {
String msg; String msg;
while (socket.isConnected()) { while (socket.isConnected()) {
@ -92,6 +98,16 @@ public class ClientHandler implements Runnable {
return clientUserName; 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) { public void broadcastMessage(String msg) {
for (ClientHandler client : connectedClients) { for (ClientHandler client : connectedClients) {
client.sendMsgToClient("CHATM:" + clientUserName + ": \"" + msg + "\""); client.sendMsgToClient("CHATM:" + clientUserName + ": \"" + msg + "\"");

View File

@ -21,6 +21,9 @@ public class JServerProtocolParser {
case "CHATA": case "CHATA":
h.broadcastMessage(msg.substring(6)); h.broadcastMessage(msg.substring(6));
break; break;
case "NAMEC":
h.changeUsername(msg.substring(6));
break;
case "CPING": case "CPING":
h.sendMsgToClient("PINGB"); h.sendMsgToClient("PINGB");
break; break;

View File

@ -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;
}
}

View File

@ -26,6 +26,12 @@ public class Server {
Thread th = new Thread(nextClient); Thread th = new Thread(nextClient);
connectedClients.add(nextClient); connectedClients.add(nextClient);
th.start(); 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) { } catch (IOException e) {