src/Server.cpp

00001 #include "Server.h"
00002 #include "MessageOut.h"
00003 #include "Message.h"
00004 #include "Client.h"
00005 #include "Gamefsm.h"
00006 
00007 Server::Server(int port)
00008         :mxClients(SDL_CreateMutex()),
00009         exit_request(false),
00010         chat_mode(false),
00011         mxGoSerial(SDL_CreateMutex()),
00012         gameObjectSerial(1),
00013         initialized(false)
00014 {
00015         /*
00016          * Fills the IPaddress object with correct data to create
00017          * a valid TCP listening socket for the server.
00018          */
00019         if(SDLNet_ResolveHost(&(this->data->address),NULL,port)==-1)
00020         {
00021                 std::cerr << "SDLNet_ResolveHost: " << SDLNet_GetError() << std::endl;
00022                 SDLNet_Quit();
00023                 SDL_Quit();
00024                 exit(3);
00025         }
00026 
00027         /*
00028          * Creates the server's socket that will accept new connections.
00029          */
00030         this->data->socket = SDLNet_TCP_Open(&(this->data->address));
00031         if(!(this->data->socket)){
00032                 std::cerr << "SDserverDLNet_TCP_Open: " << SDLNet_GetError() << std::endl;
00033                 exit(4);
00034         }
00035 
00036         this->data->running = true; // The server is running ...
00037         this->data->self = this;        // Pointer to self.
00038         this->data->id= 0;                      // For the moment we set this to 0.
00039 
00040         /*
00041          * Creates a new thread for the server socket.
00042          */
00043          this->data->thread = SDL_CreateThread(startThread, this->data);
00044          if (this->data->thread == NULL) {
00045                 std::cerr << "SDL_CreateThread: " << SDL_GetError() << std::endl;
00046         exit(5);
00047     }
00048 }
00049 
00050 Server::~Server(){
00051         SDL_DestroyMutex(mxClients);
00052         SDL_DestroyMutex(mxGoSerial);
00053 }
00054 
00055 void Server::startListen(ConnectionData * data){
00056         int ready = 0;
00057         TCPsocket newSocket = NULL;
00058         SDLNet_SocketSet set = NULL;
00059         Client* newClient = NULL;
00060 
00061         set = SDLNet_AllocSocketSet(1);
00062         if(!set) {
00063                 std::cerr << "SDLNet_AllocSocketSet: " << SDLNet_GetError() << std::endl;
00064                 exit(0);
00065         }
00066         SDLNet_TCP_AddSocket(set, data->socket);
00067 
00068     Gamefsm* myGamefsm = new Gamefsm(this);
00069     myGamefsm->Start(); // Starts the game state machine.
00070 
00071     while(!initialized){ // Wait for the server to be initialized
00072         SDL_Delay(100);
00073     }
00074 
00075     #ifdef TESTPHASE
00076         std::cout << "Server " << (Uint32)(data->thread) << " is now listening." << std::endl;
00077         #endif
00078 
00079         while(!exit_request){ // Main server loop
00080                 ready = SDLNet_CheckSockets(set, (Uint32) 500);
00081                 if(ready==-1){
00082                         std::cout << "SDLNet_CheckSockets: " << SDLNet_GetError() << std::endl;
00083                         break;
00084                 }
00085                 if(!ready)
00086                         continue;
00087                 if(SDLNet_SocketReady(data->socket)){
00088                         newSocket=SDLNet_TCP_Accept(data->socket);
00089                         if (newSocket){
00090                                 std::cerr<<"Socket id: "<< newSocket <<"\n";
00091                                 newClient = new Client(newSocket, this);
00092                                 addClient(newClient);
00093                                 std::cout << std::endl << "<Server> Now " << this->mClients.size() << " are connected." << std::endl;
00094                         }
00095                 }
00096         }
00097 
00098         // Since the server is exiting do the same with the game FSM.
00099         myGamefsm->Stop();
00100         SDL_Thread* tmpThread = myGamefsm->getThread();
00101         if (tmpThread != NULL) // If necessary wait for the GameFSM to finish.
00102         SDL_WaitThread(tmpThread, NULL);
00103 
00104         #ifdef TESTPHASE
00105         std::cout << "<Server> Now quitting!" << std::endl;
00106         #endif
00107 }
00108 
00109 
00110 bool Server::addClient(Client* newClient){
00111         Uint32 tmp = reinterpret_cast<Uint32>(newClient);
00112 
00113         SDL_LockMutex(this->mxClients); // Locks the mutex..
00114         this->mClients.insert(std::pair<Uint32, Client*>(tmp,newClient));// Adds the client to the map.
00115         SDL_UnlockMutex(this->mxClients);// ...unlocks the mutex
00116         return true;
00118         //      return false;
00119 }
00120 
00121 bool Server::removeClient(Client* oldClient){
00122         Uint32 tmp = reinterpret_cast<Uint32>(oldClient);
00123 
00124         SDL_LockMutex(this->mxClients);// Locks the mutex...
00125         std::map<Uint32, Client*>::iterator i;// Gets an iterator for the clients' map.
00126 
00127         i = this->mClients.find(tmp);
00128         if (i != this->mClients.end()){ // Client found!
00129                 delete i->second;
00130                 this->mClients.erase(i);
00131                 SDL_UnlockMutex(this->mxClients);// ...unlocks the mutex
00132                 return true;
00133         }
00134     else{ // Client is not in the map...that's bad I guess..
00135                 SDL_UnlockMutex(this->mxClients);// ... unlocks the mutex
00136                 return false;
00137         }
00138 }
00139 
00140 void Server::requestExit(){
00141     exit_request = true;
00142 }
00143 
00144 void Server::setChatMode(bool value){
00145     chat_mode = value;
00146 }
00147 
00148 void Server::generalChatMsg(Uint32 sender, std::string msg){
00149     if (chat_mode && sender != 0) // The sender 0 (zero) is the server itself!
00150         std::cout << msg << std::endl;
00151 
00152     std::map<Uint32, Client*>::iterator p;
00153     for (p = mClients.begin(); p != mClients.end(); p++){
00154         if(p->first != sender){ // don't sentd the message to the original sender.
00155             MessageOut* messageout = new MessageOut(MSG_CHAT);
00156             messageout->writeString(msg);
00157             messageout->addCRC();
00158             Connection::putMessage(p->second->getSocket(), messageout);
00159             delete messageout;
00160         }
00161     }
00162 }
00163 
00164 void Server::getNextGoSerial(Uint32& validSerial){
00165     SDL_LockMutex(this->mxGoSerial);
00166     validSerial = gameObjectSerial++;
00167     SDL_UnlockMutex(this->mxGoSerial);
00168     return;
00169 }
00170 
00171 void Server::setInit(bool value){
00172     initialized = value;
00173 }

Generated on Mon Dec 3 04:30:13 2007 for lo-testserver by  doxygen 1.3.9.1