package client;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.net.ConnectException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import client.gui.JXoFrame;
import client.gui.dialogs.ConnexionDialog;
import client.gui.misc.GU;
import common.Conteneur;
import common.Joueur;
import common.Point;
import common.TypeConteneur;
import common.misc.Utils;
public class JxoClient {
/* Le port par défaut */
public int DEFAULT_PORT = 7050;
private InetAddress ip;
private int port;
/* La machine hote à laquelle on se connecte ie. Le serveur */
private String host;
/* La socket avec le serveur */
private Socket socketServeur;
private BufferedInputStream in;
private BufferedOutputStream out;
private String pseudo;
private boolean gameStarted;
private boolean souhaiteRejouer;
private JXoFrame jxoGui;
/**
*
* @param host
* @param port
* @throws UnknownHostException
* @throws IOException
*/
public JxoClient(String host, String pseudo, int port, JXoFrame gui)
throws UnknownHostException, IOException {
new JxoClient(host, pseudo, gui);
this.port = port;
if (socketServeur == null)
socketServeur = new Socket(host, port);
/* On prévient le serveur que l'on arrive */
// On écoute les messages du serveur
}
/**
*
*
* @param host
* @throws UnknownHostException
* @throws IOException
*/
public JxoClient(String host, String pseudo, JXoFrame gui)
throws UnknownHostException {
// String nomMachine = Ip.getHostAddress();
this.host = host;
this.jxoGui = gui;
this.ip = InetAddress.getLocalHost();
this.port = DEFAULT_PORT;
this.pseudo = pseudo;
this.jxoGui.setJxoClient(this);
/* on tente d'etablir une connexion uniquement si le
* dialogue de connexion du GUI a ete confirme.
*/
if(jxoGui.getCONNECT_ACTION() == ConnexionDialog.CONNECT){
this.reconnect();
}
// try{
// this.socketServeur = new Socket(host, port);
// this.in = new BufferedInputStream(socketServeur.getInputStream());
// this.out = new BufferedOutputStream(socketServeur.getOutputStream());
// // On prévient le serveur de notre arrivée
// Conteneur c = new Conteneur(TypeConteneur.JOUEUR, new Joueur(pseudo));
// this.envoyerConteneur(c);
// Thread fils = new ClientFils();
// fils.start();
// }catch(ConnectException cex){
// GU.warn("Le serveur a refuse la connexion !");
// this.jxoGui.setCONNECT_ACTION(ConnexionDialog.RECONNECT);
// this.jxoGui.reshowConnexionDialog();
// }
// try {
// Thread.sleep(15000);
// } catch (Exception e) {
// e.printStackTrace();
// }
// TEST: On envoit un point
/* Point p = new Point(1, 2, TypeConteneur.ROND);
if (gameStarted) {
System.out.println("[" + pseudo + "] Envoi d'un point !");
Conteneur c1 = new Conteneur(TypeConteneur.POINT, p);
c1.setPseudo(pseudo);
envoyerConteneur(c1);
}
*/
}
/**
* reconnexion au serveur, avec fermeture de la socket en cours
*/
public void reconnect(){
// fermeture de la socket en cours.
this.disconnect();
this.host = jxoGui.getHostName();
this.pseudo = jxoGui.getUserName();
try{
this.socketServeur = new Socket(host, port);
this.in = new BufferedInputStream(socketServeur.getInputStream());
this.out = new BufferedOutputStream(socketServeur.getOutputStream());
// On prévient le serveur de notre arrivée
Conteneur c = new Conteneur(TypeConteneur.JOUEUR, new Joueur(pseudo));
this.envoyerConteneur(c);
Thread fils = new ClientFils();
fils.start();
}catch(Exception e){
GU.warn("Le serveur a refuse la connexion !");
this.jxoGui.setCONNECT_ACTION(ConnexionDialog.RECONNECT);
this.jxoGui.reshowConnexionDialog();
}
}
/**
* Envoie un objet <code>Conteneur</code> au serveur. Ce conteneur
* plusieurs types d'objets
*
* @param c
* @throws IOException
*/
public synchronized void envoyerConteneur(Conteneur c) throws IOException {
// On sérialize et on envoie au serveur
byte[] data = Utils.serialize(c);
out.write(data);
out.flush();
// socketServeur.close();
}
/**
*
* @author Ait Elhaj Brahim
*
*/
public class ClientFils extends Thread {
public void run() {
//jxoGui.info("Veuillez attendre la connexion d'un adversaire...\n" +
// "Son arrivee sera signalee par un nouveau message.");
jxoGui.setStatusBarText("Attente de connexion d'un adversaire...");
boolean fini = false;
try {
while (!fini) {
BufferedInputStream reader = new BufferedInputStream(in);
Conteneur c = (Conteneur) Utils.deserialize(reader);
if (c != null) {
String tp = c.getTypeConteneur();
if (tp.equals(TypeConteneur.ARRET_SERVEUR)) {
System.out.println("[" + pseudo
+ "] Le serveur va déco => Goodbye");
jxoGui.resetMainPanel();
jxoGui.desactiverTousChamps();
jxoGui.info("Le serveur va s'arreter !");
fini = true;
} else if (tp.equals(TypeConteneur.PSEUDO_EXISTANT)) {
System.out
.println("["
+ pseudo
+ "] Aie, Mon pseudo existe déja sur le serveur !");
jxoGui.resetMainPanel();
jxoGui.desactiverTousChamps();
jxoGui.warning("Le pseudo "+pseudo+" existe deja sur le serveur");
/*
* Etant donne qu'on sort de la boucle, on relance une demande de
* connexion.
*/
fini = true;
} else if (tp
.equals(TypeConteneur.PARTIE_PEUT_COMMENCER)) {
String symbole = (String) c.getObject();
System.out.println("[" + pseudo + "] Je joue les "
+ symbole + " la partie commence");
// remise du texte de base dans la barre de status.
jxoGui.setDefaultStatusBarText();
jxoGui.info("La partie peut commencer, vous avez le symbole "
+symbole);
/* Definir le symbole joue par ce joueur
* + debloquage de la grille de jeu
*/
jxoGui.setTypeSymbole2Gui(symbole);
gameStarted = true;
} else if (tp.equals(TypeConteneur.POINT)) {
System.out.println("[" + pseudo
+ "] J'ai recu le point :");
Point p = (Point) c.getObject();
System.out.println("Symbole = " + p.getSymbole()
+ " X = " + p.getX() + " Y = " + p.getY());
// action sur la reception d'un point
jxoGui.showPointAdversaire(p);
} else if (tp.equals(TypeConteneur.GAGNE)) {
// J'ai gagné
System.out.println("[" + pseudo+"] Vous avez gagne !");
jxoGui.desactiverTousChamps();
jxoGui.info("Vous avez gagne cette partie !\nFelicitations !");
fini = veutTerminer();
// if(jxoGui.rejouer()){
// envoyerMessage(TypeConteneur.REJOUER_OK, TypeConteneur.REJOUER_OK);
// }else{
// envoyerMessage(TypeConteneur.REJOUER_KO, TypeConteneur.REJOUER_KO);
// fini = true;
// disconnect();
// }
}else if(tp.equals(TypeConteneur.MATCH_NUL)){
System.out.println("[" + pseudo+"] Match nul");
jxoGui.desactiverTousChamps();
jxoGui.info("Match Nul !");
fini = veutTerminer();
// if(jxoGui.rejouer()){
// envoyerMessage(TypeConteneur.REJOUER_OK, TypeConteneur.REJOUER_OK);
// }else{
// envoyerMessage(TypeConteneur.REJOUER_KO, TypeConteneur.REJOUER_KO);
// fini = true;
// disconnect();
// }
jxoGui.resetMainPanel();
jxoGui.desactiverTousChamps();
}else if (tp.equals(TypeConteneur.PERDU)) {
// J'ai perdu
System.out.println("[" + pseudo+"]J'ai perdu !");
// affichage du point du gagnant.
Point p = (Point) c.getObject();
jxoGui.showPointAdversaire(p);
jxoGui.desactiverTousChamps();
jxoGui.info("Vous avez perdu cette partie !");
// demander si on veut rejouer une autre partie.
fini = veutTerminer();
// if(jxoGui.rejouer()){
// envoyerMessage(TypeConteneur.REJOUER_OK, "Je veux rejouer");
// }else{
// envoyerMessage(TypeConteneur.REJOUER_KO, "Je veux pas rejouer");
// fini = true;
// disconnect();
// }
jxoGui.resetMainPanel();
jxoGui.desactiverTousChamps();
// afficher le dernier point + le dialogue de perte.
} else if(tp.equals(TypeConteneur.REJOUER_OK)){
/*
* Relancement d'une nouvelle partie.
*/
jxoGui.setDefaultStatusBarText();
jxoGui.info("On rejoue");
jxoGui.resetMainPanel();
jxoGui.enableMainPanel();
}else if (tp.equals(TypeConteneur.DECO_ADVERSAIRE)) {
// L'adversaire s'est deconnecté => Fin de la partie
// en cours
System.out.println("[" + pseudo
+ "] Adversaire s'est deconnecté ");
jxoGui.resetMainPanel();
jxoGui.desactiverTousChamps();
jxoGui.warning("L'adversaire a quitte");
fini = !GU.confirm("Souhaitez vous rester connecte au serveur\n" +
"en attendant une autre partie?");
if(!fini){
envoyerMessage(TypeConteneur.RESTER, "Je veux rejouer");
jxoGui.setStatusBarText("Attente d'un adversaire...");
}
}
}
}
} catch (ClassNotFoundException cnfe) {
// cnfe.printStackTrace();
} catch (IOException ioe) {
jxoGui.setStatusBarText("Deconnecte...");
try {
// Fermeture de la socket
socketServeur.close();
} catch (IOException ioe2) {
ioe2.printStackTrace();
}
}
/* Le client a fini de jouer, on doit demander si
* le joueur veut reconnecter a nouveau
* - en cas de coupure serveur
* - en cas de depart d'adversaire
* - en cas d'abandon de poursuite
* ...
*/
jxoGui.resetMainPanel();
jxoGui.desactiverTousChamps();
jxoGui.setCONNECT_ACTION(ConnexionDialog.RECONNECT);
jxoGui.reshowConnexionDialog();
}
}
/**
* Dialogue de fin d'exercice:
*
*/
private boolean veutTerminer(){
if(jxoGui.rejouer()){
envoyerMessage(TypeConteneur.REJOUER_OK, TypeConteneur.REJOUER_OK);
jxoGui.setStatusBarText("Attente de reponse de l'adversaire");
return false;
}else{
envoyerMessage(TypeConteneur.REJOUER_KO, TypeConteneur.REJOUER_KO);
disconnect();
return true;
}
}
/**
* Prévenir le serveur de la demande de déplacement afin que ce dernier
* prévienne l'adversaire
*
* @param p
*/
public void envoyerDeplacementAuServeur(Point p) {
Conteneur c = new Conteneur(TypeConteneur.POINT, p);
try {
envoyerConteneur(c);
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
/**
*
* @return
*/
public boolean partieEstCommence() {
return gameStarted;
}
/**
* Envoi d'un conteneur de contenu quelconque
*/
public boolean envoyerMessage(String type, Object contenu){
Conteneur c1 = new Conteneur(type, contenu);
c1.setPseudo(pseudo);
try{
envoyerConteneur(c1);
return true;
}catch(IOException ioe){
return false;
}
}
/**
* Deconnexion du serveur cote client.
*/
public void disconnect() {
// envoi d'un message au serveur pour dire qu'on se deconnecte d'une partie.
try{
// fermeture de la socket en cours.
if(this.socketServeur != null && this.socketServeur.isConnected())
this.socketServeur.close();
}catch(IOException ioe){
ioe.printStackTrace();
}
}
/**
*
* @param args
*/
public static void main(String[] args) {
// Lancement du GUI
JXoFrame guiJXo = new JXoFrame();
try {
// recuperation des parametres du gui.
String hostName = guiJXo.getHostName();
String userName = guiJXo.getUserName();
// if(!hostName.equals("") && !userName.equals("")){
JxoClient client = new JxoClient(hostName, userName, guiJXo);
// et on reste bloque ici jusqu'a la fin du monde...
// }
} catch (UnknownHostException uhe) {
}
}
}