From 5401ead19815b406bcaeb3b6a053f92be162bda3 Mon Sep 17 00:00:00 2001 From: Mathis Ginkel Date: Sun, 15 Mar 2026 22:31:10 +0100 Subject: [PATCH 1/3] add: Network Protocol docs --- .../Network-Protocol-Documentation.md | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 documents/docs/networking/Network-Protocol-Documentation.md diff --git a/documents/docs/networking/Network-Protocol-Documentation.md b/documents/docs/networking/Network-Protocol-Documentation.md new file mode 100644 index 0000000..7099c7e --- /dev/null +++ b/documents/docs/networking/Network-Protocol-Documentation.md @@ -0,0 +1,63 @@ +This Document states the Network-Protocol as it is currently implemented + +## GET_MESSAGE_COUNT +This Command gets the number of messages, currently stored in the queue for the specific client. +(Is used together with GET_NEXT_MESSAGE, to get all messages that are currently in the queue) + +Example: + +``` +GET_MESSAGE_COUNT + +1 ++OK +``` + +## GET_NEXT_MESSAGE +This Command gets the next Message that is being stored in the queue for the client. +(Command is being sent the amount of times, the GET_MESSAGE_COUNT Command returns) + +Example: + +``` +GET_NEXT_MESSAGE + +TYPE=LOBBY GAME=1 USER=player1 TARGET=null TIME=9:30 TEXT="Guten Tag" ++OK +``` + +## SEND_MESSAGE +This Command gets sent if the user of that client writes a message to one of the three possible chats + +(The Arguments / Parameters of the Command describe all the parameters of the Object "Message" being used internally by both the Client and the Server) + +Example: +``` +SEND_MESSAGE TYPE=LOBBY GAME=1 USER=player1 TARGET=null TIME=10:30 TEXT="Hallo Welt" + ++OK +``` + +## LOG_IN +This Command is used to create a user on the server and associate that user with a username +Server returns the username, slightly changed if it is already used by someone else, and an ID to identify the client. + +Example: + +``` +LOG_IN USERNAME="Peter" + +USERNAME="Peter" ID= ++OK +``` + +## LOG_OUT +This Command is used to quit the connection between client and server. + +Example: + +``` +LOG_OUT + ++OK +``` From cc33411911db3c10f5ce159f7c51b286f1a8179c Mon Sep 17 00:00:00 2001 From: Mathis Ginkel Date: Thu, 2 Apr 2026 10:20:03 +0200 Subject: [PATCH 2/3] Add: basic chat functionality --- .../casono/client/chat/ChatController.java | 62 ++++++ .../cs108/casono/client/chat/ChatModel.java | 67 ++++++ .../cs108/casono/client/chat/Message.java | 136 ++++++++++++ .../casono/client/network/ClientService.java | 210 ++++++++++++++++++ .../client/ui/chatui/ChatController.java | 85 ------- .../client/ui/chatui/ChatViewController.java | 87 ++++++++ .../gameuicomponents/chatui/chatbox.fxml | 58 +++++ .../gameuicomponents/chatui/chatui.css | 155 +++++++++++++ .../client/chat/ChatControllerTest.java | 28 +++ 9 files changed, 803 insertions(+), 85 deletions(-) create mode 100644 src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/chat/ChatController.java create mode 100644 src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/chat/ChatModel.java create mode 100644 src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/chat/Message.java create mode 100644 src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/network/ClientService.java delete mode 100644 src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/ui/chatui/ChatController.java create mode 100644 src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/ui/chatui/ChatViewController.java create mode 100644 src/main/resources/ui-structure/gameuicomponents/chatui/chatbox.fxml create mode 100644 src/main/resources/ui-structure/gameuicomponents/chatui/chatui.css create mode 100644 src/test/java/ch/unibas/dmi/dbis/cs108/casono/client/chat/ChatControllerTest.java diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/chat/ChatController.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/chat/ChatController.java new file mode 100644 index 0000000..ac2bb0e --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/chat/ChatController.java @@ -0,0 +1,62 @@ +package ch.unibas.dmi.dbis.cs108.casono.client.chat; + +import ch.unibas.dmi.dbis.cs108.casono.client.network.ClientService; +import java.util.List; + +/** + * responsible for the transferring of messages from the server to the ChatModel + * or from the ChatViewController to the server + */ +public class ChatController { + + private final String username; + private final ClientService clientService; + + private ChatModel chatModel; + + private int game_id; + + public ChatController(String username, ClientService clientService) { + this.username = username; + this.clientService = clientService; + } + + public void createChat(int game_id) { + chatModel = new ChatModel(ChatModel.ChatType.GLOBAL, username); + this.game_id = game_id; + } + + public ChatModel getChatModel() { + return chatModel; + } + + /** + * method to send a message, the ChatViewController received to the server + */ + public void sendMessage(String msg, String username) { + Message message = new Message(Message.MessageType.GLOBAL, 0, username, null, msg); + onSendToNetwork(message); + } + + /** + * method to get all messages from the server + */ + public Boolean receiveMessage() { + List newMessages = clientService.getMessages(); + if (!newMessages.isEmpty()) { + for (Message msg : newMessages) { + chatModel.addMessage(msg); + } + return true; + } else { return false; } + } + + /** + * method to send a message to the server + * @param message + */ + public void onSendToNetwork(Message message) { + clientService.sendMessage(message); + } + +} diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/chat/ChatModel.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/chat/ChatModel.java new file mode 100644 index 0000000..0c2f075 --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/chat/ChatModel.java @@ -0,0 +1,67 @@ +package ch.unibas.dmi.dbis.cs108.casono.client.chat; + +import java.util.ArrayList; + +/** + * ChatModel, stores the data for a specific chat + * + * Holds the current state of a chat + */ + +public class ChatModel { + + public ArrayList messages; + + public ChatType chattype; + + public String username; + + public int count; + + public enum ChatType { + GLOBAL, + LOBBY, + WHISPER + } + + /** + * Creates a new ChatModel, given a username of the client + * @param chattype + * @param username + */ + + public ChatModel(ChatType chattype, String username) { + this.messages = new ArrayList(); + this.chattype = chattype; + this.username = username; + this.count = 0; + } + + /** + * method, used by the ChatViewController, to access all new messages, that are stored in the ChatModel + */ + public synchronized String viewNextMessage() { + count--; + Message msg = messages.getLast(); + return String.format("[%s] %s: %s", msg.timestamp, msg.user, msg.getMessage()); + } + + /** + * Adds a new message + * method used by the ChatController + * @param msg + */ + public synchronized void addMessage(Message msg) { + messages.add(msg); + count++; + } + + /** + * method to send all current messages to the ChatViewController, if needed + */ + public void addCompleteChat() { + for (int i = 0; i < this.messages.size(); i++) { + Message msg = this.messages.get(i); + } + } +} diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/chat/Message.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/chat/Message.java new file mode 100644 index 0000000..8fb2b0e --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/chat/Message.java @@ -0,0 +1,136 @@ +package ch.unibas.dmi.dbis.cs108.casono.client.chat; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Message Object for internal handling of Chat-Messages + * TODO: Should be used on both sides of the network + */ + +public class Message { + private final MessageType type; + private final String message; + public String user; + public String timestamp; + public int game_id = 0; + public String target = null; + public enum MessageType { + GLOBAL, LOBBY, WHISPER + }; + + /** + * Constructor for creating Messages with all information given + * @param type - Either global, local or whisper + * @param game_id - lobby id, or null, if the type is global + * @param user - username + * @param target - username of the target user, for whisper chat + * @param message + */ + + public Message(MessageType type, int game_id, String user, String target, String timestamp, String message) { + this.type = type; + this.game_id = game_id; + this.user = user; + this.target = target; + this.timestamp = timestamp; + this.message = message; + } + + /** + * Constructor for creating the Messages of the current user, using this client -> time of writing is being recorded + * @param type - Either global, local or whisper + * @param game_id - lobby id, or null, if the type is global + * @param user - username + * @param target - username of the target user, for whisper chat + * @param message + */ + + public Message(MessageType type, int game_id, String user, String target, String message) { + this.type = type; + this.game_id = game_id; + this.user = user; + this.target = target; + this.message = message; + LocalDateTime now = LocalDateTime.now(); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm"); + this.timestamp = now.format(formatter); + } + + + public String getMessage() { + return message; + } + + public MessageType getMessageType() { + return type; + } + + /* + * Method to test the system + * @return - String representation of the Message instance, as for example "player1: Hello World" + + public String toString() { + return String.format("%s: %s", this.user, this.message); + } + */ + /** + * Method to create the request representation of the message object, to be sent to the server + * @return - request as specified in the network protocol, as String + */ + public String toArgsString() { + return String.format("TYPE=%s GAME=%d USER=%s TARGET=%s TIME=%s TEXT=%s", + this.type.toString(), this.game_id, this.user, this.target, this.timestamp, this.message); + } + + + /** + * Pattern, to analyze the response String with the given parameters + */ + public static Pattern msgRex = Pattern.compile( + "TYPE=(?\\w+) GAME=(?\\w+) USER=(?\\w+) TARGET=(?\\w+) TIME=(?