summaryrefslogblamecommitdiff
path: root/src/connectionhandler.cpp
blob: 5f09e9c77f5b2d07f7f4cd8a2945d1b09faa53ed (plain) (tree)























                                                                             
                       
                
 



                     
                        
 




                         


                                      
 




                                                              
                                                                    




                                                     
                                                               










                                                                   
                                                                      




                                                              
                                                                 








                                                                  
                                                                               




                                                                  
                                                                            
























                                                                  

                                                                          
                                           
                                                           
                     
                                                  
      























                                                                       
                                       



                                                               
                                          

 

                                                    


                              
/*
 *  The Mana World Server
 *  Copyright 2004 The Mana World Development Team
 *
 *  This file is part of The Mana World.
 *
 *  The Mana World is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  any later version.
 *
 *  The Mana World is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with The Mana World; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 *  $Id$
 */

#include "connectionhandler.h"
#include "netsession.h"
#include "log.h"

#ifdef SCRIPT_SUPPORT
#include "script.h"
#endif

#define MAX_CLIENTS 1024

ClientData::ClientData():
    inp(0)
{
}

ConnectionHandler::ConnectionHandler()
{
}

void ConnectionHandler::startListen(ListenThreadData *ltd)
{
    // Allocate a socket set
    SDLNet_SocketSet set = SDLNet_AllocSocketSet(MAX_CLIENTS);
    if (!set) {
        logger->log("SDLNet_AllocSocketSet: %s", SDLNet_GetError());
        exit(1);
    }

    // Add the server socket to the socket set
    if (SDLNet_TCP_AddSocket(set, ltd->socket) < 0) {
        logger->log("SDLNet_AddSocket: %s", SDLNet_GetError());
        exit(1);
    }

    // Keep checking for socket activity while running
    while (ltd->running)
    {
        int numready = SDLNet_CheckSockets(set, 100);

        if (numready == -1)
        {
            printf("SDLNet_CheckSockets: %s\n", SDLNet_GetError());
            logger->log("SDLNet_CheckSockets: %s", SDLNet_GetError());
            // When this is a system error, perror may help us
            perror("SDLNet_CheckSockets");
        }
        else if (numready > 0)
        {
            logger->log("%d sockets with activity!\n", numready);

            // Check server socket
            if (SDLNet_SocketReady(ltd->socket))
            {
                TCPsocket client = SDLNet_TCP_Accept(ltd->socket);
                if (client)
                {
                    // Add the client socket to the socket set
                    if (SDLNet_TCP_AddSocket(set, client) < 0) {
                        logger->log("SDLNet_AddSocket: %s", SDLNet_GetError());
                    }
                    else {
                        NetComputer *comp = new NetComputer(this);
                        clients[comp] = client;
                        computerConnected(comp);
                        logger->log("%d clients connected", clients.size());
                    }
                }
            }

            // Check client sockets
            std::map<NetComputer*, TCPsocket>::iterator i;
            for (i = clients.begin(); i != clients.end(); )
            {
                NetComputer *comp = (*i).first;
                TCPsocket s = (*i).second;

                if (SDLNet_SocketReady(s))
                {
                    char buffer[1024];
                    int result = SDLNet_TCP_Recv(s, buffer, 1024);
                    if (result <= 0)
                    {
                        SDLNet_TCP_DelSocket(set, s);
                        SDLNet_TCP_Close(s);
                        computerDisconnected(comp);
                        delete comp;
                        comp = NULL;
                    }
                    else
                    {
                        // Copy the incoming data to the in buffer of this
                        // client
                        buffer[result] = 0;
                        logger->log("Received %s", buffer);
#ifdef SCRIPT_SUPPORT
                        //script->message(buffer);
#endif
                    }
                }

                // Traverse to next client, possibly deleting current
                if (comp == NULL) {
                    std::map<NetComputer*, TCPsocket>::iterator ii = i;
                    ii++;
                    clients.erase(i);
                    i = ii;
                }
                else {
                    i++;
                }
            }
        }
    }

    // - Disconnect all clients (close sockets)

    SDLNet_FreeSocketSet(set);
}

void ConnectionHandler::computerConnected(NetComputer *comp)
{
    logger->log("A client connected!");
}

void ConnectionHandler::computerDisconnected(NetComputer *comp)
{
    logger->log("A client disconnected!");
}

void ConnectionHandler::registerHandler(
        unsigned int msgId, MessageHandler *handler)
{
    handlers[msgId] = handler;
}