ServeurJeu.h

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2007 by Pierre Schmitt, Ludovic Giacomello, Nhi Ly      *
00003  *                                                                         *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  *   This program is distributed in the hope that it will be useful,       *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013  *   GNU General Public License for more details.                          *
00014  *                                                                         *
00015  *   You should have received a copy of the GNU General Public License     *
00016  *   along with this program; if not, write to the                         *
00017  *   Free Software Foundation, Inc.,                                       *
00018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00019  ***************************************************************************/
00020 
00021 
00022 #ifndef SERVEURJEU_H
00023 #define SERVEURJEU_H
00024 
00025 #include<string>
00026 #include<iostream>
00027 
00028 #include "SocketTCP.h"
00029 #include "SocketUDP.h"
00030 
00031 #include "TraitementJoueur.h"
00032 #include "TraitementComServeurPrincipal.h"
00033 
00037 class ServeurJeu {
00038 public:
00045         ServeurJeu(unsigned int port, unsigned int nbFantomeAuto=0){
00046                 mJeu=Jeu::GetInstance();
00047                 mPort=port; mNbFantomeAuto=nbFantomeAuto;
00048                 mJeu->SetNbFantomeAuto(nbFantomeAuto);
00049                 cout<<endl<<"    SJ ServeurJeu::Création d'un serveur de jeu sur le port "<<port<<" avec "<<mJeu->GetNbFantomeAuto()<<" fantomes automatiques"<<endl;
00050                 Traitement();
00051         }
00052 
00053         ~ServeurJeu(){ 
00054                 cout<<"    SJ ServeurJeu::Destruction du serveur de jeu"<<endl;
00055                 cout<<"      SJ ServeurJeu::Destruction de la socket d'écoute"<<endl;
00056                 if(mSocketEcoute!=NULL) delete mSocketEcoute; 
00057                 cout<<"      SJ ServeurJeu::Destruction des threads de traitement des clients"<<endl;
00058                 for(int i=0; i<4; i++){
00059                         if(mTJ[i]!=NULL) delete mTJ[i]; 
00060                 }
00061                 if(mServeurPrincipal!=NULL) delete mServeurPrincipal;
00062                 Jeu::KillInstance(); 
00063         }
00064 
00065 
00066 private:
00070         void Traitement(){
00071                 if(!CreationSocketEcoute()){
00072                         cout<<"    SJ ServeurJeu::"; printf( "\e[31m[Erreur Fatale]\e[m\n" );
00073                         exit(-1);
00074                 }
00075                 DemarrerFantomeAuto();
00076                 CreationThreadComServeurPrincipal();
00077                 do{
00078                         if(!AttendreClient()){
00079                                 cout<<"    SJ ServeurJeu::"; printf( "\e[31m[Erreur Fatale]\e[m\n" );
00080                                 exit(-1);
00081                         }
00082                 } while(!AttendreDebutPartie());
00083                 AttendreFinPartie();
00084         }
00085 
00090         bool CreationSocketEcoute(){
00091                 bool stop=true;
00092                 cout<<endl<<"    SJ ServeurJeu::Création du serveur avec "<<mNbFantomeAuto<<" fantomes automatiques"<<endl;
00093                 try{
00094                         mSocketEcoute=new SocketTCP((unsigned int)mPort); 
00095                 } catch(SocketException s){
00096                         cout<<"    SJ ServeurJeu::"; printf( "\e[31m[Erreur] \e[m" ); cout<<"Impossible de créer la socket d'écoute"<<endl;
00097                         return false;
00098                 }
00099                 return true;
00100         }
00101         
00106         void DemarrerFantomeAuto(){
00107                 unsigned int k=0;
00108                 //On initialise les places pour les threads à NULL
00109                 for(unsigned int i=0; i<4; i++){
00110                         mTJ[i]=NULL;
00111                 }
00112                 //Création des fantomes automatiques 
00113                 if(mNbFantomeAuto<=3){
00114                         for(unsigned int i=0; i<mNbFantomeAuto; i++){
00115                                 cout<<"    SJ ServeurJeu::Démarrage d'un thread fantome"<<endl;
00116                                 TraitementJoueur *t=new TraitementJoueur(NULL);
00117                                 t->Demarrer();
00118                                 mTJ[k]=t; k++;
00119                         }
00120                 } else cerr<<"    SJ ServeurJeu::Trop de fantomes automatiques!!!"<<endl;
00121         }
00122 
00126         void CreationThreadComServeurPrincipal(){
00127                 cout<<"    SJ ServeurJeu::Création d'un thread de communication avec le serveur principal"<<endl;
00128                 //On créé un thread afin de communiquer l'état de la partie au serveur principal
00129                 mServeurPrincipal=new TraitementComServeurPrincipal(mPort);
00130                 mServeurPrincipal->Demarrer();
00131         }
00132 
00137         bool AttendreClient(){
00138                 cout<<"    SJ ServeurJeu::Attente des clients"<<endl;
00139                 while(1){
00140                         //On attend la connexion des clients tant qu'il y a de la place
00141                         bool place=false; unsigned int pos;
00142                         for(unsigned int i=0; i<4; i++){
00143                                 if(mTJ[i]==NULL) {
00144                                         place=true;
00145                                         pos=i;
00146                                         break;
00147                                 }
00148                         }
00149                         if(place){
00150                                 //On attend la connexion d'un client 
00151                                 try{
00152                                         Socket *s=mSocketEcoute->Accept();
00153                                         cout<<endl<<"    SJ ServeurJeu::Connexion d'un client"<<endl;
00154                                         //Passer la nouvelle socket à un thread qui va gérer le traitement
00155                                         TraitementJoueur *t=new TraitementJoueur(s);
00156                                         t->Demarrer();
00157                                         //On stock le thread dans une case libre 
00158                                         mTJ[pos]=t;
00159                                 } catch(SocketException s){
00160                                         cout<<"    SJ ServeurJeu::"; printf( "\e[31m[Erreur] \e[m" ); cout<<"Impossible d'accepter le nouveau client"<<endl;
00161                                         return false;
00162                                 }
00163                         } else break;
00164                 }
00165                 cout<<"    SJ ServeurJeu::Tous les clients attendus sont connectés"<<endl;
00166                 return true;
00167         }
00168 
00174         bool AttendreDebutPartie(){
00175                 cout<<"    SJ ServeurJeu::Attente du début de la partie"<<endl;
00176                 while(!mJeu->JeuPret()){
00177                         //On vérifie qu'un client ne s'est pas déconnecté avant que la partie ne commence 
00178                         for(unsigned int i=0; i<4; i++){
00179                                 bool unZombi=false;
00180                                 if(mTJ[i]!=NULL) if(mTJ[i]->IsZombie()) {
00181                                         cout<<"    SJ ServeurJeu::"; printf( "\e[31m[Avertissement] \e[m" ); cout<<"Un thread en mode "; printf( "\e[31mZombie \e[m" ); cout<<"a été détecté"<<endl;
00182                                         cout<<"    SJ ServeurJeu::"; printf( "\e[32m[Récupération] \e[m" ); cout<<"On supprime le thread et on repasse en mode d'attente"<<endl;
00183                                         delete mTJ[i];
00184                                         mTJ[i]=NULL;
00185                                         unZombi=true;
00186                                 }
00187                                 if(unZombi) return false; //Afin que Traitement() boucle sur l'attente des clients
00188                         }
00189                         sleep(1);
00190                 }
00191                 cout<<"    SJ ServeurJeu::La partie commence"<<endl;
00192                 return true;
00193         }
00194 
00201         void AttendreFinPartie(){
00202                 cout<<"    SJ ServeurJeu::Attente de la fin de la partie"<<endl;        
00203                 unsigned int nbJoueurVivant=4-mNbFantomeAuto;
00204                 bool stop=false;
00205                 while((!mJeu->GameOver())&&(stop==false)){
00206                         //On vérifie qu'un client ne s'est pas déconnecté pendant la partie
00207                         for(unsigned int i=0; i<4; i++){
00208                                 if(mTJ[i]!=NULL) if(mTJ[i]->IsZombie()) {
00209                                         cout<<"    SJ ServeurJeu::"; printf( "\e[31m[Avertissement] \e[m" ); cout<<"Un thread en mode "; printf( "\e[31mZombie \e[m" ); cout<<"a été détecté"<<endl;
00210                                         cout<<"    SJ ServeurJeu::"; printf( "\e[32m[Récupération] \e[m" ); cout<<"On supprime le thread"<<endl;
00211                                         delete mTJ[i];
00212                                         mTJ[i]=NULL;
00213                                         nbJoueurVivant--;
00214                                         if(nbJoueurVivant==0){
00215                                                 cout<<"    SJ ServeurJeu::"; printf( "\e[31m[Erreur Récupération] \e[m" ); cout<<"Plus de joueur vivant, abandon de la partie"<<endl;
00216                                                 mJeu->KillGame(); //De cette manière on indique en udp au serveur que le jeu a été aborté
00217                                                 stop=true;
00218                                                 break;
00219                                         } else {
00220                                                 cout<<"    SJ ServeurJeu::"; printf( "\e[32m[Récupération] \e[m" ); cout<<"On remplace le joueur par un joueur automatique"<<endl;
00221                                                 TraitementJoueur *t=new TraitementJoueur(NULL,true);
00222                                                 t->Demarrer();
00223                                                 mTJ[i]=t;       
00224                                                 
00225                                         }
00226                                 }
00227                         }
00228                         sleep(1); //On attend la fin de la partie...
00229                 }
00230                 cout<<"    SJ ServeurJeu::La partie est terminée"<<endl;
00231                 sleep(3);//On attend avant de fermer pour laisser le temps au thread de communication avec le SP d'indiquer que la partie est terminée
00232         }
00233 
00237         unsigned int mPort;
00238 
00242         unsigned int mNbFantomeAuto;
00243 
00247         Socket *mSocketEcoute;
00248 
00252         TraitementJoueur *mTJ[4];
00253 
00257         TraitementComServeurPrincipal *mServeurPrincipal;
00258 
00262         Jeu *mJeu;
00263 };
00264 
00265 #endif

Generated on Wed Jan 2 14:01:41 2008 for Pacman by  doxygen 1.5.1