diff --git a/.idea/intellij-javadocs-4.0.1.xml b/.idea/intellij-javadocs-4.0.1.xml
new file mode 100644
index 0000000..dd24abe
--- /dev/null
+++ b/.idea/intellij-javadocs-4.0.1.xml
@@ -0,0 +1,204 @@
+
+
+
+
+ UPDATE
+ false
+ true
+
+ FIELD
+ METHOD
+ TYPE
+
+
+ PROTECTED
+ DEFAULT
+ PUBLIC
+
+
+
+
+
+ ^.*(public|protected|private)*.+interface\s+\w+.*
+ /**\n
+ * The interface ${name}.\n
+<#if element.typeParameters?has_content> * \n
+</#if>
+<#list element.typeParameters as typeParameter>
+ * @param <${typeParameter.name}> the type parameter\n
+</#list>
+ */
+
+
+ ^.*(public|protected|private)*.+enum\s+\w+.*
+ /**\n
+ * The enum ${name}.\n
+ */
+
+
+ ^.*(public|protected|private)*.+class\s+\w+.*
+ /**\n
+ * The type ${name}.\n
+<#if element.typeParameters?has_content> * \n
+</#if>
+<#list element.typeParameters as typeParameter>
+ * @param <${typeParameter.name}> the type parameter\n
+</#list>
+ */
+
+
+ .+
+ /**\n
+ * The type ${name}.\n
+ */
+
+
+
+
+ .+
+ /**\n
+ * Instantiates a new ${name}.\n
+<#if element.parameterList.parameters?has_content>
+ *\n
+</#if>
+<#list element.parameterList.parameters as parameter>
+ * @param ${parameter.name} the ${paramNames[parameter.name]}\n
+</#list>
+<#if element.throwsList.referenceElements?has_content>
+ *\n
+</#if>
+<#list element.throwsList.referenceElements as exception>
+ * @throws ${exception.referenceName} the ${exceptionNames[exception.referenceName]}\n
+</#list>
+ */
+
+
+
+
+ ^.*(public|protected|private)*\s*.*(\w(\s*<.+>)*)+\s+get\w+\s*\(.*\).+
+ /**\n
+ * Gets ${partName}.\n
+<#if element.typeParameters?has_content> * \n
+</#if>
+<#list element.typeParameters as typeParameter>
+ * @param <${typeParameter.name}> the type parameter\n
+</#list>
+<#if element.parameterList.parameters?has_content>
+ *\n
+</#if>
+<#list element.parameterList.parameters as parameter>
+ * @param ${parameter.name} the ${paramNames[parameter.name]}\n
+</#list>
+<#if isNotVoid>
+ *\n
+ * @return the ${partName}\n
+</#if>
+<#if element.throwsList.referenceElements?has_content>
+ *\n
+</#if>
+<#list element.throwsList.referenceElements as exception>
+ * @throws ${exception.referenceName} the ${exceptionNames[exception.referenceName]}\n
+</#list>
+ */
+
+
+ ^.*(public|protected|private)*\s*.*(void|\w(\s*<.+>)*)+\s+set\w+\s*\(.*\).+
+ /**\n
+ * Sets ${partName}.\n
+<#if element.typeParameters?has_content> * \n
+</#if>
+<#list element.typeParameters as typeParameter>
+ * @param <${typeParameter.name}> the type parameter\n
+</#list>
+<#if element.parameterList.parameters?has_content>
+ *\n
+</#if>
+<#list element.parameterList.parameters as parameter>
+ * @param ${parameter.name} the ${paramNames[parameter.name]}\n
+</#list>
+<#if isNotVoid>
+ *\n
+ * @return the ${partName}\n
+</#if>
+<#if element.throwsList.referenceElements?has_content>
+ *\n
+</#if>
+<#list element.throwsList.referenceElements as exception>
+ * @throws ${exception.referenceName} the ${exceptionNames[exception.referenceName]}\n
+</#list>
+ */
+
+
+ ^.*((public\s+static)|(static\s+public))\s+void\s+main\s*\(\s*String\s*(\[\s*\]|\.\.\.)\s+\w+\s*\).+
+ /**\n
+ * The entry point of application.\n
+
+ <#if element.parameterList.parameters?has_content>
+ *\n
+</#if>
+ * @param ${element.parameterList.parameters[0].name} the input arguments\n
+<#if element.throwsList.referenceElements?has_content>
+ *\n
+</#if>
+<#list element.throwsList.referenceElements as exception>
+ * @throws ${exception.referenceName} the ${exceptionNames[exception.referenceName]}\n
+</#list>
+ */
+
+
+ .+
+ /**\n
+ * ${name}<#if isNotVoid> ${return}</#if>.\n
+<#if element.typeParameters?has_content> * \n
+</#if>
+<#list element.typeParameters as typeParameter>
+ * @param <${typeParameter.name}> the type parameter\n
+</#list>
+<#if element.parameterList.parameters?has_content>
+ *\n
+</#if>
+<#list element.parameterList.parameters as parameter>
+ * @param ${parameter.name} the ${paramNames[parameter.name]}\n
+</#list>
+<#if isNotVoid>
+ *\n
+ * @return the ${return}\n
+</#if>
+<#if element.throwsList.referenceElements?has_content>
+ *\n
+</#if>
+<#list element.throwsList.referenceElements as exception>
+ * @throws ${exception.referenceName} the ${exceptionNames[exception.referenceName]}\n
+</#list>
+ */
+
+
+
+
+ ^.*(public|protected|private)*.+static.*(\w\s\w)+.+
+ /**\n
+ * The constant ${element.getName()}.\n
+ */
+
+
+ ^.*(public|protected|private)*.*(\w\s\w)+.+
+ /**\n
+ <#if element.parent.isInterface()>
+ * The constant ${element.getName()}.\n
+<#else>
+ * The ${name}.\n
+</#if> */
+
+
+ .+
+ /**\n
+ <#if element.parent.isEnum()>
+ *${name} ${typeName}.\n
+<#else>
+ * The ${name}.\n
+</#if>*/
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
index 2b63946..c63e975 100644
--- a/.idea/uiDesigner.xml
+++ b/.idea/uiDesigner.xml
@@ -11,9 +11,6 @@
-
- -
-
-
-
@@ -38,6 +35,9 @@
+ -
+
+
-
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index 13c4130..ed49456 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -2,17 +2,26 @@
-
-
-
-
-
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -31,6 +40,92 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -42,26 +137,27 @@
- {
- "keyToString": {
- "Downloaded.Files.Path.Enabled": "false",
- "Repository.Attach.Annotations": "false",
- "Repository.Attach.JavaDocs": "false",
- "Repository.Attach.Sources": "false",
- "RunOnceActivity.OpenProjectViewOnStart": "true",
- "RunOnceActivity.ShowReadmeOnStart": "true",
- "WebServerToolWindowFactoryState": "false",
- "codeWithMe.voiceChat.enabledByDefault": "false",
- "com.intellij.testIntegration.createTest.CreateTestDialog.defaultLibrary": "JUnit5",
- "com.intellij.testIntegration.createTest.CreateTestDialog.defaultLibrarySuperClass.JUnit5": "",
- "create.test.in.the.same.root": "true",
- "last_opened_file_path": "/Users/lucas/Documents/GitHub/projet-mini-chat/src/serveur",
- "project.structure.last.edited": "Modules",
- "project.structure.proportion": "0.15",
- "project.structure.side.proportion": "0.2",
- "settings.editor.selected.configurable": "preferences.lookFeel"
+
+}]]>
@@ -77,7 +173,20 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -143,37 +252,21 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
+
+
-
-
@@ -189,6 +282,7 @@
+
@@ -206,4 +300,8 @@
+
+
+
+
\ No newline at end of file
diff --git a/src/client/Client.java b/src/client/Client.java
index 6be4bf1..424d944 100644
--- a/src/client/Client.java
+++ b/src/client/Client.java
@@ -1,3 +1,9 @@
+/*
+ * Client.java, 06/12/2022
+ * INU Champollion, 2022-2023
+ * pas de copyright, aucun droits
+ */
+
package client;
import ui.FenetreClient;
@@ -5,7 +11,6 @@ import ui.FenetreErreur;
import utils.RSA;
import utils.ResolutionDeNom;
-import javax.swing.*;
import java.io.EOFException;
import java.io.IOException;
import java.io.ObjectInputStream;
@@ -18,22 +23,50 @@ import java.util.ArrayList;
import java.util.Objects;
import java.util.Scanner;
+/**
+ * Utilisateur Client
+ *
+ * @author Gaël Burguès
+ * @author Laurian Dufrechou
+ * @author Lucàs Vabre
+ */
+
public class Client extends Thread{
+ //elements d'un client
private final String SERVER_IP;
private final int SERVER_PORT;
private final FenetreClient fenetre;
private String pseudo;
-
- private final Scanner scanner;
private KeyPair clientKeys;
private PublicKey serverKey;
+ private final Scanner scanner;
+
+ // Sockets de connexion
private ObjectInputStream inputStream;
private ObjectOutputStream outputStream;
private ArrayList fileAttenteMessage;
+ public Client(String ip, int port) {
+ this.SERVER_IP = ResolutionDeNom.getIPAddress(ip);
+ this.SERVER_PORT = port;
+ this.pseudo = null;
+ this.fenetre = null;
+
+ this.scanner = new Scanner(System.in);
+ this.clientKeys = RSA.genererCle();
+
+ this.fileAttenteMessage = new ArrayList<>();
+ }
+
+ /**
+ * ancien object client sans fenetre
+ * @param ip adresse ip du client
+ * @param port numeros de port du client
+ * @param pseudo pseudo du client
+ */
public Client(String ip, int port, String pseudo) {
this.SERVER_IP = ResolutionDeNom.getIPAddress(ip);
this.SERVER_PORT = port;
@@ -46,6 +79,13 @@ public class Client extends Thread{
this.fileAttenteMessage = new ArrayList<>();
}
+ /**
+ * Object client actuel
+ * @param ip adresse ip du client
+ * @param port numeros de port du client
+ * @param pseudo nom du client
+ * @param fenetre fenetreClient assicié au client
+ */
public Client(String ip, int port, String pseudo, FenetreClient fenetre) {
this.SERVER_IP = ResolutionDeNom.getIPAddress(ip);
this.SERVER_PORT = port;
@@ -103,6 +143,11 @@ public class Client extends Thread{
}
}
+ /**
+ * envoie la clef client au serveur
+ * @throws IOException
+ * @throws ClassNotFoundException
+ */
public void exchangeKeys() throws IOException, ClassNotFoundException {
// Envoie sa clé
outputStream.writeObject(clientKeys.getPublic());
@@ -111,11 +156,22 @@ public class Client extends Thread{
serverKey = (PublicKey) inputStream.readObject();
}
+ /**
+ * envoie un message dans la socket
+ * @param message message a envoyer au serveur
+ * @throws IOException
+ */
public void sendMessage(String message) throws IOException {
byte[] messageCrypte = RSA.encrypter(message, serverKey);
outputStream.writeObject(messageCrypte);
}
+ /**
+ * Recupere un message evoye par le serveur
+ * @return
+ * @throws IOException
+ * @throws ClassNotFoundException
+ */
public String getMessage() throws IOException, ClassNotFoundException {
byte[] messageCrypte = (byte[]) inputStream.readObject();
return RSA.decrypter(messageCrypte, clientKeys.getPrivate());
@@ -123,7 +179,7 @@ public class Client extends Thread{
/**
* Ajoute un message à la file d'attente
- * @param message
+ * @param message messsage a ajouter a la file
*/
public void addMessage(String message) {
this.fileAttenteMessage.add(message);
diff --git a/src/client/ListenThread.java b/src/client/ListenThread.java
index 434bb92..1c3ed25 100644
--- a/src/client/ListenThread.java
+++ b/src/client/ListenThread.java
@@ -1,3 +1,9 @@
+/*
+ * ListenThread.java, 06/12/2022
+ * INU Champollion, 2022-2023
+ * pas de copyright, aucun droits
+ */
+
package client;
import ui.FenetreClient;
@@ -8,18 +14,36 @@ import java.io.IOException;
import java.net.SocketException;
/**
- * Thread for clients
+ * Écoute des messages du serveur
+ *
+ * @author Gaël Burguès
+ * @author Laurian Dufrechou
+ * @author Lucàs Vabre
*/
public class ListenThread extends Thread {
+ /** Instance du client */
private final Client client;
+
+ /** Interface utilisateur du client */
private final FenetreClient fenetre;
+ /**
+ * Crée un nouveau thread
+ *
+ * @param client Le client lié à cette écoute
+ */
public ListenThread(Client client) {
this.client = client;
this.fenetre = null;
}
+ /**
+ * Object d'ecoute avec fenetre
+ *
+ * @param client client associe à l'ecoute
+ * @param fenetre fenetreClient associe à l'ecoute
+ */
public ListenThread(Client client, FenetreClient fenetre) {
this.client = client;
this.fenetre = fenetre;
@@ -45,7 +69,7 @@ public class ListenThread extends Thread {
new FenetreErreur("Connexion perdue", fenetre);
fenetre.deconnexion();
}
- }catch (IOException | ClassNotFoundException e) {
+ } catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
diff --git a/src/server/Server.java b/src/server/Server.java
index e95d53f..986ecb1 100644
--- a/src/server/Server.java
+++ b/src/server/Server.java
@@ -1,3 +1,9 @@
+/*
+ * Server.java, 06/12/2022
+ * INU Champollion, 2022-2023
+ * pas de copyright, aucun droits
+ */
+
package server;
import ui.FenetreServeur;
@@ -6,19 +12,47 @@ import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
-public class Server extends Thread{
+/**
+ * serveur
+ *
+ * @author Gaël Burguès
+ * @author Laurian Dufrechou
+ * @author Lucàs Vabre
+ */
+public class Server extends Thread {
+ /**
+ * Le port de connexion du serveur
+ */
private final int PORT;
+
+ /**
+ * La liste des threads, connexion aux clients
+ */
private final ArrayList threads;
+
+ /**
+ * Interface graphique du serveur
+ */
private final FenetreServeur fenetre;
+ /**
+ * Crée un nouveau serveur qui n'est pas lié à une interface
+ *
+ * @param port Numéro de port du serveur
+ */
public Server(int port) {
this.PORT = port;
this.threads = new ArrayList<>();
-
this.fenetre = null;
}
+ /**
+ * Crée un nouveau serveur lié à une interface
+ *
+ * @param port Numéros de port du serveur
+ * @param fenetre Interface utilisateur du serveur
+ */
public Server(int port, FenetreServeur fenetre) {
this.PORT = port;
this.fenetre = fenetre;
@@ -33,14 +67,15 @@ public class Server extends Thread{
fenetre.displayNewMessage(msg);
while (true) {
- Socket socket = serversocket.accept();
+ Socket socket = serversocket.accept(); // Une nouvelle connexion !
+ // Messages
String connexionMessage = String.format("Nouvelle connexion : %s\n", socket);
System.out.printf(connexionMessage);
- fenetre.displayNewMessage(connexionMessage);
+ if (fenetre != null) fenetre.displayNewMessage(connexionMessage);
+ // Crée le thread d'écoute du client et l'ajoute dans la liste et le démarre
ThreadServer thread = new ThreadServer(socket, threads, fenetre);
-
threads.add(thread);
thread.start();
}
@@ -48,9 +83,4 @@ public class Server extends Thread{
e.printStackTrace();
}
}
-
- public static void main(String[] args) {
- Server serveur = new Server(4444);
- serveur.start();
- }
}
diff --git a/src/server/ThreadServer.java b/src/server/ThreadServer.java
index 0edb559..e8ab1c5 100644
--- a/src/server/ThreadServer.java
+++ b/src/server/ThreadServer.java
@@ -1,3 +1,9 @@
+/*
+ * ThreadServer.java, 06/12/2022
+ * INU Champollion, 2022-2023
+ * pas de copyright, aucun droits
+ */
+
package server;
import ui.FenetreServeur;
@@ -10,17 +16,55 @@ import java.security.PublicKey;
import java.util.ArrayList;
import java.util.Objects;
+/**
+ * Thread dédié à l'écoute de message venant d'un client
+ *
+ * @author Gaël Burguès
+ * @author Laurian Dufrechou
+ * @author Lucàs Vabre
+ * @see Thread
+ */
public class ThreadServer extends Thread {
+ /**
+ * Référence des autres threads entre le serveur et d'autres clients
+ */
private final ArrayList threads;
+
+ /**
+ * Flux d'entrée du socket
+ */
private final ObjectInputStream inputStream;
+
+ /**
+ * Flux de sortie du socket
+ */
private final ObjectOutputStream outputStream;
+
+ /**
+ * Les clés RSA du serveur
+ */
private final KeyPair serverKeys;
- private final FenetreServeur fenetre;
private PublicKey clientKey;
+
+ /**
+ * Interface graphique
+ */
+ private final FenetreServeur fenetre;
+
+ /**
+ * Pseudo du client
+ */
private String clientPseudo;
+ /**
+ * Crée un thread pour initialiser la connexion entre le serveur et un client(socket) sans interface
+ *
+ * @param socket Socket du client
+ * @param threads Référence vers la liste des autres threads du serveur
+ * @throws IOException Si le serveur n'arrive pas à récupérer les flux d'entrée/sortie du socket client
+ */
public ThreadServer(Socket socket, ArrayList threads) throws IOException {
this.threads = threads;
this.fenetre = null;
@@ -30,6 +74,14 @@ public class ThreadServer extends Thread {
this.serverKeys = RSA.genererCle();
}
+ /**
+ * Crée un thread pour initialiser la connexion entre le serveur et un client(socket) avec une interface
+ *
+ * @param socket Socket du client
+ * @param threads Référence vers la liste des autres threads du serveur
+ * @param fenetre Interface graphique
+ * @throws IOException Si le serveur n'arrive pas à récupérer les flux d'entrée/sortie du socket client
+ */
public ThreadServer(Socket socket, ArrayList threads, FenetreServeur fenetre) throws IOException {
this.threads = threads;
this.fenetre = fenetre;
@@ -70,6 +122,12 @@ public class ThreadServer extends Thread {
}
+ /**
+ * Envoie la cle public du serveur à la reception de celle du client
+ *
+ * @throws IOException Erreur de connexion avec le socket
+ * @throws ClassNotFoundException La classe {@link PublicKey} n'est pas trouvée
+ */
public void exchangeKeys() throws IOException, ClassNotFoundException {
// Attend la clé du client
clientKey = (PublicKey) inputStream.readObject();
@@ -78,23 +136,51 @@ public class ThreadServer extends Thread {
outputStream.writeObject(serverKeys.getPublic());
}
+ /**
+ * Attend un message du client (fonction bloquante)
+ *
+ * @return Le message reçu
+ * @throws EOFException Le socket est fermé
+ * @throws IOException Erreur de connexion avec le socket
+ * @throws ClassNotFoundException La classe byte[] n'est pas trouvée
+ */
public String getMessage() throws EOFException, IOException, ClassNotFoundException {
byte[] messageCrypte = (byte[]) inputStream.readObject();
return RSA.decrypter(messageCrypte, serverKeys.getPrivate());
}
+ /**
+ * Envoie un message au client
+ *
+ * @param message message envoyé au client
+ * @param log Si vrai affiche dans la console
+ * @throws IOException Erreur de connexion avec le socket
+ */
public void sendMessage(String message, boolean log) throws IOException {
byte[] messageCrypte = RSA.encrypter(message, clientKey);
outputStream.writeObject(messageCrypte);
- if (log) System.out.println(message);
- if (log && fenetre != null) {fenetre.displayNewMessage(message);}
+
+ // Log
+ if (!log) return;
+ System.out.println(message);
+ if (fenetre != null) fenetre.displayNewMessage(message);
}
+ /**
+ * Envoie un message à tous les clients connecté au serveur
+ *
+ * @param message Message à envoyer à tous les clients
+ * @param log si vrai affiche dans la console
+ * @throws IOException Erreur de connexion avec un des sockets du serveur
+ */
public void sendMessageToEveryone(String message, boolean log) throws IOException {
for (ThreadServer thread : threads) {
thread.sendMessage(message, false);
}
- if (log) System.out.println(message);
- if (log && fenetre != null) {fenetre.displayNewMessage(message);}
+
+ // Log
+ if (!log) return;
+ System.out.println(message);
+ if (fenetre != null) fenetre.displayNewMessage(message);
}
}
diff --git a/src/ui/FenetreClient.java b/src/ui/FenetreClient.java
index 1232987..360ba65 100644
--- a/src/ui/FenetreClient.java
+++ b/src/ui/FenetreClient.java
@@ -1,8 +1,15 @@
+/*
+ * FenetreClient.java, 06/12/2022
+ * INU Champollion, 2022-2023
+ * pas de copyright, aucun droits
+ */
+
package ui;
import client.Client;
import javax.swing.*;
+import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
@@ -10,6 +17,13 @@ import java.awt.event.WindowEvent;
import java.io.IOException;
import java.util.Objects;
+/**
+ * Interface du client
+ *
+ * @author Gaël Burguès
+ * @author Laurian Dufrechou
+ * @author Lucàs Vabre
+ */
public class FenetreClient extends JFrame {
private JTextField addressInput, portInput, pseudoInput, messageInput;
private JButton connexionButton, envoyerButton, deconnexionButton;
@@ -17,14 +31,22 @@ public class FenetreClient extends JFrame {
private JTextArea chatArea;
private JScrollPane scrollPane;
+ /**
+ * Le client lié à cette fenêtre
+ */
private Client client;
+ /**
+ * Crée une nouvelle fenêtre client
+ */
public FenetreClient() {
super("Fenêtre client");
add(mainPanel);
- // On ne peut pas saisir dans la boîte de dialogue directement
+ // Configure le tchat
chatArea.setEnabled(false);
+ chatArea.setLineWrap(true);
+ chatArea.setDisabledTextColor(Color.BLACK);
// Au lancement, on ne peut pas envoyer de message sans être connecté au serveur
messageInput.setEnabled(false);
@@ -41,9 +63,11 @@ public class FenetreClient extends JFrame {
envoyerButton.addActionListener(e -> envoyerMessage());
deconnexionButton.addActionListener(e -> deconnexion());
- // Quand on clique sur fermer la fenêtre, on ferme la connexion
+ // Quand on clique sur fermer la fenêtre, on ferme la connexion.
this.addWindowListener(new WindowAdapter() {
- public void windowClosing(WindowEvent e) {deconnexion();}
+ public void windowClosing(WindowEvent e) {
+ deconnexion();
+ }
});
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
@@ -51,6 +75,9 @@ public class FenetreClient extends JFrame {
this.setVisible(true);
}
+ /**
+ * Récupère la saisie de l'utilisateur et l'envoie au serveur
+ */
private void envoyerMessage() {
{
String message = this.messageInput.getText();
@@ -66,6 +93,9 @@ public class FenetreClient extends JFrame {
}
}
+ /**
+ * Crée un client et le connecte au serveur à partir de l'IP et port du serveur avec le pseudo du client.
+ */
public void connexion() {
String address = addressInput.getText();
int port = Integer.parseInt(portInput.getText());
@@ -80,14 +110,19 @@ public class FenetreClient extends JFrame {
this.client = new Client(address, port, pseudo, this);
this.client.start();
+ // Désactive le formulaire de connexion
addressInput.setEnabled(false);
portInput.setEnabled(false);
pseudoInput.setEnabled(false);
+ // Active l'interface de tchat
messageInput.setEnabled(true);
envoyerButton.setEnabled(true);
}
+ /**
+ * Déconnecte le client du serveur
+ */
public void deconnexion() {
if (client == null) return;
@@ -95,28 +130,36 @@ public class FenetreClient extends JFrame {
this.client.addMessage("bye");
this.client = null;
- // Vide le chat
+ // Vide le tchat
this.chatArea.setText("");
- // Active les boutons pour changer de serveur
+ // Active le formulaire de connexion
addressInput.setEnabled(true);
portInput.setEnabled(true);
pseudoInput.setEnabled(true);
- // Désactive les commandes de chats
+ // Désactive l'interface de tchat
messageInput.setEnabled(false);
envoyerButton.setEnabled(false);
}
+ /**
+ * Affiche un nouveau message dans la fenêtre de tchat
+ * @param message message à afficher dans le tchat
+ */
public void displayNewMessage(String message) {
- // Ajoute le message
- chatArea.append(message + "\n");
+ // Ajoute le message dans l'interface de tchat
+ chatArea.append(String.format("%s\n", message));
// Va en bas de la fenêtre
JScrollBar vertical = scrollPane.getVerticalScrollBar();
vertical.setValue(vertical.getMaximum());
}
+ /**
+ * Lance une nouvelle fenêtre de client
+ * @param args non utilisé
+ */
public static void main(String[] args) {
new FenetreClient();
}
diff --git a/src/ui/FenetreErreur.java b/src/ui/FenetreErreur.java
index 7e39d3e..6bf7142 100644
--- a/src/ui/FenetreErreur.java
+++ b/src/ui/FenetreErreur.java
@@ -1,15 +1,30 @@
+/*
+ * FenetreErreur.java, 06/12/2022
+ * INU Champollion, 2022-2023
+ * pas de copyright, aucun droits
+ */
+
package ui;
import javax.swing.*;
+/**
+ * Gestion de l'affichage des erreurs pour les utilisateurs
+ *
+ * @author Gaël Burguès
+ * @author Laurian Dufrechou
+ * @author Lucàs Vabre
+ */
public class FenetreErreur {
+ /**
+ * Crée une fenêtre d'erreur avec un message
+ *
+ * @param message Message d'erreur
+ * @param parent La fenêtre parente
+ */
public FenetreErreur(String message, JFrame parent) {
final String TITLE = "Erreur";
JOptionPane.showMessageDialog(parent, message, TITLE, JOptionPane.ERROR_MESSAGE);
}
-
- public static void main(String[] args) {
- new FenetreErreur("Message", null);
- }
}
\ No newline at end of file
diff --git a/src/ui/FenetreServeur.java b/src/ui/FenetreServeur.java
index e280413..71851eb 100644
--- a/src/ui/FenetreServeur.java
+++ b/src/ui/FenetreServeur.java
@@ -1,23 +1,48 @@
+/*
+ * FenetreServeur.java, 06/12/2022
+ * INU Champollion, 2022-2023
+ * pas de copyright, aucun droits
+ */
+
package ui;
import server.Server;
import javax.swing.*;
+import java.awt.*;
+/**
+ * Interface du serveur
+ *
+ * @author Gaël Burguès
+ * @author Laurian Dufrechou
+ * @author Lucàs Vabre
+ */
public class FenetreServeur extends JFrame {
private JTextArea chatArea;
private JPanel mainPanel;
private JScrollPane scrollPane;
private JTextField portInput;
private JButton demarrerButton;
+
+ /**
+ * Le serveur lié à cette fenêtre
+ */
private Server server;
+ /**
+ * Crée une nouvelle fenêtre de serveur
+ */
public FenetreServeur() {
super("Fenetre Serveur");
add(mainPanel);
+ // Configure le tchat
chatArea.setEnabled(false);
+ chatArea.setLineWrap(true);
+ chatArea.setDisabledTextColor(Color.BLACK);
+ // Actions
demarrerButton.addActionListener(e -> demarrerServeur());
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
@@ -25,24 +50,40 @@ public class FenetreServeur extends JFrame {
this.setVisible(true);
}
+ /**
+ * Crée une nouvelle instance de serveur sur le port saisi par l'utilisateur
+ */
public void demarrerServeur() {
int port = Integer.parseInt(portInput.getText());
+
+ // Crée le serveur
server = new Server(port, this);
server.start();
+ // Désactive le formulaire de connexion (la saisie du port et le bouton)
portInput.setEnabled(false);
demarrerButton.setEnabled(false);
}
+ /**
+ * Affiche un nouveau message dans le tchat
+ *
+ * @param message Message à afficher
+ */
public void displayNewMessage(String message) {
// Ajoute le message
- chatArea.append(message + "\n");
+ chatArea.append(String.format("%s\n", message));
// Va en bas de la fenêtre
JScrollBar vertical = scrollPane.getVerticalScrollBar();
vertical.setValue(vertical.getMaximum());
}
+ /**
+ * Lance une nouvelle fenêtre de serveur
+ *
+ * @param args non utilisé
+ */
public static void main(String[] args) {
new FenetreServeur();
}
diff --git a/src/utils/AES.java b/src/utils/AES.java
index f2eb994..6a36915 100644
--- a/src/utils/AES.java
+++ b/src/utils/AES.java
@@ -1,3 +1,9 @@
+/*
+ * AES.java, 06/12/2022
+ * INU Champollion, 2022-2023
+ * pas de copyright, aucun droits
+ */
+
package utils;
import javax.crypto.*;
@@ -5,14 +11,22 @@ import java.io.*;
import java.nio.charset.StandardCharsets;
import java.security.*;
+/**
+ * Gestion du cryptage AES(DES)
+ *
+ * @author Gaël Burguès
+ * @author Laurian Dufrechou
+ * @author Lucàs Vabre
+ */
public class AES {
+ /** Nom du fichier de sauvegarde de la clé. */
private static final String SAVE_FILE = "key.sav";
/**
- * TODO
+ * Génère une clé DES et la renvoie.
*
- * @return
+ * @return La clé générée
*/
public static Key genererCle() {
Key key = null;
@@ -26,60 +40,64 @@ public class AES {
return key;
}
+
/**
- * TODO
+ * Crypte un message avec une clé.
*
- * @param msg
- * @param key
- * @return
+ * @param message La chaîne de caractère à crypter
+ * @param cle La clé de cryptage
+ * @return Le message crypté sous forme d'un tableau d'octets
*/
- public static byte[] encrypter(String msg, Key key) {
+ public static byte[] encrypter(String message, Key cle) {
try {
Cipher cipher = Cipher.getInstance("DES");
- cipher.init(Cipher.ENCRYPT_MODE, key);
- return cipher.doFinal(msg.getBytes());
+ cipher.init(Cipher.ENCRYPT_MODE, cle);
+ return cipher.doFinal(message.getBytes());
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
+
/**
- * TODO
+ * Décrypte un message à partir d'un tableau d'octet et de la clé de cryptage.
*
- * @param message
- * @param cle
- * @return
+ * @param messageCrypte Le message crypté
+ * @param cle La clé de cryptage
+ * @return Le message une fois décrypté
*/
- public static String decrypter(byte[] message, Key cle) {
+ public static String decrypter(byte[] messageCrypte, Key cle) {
try {
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.DECRYPT_MODE, cle);
- return new String(cipher.doFinal(message), StandardCharsets.UTF_8);
+ return new String(cipher.doFinal(messageCrypte), StandardCharsets.UTF_8);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
+
/**
- * TODO
+ * Enregistre la clé dans le fichier {@link #SAVE_FILE}.
*
- * @param key
+ * @param cle La clé à sauvegarder
*/
- public static void sauvegarderCle(Key key) {
+ public static void sauvegarderCle(Key cle) {
try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(SAVE_FILE))) {
- objectOutputStream.writeObject(key);
+ objectOutputStream.writeObject(cle);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
+
/**
- * TODO
+ * Charge une clé à partir du fichier de sauvegarde {@link #SAVE_FILE}.
*
- * @return
+ * @return La clé une fois chargée
*/
public static Key chargerCle() {
Key key;
diff --git a/src/utils/RSA.java b/src/utils/RSA.java
index d6e19d3..43f79fe 100644
--- a/src/utils/RSA.java
+++ b/src/utils/RSA.java
@@ -1,11 +1,29 @@
+/*
+ * RSA.java, 06/12/2022
+ * INU Champollion, 2022-2023
+ * pas de copyright, aucun droits
+ */
+
package utils;
import javax.crypto.Cipher;
import java.nio.charset.StandardCharsets;
import java.security.*;
+/**
+ * Gestion du cryptage RSA.
+ *
+ * @author Gaël Burguès
+ * @author Laurian Dufrechou
+ * @author Lucàs Vabre
+ */
public class RSA {
+ /**
+ * Génère une paire de clés RSA et nous les renvoie.
+ *
+ * @return La paire de clé générée (publique et privée)
+ */
public static KeyPair genererCle() {
KeyPair keyPair = null;
@@ -20,22 +38,36 @@ public class RSA {
return keyPair;
}
- public static byte[] encrypter(String msg, PublicKey key){
+ /**
+ * Crypte un message avec la clé publique.
+ *
+ * @param message La chaîne de caractère à crypter
+ * @param publicKey La clé de cryptage
+ * @return Le message crypté sous forme d'un tableau d'octets
+ */
+ public static byte[] encrypter(String message, PublicKey publicKey) {
try {
- Cipher cipher = Cipher.getInstance("RSA") ;
- cipher.init(Cipher.ENCRYPT_MODE, key) ;
- return cipher.doFinal(msg.getBytes());
- } catch(Exception e){
+ Cipher cipher = Cipher.getInstance("RSA");
+ cipher.init(Cipher.ENCRYPT_MODE, publicKey);
+ return cipher.doFinal(message.getBytes());
+ } catch (Exception e) {
e.printStackTrace();
}
return null;
}
- public static String decrypter(byte[] msg, PrivateKey key) {
+ /**
+ * Décrypte un message à partir d'un tableau d'octet et de la clé privée.
+ *
+ * @param message Le message crypté
+ * @param privateKey La clé privée de cryptage
+ * @return Le message une fois décrypté
+ */
+ public static String decrypter(byte[] message, PrivateKey privateKey) {
try {
- Cipher cipher = Cipher.getInstance("RSA") ;
- cipher.init(Cipher.DECRYPT_MODE, key);
- return new String(cipher.doFinal(msg), StandardCharsets.UTF_8);
+ Cipher cipher = Cipher.getInstance("RSA");
+ cipher.init(Cipher.DECRYPT_MODE, privateKey);
+ return new String(cipher.doFinal(message), StandardCharsets.UTF_8);
} catch (Exception e) {
e.printStackTrace();
}
diff --git a/src/utils/ResolutionDeNom.java b/src/utils/ResolutionDeNom.java
index c723d3b..5ee1a6a 100644
--- a/src/utils/ResolutionDeNom.java
+++ b/src/utils/ResolutionDeNom.java
@@ -1,20 +1,33 @@
+/*
+ * ResolutionDeNom.java, 06/12/2022
+ * INU Champollion, 2022-2023
+ * pas de copyright, aucun droits
+ */
+
package utils;
import java.net.InetAddress;
import java.net.UnknownHostException;
+/**
+ * Utilitaire à la gestion des adresses IP.
+ *
+ * @author Gaël Burguès
+ * @author Laurian Dufrechou
+ * @author Lucàs Vabre
+ */
public class ResolutionDeNom {
/**
- * TODO
+ * Convertis une URI en on adresse IP
*
- * @param host
- * @return
+ * @param uri Adresse URI à convertir
+ * @return L'adresse IP correspondante à l'URI
*/
- public static String getIPAddress(String host) {
+ public static String getIPAddress(String uri) {
String address = null;
try {
- address = InetAddress.getByName(host).getHostAddress();
+ address = InetAddress.getByName(uri).getHostAddress();
} catch (UnknownHostException e) {
e.printStackTrace();
}