/Desktop/MGS-MultithreadedGameServer/Plugins/Games/ChatRoom.cc

Vai alla documentazione di questo file.
00001 //
00002 // File: ChatRoom.cc
00003 // Created by: <Detro /> aka Ivan De Marino 
00004 // <detro@mandolinux.org, demarino@studenti.unina.it, demarino@na.astro.it>
00005 // Created on: Wed Oct 27 15:37:00 2004
00006 //
00007 
00008 #include "ChatRoom.h"
00009 
00010 /** Costruttore di default della Classe ChatRoom */
00011 ChatRoom::ChatRoom(void) {}
00012 
00013 /** 
00014  * Costruttore overlodato della Classe ChatRoom.
00015  *
00016  * @param firstPlayer Primo giocatore della nuova ChatRoom */
00017 ChatRoom::ChatRoom(Player *firstPlayer) {
00018    addPlayer(firstPlayer);
00019 }
00020 
00021 /** Distruttore della Classe ChatRoom. */
00022 ChatRoom::~ChatRoom(void) {exit();}
00023 
00024 /** 
00025  * Inizializzazione della ChatRoom. 
00026  * Metodo vuoto ereditato da <code>Game</code>. */
00027 void ChatRoom::init(void) {}
00028 
00029 /**
00030  * Flusso di Controllo di ChatRoom.
00031  * Questo metodo rappresenta il Flusso di Controllo principale
00032  * del @c Thread. <br>
00033  * Qui' e' concentrato il funzionamento della ChatRoom. */
00034 void ChatRoom::run(void) {
00035    string message;
00036    string completeMessage;
00037    
00038    list<Player *>::iterator pli;
00039    char time_buffer[64];
00040    int last;
00041    time_t t;
00042    tm *tbp;
00043    string now;
00044 
00045    while (true) {
00046       if ( playerList.size() == 0 ) {
00047          cout << "<ChatRoom msg> ChatRoom Empty: Suspended." << endl;
00048          suspend();
00049          cout << "<ChatRoom msg> ChatRoom Resumed." << endl;
00050       }
00051       pli = playerList.begin();
00052          
00053       while ( pli != playerList.end() ) {
00054          /* Recupera eventuale messaggio digitato dall'utente:
00055           * attende 5 decimi di secondo */
00056          message = (*pli)->hear(500);
00057       
00058          /* Calcola l'ora e la data corrente. */
00059          t = std::time(NULL);
00060          tbp = std::localtime(&t);
00061          last = std::strftime(time_buffer, 64, "%Y-%m-%d %H:%M:%S", tbp);
00062          time_buffer[last] = '\0';
00063          now = time_buffer;
00064          
00065          /* Costruisce il Messaggio */ 
00066          completeMessage = "[" + now + "] ";
00067          completeMessage += (*pli)->getName();
00068          completeMessage += " >>> " + message + "\n";
00069             
00070          if ( !message.empty() ) {
00071             if ( !strcmp(message.data(), "\\quit") ) {
00072                delPlayer(*pli);
00073                break;
00074             }
00075             else {
00076                /* Invia il messaggio a tutti, tranne che
00077                 * al Player "pli" */
00078                sayToAll(completeMessage, *pli);
00079             }
00080          }
00081          pli++;
00082       
00083          /* e' necessario ripulire la stringa del messaggio dell'utente */
00084          message.clear();
00085       }
00086       /* Attendiamo 2 decimi di second prima di ricominciare
00087        * a trasmettere messaggi. */
00088       sleep(200);
00089    }
00090    
00091 }
00092 
00093 /** 
00094  * Chiusura della ChatRoom.
00095  * Metodo ereditato da <code>Thread</code>,
00096  * richiamato (automaticamente dalla Librerie) 
00097  * alla fine del metodo <code>run()</code>. <br>
00098  * Gestisce la corretta chiusura della <code>ChatRoom</code>: 
00099  * viene richiamato al termine del metodo 
00100  * @c "run()" o del metodo @c "exit()". */
00101 void ChatRoom::final(void) {
00102    if ( playerList.size() > 0 ) {
00103       list<Player *>::iterator pli;
00104       Player *temp;
00105       mutex.enterMutex();
00106       
00107       while ( pli != playerList.end() ) {
00108          /* Se il player e' presente:
00109           * 1) riceve un messaggio di arrivederci
00110           * 2) Viene riattivato il suo ConnectionHandler
00111           * 3) Viene eliminato dalla lista */
00112          (*pli)->say("<ChatRoom msg> ChatRoom Terminated. Now exit.\n");
00113          (*pli)->resumeConnHandler();
00114          temp = *pli;
00115          pli++;
00116          playerList.remove(temp);
00117       }
00118       
00119       mutex.leaveMutex();
00120    }
00121 }
00122 
00123 
00124 /**
00125  * Aggiungi un <code>Player</code> alla ChatRoom.
00126  * Un messaggio di Benvenuto viene inviato all'utente e
00127  * gli altri partecipanti alla ChatRoom vengono avvertiti
00128  * dell'arrivo del nuovo Player.
00129  *
00130  * @param newPlayer Nuovo giocatore. */
00131 void ChatRoom::addPlayer (Player *newPlayer) {
00132    mutex.enterMutex();
00133    
00134    playerList.push_back(newPlayer);
00135    /* Messaggi di Benvenuto */
00136    /* ...per il nuovo utente... */
00137    newPlayer->say("\n<----------------------------------------->\n");
00138    newPlayer->say(">>>>>     Hello at MGS's ChatRoom     <<<<<\n");
00139    newPlayer->say("<----------------------------------------->\n\n");
00140    newPlayer->say("[Users On-Line: ");
00141    newPlayer->say((int)(playerList.size() -1));
00142    newPlayer->say("]\n");
00143 
00144    /* ...per i restanti... */
00145    sayToAll("<ChatRoom msg> " + newPlayer->getName() + " has joined at this ChatRoom\n",
00146       newPlayer);
00147    cout << "<ChatRoom msg> " << newPlayer->getName() << " has joined at this ChatRoom\n";
00148 
00149    /* Riattiva o Avvia il Thread se l'utente appena inserito e'
00150     * l'unico */
00151    if ( playerList.size() == 1 ) {
00152       if ( isRunning() )
00153          resume();
00154       else
00155          start();
00156    }
00157 
00158    mutex.leaveMutex();
00159 }
00160 
00161 /**
00162  * Rimuovi un <code>Player</code> dalla ChatRoom (overloaded).
00163  * Un messaggio di Arrivederci viene inviato all'utente e
00164  * gli altri partecipanti alla ChatRoom vengono avvertiti.
00165  *
00166  * @param toDelete Nome del Player da eliminare. 
00167  * @return @c true se il Player viene trovato e rimosso, 
00168  *    @c false altrimenti */
00169 bool ChatRoom::delPlayer (const string &toDelete) {
00170    list<Player *>::iterator pli;
00171    mutex.enterMutex();
00172 
00173    pli = playerList.begin();
00174    while ( pli != playerList.end() ) {
00175       if ( (*pli)->getName() == toDelete) {
00176          /* Se il player é presente:
00177           * 1) riceve un messaggio di arrivederci
00178           * 2) Viene riattivato il suo ConnectionHandler
00179           * 3) Viene eliminato dalla lista */
00180          (*pli)->say("<ChatRoom msg> GoodBye. ;-)\n");
00181          sayToAll("<ChatRoom msg> " + (*pli)->getName() + " has leaved this ChatRoom\n", *pli);
00182          (*pli)->resumeConnHandler();
00183          playerList.remove(*pli);
00184          mutex.leaveMutex();
00185          return true;
00186       }
00187       pli++;
00188    }
00189    
00190    mutex.leaveMutex();
00191    return false;
00192 }
00193 
00194 /**
00195  * Rimuovi un <code>Player</code> dalla ChatRoom (overloaded).
00196  * Un messaggio di Arrivederci viene inviato all'utente e
00197  * gli altri partecipanti alla ChatRoom vengono avvertiti.
00198  *
00199  * @param toDelete Puntatore al Player da eliminare. */
00200 void ChatRoom::delPlayer (Player *toDelete) {
00201    mutex.enterMutex();
00202 
00203    toDelete->say("<ChatRoom msg> GoodBye. ;-)\n");
00204    sayToAll("<ChatRoom msg> " + toDelete->getName() + " has leaved this ChatRoom\n", toDelete);
00205    toDelete->resumeConnHandler();
00206    playerList.remove(toDelete);
00207    
00208    mutex.leaveMutex();
00209 }
00210 
00211 /** 
00212  * Ritorna il numero di <code>Player</code> presenti nella ChatRoom. 
00213  * @return Ritorna il numero di Player presenti nella ChatRoom */
00214 int ChatRoom::getNumPlayers (void) const {
00215    return playerList.size();
00216 }
00217 
00218 /** Stampa la lista dei <code>Player</code> presenti nella ChatRoom. */
00219 void ChatRoom::printPlayersList(iostream *streamWherePrint) {
00220    list<Player *>::iterator pli;
00221    mutex.enterMutex();
00222 
00223    pli = playerList.begin();
00224    while ( pli != playerList.end() ) {
00225       *streamWherePrint << "\t* " << (*pli)->getName() << endl;
00226       pli++;
00227    }
00228    
00229    mutex.leaveMutex();
00230 }
00231 
00232 string ChatRoom::getName(void) const {return "ChatRoom - Simple Chat for MGS";}
00233 
00234 /**
00235  * Invia un messaggio a tutti i <code>Player</code> della ChatRoom.
00236  * Questo metodo e' utilizzato per "girare" i messaggi digitati
00237  * da un <code>Player</code> a tutti gli altri 
00238  * <code>Player</code> presenti nella ChatRoom.
00239  * 
00240  * @param message Stringa del messaggio da Inviare
00241  * @param notSay Puntato del <code>Player</code> a cui NON INVIARE 
00242  *    il messaggio (probabilmente e' colui che l'ha scritto). */
00243 void ChatRoom::sayToAll(const string &message, Player *notSay) {
00244    list<Player *>::iterator pli;
00245 
00246    pli = playerList.begin();
00247    while ( pli != playerList.end() ) {
00248       if ( notSay == NULL || (notSay != NULL && *pli != notSay) )
00249          (*pli)->say(message);
00250       pli++;
00251    }
00252 }
00253 
00254 /** 
00255  * Ritorna un nuovo oggetto "ChatRoom".
00256  * E' necessario per poter utilizzare la Classe come Plug-In 
00257  * e quindi essere istanziata a Run-Time */
00258 extern "C"
00259 ChatRoom *buildObject(void) { return new ChatRoom; }

Generato il Sun Nov 28 13:27:03 2004 per MGS - Multithreaded Game Server da doxygen 1.3.4