From c3a0e3869e2b3e6ba301b40b11a3c8e9c8762064 Mon Sep 17 00:00:00 2001 From: Iakov Lysenko Date: Thu, 13 Feb 2025 23:25:47 +0300 Subject: [PATCH 1/7] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=B2=D1=80=D0=B5=D0=BC=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=20=D0=BA=20=D1=81=D0=BE=D0=BE=D0=B1=D1=89=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D1=8F=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Server/src/main/java/ru/project/ClientHandler.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Server/src/main/java/ru/project/ClientHandler.java b/Server/src/main/java/ru/project/ClientHandler.java index 2fec94d..6a8af18 100644 --- a/Server/src/main/java/ru/project/ClientHandler.java +++ b/Server/src/main/java/ru/project/ClientHandler.java @@ -6,6 +6,8 @@ import java.io.IOException; import java.net.Socket; import java.net.SocketException; +import java.text.SimpleDateFormat; +import java.util.Date; public class ClientHandler { @@ -101,7 +103,8 @@ public ClientHandler(Socket socket, Server server) throws IOException { server.kickUser(tokens[1], this); } } else { - server.broadcastMessage(username + " : " + message); + String messageWithTime = "[" + getCurrentTime() + "]" + username + " : " + message; + server.broadcastMessage(messageWithTime); } } } catch (IOException e) { @@ -158,4 +161,7 @@ public void setRole(Role role) { public Role getRole() { return role; } + private String getCurrentTime() { + return new SimpleDateFormat("HH:mm:ss").format(new Date()); + } } From a2dc16671567a8e0b9535f5e3522bf8f7f904b7e Mon Sep 17 00:00:00 2001 From: Iakov Lysenko Date: Sat, 15 Feb 2025 20:39:52 +0000 Subject: [PATCH 2/7] =?UTF-8?q?=D0=91=D0=B0=D0=BD=20=D0=BF=D0=BE=D0=BB?= =?UTF-8?q?=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8F.=20?= =?UTF-8?q?=D0=9D=D0=B0=D1=87=D0=B0=D0=BB=D0=BE=20=D1=80=D0=B0=D0=B7=D1=80?= =?UTF-8?q?=D0=B0=D0=B1=D0=BE=D1=82=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Client/src/main/java/ru/project/Client.java | 3 +++ Server/src/main/java/ru/project/ClientHandler.java | 12 +++++++++++- Server/src/main/java/ru/project/Server.java | 14 ++++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/Client/src/main/java/ru/project/Client.java b/Client/src/main/java/ru/project/Client.java index 7d6df0d..79839de 100644 --- a/Client/src/main/java/ru/project/Client.java +++ b/Client/src/main/java/ru/project/Client.java @@ -35,6 +35,9 @@ public Client() throws IOException { System.out.println("Регистрация прошла успешно! Имя пользователя: " + message.split(" ")[1]); } + if (message.equalsIgnoreCase("/banok")) { + + } } else { System.out.println(message); } diff --git a/Server/src/main/java/ru/project/ClientHandler.java b/Server/src/main/java/ru/project/ClientHandler.java index 6a8af18..3ee2899 100644 --- a/Server/src/main/java/ru/project/ClientHandler.java +++ b/Server/src/main/java/ru/project/ClientHandler.java @@ -102,7 +102,17 @@ public ClientHandler(Socket socket, Server server) throws IOException { } server.kickUser(tokens[1], this); } - } else { + } else if (message.startsWith("/ban ")) { + String[] tokens = message.split(" ", 2); + if (tokens.length != 2) { + sendMsg("Неверный формат команды /ban"); + continue; + } + server.banUser(tokens[1], this); + } + + + else { String messageWithTime = "[" + getCurrentTime() + "]" + username + " : " + message; server.broadcastMessage(messageWithTime); } diff --git a/Server/src/main/java/ru/project/Server.java b/Server/src/main/java/ru/project/Server.java index 7dd3c28..2d21912 100644 --- a/Server/src/main/java/ru/project/Server.java +++ b/Server/src/main/java/ru/project/Server.java @@ -86,6 +86,20 @@ public void kickUser(String usernameToKick, ClientHandler adminHandler) { adminHandler.sendMsg("Недостаточно прав"); } } + public void banUser(String usernameToBan, ClientHandler adminHandler) { + if (adminHandler.getRole().equals(Role.ADMIN)) { + for (ClientHandler client : client) { + if (client.getUsername().equals(usernameToBan)) { + client.sendMsg("/banok"); + broadcastMessage("Пользователь " + usernameToBan + " был забанен администратором"); + return; + } + } + adminHandler.sendMsg("Ошибка. Пользователь с ником " + usernameToBan + " не найден"); + } else { + adminHandler.sendMsg("Недостаточно прав"); + } + } public DatabaseManager getDatabaseManager() { return databaseManager; From 2e5142c94e2175decd6a901c8690446e07951c70 Mon Sep 17 00:00:00 2001 From: Iakov Lysenko Date: Sun, 16 Feb 2025 22:54:23 +0300 Subject: [PATCH 3/7] =?UTF-8?q?=D0=94=D0=BE=D1=80=D0=B0=D0=B1=D0=BE=D1=82?= =?UTF-8?q?=D0=BA=D0=B0=20=D0=B1=D0=B0=D0=BD=D0=B0=20=D0=BF=D0=BE=D0=BB?= =?UTF-8?q?=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Client/src/main/java/ru/project/Client.java | 8 ++++++-- .../src/main/java/ru/project/ClientHandler.java | 16 +++++++--------- Server/src/main/java/ru/project/Server.java | 2 +- .../ru/project/database/DatabaseManager.java | 2 +- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/Client/src/main/java/ru/project/Client.java b/Client/src/main/java/ru/project/Client.java index 79839de..04ff082 100644 --- a/Client/src/main/java/ru/project/Client.java +++ b/Client/src/main/java/ru/project/Client.java @@ -12,6 +12,7 @@ public class Client { private DataOutputStream out; private DataInputStream in; private Scanner scanner; + private boolean isBanned = false; public Client() throws IOException { scanner = new Scanner(System.in); @@ -36,7 +37,8 @@ public Client() throws IOException { + message.split(" ")[1]); } if (message.equalsIgnoreCase("/banok")) { - + isBanned = true; + System.out.println("Вы были заблокированы администратором."); } } else { System.out.println(message); @@ -52,7 +54,9 @@ public Client() throws IOException { while (!socket.isClosed()) { String message = scanner.nextLine(); try { - out.writeUTF(message); + if (!isBanned) { + out.writeUTF(message); + } else System.out.println("Вы не можете писать сообщения."); } catch (SocketException e) { System.out.println("Вы были отключены от сервера."); } diff --git a/Server/src/main/java/ru/project/ClientHandler.java b/Server/src/main/java/ru/project/ClientHandler.java index 3ee2899..1b24027 100644 --- a/Server/src/main/java/ru/project/ClientHandler.java +++ b/Server/src/main/java/ru/project/ClientHandler.java @@ -101,17 +101,15 @@ public ClientHandler(Socket socket, Server server) throws IOException { continue; } server.kickUser(tokens[1], this); + } else if (message.startsWith("/ban ")) { + String[] tokens = message.split(" ", 2); + if (tokens.length != 2) { + sendMsg("Неверный формат команды /ban"); + continue; + } + server.banUser(tokens[1], this); } - } else if (message.startsWith("/ban ")) { - String[] tokens = message.split(" ", 2); - if (tokens.length != 2) { - sendMsg("Неверный формат команды /ban"); - continue; - } - server.banUser(tokens[1], this); } - - else { String messageWithTime = "[" + getCurrentTime() + "]" + username + " : " + message; server.broadcastMessage(messageWithTime); diff --git a/Server/src/main/java/ru/project/Server.java b/Server/src/main/java/ru/project/Server.java index 2d21912..42d54c9 100644 --- a/Server/src/main/java/ru/project/Server.java +++ b/Server/src/main/java/ru/project/Server.java @@ -88,7 +88,7 @@ public void kickUser(String usernameToKick, ClientHandler adminHandler) { } public void banUser(String usernameToBan, ClientHandler adminHandler) { if (adminHandler.getRole().equals(Role.ADMIN)) { - for (ClientHandler client : client) { + for (ClientHandler client : clients) { if (client.getUsername().equals(usernameToBan)) { client.sendMsg("/banok"); broadcastMessage("Пользователь " + usernameToBan + " был забанен администратором"); diff --git a/Server/src/main/java/ru/project/database/DatabaseManager.java b/Server/src/main/java/ru/project/database/DatabaseManager.java index 77c1138..a9bb845 100644 --- a/Server/src/main/java/ru/project/database/DatabaseManager.java +++ b/Server/src/main/java/ru/project/database/DatabaseManager.java @@ -4,7 +4,7 @@ import java.sql.*; public class DatabaseManager { - private static final String DB_URL = "jdbc:postgresql://localhost:5432/postgres?currentSchema=public&user=postgres&password=admin"; + private static final String DB_URL = "jdbc:postgresql://localhost:5432/postgres?currentSchema=public&user=postgres&password=postgres"; public DatabaseManager() { From 002f4f4214953da755662c7dcfd33d3f38eb508f Mon Sep 17 00:00:00 2001 From: Iakov Lysenko Date: Sun, 16 Feb 2025 22:56:21 +0300 Subject: [PATCH 4/7] =?UTF-8?q?=D0=A7=D0=B8=D1=81=D1=82=D0=BA=D0=B0=20?= =?UTF-8?q?=D0=BA=D0=BE=D0=B4=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/ru/project/ClientHandler.java | 33 ++++++++++--------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/Server/src/main/java/ru/project/ClientHandler.java b/Server/src/main/java/ru/project/ClientHandler.java index 1b24027..22ff6de 100644 --- a/Server/src/main/java/ru/project/ClientHandler.java +++ b/Server/src/main/java/ru/project/ClientHandler.java @@ -2,19 +2,17 @@ import java.io.DataInputStream; import java.io.DataOutputStream; -import java.io.EOFException; import java.io.IOException; import java.net.Socket; -import java.net.SocketException; import java.text.SimpleDateFormat; import java.util.Date; public class ClientHandler { - private Socket socket; - private Server server; - private DataInputStream in; - private DataOutputStream out; + private final Socket socket; + private final Server server; + private final DataInputStream in; + private final DataOutputStream out; private String username; private Role role; @@ -29,10 +27,11 @@ public ClientHandler(Socket socket, Server server) throws IOException { System.out.println("Клиент подключился " + socket.getPort()); //Цикл логина while (true) { - sendMsg("Для начала работы надо пройти аутентификацию или регистрацию\n" + - "Формат команды для аутентификации: /log\n" + - "Формат команды для регистрации: /reg\n" + - "Для выхода используйте комманду /exit"); + sendMsg(""" + Для начала работы надо пройти аутентификацию или регистрацию + Формат команды для аутентификации: /log + Формат команды для регистрации: /reg + Для выхода используйте комманду /exit"""); String message = in.readUTF(); if (message.startsWith("/")) { if (message.equals("/exit")) { @@ -55,13 +54,15 @@ public ClientHandler(Socket socket, Server server) throws IOException { } if (message.equalsIgnoreCase("/reg")) { String[] regData = new String[3]; - sendMsg("Введите никнейм.\n" + - "Никнейм не должен содержать более 20 символов, и не менее 5 символов\n" + - "Можно использовать цифры, латинские буквы и знаки \"_\" и \"-\""); + sendMsg(""" + Введите никнейм. + Никнейм не должен содержать более 20 символов, и не менее 5 символов + Можно использовать цифры, латинские буквы и знаки "_" и "-\""""); regData[0] = in.readUTF(); - sendMsg("Введите логин.\n" + - "Логин не должен содержать более 20 символов, и не менее 5 символов\n" + - "Можно использовать цифры, латинские буквы и знаки \"_\" и \"-\""); + sendMsg(""" + Введите логин. + Логин не должен содержать более 20 символов, и не менее 5 символов + Можно использовать цифры, латинские буквы и знаки "_" и "-\""""); regData[1] = in.readUTF(); sendMsg("Введите пароль.\n" + "Пароль должен содержать от 5 до 20 символов и обязательно включать в себя любой специальный символ."); From 77a5cf3d6709c8a52b06dc0710ba1b8cc7cbf22e Mon Sep 17 00:00:00 2001 From: Iakov Lysenko Date: Sun, 16 Feb 2025 23:07:18 +0300 Subject: [PATCH 5/7] =?UTF-8?q?=D0=A2=D0=B5=D0=BF=D0=B5=D1=80=D1=8C=20?= =?UTF-8?q?=D0=BC=D0=BE=D0=B6=D0=BD=D0=BE=20=D1=80=D0=B0=D0=B7=D0=B1=D0=B0?= =?UTF-8?q?=D0=BD=D0=B8=D1=82=D1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Client/src/main/java/ru/project/Client.java | 4 ++++ Server/src/main/java/ru/project/ClientHandler.java | 13 +++++++++++++ Server/src/main/java/ru/project/Server.java | 14 ++++++++++++++ 3 files changed, 31 insertions(+) diff --git a/Client/src/main/java/ru/project/Client.java b/Client/src/main/java/ru/project/Client.java index 04ff082..5d7f515 100644 --- a/Client/src/main/java/ru/project/Client.java +++ b/Client/src/main/java/ru/project/Client.java @@ -40,6 +40,10 @@ public Client() throws IOException { isBanned = true; System.out.println("Вы были заблокированы администратором."); } + if (message.equalsIgnoreCase("/unbanok")) { + isBanned = false; + System.out.println("Теперь вы не заблокированы. Вам доступна отправка сообщений в чат."); + } } else { System.out.println(message); } diff --git a/Server/src/main/java/ru/project/ClientHandler.java b/Server/src/main/java/ru/project/ClientHandler.java index 22ff6de..9a87e62 100644 --- a/Server/src/main/java/ru/project/ClientHandler.java +++ b/Server/src/main/java/ru/project/ClientHandler.java @@ -82,6 +82,7 @@ public ClientHandler(Socket socket, Server server) throws IOException { //Цикл работы while (true) { String message = in.readUTF(); + boolean targetUserIsBanned = false; if (message.startsWith("/")) { if (message.equalsIgnoreCase("/exit")) { sendMsg("/exitok"); @@ -109,6 +110,18 @@ public ClientHandler(Socket socket, Server server) throws IOException { continue; } server.banUser(tokens[1], this); + targetUserIsBanned = true; + } else if (message.startsWith("/unban ")) { + String[] tokens = message.split(" ", 2); + if (tokens.length != 2) { + sendMsg("Неверный формат комманды /unban"); + continue; + } + if (targetUserIsBanned) { + server.unbanUser(tokens[1], this); + targetUserIsBanned = false; + } else sendMsg("Пользователь " + tokens[1] + " не находится в бане"); + } } else { diff --git a/Server/src/main/java/ru/project/Server.java b/Server/src/main/java/ru/project/Server.java index 42d54c9..979ae3b 100644 --- a/Server/src/main/java/ru/project/Server.java +++ b/Server/src/main/java/ru/project/Server.java @@ -100,6 +100,20 @@ public void banUser(String usernameToBan, ClientHandler adminHandler) { adminHandler.sendMsg("Недостаточно прав"); } } + public void unbanUser(String usernameToUnban, ClientHandler adminHandler) { + if (adminHandler.getRole().equals(Role.ADMIN)) { + for (ClientHandler client : clients) { + if (client.getUsername().equals(usernameToUnban)) { + client.sendMsg("/unbanok"); + broadcastMessage("Пользователь " + usernameToUnban + " был разбанен администратором"); + return; + } + } + adminHandler.sendMsg("Ошибка. Пользователь с ником " + usernameToUnban + " не найден"); + } else { + adminHandler.sendMsg("Недостаточно прав"); + } + } public DatabaseManager getDatabaseManager() { return databaseManager; From fb7970e4d39c0708a649bfec24721b538c696e30 Mon Sep 17 00:00:00 2001 From: Iakov Lysenko Date: Tue, 18 Feb 2025 22:03:00 +0300 Subject: [PATCH 6/7] =?UTF-8?q?=D0=9F=D1=80=D0=BE=D0=B2=D0=B5=D1=80=D0=BA?= =?UTF-8?q?=D0=B0=20=D0=BF=D0=BE=D1=81=D0=BB=D0=B5=D0=B4=D0=BD=D0=B5=D0=B9?= =?UTF-8?q?=20=D0=B0=D0=BA=D1=82=D0=B8=D0=B2=D0=BD=D0=BE=D1=81=D1=82=D0=B8?= =?UTF-8?q?=20=D0=B8=20=D0=B8=D0=BA=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D0=B5=20=D0=BD=D0=B5=D0=B0=D0=BA=D1=82=D0=B8=D0=B2=D0=BD=D1=8B?= =?UTF-8?q?=D1=85=20=D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=82?= =?UTF-8?q?=D0=B5=D0=BB=D0=B5=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/ru/project/ClientHandler.java | 10 +++++- Server/src/main/java/ru/project/Server.java | 14 ++++++++ .../java/ru/project/checktime/CheckTime.java | 35 +++++++++++++++++++ 3 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 Server/src/main/java/ru/project/checktime/CheckTime.java diff --git a/Server/src/main/java/ru/project/ClientHandler.java b/Server/src/main/java/ru/project/ClientHandler.java index c86d631..cdcb595 100644 --- a/Server/src/main/java/ru/project/ClientHandler.java +++ b/Server/src/main/java/ru/project/ClientHandler.java @@ -15,12 +15,14 @@ public class ClientHandler { private final DataOutputStream out; private String username; private Role role; + private long lastActiveTime; public ClientHandler(Socket socket, Server server) throws IOException { this.socket = socket; this.server = server; this.in = new DataInputStream(socket.getInputStream()); this.out = new DataOutputStream(socket.getOutputStream()); + this.lastActiveTime = System.currentTimeMillis(); new Thread(() -> { try { @@ -121,7 +123,9 @@ public ClientHandler(Socket socket, Server server) throws IOException { server.unbanUser(tokens[1], this); targetUserIsBanned = false; } else sendMsg("Пользователь " + tokens[1] + " не находится в бане"); - } + } else if (message.equalsIgnoreCase("/online")) { + sendMsg(server.getOnlineUsers()); + } } else { String messageWithTime = "[" + getCurrentTime() + "]" + username + " : " + message; @@ -185,4 +189,8 @@ public Role getRole() { private String getCurrentTime() { return new SimpleDateFormat("HH:mm:ss").format(new Date()); } + + public long getLastActiveTime() { + return lastActiveTime; + } } diff --git a/Server/src/main/java/ru/project/Server.java b/Server/src/main/java/ru/project/Server.java index 5dfe3f3..40a4f29 100644 --- a/Server/src/main/java/ru/project/Server.java +++ b/Server/src/main/java/ru/project/Server.java @@ -1,5 +1,6 @@ package ru.project; +import ru.project.checktime.CheckTime; import ru.project.database.DatabaseManager; import javax.xml.crypto.Data; @@ -21,6 +22,8 @@ public Server(int port, DatabaseManager databaseManager) { this.databaseManager = databaseManager; clients = new CopyOnWriteArrayList<>(); authenticator = new inMemoryAuthenticator(this); + + new CheckTime(this).start(); } public void start(){ @@ -117,4 +120,15 @@ public void unbanUser(String usernameToUnban, ClientHandler adminHandler) { public DatabaseManager getDatabaseManager() { return databaseManager; } + + public String getOnlineUsers() { + StringBuilder sb = new StringBuilder("Сейчас онлайн:\n"); + for (ClientHandler client : clients) { + sb.append(client.getUsername()).append("\n"); + } + return sb.toString(); + } + public List getClients() { + return this.clients; + } } diff --git a/Server/src/main/java/ru/project/checktime/CheckTime.java b/Server/src/main/java/ru/project/checktime/CheckTime.java new file mode 100644 index 0000000..3af8b5c --- /dev/null +++ b/Server/src/main/java/ru/project/checktime/CheckTime.java @@ -0,0 +1,35 @@ +package ru.project.checktime; + +import ru.project.*; + +import java.util.ArrayList; + +public class CheckTime extends Thread { + private static final long TIMEOUT = 20 * 60 * 1000; + private Server server; + private ClientHandler clientHandler; + + public CheckTime(Server server) { + this.server = server; + } + @Override + public void run() { + while (true) { + try { + Thread.sleep(60*1000); + long currentTime = System.currentTimeMillis(); + + for (ClientHandler client : server.getClients()) { + if (currentTime - client.getLastActiveTime() > TIMEOUT) { + System.out.println("Отключение неактивного клиента: " + client.getUsername()); + client.sendMsg("/exitok"); + server.unsubscribe(client); + client.disconnect(); + } + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } +} From 496cdd64bac1828baab790663f3b71c0bf6df86f Mon Sep 17 00:00:00 2001 From: iakovlysenko Date: Wed, 19 Feb 2025 23:29:42 +0300 Subject: [PATCH 7/7] =?UTF-8?q?=D0=98=D0=BD=D1=82=D0=B5=D1=80=D1=84=D0=B5?= =?UTF-8?q?=D0=B9=D1=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/ru/project/ChatClientGUI.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 Client/src/main/java/ru/project/ChatClientGUI.java diff --git a/Client/src/main/java/ru/project/ChatClientGUI.java b/Client/src/main/java/ru/project/ChatClientGUI.java new file mode 100644 index 0000000..2f31496 --- /dev/null +++ b/Client/src/main/java/ru/project/ChatClientGUI.java @@ -0,0 +1,27 @@ +package ru.project; +import javafx.application.Application; +import javafx.scene.Scene; +import javafx.scene.control.Button; +import javafx.scene.control.TextField; +import javafx.scene.layout.VBox; +import javafx.stage.Stage; + +public class ChatClientGUI extends Application { + + @Override + public void start(Stage primaryStage) { + TextField inputField = new TextField(); + inputField.setPromptText("Введите сообщение..."); + Button sendButton = new Button("Отправить"); + VBox root = new VBox(10, inputField, sendButton); + Scene scene = new Scene(root, 400, 300); + + primaryStage.setTitle("Чат-клиент"); + primaryStage.setScene(scene); + primaryStage.show(); + } + + public static void main(String[] args) { + launch(args); + } +}