package src.Controller; import java.io.IOException; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.InterfaceAddress; import java.net.NetworkInterface; import java.net.SocketException; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import src.Protocoles.*; import src.Model.*; /** *

* Classe recapitulant toutes les actions possibles pour un utilisateur *

*/ public class ChatApp extends Thread{ /* Liste des utilisateurs actifs */ private ListUtilisateurs actifUsers ; /* Map on l'on stocke localement les historiques des messages */ private Map mapHistorique ; private boolean historiqueAvailable = true; /* ChatApp est associe a un utilisateur */ private Utilisateur me; /** * Constructeur de l'application de chat * * @param pseudo Pseudo de l'utilisateur * @param port Port de communication */ public ChatApp(String pseudo, Integer port){ this.actifUsers = new ListUtilisateurs() ; // Recuperer adresse IP de l'utilisateur InetAddress ip = null ; ip = UDPEchange.getCurrentIp(); this.me = new Utilisateur(pseudo,port,ip); this.actifUsers.addList(getMe()); this.mapHistorique = new HashMap() ; } /** * Mettre a jour dans Maphistorique, l'historique avec un utilisateur dont le nom est pseudo * * @param pseudo Pseudo de l'utilisateur * @param h nouvel Historique entre les deux utilisateurs */ public synchronized void majHistorique(Historique h) { getMapHistorique().put(h.getUser2().getPseudo(),h); } /*public void majHistorique2(MessageHorodate mh, String pseudo) { Historique h = getMapHistorique().get(pseudo); //h.addMessage(mh); getMapHistorique().put(h.getUser2().getPseudo(),h); }*/ public void majHistorique2(String mh, String pseudo) { Historique h = getMapHistorique().get(pseudo); MessageHorodate msghor = new MessageHorodate(this.getMe(),this.getMe(),"rien",1); System.out.println(">>"+mh+"<<"); System.out.print(msghor.getDateHorodatage()); System.out.println(msghor.getDestinataire()); System.out.println(msghor.getSource()); System.out.println(msghor.getType()); h.addMessage(msghor); getMapHistorique().put(h.getUser2().getPseudo(),h); } /** * Modification du pseudo de l'utilisateur * Envoie en broadcast ses informations utilisateurs et son nouveau pseudo * * @param nouveau correspond au nouveau pseudo * @return False si modiferPseudo a echoue, True sinon */ public Boolean modifierPseudo(String nouveau) throws IOException { // Message que l'on envoie à tous les utilisateurs actifs String broadcastMessage = "Demande Modification Pseudo\n" + this.getMe().toString() + "\n" + nouveau + "\n"; UDPEchange.EnvoiBroadcast(broadcastMessage); try { Thread.sleep(2000); /* L'utilisateur doit attendre la reponse de tous les utilisateurs connectes * pour savoir si son pseudo est accepte */ } catch (InterruptedException e) { e.printStackTrace(); } if (UDPEchange.getPseudoValide()) { System.out.println("Modification pseudo reussie"); //Envoi un msg en broadcast a tout les utilisateurs pour les prevenir de son nouveau pseudo// broadcastMessage = "Modification pseudo reussie\n" + this.getMe().toString() + "\n" + nouveau + "\n"; UDPEchange.EnvoiBroadcast(broadcastMessage); //-------Change son propre nom d'utilisateur-------// this.getActifUsers().modifierList(this.getMe().getPseudo(), nouveau); this.getMe().setPseudo(nouveau); System.out.println("Changement pseudo accepte, nouvelle liste des utilisateurs actifs:"); this.getActifUsers().afficherListeUtilisateurs(); return true; } else { System.out.println("Echec Modification pseudo"); return false; } } /** * Methode appelee lors de la connexion d'un nouvel utilisateur. * Il va prevenir les utilisateurs du reseau de son arrivee. * @return False si Connexion a echoue, True sinon */ public Boolean connexion() throws IOException { // Message que l'on envoie à tous les utilisateurs actifs String broadcastMessage = "Connexion\n" + this.getMe().toString() ; UDPEchange.EnvoiBroadcast(broadcastMessage); try { Thread.sleep(2000); // L'utilisateur doit attendre la reponse de tous les utilisateurs connectes } catch (InterruptedException e) { e.printStackTrace(); } if (UDPEchange.getConnecte()) { System.out.println("Connexion reussie"); return true; } else { System.out.println("Connexion echoue"); UDPEchange.setConnecte(true); return false ; } } /** * Methode appelee lors de la deconnexion de l'utilisateur. * Il va prevenir les utilisateurs du reseau de son depart. * */ public void deconnexion() throws IOException { // Message que l'on envoie à tous les utilisateurs actifs String broadcastMessage = "Deconnexion\n" + this.getMe().toString() ; UDPEchange.EnvoiBroadcast(broadcastMessage); System.exit(1); } /** * Getter * @return Utilisateur associee a ChatApp */ public Utilisateur getMe() { return me; } /** * Getter * @return Liste des utilisateurs actifs associee a ChatApp */ public ListUtilisateurs getActifUsers() { return actifUsers; } /** * Getter * @return la map des historiques */ public Map getMapHistorique() { return mapHistorique; } /** * Obtenir l'historique entre deux utilisateurs * @param pseudo Pseudo de l'utilisateur dont on souhaite obtenir l'historique * @return Un historique */ public synchronized Historique getHist(String pseudo) { Historique h = this.mapHistorique.get(pseudo); if( h != null) { return h ; } else { h = new Historique(this.me, this.getActifUsers().getPseudoList(pseudo)); return h ; } } public static void main (String[] args) throws IOException { ChatApp app = new ChatApp(args[0],Integer.parseInt(args[1])) ; System.out.println("On lance le chatapp"); ExecutorService execUDP = Executors.newFixedThreadPool(1000); execUDP.submit(new RunnerEcouteUDP(app)); try { app.connexion(); } catch (IOException e) { e.printStackTrace(); } ExecutorService execTCP = Executors.newFixedThreadPool(1000); System.out.println("On lance l'écoute TCP de chatapp"); execTCP.submit(new RunnerEcouteTCP(app)); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } if(app.getMe().getPseudo().equals("Marvel")) { app.getHist("Doudou").afficher10derniers(); System.out.println("Tentative de connexion avec Doudou"); TCPEchange.demarrerSession(app, app.actifUsers.getPseudoList("Doudou")); } } public boolean isHistoriqueAvailable() { return historiqueAvailable; } public void setHistoriqueAvailable(boolean historiqueAvailable) { this.historiqueAvailable = historiqueAvailable; } }