import java.io.IOException; import java.net.DatagramPacket; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.Map; import java.util.Scanner; import java.util.Vector; import java.util.concurrent.ConcurrentHashMap; public class Klient { static String nazwaUzytkownika = null; static ChatPrywatny chatPrywatny = null; static ChatMulticast chatMulticast = null; static InetAddress adresWlasny = null; static InetAddress adresRozgloszeniowy = null; static int port = 12344; static int portMulticast = 12345; static ConcurrentHashMap listaUzytkownikow = new ConcurrentHashMap(); static ConcurrentHashMap listaGrup = new ConcurrentHashMap(); public static void main(String[] args) throws IOException, InterruptedException { if(args.length != 3) { System.out.println("Program wymaga 3 parametrow: adres rozgloszeniowy, adres wlasny i nazwe uzytkownika"); System.out.println("Przyklad: 224.0.0.1 192.168.1.2 Student"); return; } try { adresRozgloszeniowy = InetAddress.getByName(args[0]); } catch(UnknownHostException e) { System.out.println("Podany adres rozgloszeniowy ('" + args[0] + "') nie jest poprawnym adresem."); return; } if(!adresRozgloszeniowy.isMulticastAddress()) { System.out.println("Podany adres ('" + args[0] + "') nie jest adresem rozgloszeniowym."); return; } try { adresWlasny = InetAddress.getByName(args[1]); } catch(UnknownHostException e) { System.out.println("Podany adres wlasny ('" + args[1] + "') nie jest poprawnym adresem."); return; } nazwaUzytkownika = args[2]; if(nazwaUzytkownika.contains("#") || nazwaUzytkownika.contains("@") || nazwaUzytkownika.contains("(") || nazwaUzytkownika.contains(")") || nazwaUzytkownika.contains("=") || nazwaUzytkownika.contains(" ")) { System.out.println("Nazwa uzytkownika ('" + args[0] + "') nie moze zawierac znakow: #, @, (, ), = oraz spacji)"); return; } chatMulticast = new ChatMulticast(); chatMulticast.initilize(); new Thread(chatMulticast).start(); chatPrywatny = new ChatPrywatny(); chatPrywatny.initilize(); new Thread(chatPrywatny).start(); chatMulticast.sendPacket("LogujeSie " + Klient.nazwaUzytkownika); System.out.print("Trwa logowanie..."); // czeka 2 sekundy na odpowiedz o zajetym nicku od kogos z sieci for(int i = 0; i < 5; i++) { System.out.print(5 - i + ", "); Thread.sleep(400); } System.out.println("zalogowano - prawdopodobnie nikt nie uzywa nazwy uzytkownika: " + Klient.nazwaUzytkownika); Scanner skaner = new Scanner(System.in); String wejscie = null; while(true) { wejscie = skaner.nextLine(); System.out.println(wejscie); if(wejscie.startsWith("@")) { int startListyUzytkownikow = wejscie.indexOf('('); int koniecListyUzytkownikow = wejscie.indexOf(')'); if(startListyUzytkownikow > 0 && koniecListyUzytkownikow > 0 && startListyUzytkownikow < koniecListyUzytkownikow) { String listaDocelowychUzytkownikow = wejscie.substring(startListyUzytkownikow+1, koniecListyUzytkownikow); String[] uzytkownicyDocelowi = listaDocelowychUzytkownikow.split(","); String wiadomosc = wejscie.substring(koniecListyUzytkownikow+2); for(String uzytkownik : uzytkownicyDocelowi) { if(uzytkownik.startsWith("#")) { // wysylanie do grupu String nazwaGrupy = uzytkownik.substring(1); Vector ipDocelowe = Klient.getGroupMembersIPsByName(nazwaGrupy); if(ipDocelowe != null) { for(InetAddress ipCzlonka : ipDocelowe) { chatPrywatny.sendPacket("Wiadomosc " + wiadomosc, ipCzlonka); } } else { System.out.println("Grupa o nazwie '" + nazwaGrupy + "' nie istnieje."); } } else { // wysylanie do uzytkownika InetAddress ipDocelowe = Klient.getUserIPbyName(uzytkownik); if(ipDocelowe != null) { chatPrywatny.sendPacket("Wiadomosc " + wiadomosc, ipDocelowe); } else { System.out.println("Uzytkownik o nazwie '" + uzytkownik + "' nie istnieje."); } } } System.out.println(Klient.nazwaUzytkownika + "@(" + listaDocelowychUzytkownikow + "):" + wiadomosc); } else { System.out.println("Nie poprawny format docelowych uzytkownikow, powinno byc: @(uzytkownik1,innyUzytkownik,#nazwaGrupy):tresc wiadomosci"); } } else if(wejscie.startsWith("#")) { int koniecNazwyGrupy = wejscie.indexOf('='); int startListyUzytkownikow = wejscie.indexOf('('); int koniecListyUzytkownikow = wejscie.indexOf(')'); if(koniecNazwyGrupy > 0 && startListyUzytkownikow > 0 && koniecListyUzytkownikow > 0 && koniecNazwyGrupy < startListyUzytkownikow && startListyUzytkownikow < koniecListyUzytkownikow) { String nazwaGrupy = wejscie.substring(1, koniecNazwyGrupy); String listaUzytkownikowGrupy = wejscie.substring(startListyUzytkownikow+1, koniecListyUzytkownikow); String[] wpisaniUzytkownicyGrupy = listaUzytkownikowGrupy.split(","); Vector uzytkownicyGrupy = new Vector(); for(String uzytkownikGrupy : wpisaniUzytkownicyGrupy) { if(Klient.getUserIPbyName(uzytkownikGrupy) != null) { uzytkownicyGrupy.add(uzytkownikGrupy); } else { System.out.println("Nie udalo sie dodac uzytkownika '" + uzytkownikGrupy + "' - taki uzytkownik nie istnieje na liscie osob online."); } } String[] nowaLista = new String[uzytkownicyGrupy.size()]; int i = 0; for(String nowyUzytkownik : uzytkownicyGrupy) { nowaLista[i] = nowyUzytkownik; i++; } if(Klient.listaGrup.get(nazwaGrupy) != null) { Klient.listaGrup.replace(nazwaGrupy, nowaLista); System.out.println("Zastapiono liste uzytkownikow w grupie '" + nazwaGrupy + "'."); } else { Klient.listaGrup.put(nazwaGrupy, nowaLista); System.out.println("Utworzono nowa grupe '" + nazwaGrupy + "'."); } } else { System.out.println("Nie poprawny format tworzenia grupy."); } } else if(wejscie.toLowerCase().startsWith("kontakty")) { System.out.println("Lista uzytkownikow online: "); for(Map.Entry uzytkownikLista : Klient.listaUzytkownikow.entrySet()) { System.out.println("- " + uzytkownikLista.getValue()); } System.out.println("Lista grup i ich czlonków:"); String nazwaCzlonka = null; for(Map.Entry grupa : Klient.listaGrup.entrySet()) { String listaCzlonkowGrupy = ""; if(Klient.getGroupMembersIPsByName(grupa.getKey()).size() == 0) { System.out.println("- " + grupa.getKey() + " - GRUPA PUSTA"); continue; } for(InetAddress czlonekGrupy : Klient.getGroupMembersIPsByName(grupa.getKey())) { nazwaCzlonka = Klient.listaUzytkownikow.get(czlonekGrupy); if(nazwaCzlonka != null) { listaCzlonkowGrupy += nazwaCzlonka + ","; } } System.out.println("- " + grupa.getKey() + " (" + listaCzlonkowGrupy.substring(0, listaCzlonkowGrupy.length()-1) + ")"); } } else if(wejscie.toLowerCase().startsWith("quit")) { System.out.println("Zamykanie programu."); break; } else { System.out.println("------------------"); System.out.println("DOSTEPNE KOMENDY"); System.out.println("Wysylanie wiadomosci: @(nazwa Uzytkownika,#nazwa Grupy):tresc wiadomosci"); System.out.println("Tworzenie grupy: #nazwa grupy=(uzytkownik 1,inny uzytkownik)"); System.out.println("Lista uzytkownikow i grup: kontakty"); System.out.println("Wylaczenie programu: quit"); System.out.println("------------------"); } } chatMulticast.sendPacket("WylogowujeSie"); chatMulticast.multicastSocket.close(); chatPrywatny.udpSocket.close(); /* chatPrywatny.sendPacket("LogujeSie " + Klient.nazwaUzytkownika, adresWlasny); chatPrywatny.sendPacket("Wiadomosc priv", adresWlasny); chatMulticast.sendPacket("Wiadomosc multi"); */ } public static synchronized void obsluzPakiet(DatagramPacket pakiet, String msg) throws IOException { System.out.println("OTRZYMANO PAKIET - " + pakiet.getAddress().getHostName() + ": "+ msg); if(msg.startsWith("NazwaUzytkownikaZajeta")) { InetAddress ipUzytkownika = pakiet.getAddress(); chatMulticast.sendPacket("WylogowujeSie"); System.out.println(ipUzytkownika.getHostName() + ": nazwa uzytkownika '" + Klient.nazwaUzytkownika + "' jest juz zajeta"); System.exit(1); } /* * pakiet wysylany jako odpowiedz na 'LogujeSie' * aby nowy uzytkownik poznal wszystkich w sieci */ else if(msg.startsWith("ZapamietajLogin")) { InetAddress ipUzytkownika = pakiet.getAddress(); String nazwaUzytkownika = msg.substring(16); if(Klient.getUserIPbyName(nazwaUzytkownika) != null) { System.out.println("Uzytkownik " + nazwaUzytkownika + " (IP " + ipUzytkownika.getHostAddress() + ") przeslal swoj login, ale juz istnieje uzytkownik o takim loginie."); } else { if(Klient.listaUzytkownikow.get(ipUzytkownika) == null) { Klient.listaUzytkownikow.put(ipUzytkownika, nazwaUzytkownika); } else { Klient.listaUzytkownikow.replace(ipUzytkownika, nazwaUzytkownika); } System.out.println("Uzytkownik " + nazwaUzytkownika + " (IP " + ipUzytkownika.getHostAddress() + ") dodany do listy osob online."); } } /* * pakiet wysylany przy odpalaniu programu w celu pozniania innych * uzytkownikow sieci i upewnienia sie, ze nikt nie ma wybranego nicku */ else if(msg.startsWith("LogujeSie")) { InetAddress ipUzytkownika = pakiet.getAddress(); String nazwaUzytkownika = msg.substring(10); boolean uzytkownikIstnieje = false; if(nazwaUzytkownika.equals(Klient.nazwaUzytkownika)) { chatPrywatny.sendPacket("NazwaUzytkownikaZajeta", pakiet.getAddress()); uzytkownikIstnieje = true; } else { chatPrywatny.sendPacket("ZapamietajLogin " + Klient.nazwaUzytkownika, pakiet.getAddress()); } if(Klient.getUserIPbyName(nazwaUzytkownika) != null && Klient.getUserIPbyName(nazwaUzytkownika).equals(ipUzytkownika)) { uzytkownikIstnieje = true; } if(uzytkownikIstnieje) { System.out.println("Uzytkownik " + nazwaUzytkownika + " (IP " + ipUzytkownika.getHostAddress() + ") probowal dolaczyc do chatu, ale uzytkownik o takiej nazwie juz istnieje."); } else { if(Klient.listaUzytkownikow.containsKey(ipUzytkownika)) { Klient.listaUzytkownikow.replace(ipUzytkownika, nazwaUzytkownika); } else { Klient.listaUzytkownikow.put(ipUzytkownika, nazwaUzytkownika); } System.out.println("Uzytkownik " + nazwaUzytkownika + " (IP " + ipUzytkownika.getHostAddress() + ") zalogowal sie."); } } /* * pakiet wysylany przy wylaczaniu programu * oraz jesli inny uzytkownik zglosi, ze juz uzywa nicka ktorego my chcemy uzywac * (wtedy program sie wylacza) */ else if(msg.startsWith("WylogowujeSie")) { InetAddress ipUzytkownika = pakiet.getAddress(); if(Klient.listaUzytkownikow.get(ipUzytkownika) != null) { System.out.println("Uzytkownik " + Klient.listaUzytkownikow.get(ipUzytkownika) + " (IP " + ipUzytkownika.getHostName() + ") sie rozlaczyl."); Klient.listaUzytkownikow.remove(ipUzytkownika); // sklady grup aktualizuja sie przy pobieraniu listy IP czlonkow grupy } else { System.out.println("Nie znany uzytkownik o IP " + ipUzytkownika.getHostName() + " wylogowal sie."); } } /* * pakiet z wiadomoscia od uzytkownika sieci */ else if(msg.startsWith("Wiadomosc")) { InetAddress ipUzytkownika = pakiet.getAddress(); String wiadomosc = msg.substring(10); String nazwaUzytkownika = null; if(Klient.listaUzytkownikow.get(ipUzytkownika) != null) { nazwaUzytkownika = Klient.listaUzytkownikow.get(ipUzytkownika); } if(nazwaUzytkownika != null) { System.out.println(nazwaUzytkownika + ": " + wiadomosc); } else { System.out.println("Otrzymano wiadomosc od IP " + ipUzytkownika.getHostName() + ", ale nazwa uzytkownika nie jest znana."); } } else { System.out.println("OTRZYMANO NIEZROZUMIALY PAKIET OD " + pakiet.getAddress().getHostName() + ", TRESC: "+ msg); } } static InetAddress getUserIPbyName(String nazwa) { for(Map.Entry uzytkownikLista : Klient.listaUzytkownikow.entrySet()) { if(uzytkownikLista.getValue().equals(nazwa)) { return uzytkownikLista.getKey(); } } return null; } static Vector getGroupMembersIPsByName(String nazwaGrupy) { String[] nazwyCzlonkow = Klient.listaGrup.get(nazwaGrupy); if(nazwyCzlonkow != null) { Vector ipCzlonkowGrupy = new Vector(); for(String czlonekGrupy : nazwyCzlonkow) { InetAddress ipDocelowe = Klient.getUserIPbyName(czlonekGrupy); if(ipDocelowe != null) // uzytkownik sie nie wylogowal { ipCzlonkowGrupy.add(ipDocelowe); } } return ipCzlonkowGrupy; } else { return null; } } }