Fix: Resolving Git Merge Conflicts #253
@@ -3,7 +3,6 @@ package ch.unibas.dmi.dbis.cs108.casono.client;
|
|||||||
/**
|
/**
|
||||||
* Entry point for the Casono client application. Handles client startup and connection parameters.
|
* Entry point for the Casono client application. Handles client startup and connection parameters.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.client.ui.Launcher;
|
import ch.unibas.dmi.dbis.cs108.casono.client.ui.Launcher;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|||||||
@@ -3,15 +3,13 @@ package ch.unibas.dmi.dbis.cs108.casono.client.chat;
|
|||||||
import ch.unibas.dmi.dbis.cs108.casono.client.network.ChatClient;
|
import ch.unibas.dmi.dbis.cs108.casono.client.network.ChatClient;
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.client.network.ClientService;
|
import ch.unibas.dmi.dbis.cs108.casono.client.network.ClientService;
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.client.ui.chatui.ChatBoxController;
|
import ch.unibas.dmi.dbis.cs108.casono.client.ui.chatui.ChatBoxController;
|
||||||
import javafx.application.Platform;
|
import java.util.LinkedHashMap;
|
||||||
import org.jspecify.annotations.Nullable;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Timer;
|
import java.util.Timer;
|
||||||
import java.util.TimerTask;
|
import java.util.TimerTask;
|
||||||
import java.util.Map;
|
import javafx.application.Platform;
|
||||||
import java.util.List;
|
import org.jspecify.annotations.Nullable;
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* responsible for the transferring of messages from the server to the ChatModel or from the
|
* responsible for the transferring of messages from the server to the ChatModel or from the
|
||||||
@@ -31,9 +29,8 @@ public class ChatController {
|
|||||||
private int lobbyId = -1;
|
private int lobbyId = -1;
|
||||||
private final Timer timer;
|
private final Timer timer;
|
||||||
|
|
||||||
|
public record ChatKey(ChatType type, @Nullable String targetUser) {
|
||||||
public record ChatKey(ChatType type, @Nullable String targetUser){
|
public ChatKey(ChatType type) {
|
||||||
public ChatKey(ChatType type){
|
|
||||||
this(type, null);
|
this(type, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -56,10 +53,11 @@ public class ChatController {
|
|||||||
new TimerTask() {
|
new TimerTask() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(
|
||||||
clientService.ping();
|
() -> {
|
||||||
receiveMessage();
|
clientService.ping();
|
||||||
});
|
receiveMessage();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
0,
|
0,
|
||||||
@@ -84,21 +82,30 @@ public class ChatController {
|
|||||||
break;
|
break;
|
||||||
case ChatType.LOBBY:
|
case ChatType.LOBBY:
|
||||||
if (msg.lobbyId == lobbyId) {
|
if (msg.lobbyId == lobbyId) {
|
||||||
chatModelMap.computeIfAbsent(new ChatKey(ChatType.LOBBY),
|
chatModelMap
|
||||||
(_key) -> new ChatModel(ChatType.LOBBY, username, msg.lobbyId, null)).addMessage(msg);
|
.computeIfAbsent(
|
||||||
|
new ChatKey(ChatType.LOBBY),
|
||||||
|
(_key) ->
|
||||||
|
new ChatModel(
|
||||||
|
ChatType.LOBBY,
|
||||||
|
username,
|
||||||
|
msg.lobbyId,
|
||||||
|
null))
|
||||||
|
.addMessage(msg);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ChatType.WHISPER:
|
case ChatType.WHISPER:
|
||||||
if (msg.target.equals(username)) {
|
if (msg.target.equals(username)) {
|
||||||
if (chatModelMap.containsKey(new ChatKey(ChatType.WHISPER, msg.sender))) {
|
if (chatModelMap.containsKey(
|
||||||
chatModelMap.get(new ChatKey(ChatType.WHISPER, msg.sender)).addMessage(msg);
|
new ChatKey(ChatType.WHISPER, msg.sender))) {
|
||||||
|
chatModelMap
|
||||||
|
.get(new ChatKey(ChatType.WHISPER, msg.sender))
|
||||||
|
.addMessage(msg);
|
||||||
} else {
|
} else {
|
||||||
chatBoxController.addWhisperChat(msg.sender);
|
chatBoxController.addWhisperChat(msg.sender);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -106,6 +113,7 @@ public class ChatController {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* method to send a message to the server
|
* method to send a message to the server
|
||||||
|
*
|
||||||
* @param message
|
* @param message
|
||||||
*/
|
*/
|
||||||
public void onSendToNetwork(Message message) {
|
public void onSendToNetwork(Message message) {
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
package ch.unibas.dmi.dbis.cs108.casono.client.chat;
|
package ch.unibas.dmi.dbis.cs108.casono.client.chat;
|
||||||
|
|
||||||
import javafx.beans.property.IntegerProperty;
|
|
||||||
import javafx.beans.property.SimpleIntegerProperty;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
import javafx.beans.property.IntegerProperty;
|
||||||
|
import javafx.beans.property.SimpleIntegerProperty;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ChatModel, stores the data for a specific chat
|
* ChatModel, stores the data for a specific chat
|
||||||
@@ -19,15 +18,10 @@ public class ChatModel {
|
|||||||
|
|
||||||
private final ChatType chattype;
|
private final ChatType chattype;
|
||||||
|
|
||||||
/**
|
/** The person currently using this client */
|
||||||
* The person currently using this client
|
|
||||||
*/
|
|
||||||
public final String username;
|
public final String username;
|
||||||
|
|
||||||
/**
|
/** The person to send the message to If the chat is a whisper chat */
|
||||||
* The person to send the message to
|
|
||||||
* If the chat is a whisper chat
|
|
||||||
*/
|
|
||||||
private final String target;
|
private final String target;
|
||||||
|
|
||||||
private final IntegerProperty count;
|
private final IntegerProperty count;
|
||||||
@@ -64,10 +58,9 @@ public class ChatModel {
|
|||||||
*/
|
*/
|
||||||
public synchronized void addMessage(Message msg) {
|
public synchronized void addMessage(Message msg) {
|
||||||
messages.add(msg);
|
messages.add(msg);
|
||||||
listeners.stream().forEach((l)-> l.accept(messages.getLast()));
|
listeners.stream().forEach((l) -> l.accept(messages.getLast()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void addListener(Consumer<Message> listener) {
|
public void addListener(Consumer<Message> listener) {
|
||||||
this.listeners.add(listener);
|
this.listeners.add(listener);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,13 +3,12 @@ package ch.unibas.dmi.dbis.cs108.casono.client.chat;
|
|||||||
import ch.unibas.dmi.dbis.cs108.casono.server.network.command.parsing.RequestParameter;
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.command.parsing.RequestParameter;
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.builder.ResponseBody;
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.builder.ResponseBody;
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.builder.ResponseBodyBuilder;
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.builder.ResponseBodyBuilder;
|
||||||
import org.jspecify.annotations.NonNull;
|
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
import org.jspecify.annotations.NonNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Message Object for internal handling of Chat-Messages TODO: Should be used on both sides of the
|
* Message Object for internal handling of Chat-Messages TODO: Should be used on both sides of the
|
||||||
@@ -82,11 +81,11 @@ public class Message {
|
|||||||
* @return - request as specified in the network protocol, as String
|
* @return - request as specified in the network protocol, as String
|
||||||
*/
|
*/
|
||||||
public String toArgsString() {
|
public String toArgsString() {
|
||||||
String gameIdString="";
|
String gameIdString = "";
|
||||||
if(lobbyId >= 0) {
|
if (lobbyId >= 0) {
|
||||||
gameIdString=" GAME="+lobbyId;
|
gameIdString = " GAME=" + lobbyId;
|
||||||
} else {
|
} else {
|
||||||
gameIdString=" GAME='-1'";
|
gameIdString = " GAME='-1'";
|
||||||
}
|
}
|
||||||
return String.format(
|
return String.format(
|
||||||
"TYPE=%s%s USER='%s' TARGET='%s' TIME='%s' TEXT='%s'",
|
"TYPE=%s%s USER='%s' TARGET='%s' TIME='%s' TEXT='%s'",
|
||||||
@@ -101,10 +100,12 @@ public class Message {
|
|||||||
/** Pattern, to analyze the response String with the given parameters */
|
/** Pattern, to analyze the response String with the given parameters */
|
||||||
public static Pattern msgRex =
|
public static Pattern msgRex =
|
||||||
Pattern.compile(
|
Pattern.compile(
|
||||||
"TYPE=(?<type>\\w+) " + "(GAME=(?<game>\\w+) )?" +
|
"TYPE=(?<type>\\w+) "
|
||||||
"USER=(?<user>\\w+) " + "(TARGET=(?<target>\\w+) )?" +
|
+ "(GAME=(?<game>\\w+) )?"
|
||||||
"TIME=(?<time>[0-9:.]+) " + "TEXT='(?<text>([^']|\\')+)'");
|
+ "USER=(?<user>\\w+) "
|
||||||
|
+ "(TARGET=(?<target>\\w+) )?"
|
||||||
|
+ "TIME=(?<time>[0-9:.]+) "
|
||||||
|
+ "TEXT='(?<text>([^']|\\')+)'");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method to create a Message Object, from the information given by the String
|
* Method to create a Message Object, from the information given by the String
|
||||||
@@ -167,38 +168,46 @@ public class Message {
|
|||||||
String typeString = getParString(parameters, "TYPE");
|
String typeString = getParString(parameters, "TYPE");
|
||||||
ChatType type = ChatType.valueOf(typeString);
|
ChatType type = ChatType.valueOf(typeString);
|
||||||
return switch (type) {
|
return switch (type) {
|
||||||
case GLOBAL -> new Message(ChatType.GLOBAL,
|
case GLOBAL ->
|
||||||
-1,
|
new Message(
|
||||||
getParString(parameters, "USER"),
|
ChatType.GLOBAL,
|
||||||
null,
|
-1,
|
||||||
getParString(parameters, "TIME"),
|
getParString(parameters, "USER"),
|
||||||
getParString(parameters, "TEXT")
|
null,
|
||||||
);
|
getParString(parameters, "TIME"),
|
||||||
case LOBBY -> new Message(ChatType.LOBBY,
|
getParString(parameters, "TEXT"));
|
||||||
Integer.parseInt(getParString(parameters, "GAME")),
|
case LOBBY ->
|
||||||
getParString(parameters, "USER"),
|
new Message(
|
||||||
null,
|
ChatType.LOBBY,
|
||||||
getParString(parameters, "TIME"),
|
Integer.parseInt(getParString(parameters, "GAME")),
|
||||||
getParString(parameters, "TEXT")
|
getParString(parameters, "USER"),
|
||||||
);
|
null,
|
||||||
case WHISPER -> new Message(ChatType.WHISPER,
|
getParString(parameters, "TIME"),
|
||||||
Integer.parseInt(getParString(parameters, "GAME", "-1")),
|
getParString(parameters, "TEXT"));
|
||||||
getParString(parameters, "USER"),
|
case WHISPER ->
|
||||||
getParString(parameters, "TARGET"),
|
new Message(
|
||||||
getParString(parameters, "TIME"),
|
ChatType.WHISPER,
|
||||||
getParString(parameters, "TEXT")
|
Integer.parseInt(getParString(parameters, "GAME", "-1")),
|
||||||
);
|
getParString(parameters, "USER"),
|
||||||
|
getParString(parameters, "TARGET"),
|
||||||
|
getParString(parameters, "TIME"),
|
||||||
|
getParString(parameters, "TEXT"));
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
private static @NonNull String getParString(List<RequestParameter> parameters, String keyString) {
|
|
||||||
|
private static @NonNull String getParString(
|
||||||
|
List<RequestParameter> parameters, String keyString) {
|
||||||
return getParString(parameters, keyString, null);
|
return getParString(parameters, keyString, null);
|
||||||
}
|
}
|
||||||
private static @NonNull String getParString(List<RequestParameter> parameters, String keyString, String defaultVal) {
|
|
||||||
Optional<String> parOption = parameters.stream().filter((p) -> keyString.equals(p.key()))
|
private static @NonNull String getParString(
|
||||||
.findFirst()
|
List<RequestParameter> parameters, String keyString, String defaultVal) {
|
||||||
.map(RequestParameter::value);
|
Optional<String> parOption =
|
||||||
if(parOption.isEmpty()) {
|
parameters.stream()
|
||||||
|
.filter((p) -> keyString.equals(p.key()))
|
||||||
|
.findFirst()
|
||||||
|
.map(RequestParameter::value);
|
||||||
|
if (parOption.isEmpty()) {
|
||||||
if (defaultVal == null) {
|
if (defaultVal == null) {
|
||||||
throw new RuntimeException("No " + keyString + " found");
|
throw new RuntimeException("No " + keyString + " found");
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -2,16 +2,15 @@ package ch.unibas.dmi.dbis.cs108.casono.client.network;
|
|||||||
|
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.client.chat.Message;
|
import ch.unibas.dmi.dbis.cs108.casono.client.chat.Message;
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.server.network.command.parsing.RequestParameter;
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.command.parsing.RequestParameter;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
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 java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The ChatClient class is responsible for sending messages to the server and
|
* The ChatClient class is responsible for sending messages to the server and retrieving messages
|
||||||
* retrieving messages from the server. It uses the ClientService to send
|
* from the server. It uses the ClientService to send commands and receive responses from the
|
||||||
* commands and receive responses from the server.
|
* server.
|
||||||
*/
|
*/
|
||||||
public class ChatClient {
|
public class ChatClient {
|
||||||
|
|
||||||
@@ -21,8 +20,8 @@ public class ChatClient {
|
|||||||
/**
|
/**
|
||||||
* Constructs a ChatClient with the given ClientService for communication.
|
* Constructs a ChatClient with the given ClientService for communication.
|
||||||
*
|
*
|
||||||
* @param clientService The ClientService instance used to send commands and
|
* @param clientService The ClientService instance used to send commands and receive responses
|
||||||
* receive responses from the server.
|
* from the server.
|
||||||
*/
|
*/
|
||||||
public ChatClient(ClientService clientService) {
|
public ChatClient(ClientService clientService) {
|
||||||
this.clientService = clientService;
|
this.clientService = clientService;
|
||||||
@@ -30,8 +29,8 @@ public class ChatClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send a Message to the server by converting it to a string format and
|
* Send a Message to the server by converting it to a string format and sending a "SEND_MESSAGE"
|
||||||
* sending a "SEND_MESSAGE" command with the message content as arguments.
|
* command with the message content as arguments.
|
||||||
*
|
*
|
||||||
* @param message The Message object to be sent to the server.
|
* @param message The Message object to be sent to the server.
|
||||||
*/
|
*/
|
||||||
@@ -42,17 +41,18 @@ public class ChatClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve messages from the server by first sending a "GET_MESSAGE_COUNT"
|
* Retrieve messages from the server by first sending a "GET_MESSAGE_COUNT" command to determine
|
||||||
* command to determine how many messages are available and then sending
|
* how many messages are available and then sending "GET_NEXT_MESSAGE" commands in a loop to
|
||||||
* "GET_NEXT_MESSAGE" commands in a loop to retrieve each message. The
|
* retrieve each message. The retrieved messages are parsed into Message objects and returned as
|
||||||
* retrieved messages are parsed into Message objects and returned as a list.
|
* a list.
|
||||||
*
|
*
|
||||||
* @return A list of Message objects representing the messages retrieved from
|
* @return A list of Message objects representing the messages retrieved from the server.
|
||||||
* the server.
|
|
||||||
*/
|
*/
|
||||||
public List<Message> getMessages() {
|
public List<Message> getMessages() {
|
||||||
logger.info("Asking server for new messages");
|
logger.info("Asking server for new messages");
|
||||||
List<RequestParameter> countStr = ClientService.convertToRequestParameters(clientService.processCommand("GET_MESSAGE_COUNT"));
|
List<RequestParameter> countStr =
|
||||||
|
ClientService.convertToRequestParameters(
|
||||||
|
clientService.processCommand("GET_MESSAGE_COUNT"));
|
||||||
RequestParameter countRes = countStr.getFirst();
|
RequestParameter countRes = countStr.getFirst();
|
||||||
if (!countRes.key().equals("COUNT")) {
|
if (!countRes.key().equals("COUNT")) {
|
||||||
logger.error("Not the right response from server");
|
logger.error("Not the right response from server");
|
||||||
@@ -61,7 +61,9 @@ public class ChatClient {
|
|||||||
logger.info("Got " + count + " messages");
|
logger.info("Got " + count + " messages");
|
||||||
ArrayList<Message> messages = new ArrayList<>();
|
ArrayList<Message> messages = new ArrayList<>();
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
List<RequestParameter> msgRes = ClientService.convertToRequestParameters(clientService.processCommand("GET_NEXT_MESSAGE"));
|
List<RequestParameter> msgRes =
|
||||||
|
ClientService.convertToRequestParameters(
|
||||||
|
clientService.processCommand("GET_NEXT_MESSAGE"));
|
||||||
Message msg = Message.toMessageReqPars(msgRes);
|
Message msg = Message.toMessageReqPars(msgRes);
|
||||||
messages.add(msg);
|
messages.add(msg);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,9 +3,6 @@ package ch.unibas.dmi.dbis.cs108.casono.client.network;
|
|||||||
import ch.unibas.dmi.dbis.cs108.casono.server.network.command.parsing.RequestParameter;
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.command.parsing.RequestParameter;
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.server.network.transport.RawPacket;
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.transport.RawPacket;
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.server.network.transport.TcpTransport;
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.transport.TcpTransport;
|
||||||
import org.apache.logging.log4j.LogManager;
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -17,13 +14,13 @@ import java.util.concurrent.Future;
|
|||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The ClientService class is responsible for managing the connection to the
|
* The ClientService class is responsible for managing the connection to the server, sending
|
||||||
* server,
|
* commands, and receiving responses. It uses a TcpTransport to communicate with the server and an
|
||||||
* sending commands, and receiving responses. It uses a TcpTransport to
|
* ExecutorService to handle asynchronous requests.
|
||||||
* communicate
|
|
||||||
* with the server and an ExecutorService to handle asynchronous requests.
|
|
||||||
*/
|
*/
|
||||||
public class ClientService {
|
public class ClientService {
|
||||||
|
|
||||||
@@ -35,6 +32,7 @@ public class ClientService {
|
|||||||
public static ArrayList<String> response;
|
public static ArrayList<String> response;
|
||||||
private final AtomicInteger idGenerator;
|
private final AtomicInteger idGenerator;
|
||||||
private final Logger logger;
|
private final Logger logger;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Constructs a ClientService with the given server IP and port. It establishes
|
* Constructs a ClientService with the given server IP and port. It establishes
|
||||||
* a socket connection to the server and initializes the TcpTransport and
|
* a socket connection to the server and initializes the TcpTransport and
|
||||||
@@ -58,10 +56,11 @@ public class ClientService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
executor = Executors.newSingleThreadExecutor();
|
executor = Executors.newSingleThreadExecutor();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static Pattern responseRex = Pattern.compile("(?<key>\\w+)=(('(?<string>([^']|\\')+)')|(?<primVal>[+-]?[\\d\\w:]+))");
|
static Pattern responseRex =
|
||||||
|
Pattern.compile(
|
||||||
|
"(?<key>\\w+)=(('(?<string>([^']|\\')+)')|(?<primVal>[+-]?[\\d\\w:]+))");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends the Requests to the server and waits for the response If the response is "+OK" it
|
* Sends the Requests to the server and waits for the response If the response is "+OK" it
|
||||||
@@ -73,19 +72,25 @@ public class ClientService {
|
|||||||
private static String unescape(String input) {
|
private static String unescape(String input) {
|
||||||
return input.replaceAll("\\\\'", "'");
|
return input.replaceAll("\\\\'", "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<RequestParameter> convertToRequestParameters(List<String> input) {
|
public static List<RequestParameter> convertToRequestParameters(List<String> input) {
|
||||||
return input.stream().map((String parString)-> responseRex.matcher(parString))
|
return input.stream()
|
||||||
|
.map((String parString) -> responseRex.matcher(parString))
|
||||||
.filter(Matcher::matches)
|
.filter(Matcher::matches)
|
||||||
.map((m)->{
|
.map(
|
||||||
if (!(m.group("string") == null)) {
|
(m) -> {
|
||||||
return new RequestParameter(m.group("key"), unescape(m.group("string")));
|
if (!(m.group("string") == null)) {
|
||||||
} else if (!(m.group("primVal") == null)){
|
return new RequestParameter(
|
||||||
return new RequestParameter(m.group("key"), m.group("primVal"));
|
m.group("key"), unescape(m.group("string")));
|
||||||
} else {
|
} else if (!(m.group("primVal") == null)) {
|
||||||
throw new RuntimeException();
|
return new RequestParameter(m.group("key"), m.group("primVal"));
|
||||||
}
|
} else {
|
||||||
}).toList();
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected List<String> processCommand(String message) {
|
protected List<String> processCommand(String message) {
|
||||||
List<String> response = new ArrayList<>();
|
List<String> response = new ArrayList<>();
|
||||||
sendRequest(
|
sendRequest(
|
||||||
@@ -98,7 +103,7 @@ public class ClientService {
|
|||||||
logger.info("Raw message '" + responseText + "'");
|
logger.info("Raw message '" + responseText + "'");
|
||||||
Boolean success = null;
|
Boolean success = null;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for(String line: responseText.split("\n")) {
|
for (String line : responseText.split("\n")) {
|
||||||
if (success == null) {
|
if (success == null) {
|
||||||
if ("+OK".equals(line)) {
|
if ("+OK".equals(line)) {
|
||||||
success = true;
|
success = true;
|
||||||
@@ -113,12 +118,11 @@ public class ClientService {
|
|||||||
}
|
}
|
||||||
line = line.replaceFirst("^\t", "");
|
line = line.replaceFirst("^\t", "");
|
||||||
response.add(line);
|
response.add(line);
|
||||||
|
|
||||||
}
|
}
|
||||||
if (success!= null && success) {
|
if (success != null && success) {
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
throw new RuntimeException("Error in "+message+": "+response);
|
throw new RuntimeException("Error in " + message + ": " + response);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw getRuntimeException(e);
|
throw getRuntimeException(e);
|
||||||
@@ -128,13 +132,11 @@ public class ClientService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method to send a request to the server using the ExecutorService. It
|
* Helper method to send a request to the server using the ExecutorService. It submits the
|
||||||
* submits the request as a Runnable task and waits for its completion. If
|
* request as a Runnable task and waits for its completion. If the task is interrupted or
|
||||||
* the task is interrupted or encounters an execution exception, it throws a
|
* encounters an execution exception, it throws a RuntimeException with the appropriate cause.
|
||||||
* RuntimeException with the appropriate cause.
|
|
||||||
*
|
*
|
||||||
* @param request The Runnable task representing the request to be sent to the
|
* @param request The Runnable task representing the request to be sent to the server.
|
||||||
* server.
|
|
||||||
*/
|
*/
|
||||||
private void sendRequest(Runnable request) {
|
private void sendRequest(Runnable request) {
|
||||||
Future<?> future = executor.submit(request);
|
Future<?> future = executor.submit(request);
|
||||||
@@ -148,11 +150,10 @@ public class ClientService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method to extract the cause of an exception and return it as a
|
* Helper method to extract the cause of an exception and return it as a RuntimeException. If
|
||||||
* RuntimeException. If the cause is null, it returns the original exception as
|
* the cause is null, it returns the original exception as a RuntimeException. If the cause is
|
||||||
* a RuntimeException. If the cause is already a RuntimeException, it returns
|
* already a RuntimeException, it returns it directly. Otherwise, it wraps the cause in a new
|
||||||
* it directly. Otherwise, it wraps the cause in a new RuntimeException and
|
* RuntimeException and returns it.
|
||||||
* returns it.
|
|
||||||
*
|
*
|
||||||
* @param e The exception from which to extract the cause.
|
* @param e The exception from which to extract the cause.
|
||||||
* @return A RuntimeException representing the cause of the original exception.
|
* @return A RuntimeException representing the cause of the original exception.
|
||||||
@@ -170,10 +171,9 @@ public class ClientService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Closes the socket connection to the server and shuts down the
|
* Closes the socket connection to the server and shuts down the ExecutorService. It also closes
|
||||||
* ExecutorService.
|
* the TcpTransport used for communication. If any IOException occurs during this process, it
|
||||||
* It also closes the TcpTransport used for communication. If any IOException
|
* prints the exception to the console.
|
||||||
* occurs during this process, it prints the exception to the console.
|
|
||||||
*/
|
*/
|
||||||
public void closeSocket() {
|
public void closeSocket() {
|
||||||
try {
|
try {
|
||||||
@@ -200,6 +200,4 @@ public class ClientService {
|
|||||||
public void ping() {
|
public void ping() {
|
||||||
processCommand("PING");
|
processCommand("PING");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,27 +1,26 @@
|
|||||||
package ch.unibas.dmi.dbis.cs108.casono.client.network;
|
package ch.unibas.dmi.dbis.cs108.casono.client.network;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The CoreClient class provides basic functionalities for communicating with
|
* The CoreClient class provides basic functionalities for communicating with the server, such as
|
||||||
* the
|
* sending a ping command to check connectivity and logging in with a username. It uses the
|
||||||
* server, such as sending a ping command to check connectivity and logging in
|
* ClientService to send commands and receive responses from the server.
|
||||||
* with a username. It uses the ClientService to send commands and receive
|
|
||||||
* responses from the server.
|
|
||||||
*/
|
*/
|
||||||
public class CoreClient {
|
public class CoreClient {
|
||||||
private final ClientService clientService;
|
private final ClientService clientService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a CoreClient with the given ClientService for communication.
|
* Constructs a CoreClient with the given ClientService for communication.
|
||||||
*
|
*
|
||||||
* @param clientservice The ClientService instance used to send commands and
|
* @param clientservice The ClientService instance used to send commands and receive responses
|
||||||
* receive responses from the server.
|
* from the server.
|
||||||
*/
|
*/
|
||||||
public CoreClient(ClientService clientservice) {
|
public CoreClient(ClientService clientservice) {
|
||||||
this.clientService = clientservice;
|
this.clientService = clientservice;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a "PING" command to the server to check connectivity. The server
|
* Sends a "PING" command to the server to check connectivity. The server should respond with a
|
||||||
* should respond with a "PONG" message if the connection is successful.
|
* "PONG" message if the connection is successful.
|
||||||
*/
|
*/
|
||||||
public void ping() {
|
public void ping() {
|
||||||
clientService.processCommand("PING");
|
clientService.processCommand("PING");
|
||||||
|
|||||||
@@ -3,14 +3,12 @@ package ch.unibas.dmi.dbis.cs108.casono.client.network;
|
|||||||
import ch.unibas.dmi.dbis.cs108.casono.client.game.Card;
|
import ch.unibas.dmi.dbis.cs108.casono.client.game.Card;
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.client.game.GameState;
|
import ch.unibas.dmi.dbis.cs108.casono.client.game.GameState;
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.client.game.Player;
|
import ch.unibas.dmi.dbis.cs108.casono.client.game.Player;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The GameClient class is responsible for communicating with the server to
|
* The GameClient class is responsible for communicating with the server to retrieve the current
|
||||||
* retrieve the current game state. It sends a command to the server and
|
* game state. It sends a command to the server and parses the response into a structured GameState
|
||||||
* parses the response into a structured GameState object.
|
* object.
|
||||||
*/
|
*/
|
||||||
public class GameClient {
|
public class GameClient {
|
||||||
|
|
||||||
@@ -19,16 +17,16 @@ public class GameClient {
|
|||||||
/**
|
/**
|
||||||
* Constructs a GameClient with the given ClientService for communication.
|
* Constructs a GameClient with the given ClientService for communication.
|
||||||
*
|
*
|
||||||
* @param client The ClientService instance used to send commands and receive
|
* @param client The ClientService instance used to send commands and receive responses from the
|
||||||
* responses from the server.
|
* server.
|
||||||
*/
|
*/
|
||||||
public GameClient(ClientService client) {
|
public GameClient(ClientService client) {
|
||||||
this.client = client;
|
this.client = client;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the current game state from the server by sending a command and
|
* Retrieves the current game state from the server by sending a command and parsing the
|
||||||
* parsing the response.
|
* response.
|
||||||
*
|
*
|
||||||
* @return A GameState object representing the current state of the game.
|
* @return A GameState object representing the current state of the game.
|
||||||
*/
|
*/
|
||||||
@@ -43,13 +41,10 @@ public class GameClient {
|
|||||||
* @param input The raw response string from the server.
|
* @param input The raw response string from the server.
|
||||||
* @return A GameState object representing the current state of the game.
|
* @return A GameState object representing the current state of the game.
|
||||||
*/
|
*/
|
||||||
private GameState parseGameState(String input) {
|
|
||||||
private GameState parseGameState(List<String> input) {
|
private GameState parseGameState(List<String> input) {
|
||||||
|
|
||||||
GameState state = new GameState();
|
GameState state = new GameState();
|
||||||
|
|
||||||
String[] lines = input.split("\n");
|
|
||||||
|
|
||||||
Player currentPlayer = null;
|
Player currentPlayer = null;
|
||||||
Card currentCard = null;
|
Card currentCard = null;
|
||||||
|
|
||||||
@@ -63,46 +58,26 @@ public class GameClient {
|
|||||||
|
|
||||||
if (line.startsWith("PHASE=")) {
|
if (line.startsWith("PHASE=")) {
|
||||||
state.phase = line.split("=")[1];
|
state.phase = line.split("=")[1];
|
||||||
}
|
} else if (line.startsWith("POT=")) {
|
||||||
|
|
||||||
else if (line.startsWith("POT=")) {
|
|
||||||
state.pot = Integer.parseInt(line.split("=")[1]);
|
state.pot = Integer.parseInt(line.split("=")[1]);
|
||||||
}
|
} else if (line.startsWith("CURRENT_BET=")) {
|
||||||
|
|
||||||
else if (line.startsWith("CURRENT_BET=")) {
|
|
||||||
state.currentBet = Integer.parseInt(line.split("=")[1]);
|
state.currentBet = Integer.parseInt(line.split("=")[1]);
|
||||||
}
|
} else if (line.startsWith("DEALER=")) {
|
||||||
|
|
||||||
else if (line.startsWith("DEALER=")) {
|
|
||||||
state.dealer = Integer.parseInt(line.split("=")[1]);
|
state.dealer = Integer.parseInt(line.split("=")[1]);
|
||||||
}
|
} else if (line.startsWith("ACTIVE_PLAYER=")) {
|
||||||
|
|
||||||
else if (line.startsWith("ACTIVE_PLAYER=")) {
|
|
||||||
state.activePlayer = Integer.parseInt(line.split("=")[1]);
|
state.activePlayer = Integer.parseInt(line.split("=")[1]);
|
||||||
}
|
} else if (line.startsWith("PLAYER")) {
|
||||||
|
|
||||||
else if (line.startsWith("PLAYER")) {
|
|
||||||
currentPlayer = new Player();
|
currentPlayer = new Player();
|
||||||
state.players.add(currentPlayer);
|
state.players.add(currentPlayer);
|
||||||
}
|
} else if (line.startsWith("NAME=") && currentPlayer != null) {
|
||||||
|
|
||||||
else if (line.startsWith("NAME=") && currentPlayer != null) {
|
|
||||||
currentPlayer.name = line.split("=")[1];
|
currentPlayer.name = line.split("=")[1];
|
||||||
}
|
} else if (line.startsWith("CHIPS=") && currentPlayer != null) {
|
||||||
|
|
||||||
else if (line.startsWith("CHIPS=") && currentPlayer != null) {
|
|
||||||
currentPlayer.chips = Integer.parseInt(line.split("=")[1]);
|
currentPlayer.chips = Integer.parseInt(line.split("=")[1]);
|
||||||
}
|
} else if (line.startsWith("BET=") && currentPlayer != null) {
|
||||||
|
|
||||||
else if (line.startsWith("BET=") && currentPlayer != null) {
|
|
||||||
currentPlayer.bet = Integer.parseInt(line.split("=")[1]);
|
currentPlayer.bet = Integer.parseInt(line.split("=")[1]);
|
||||||
}
|
} else if (line.startsWith("STATE=") && currentPlayer != null) {
|
||||||
|
|
||||||
else if (line.startsWith("STATE=") && currentPlayer != null) {
|
|
||||||
currentPlayer.state = line.split("=")[1];
|
currentPlayer.state = line.split("=")[1];
|
||||||
}
|
} else if (line.startsWith("CARD")) {
|
||||||
|
|
||||||
else if (line.startsWith("CARD")) {
|
|
||||||
currentCard = new Card();
|
currentCard = new Card();
|
||||||
|
|
||||||
if (currentPlayer != null) {
|
if (currentPlayer != null) {
|
||||||
@@ -110,13 +85,9 @@ public class GameClient {
|
|||||||
} else {
|
} else {
|
||||||
state.communityCards.add(currentCard);
|
state.communityCards.add(currentCard);
|
||||||
}
|
}
|
||||||
}
|
} else if (line.startsWith("VALUE=") && currentCard != null) {
|
||||||
|
|
||||||
else if (line.startsWith("VALUE=") && currentCard != null) {
|
|
||||||
currentCard.value = line.split("=")[1];
|
currentCard.value = line.split("=")[1];
|
||||||
}
|
} else if (line.startsWith("SUIT=") && currentCard != null) {
|
||||||
|
|
||||||
else if (line.startsWith("SUIT=") && currentCard != null) {
|
|
||||||
currentCard.suit = line.split("=")[1];
|
currentCard.suit = line.split("=")[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
package ch.unibas.dmi.dbis.cs108.casono.client.network;
|
package ch.unibas.dmi.dbis.cs108.casono.client.network;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The LobbyClient class is responsible for communicating with the server to
|
* The LobbyClient class is responsible for communicating with the server to manage game lobbies. It
|
||||||
* manage game lobbies. It provides methods to create a lobby, join a lobby,
|
* provides methods to create a lobby, join a lobby, and fetch the current status of a lobby by
|
||||||
* and fetch the current status of a lobby by sending appropriate commands to
|
* sending appropriate commands to the server and processing the responses.
|
||||||
* the server and processing the responses.
|
|
||||||
*/
|
*/
|
||||||
public class LobbyClient {
|
public class LobbyClient {
|
||||||
private final ClientService client;
|
private final ClientService client;
|
||||||
@@ -12,8 +11,8 @@ public class LobbyClient {
|
|||||||
/**
|
/**
|
||||||
* Constructs a LobbyClient with the given ClientService for communication.
|
* Constructs a LobbyClient with the given ClientService for communication.
|
||||||
*
|
*
|
||||||
* @param client The ClientService instance used to send commands and receive
|
* @param client The ClientService instance used to send commands and receive responses from the
|
||||||
* responses from the server.
|
* server.
|
||||||
*/
|
*/
|
||||||
public LobbyClient(ClientService client) {
|
public LobbyClient(ClientService client) {
|
||||||
this.client = client;
|
this.client = client;
|
||||||
@@ -23,16 +22,14 @@ public class LobbyClient {
|
|||||||
* Fetch the current status of the lobby with the given id from the server.
|
* Fetch the current status of the lobby with the given id from the server.
|
||||||
*
|
*
|
||||||
* @param lobbyId The id of the lobby to fetch the status for.
|
* @param lobbyId The id of the lobby to fetch the status for.
|
||||||
* @return A string representing the current status of the lobby, as returned
|
* @return A string representing the current status of the lobby, as returned by the server.
|
||||||
* by the server.
|
|
||||||
*/
|
*/
|
||||||
public String fetchLobbyStatusString(int lobbyId) {
|
public String fetchLobbyStatusString(int lobbyId) {
|
||||||
return client.processCommand("GET_LOBBY_STATUS ID=" + lobbyId).getFirst();
|
return client.processCommand("GET_LOBBY_STATUS ID=" + lobbyId).getFirst();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request the server to create a new lobby and return the id of the newly
|
* Request the server to create a new lobby and return the id of the newly created lobby.
|
||||||
* created lobby.
|
|
||||||
*
|
*
|
||||||
* @return The id of the newly created lobby, as returned by the server.
|
* @return The id of the newly created lobby, as returned by the server.
|
||||||
*/
|
*/
|
||||||
@@ -42,11 +39,9 @@ public class LobbyClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request the server to return the id of the lobby that the client is
|
* Request the server to return the id of the lobby that the client is currently in.
|
||||||
* currently in.
|
|
||||||
*
|
*
|
||||||
* @return The id of the lobby that the client is currently in, as returned by
|
* @return The id of the lobby that the client is currently in, as returned by the server.
|
||||||
* the server.
|
|
||||||
*/
|
*/
|
||||||
public int getLobbyId() {
|
public int getLobbyId() {
|
||||||
String response = client.processCommand("GET_LOBBY_ID").getFirst();
|
String response = client.processCommand("GET_LOBBY_ID").getFirst();
|
||||||
|
|||||||
+22
-17
@@ -3,6 +3,9 @@ package ch.unibas.dmi.dbis.cs108.casono.client.ui.chatui;
|
|||||||
import ch.unibas.dmi.dbis.cs108.casono.client.chat.ChatController;
|
import ch.unibas.dmi.dbis.cs108.casono.client.chat.ChatController;
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.client.chat.ChatModel;
|
import ch.unibas.dmi.dbis.cs108.casono.client.chat.ChatModel;
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.client.chat.ChatType;
|
import ch.unibas.dmi.dbis.cs108.casono.client.chat.ChatType;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.List;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.fxml.FXMLLoader;
|
import javafx.fxml.FXMLLoader;
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
@@ -10,12 +13,9 @@ import javafx.scene.control.MenuButton;
|
|||||||
import javafx.scene.control.MenuItem;
|
import javafx.scene.control.MenuItem;
|
||||||
import javafx.scene.control.Tab;
|
import javafx.scene.control.Tab;
|
||||||
import javafx.scene.control.TabPane;
|
import javafx.scene.control.TabPane;
|
||||||
|
import javafx.scene.layout.Priority;
|
||||||
import javafx.scene.layout.VBox;
|
import javafx.scene.layout.VBox;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class ChatBoxController {
|
public class ChatBoxController {
|
||||||
|
|
||||||
private String username;
|
private String username;
|
||||||
@@ -24,7 +24,7 @@ public class ChatBoxController {
|
|||||||
|
|
||||||
@FXML private VBox chatBox;
|
@FXML private VBox chatBox;
|
||||||
|
|
||||||
@FXML private TabPane ChatTabPane;
|
@FXML private TabPane chatTabPane;
|
||||||
|
|
||||||
@FXML private MenuButton addWhisperChatButton;
|
@FXML private MenuButton addWhisperChatButton;
|
||||||
|
|
||||||
@@ -32,8 +32,7 @@ public class ChatBoxController {
|
|||||||
|
|
||||||
@FXML private List<MenuItem> whisperUsers;
|
@FXML private List<MenuItem> whisperUsers;
|
||||||
|
|
||||||
private String ressource = "/ui-structure/components/chatui/chattab.fxml";
|
private String ressource = "/ui-structure/components/chatui/chattab.fxml";
|
||||||
|
|
||||||
|
|
||||||
public ChatBoxController(String username, ChatController chatController) {
|
public ChatBoxController(String username, ChatController chatController) {
|
||||||
this.username = username;
|
this.username = username;
|
||||||
@@ -43,37 +42,43 @@ public class ChatBoxController {
|
|||||||
@FXML
|
@FXML
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
ChatModel globalChatModel = new ChatModel(ChatType.GLOBAL, username, -1, null);
|
ChatModel globalChatModel = new ChatModel(ChatType.GLOBAL, username, -1, null);
|
||||||
chatController.getChatModelMap().put(new ChatController.ChatKey(ChatType.GLOBAL), globalChatModel);
|
chatController
|
||||||
|
.getChatModelMap()
|
||||||
|
.put(new ChatController.ChatKey(ChatType.GLOBAL), globalChatModel);
|
||||||
addChatTab("GLOBAL", globalChatModel);
|
addChatTab("GLOBAL", globalChatModel);
|
||||||
//TODO: Button to add new Whisper Chat
|
// TODO: Button to add new Whisper Chat
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void addWhisperUser(String targetUserName) {
|
public void addWhisperUser(String targetUserName) {
|
||||||
MenuItem menuItem = new MenuItem(targetUserName);
|
MenuItem menuItem = new MenuItem(targetUserName);
|
||||||
whisperUsers.add(menuItem);
|
whisperUsers.add(menuItem);
|
||||||
addWhisperChatButton.getItems().add(menuItem);
|
addWhisperChatButton.getItems().add(menuItem);
|
||||||
|
|
||||||
menuItem.setOnAction(event -> addWhisperChat(targetUserName));
|
menuItem.setOnAction(event -> addWhisperChat(targetUserName));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addWhisperChat(String target) {
|
public void addWhisperChat(String target) {
|
||||||
ChatModel chatModel = new ChatModel(ChatType.WHISPER, username, -1, target);
|
ChatModel chatModel = new ChatModel(ChatType.WHISPER, username, -1, target);
|
||||||
chatController.getChatModelMap().put(new ChatController.ChatKey(ChatType.WHISPER, target), chatModel);
|
chatController
|
||||||
|
.getChatModelMap()
|
||||||
|
.put(new ChatController.ChatKey(ChatType.WHISPER, target), chatModel);
|
||||||
addChatTab(target, chatModel);
|
addChatTab(target, chatModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void addChatTab(String title, ChatModel chatModel) {
|
public void addChatTab(String title, ChatModel chatModel) {
|
||||||
URL resource = getClass().getResource(ressource);
|
URL resource = getClass().getResource(ressource);
|
||||||
FXMLLoader fxmlLoader = new FXMLLoader(resource);
|
FXMLLoader fxmlLoader = new FXMLLoader(resource);
|
||||||
try {
|
try {
|
||||||
ChatViewController chatViewController = new ChatViewController(this.chatController, chatModel, this.username);
|
ChatViewController chatViewController =
|
||||||
|
new ChatViewController(this.chatController, chatModel, this.username);
|
||||||
fxmlLoader.setController(chatViewController);
|
fxmlLoader.setController(chatViewController);
|
||||||
Node load = fxmlLoader.load();
|
Node load = fxmlLoader.load();
|
||||||
chatModel.addListener((msg)-> chatViewController.showMessage(msg));
|
VBox.setVgrow(load, Priority.ALWAYS);
|
||||||
Tab newChat = new Tab(title, load);
|
VBox vbox = new VBox();
|
||||||
this.ChatTabPane.getTabs().add(newChat);
|
VBox.setVgrow(vbox, Priority.ALWAYS);
|
||||||
|
vbox.getChildren().add(load);
|
||||||
|
chatModel.addListener((msg) -> chatViewController.showMessage(msg));
|
||||||
|
Tab newChat = new Tab(title, vbox);
|
||||||
|
this.chatTabPane.getTabs().add(newChat);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-4
@@ -38,7 +38,7 @@ public class ChatViewController implements Initializable {
|
|||||||
|
|
||||||
private static final int CHAT_PADDING = 20;
|
private static final int CHAT_PADDING = 20;
|
||||||
|
|
||||||
public ChatViewController(ChatController chatController, ChatModel chatModel, String username){
|
public ChatViewController(ChatController chatController, ChatModel chatModel, String username) {
|
||||||
this.controller = chatController;
|
this.controller = chatController;
|
||||||
this.username = username;
|
this.username = username;
|
||||||
this.chatModel = chatModel;
|
this.chatModel = chatModel;
|
||||||
@@ -55,7 +55,13 @@ public class ChatViewController implements Initializable {
|
|||||||
String message = inputField.getText().trim();
|
String message = inputField.getText().trim();
|
||||||
if (!message.isEmpty()) {
|
if (!message.isEmpty()) {
|
||||||
inputField.clear();
|
inputField.clear();
|
||||||
Message msg = new Message(chatModel.getChattype(), chatModel.lobbyId, username, chatModel.getTarget(), message);
|
Message msg =
|
||||||
|
new Message(
|
||||||
|
chatModel.getChattype(),
|
||||||
|
chatModel.lobbyId,
|
||||||
|
username,
|
||||||
|
chatModel.getTarget(),
|
||||||
|
message);
|
||||||
controller.onSendToNetwork(msg);
|
controller.onSendToNetwork(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -69,6 +75,7 @@ public class ChatViewController implements Initializable {
|
|||||||
chat.getChildren().add(label);
|
chat.getChildren().add(label);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public VBox getChatInterfaceVBox() {
|
||||||
|
return chatInterfaceVBox;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,12 @@
|
|||||||
package ch.unibas.dmi.dbis.cs108.casono.client.ui.lobbyui;
|
package ch.unibas.dmi.dbis.cs108.casono.client.ui.lobbyui;
|
||||||
|
|
||||||
/** Main UI application for Casono. Loads the main FXML layout and sets up the stage. */
|
/** Main UI application for Casono. Loads the main FXML layout and sets up the stage. */
|
||||||
|
import java.io.IOException;
|
||||||
import javafx.application.Application;
|
import javafx.application.Application;
|
||||||
import javafx.fxml.FXMLLoader;
|
import javafx.fxml.FXMLLoader;
|
||||||
import javafx.scene.Scene;
|
import javafx.scene.Scene;
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JavaFX Application class for the Casono main UI.
|
* JavaFX Application class for the Casono main UI.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -3,18 +3,18 @@ package ch.unibas.dmi.dbis.cs108.casono.server;
|
|||||||
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.check_nick.CheckUsernameHandler;
|
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.check_nick.CheckUsernameHandler;
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.check_nick.CheckUsernameParser;
|
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.check_nick.CheckUsernameParser;
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.check_nick.CheckUsernameRequest;
|
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.check_nick.CheckUsernameRequest;
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.login.LoginHandler;
|
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.login.LoginParser;
|
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.login.LoginRequest;
|
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.logout.LogoutHandler;
|
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.logout.LogoutParser;
|
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.logout.LogoutRequest;
|
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.get_message_count.GetMessageCountHandler;
|
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.get_message_count.GetMessageCountHandler;
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.get_message_count.GetMessageCountParser;
|
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.get_message_count.GetMessageCountParser;
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.get_message_count.GetMessageCountRequest;
|
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.get_message_count.GetMessageCountRequest;
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.get_next_message.GetNextMessageHandler;
|
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.get_next_message.GetNextMessageHandler;
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.get_next_message.GetNextMessageParser;
|
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.get_next_message.GetNextMessageParser;
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.get_next_message.GetNextMessageRequest;
|
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.get_next_message.GetNextMessageRequest;
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.login.LoginHandler;
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.login.LoginParser;
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.login.LoginRequest;
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.logout.LogoutHandler;
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.logout.LogoutParser;
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.logout.LogoutRequest;
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.ping.PingHandler;
|
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.ping.PingHandler;
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.ping.PingParser;
|
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.ping.PingParser;
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.ping.PingRequest;
|
import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.ping.PingRequest;
|
||||||
@@ -32,13 +32,12 @@ import ch.unibas.dmi.dbis.cs108.casono.server.network.events.EventBus;
|
|||||||
import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.dispatcher.ResponseDispatcher;
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.dispatcher.ResponseDispatcher;
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionDisconnectJob;
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionDisconnectJob;
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionManager;
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionManager;
|
||||||
import org.apache.logging.log4j.LogManager;
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
/** Application class for starting the server. */
|
/** Application class for starting the server. */
|
||||||
public class ServerApp {
|
public class ServerApp {
|
||||||
@@ -118,22 +117,16 @@ public class ServerApp {
|
|||||||
LogoutRequest.class, new LogoutHandler(responseDispatcher, userRegistry));
|
LogoutRequest.class, new LogoutHandler(responseDispatcher, userRegistry));
|
||||||
parserDispatcher.register("SEND_MESSAGE", new SendMessageParser());
|
parserDispatcher.register("SEND_MESSAGE", new SendMessageParser());
|
||||||
commandRouter.register(
|
commandRouter.register(
|
||||||
SendMessageRequest.class,
|
SendMessageRequest.class, new SendMessageHandler(responseDispatcher, userRegistry));
|
||||||
new SendMessageHandler(responseDispatcher, userRegistry)
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
parserDispatcher.register("GET_MESSAGE_COUNT", new GetMessageCountParser());
|
parserDispatcher.register("GET_MESSAGE_COUNT", new GetMessageCountParser());
|
||||||
commandRouter.register(
|
commandRouter.register(
|
||||||
GetMessageCountRequest.class,
|
GetMessageCountRequest.class,
|
||||||
new GetMessageCountHandler(responseDispatcher, userRegistry)
|
new GetMessageCountHandler(responseDispatcher, userRegistry));
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
parserDispatcher.register("GET_NEXT_MESSAGE", new GetNextMessageParser());
|
parserDispatcher.register("GET_NEXT_MESSAGE", new GetNextMessageParser());
|
||||||
commandRouter.register(
|
commandRouter.register(
|
||||||
GetNextMessageRequest.class,
|
GetNextMessageRequest.class,
|
||||||
new GetNextMessageHandler(responseDispatcher, userRegistry)
|
new GetNextMessageHandler(responseDispatcher, userRegistry));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-14
@@ -5,15 +5,14 @@ import ch.unibas.dmi.dbis.cs108.casono.server.domain.user.UserRegistry;
|
|||||||
import ch.unibas.dmi.dbis.cs108.casono.server.network.command.execution.CommandHandler;
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.command.execution.CommandHandler;
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.ErrorResponse;
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.ErrorResponse;
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.dispatcher.ResponseDispatcher;
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.dispatcher.ResponseDispatcher;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public class GetMessageCountHandler implements CommandHandler<GetMessageCountRequest> {
|
public class GetMessageCountHandler extends CommandHandler<GetMessageCountRequest> {
|
||||||
public final ResponseDispatcher responseDispatcher;
|
|
||||||
private final UserRegistry userRegistry;
|
private final UserRegistry userRegistry;
|
||||||
|
|
||||||
public GetMessageCountHandler(ResponseDispatcher responseDispatcher, UserRegistry userRegistry) {
|
public GetMessageCountHandler(
|
||||||
this.responseDispatcher = responseDispatcher;
|
ResponseDispatcher responseDispatcher, UserRegistry userRegistry) {
|
||||||
|
super(responseDispatcher);
|
||||||
this.userRegistry = userRegistry;
|
this.userRegistry = userRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -22,18 +21,14 @@ public class GetMessageCountHandler implements CommandHandler<GetMessageCountReq
|
|||||||
Optional<User> user = userRegistry.getBySessionId(request.getSessionId());
|
Optional<User> user = userRegistry.getBySessionId(request.getSessionId());
|
||||||
if (user.isPresent()) {
|
if (user.isPresent()) {
|
||||||
int count = user.get().getMessageCount();
|
int count = user.get().getMessageCount();
|
||||||
GetMessageCountResponse response = new GetMessageCountResponse(
|
GetMessageCountResponse response =
|
||||||
request.getContext(),
|
new GetMessageCountResponse(request.getContext(), count);
|
||||||
count
|
|
||||||
);
|
|
||||||
responseDispatcher.dispatch(response);
|
responseDispatcher.dispatch(response);
|
||||||
} else {
|
} else {
|
||||||
ErrorResponse response = new ErrorResponse(
|
ErrorResponse response =
|
||||||
request.getContext(),
|
new ErrorResponse(
|
||||||
"",
|
request.getContext(), "", "user could not be identified by SessionId");
|
||||||
"user could not be identified by SessionId"
|
|
||||||
|
|
||||||
);
|
|
||||||
responseDispatcher.dispatch(response);
|
responseDispatcher.dispatch(response);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -7,7 +7,8 @@ import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.accessor.
|
|||||||
public class GetMessageCountParser implements CommandParser<GetMessageCountRequest> {
|
public class GetMessageCountParser implements CommandParser<GetMessageCountRequest> {
|
||||||
@Override
|
@Override
|
||||||
public GetMessageCountRequest parse(PrimitiveRequest primitiveRequest) {
|
public GetMessageCountRequest parse(PrimitiveRequest primitiveRequest) {
|
||||||
RequestParameterAccessor accessor = new RequestParameterAccessor(primitiveRequest.parameters());
|
RequestParameterAccessor accessor =
|
||||||
|
new RequestParameterAccessor(primitiveRequest.parameters());
|
||||||
return new GetMessageCountRequest(primitiveRequest.context());
|
return new GetMessageCountRequest(primitiveRequest.context());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-3
@@ -6,8 +6,6 @@ import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.builder.
|
|||||||
|
|
||||||
public class GetMessageCountResponse extends SuccessResponse {
|
public class GetMessageCountResponse extends SuccessResponse {
|
||||||
public GetMessageCountResponse(RequestContext context, int count) {
|
public GetMessageCountResponse(RequestContext context, int count) {
|
||||||
super(context, new ResponseBodyBuilder()
|
super(context, new ResponseBodyBuilder().param("COUNT", count).build());
|
||||||
.param("COUNT", count)
|
|
||||||
.build());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-14
@@ -6,15 +6,13 @@ import ch.unibas.dmi.dbis.cs108.casono.server.domain.user.UserRegistry;
|
|||||||
import ch.unibas.dmi.dbis.cs108.casono.server.network.command.execution.CommandHandler;
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.command.execution.CommandHandler;
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.ErrorResponse;
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.ErrorResponse;
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.dispatcher.ResponseDispatcher;
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.dispatcher.ResponseDispatcher;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public class GetNextMessageHandler implements CommandHandler<GetNextMessageRequest> {
|
public class GetNextMessageHandler extends CommandHandler<GetNextMessageRequest> {
|
||||||
public final ResponseDispatcher responseDispatcher;
|
|
||||||
private final UserRegistry userRegistry;
|
private final UserRegistry userRegistry;
|
||||||
|
|
||||||
public GetNextMessageHandler(ResponseDispatcher responseDispatcher, UserRegistry userRegistry) {
|
public GetNextMessageHandler(ResponseDispatcher responseDispatcher, UserRegistry userRegistry) {
|
||||||
this.responseDispatcher = responseDispatcher;
|
super(responseDispatcher);
|
||||||
this.userRegistry = userRegistry;
|
this.userRegistry = userRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -23,18 +21,14 @@ public class GetNextMessageHandler implements CommandHandler<GetNextMessageReque
|
|||||||
Optional<User> user = userRegistry.getBySessionId(request.getSessionId());
|
Optional<User> user = userRegistry.getBySessionId(request.getSessionId());
|
||||||
if (user.isPresent()) {
|
if (user.isPresent()) {
|
||||||
Message msg = user.get().dequeMessage();
|
Message msg = user.get().dequeMessage();
|
||||||
GetNextMessageResponse response = new GetNextMessageResponse(
|
GetNextMessageResponse response = new GetNextMessageResponse(request.getContext(), msg);
|
||||||
request.getContext(),
|
|
||||||
msg
|
|
||||||
);
|
|
||||||
responseDispatcher.dispatch(response);
|
responseDispatcher.dispatch(response);
|
||||||
} else {
|
} else {
|
||||||
ErrorResponse response = new ErrorResponse(
|
ErrorResponse response =
|
||||||
request.getContext(),
|
new ErrorResponse(
|
||||||
"NO_USER_ASSOCIATED",
|
request.getContext(),
|
||||||
"user could not be identified by SessionId"
|
"NO_USER_ASSOCIATED",
|
||||||
|
"user could not be identified by SessionId");
|
||||||
);
|
|
||||||
responseDispatcher.dispatch(response);
|
responseDispatcher.dispatch(response);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -7,7 +7,8 @@ import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.accessor.
|
|||||||
public class GetNextMessageParser implements CommandParser<GetNextMessageRequest> {
|
public class GetNextMessageParser implements CommandParser<GetNextMessageRequest> {
|
||||||
@Override
|
@Override
|
||||||
public GetNextMessageRequest parse(PrimitiveRequest primitiveRequest) {
|
public GetNextMessageRequest parse(PrimitiveRequest primitiveRequest) {
|
||||||
RequestParameterAccessor accessor = new RequestParameterAccessor(primitiveRequest.parameters());
|
RequestParameterAccessor accessor =
|
||||||
|
new RequestParameterAccessor(primitiveRequest.parameters());
|
||||||
return new GetNextMessageRequest(primitiveRequest.context());
|
return new GetNextMessageRequest(primitiveRequest.context());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-2
@@ -7,7 +7,6 @@ import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.builder.
|
|||||||
|
|
||||||
public class GetNextMessageResponse extends SuccessResponse {
|
public class GetNextMessageResponse extends SuccessResponse {
|
||||||
public GetNextMessageResponse(RequestContext context, Message msg) {
|
public GetNextMessageResponse(RequestContext context, Message msg) {
|
||||||
super(context, msg.toResponse(ResponseBody.builder())
|
super(context, msg.toResponse(ResponseBody.builder()));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-5
@@ -1,18 +1,16 @@
|
|||||||
package ch.unibas.dmi.dbis.cs108.casono.server.app.commands.send_message;
|
package ch.unibas.dmi.dbis.cs108.casono.server.app.commands.send_message;
|
||||||
|
|
||||||
|
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.client.chat.Message;
|
import ch.unibas.dmi.dbis.cs108.casono.client.chat.Message;
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.server.domain.user.UserRegistry;
|
import ch.unibas.dmi.dbis.cs108.casono.server.domain.user.UserRegistry;
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.server.network.command.execution.CommandHandler;
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.command.execution.CommandHandler;
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.OkResponse;
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.OkResponse;
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.dispatcher.ResponseDispatcher;
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.dispatcher.ResponseDispatcher;
|
||||||
|
|
||||||
public class SendMessageHandler implements CommandHandler<SendMessageRequest> {
|
public class SendMessageHandler extends CommandHandler<SendMessageRequest> {
|
||||||
public final ResponseDispatcher responseDispatcher;
|
|
||||||
private final UserRegistry userRegistry;
|
private final UserRegistry userRegistry;
|
||||||
|
|
||||||
public SendMessageHandler(ResponseDispatcher responseDispatcher, UserRegistry userRegistry) {
|
public SendMessageHandler(ResponseDispatcher responseDispatcher, UserRegistry userRegistry) {
|
||||||
this.responseDispatcher = responseDispatcher;
|
super(responseDispatcher);
|
||||||
this.userRegistry = userRegistry;
|
this.userRegistry = userRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -23,8 +21,8 @@ public class SendMessageHandler implements CommandHandler<SendMessageRequest> {
|
|||||||
OkResponse response = new OkResponse(request.getContext());
|
OkResponse response = new OkResponse(request.getContext());
|
||||||
responseDispatcher.dispatch(response);
|
responseDispatcher.dispatch(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void broadcast(Message message) {
|
public void broadcast(Message message) {
|
||||||
userRegistry.getAllUsers().forEach(user -> user.enqueueMessage(message));
|
userRegistry.getAllUsers().forEach(user -> user.enqueueMessage(message));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-2
@@ -1,7 +1,8 @@
|
|||||||
package ch.unibas.dmi.dbis.cs108.casono.server.domain.message;
|
package ch.unibas.dmi.dbis.cs108.casono.server.domain.message;
|
||||||
|
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.server.domain.user.UserRegistry;
|
import ch.unibas.dmi.dbis.cs108.casono.server.domain.user.UserRegistry;
|
||||||
|
|
||||||
/** NOT USED **/
|
/** NOT USED * */
|
||||||
public class MessageManager {
|
public class MessageManager {
|
||||||
private final UserRegistry userRegistry;
|
private final UserRegistry userRegistry;
|
||||||
|
|
||||||
@@ -10,6 +11,6 @@ public class MessageManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void broadcast(Message message) {
|
public void broadcast(Message message) {
|
||||||
//userRegistry.getAllUsers().forEach(user -> user.enqueueMessage(message));
|
// userRegistry.getAllUsers().forEach(user -> user.enqueueMessage(message));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
package ch.unibas.dmi.dbis.cs108.casono.server.domain.user;
|
package ch.unibas.dmi.dbis.cs108.casono.server.domain.user;
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.client.chat.Message;
|
|
||||||
|
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.client.chat.Message;
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionId;
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionId;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.*;
|
import java.util.ArrayDeque;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Queue;
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
|
|
||||||
/** Represents an authenticated user on the server. */
|
/** Represents an authenticated user on the server. */
|
||||||
@@ -85,9 +89,13 @@ public class User {
|
|||||||
messages.add(message);
|
messages.add(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized int getMessageCount() { return messages.size(); }
|
public synchronized int getMessageCount() {
|
||||||
|
return messages.size();
|
||||||
|
}
|
||||||
|
|
||||||
public synchronized Message dequeMessage() throws NoSuchElementException { return messages.remove(); }
|
public synchronized Message dequeMessage() throws NoSuchElementException {
|
||||||
|
return messages.remove();
|
||||||
|
}
|
||||||
|
|
||||||
public synchronized List<Message> dequeueAllMessages(Message message) {
|
public synchronized List<Message> dequeueAllMessages(Message message) {
|
||||||
List<Message> allMessages = new ArrayDeque<>(messages).stream().toList();
|
List<Message> allMessages = new ArrayDeque<>(messages).stream().toList();
|
||||||
|
|||||||
@@ -17,17 +17,19 @@
|
|||||||
maxWidth="Infinity">
|
maxWidth="Infinity">
|
||||||
|
|
||||||
<children>
|
<children>
|
||||||
<HBox>
|
<HBox spacing="10"
|
||||||
|
styleClass="">
|
||||||
<children>
|
<children>
|
||||||
<Label text="== CHAT ==" styleClass="chat-header" alignment="CENTER" maxWidth="Infinity"/>
|
<Label text="== CHAT ==" styleClass="chat-header" alignment="CENTER" maxWidth="Infinity"/>
|
||||||
<Region minHeight="4" styleClass="chat-separator"/>
|
<Region HBox.hgrow="ALWAYS" />
|
||||||
<MenuButton fx:id="addWhisperChatButton" styleClass="gray-button" text="+" alignment="CENTER_RIGHT">
|
<MenuButton fx:id="addWhisperChatButton" styleClass="yellow-button" text="WHISPER CHAT" alignment="CENTER_RIGHT">
|
||||||
</MenuButton>
|
</MenuButton>
|
||||||
</children>
|
</children>
|
||||||
|
|
||||||
</HBox>
|
</HBox>
|
||||||
|
|
||||||
<TabPane fx:id="ChatTabPane">
|
<TabPane fx:id="ChatTabPane"
|
||||||
|
VBox.vgrow="ALWAYS">
|
||||||
|
|
||||||
</TabPane>
|
</TabPane>
|
||||||
|
|
||||||
|
|||||||
@@ -7,14 +7,12 @@
|
|||||||
|
|
||||||
<VBox fx:id="chatInterfaceVBox"
|
<VBox fx:id="chatInterfaceVBox"
|
||||||
maxWidth="Infinity"
|
maxWidth="Infinity"
|
||||||
minHeight="500"
|
|
||||||
spacing="10"
|
spacing="10"
|
||||||
styleClass="chat-box"
|
styleClass="chat-box"
|
||||||
stylesheets="@chatui.css"
|
stylesheets="@chatui.css"
|
||||||
VBox.vgrow="ALWAYS"
|
VBox.vgrow="ALWAYS"
|
||||||
xmlns="http://javafx.com/javafx/17.0.12"
|
xmlns="http://javafx.com/javafx/17.0.12"
|
||||||
xmlns:fx="http://javafx.com/fxml/1"
|
xmlns:fx="http://javafx.com/fxml/1">
|
||||||
>
|
|
||||||
|
|
||||||
<children>
|
<children>
|
||||||
<!-- Chatnachrichten werden hier hinzugefügt -->
|
<!-- Chatnachrichten werden hier hinzugefügt -->
|
||||||
|
|||||||
@@ -83,7 +83,7 @@
|
|||||||
.gray-button {
|
.gray-button {
|
||||||
-fx-background-color: #333333;
|
-fx-background-color: #333333;
|
||||||
-fx-border-color: #666666;
|
-fx-border-color: #666666;
|
||||||
-fx-text-fill: #cccccc;
|
-fx-text-fill: #ffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.gray-button, .yellow-button, .red-button {
|
.gray-button, .yellow-button, .red-button {
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
package ch.unibas.dmi.dbis.cs108.casono.client.chat;
|
package ch.unibas.dmi.dbis.cs108.casono.client.chat;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.client.network.ClientService;
|
import ch.unibas.dmi.dbis.cs108.casono.client.network.ClientService;
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.server.network.command.parsing.RequestParameter;
|
import ch.unibas.dmi.dbis.cs108.casono.server.network.command.parsing.RequestParameter;
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
|
|
||||||
public class ChatTest {
|
public class ChatTest {
|
||||||
|
|
||||||
@@ -20,8 +19,6 @@ public class ChatTest {
|
|||||||
list.add("TEXT='Hello World'");
|
list.add("TEXT='Hello World'");
|
||||||
list.add("NUMBER=-56887387394898392849");
|
list.add("NUMBER=-56887387394898392849");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
List<RequestParameter> newList = ClientService.convertToRequestParameters(list);
|
List<RequestParameter> newList = ClientService.convertToRequestParameters(list);
|
||||||
RequestParameter par0 = newList.get(0);
|
RequestParameter par0 = newList.get(0);
|
||||||
assertEquals("COUNT", par0.key());
|
assertEquals("COUNT", par0.key());
|
||||||
@@ -31,13 +28,12 @@ public class ChatTest {
|
|||||||
assertEquals("TEXT", par1.key());
|
assertEquals("TEXT", par1.key());
|
||||||
assertEquals("test ' test", par1.value());
|
assertEquals("test ' test", par1.value());
|
||||||
|
|
||||||
RequestParameter par2 = newList.get(2);
|
RequestParameter par2 = newList.get(2);
|
||||||
assertEquals("TEXT", par2.key());
|
assertEquals("TEXT", par2.key());
|
||||||
assertEquals("%/§§%&&/%=%$/%))==/?``*''**''§?", par2.value());
|
assertEquals("%/§§%&&/%=%$/%))==/?``*''**''§?", par2.value());
|
||||||
|
|
||||||
RequestParameter par4 = newList.get(4);
|
RequestParameter par4 = newList.get(4);
|
||||||
assertEquals("NUMBER", par4.key());
|
assertEquals("NUMBER", par4.key());
|
||||||
assertEquals("-56887387394898392849", par4.value());
|
assertEquals("-56887387394898392849", par4.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user