summaryrefslogblamecommitdiff
path: root/src/game-server/accountconnection.cpp
blob: c5da8e2a21b2a944ed2feee0e290e545a51d87ac (plain) (tree)



















                                                                             
        

   

                                            
                    
                                   
                                    
                                      

                                       
                                     
                                  
                                
                                

                             
                                      
                         
                                   
                                   


                               


                                                                                   


                     
                                                              
                                   

                                                                                       
                                                      







                                                                                          
                                                       

                                      
                                      
                                    


              





                                                      
                                                                   
                                                
                                       
                                                         

                


                                     
                                        

                


                                     
                                                                   



                                                                        
 







                                                 
                                 
         




                                                          
                
 

















                                                                         
                                                  






















                                                                         





                                       







                                                     
                
                                             


                  
 
                                                                                      
 
                                              

                                           
                                                     
              
 
 

















                                                                               







                                                                 










































                                                                         



                                                                       
                                           









                                                           
              




                                                                  
                                            



                                       
/*
 *  The Mana World
 *  Copyright 2006 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 "game-server/accountconnection.hpp"

#include "defines.h"
#include "common/configuration.hpp"
#include "game-server/character.hpp"
#include "game-server/gamehandler.hpp"
#include "game-server/map.hpp"
#include "game-server/mapcomposite.hpp"
#include "game-server/mapmanager.hpp"
#include "game-server/postman.hpp"
#include "game-server/quest.hpp"
#include "game-server/state.hpp"
#include "net/messagein.hpp"
#include "net/messageout.hpp"
#include "serialize/characterdata.hpp"
#include "utils/logger.h"
#include "utils/tokendispenser.hpp"
#include "utils/tokencollector.hpp"

bool AccountConnection::start()
{
    if (!Connection::start(
            Configuration::getValue("accountServerAddress", "localhost"),
            Configuration::getValue("accountServerPort", DEFAULT_SERVER_PORT) + 1))
    {
        return false;
    }
    LOG_INFO("Connection established to the account server.");
    MessageOut msg(GAMSG_REGISTER);
    msg.writeString(Configuration::getValue("gameServerAddress", "localhost"));
    msg.writeShort(Configuration::getValue("gameServerPort", DEFAULT_SERVER_PORT + 3));
    MapManager::Maps const &m = MapManager::getMaps();
    for (MapManager::Maps::const_iterator i = m.begin(), i_end = m.end(); i != i_end; ++i)
    {
        msg.writeShort(i->first);
    }
    send(msg);
    return true;
}

void AccountConnection::sendCharacterData(Character *p)
{
    MessageOut msg(GAMSG_PLAYER_DATA);
    msg.writeLong(p->getDatabaseID());
    serializeCharacterData(*p, msg);
    send(msg);
}

void AccountConnection::processMessage(MessageIn &msg)
{
    switch (msg.getId())
    {
        case AGMSG_PLAYER_ENTER:
        {
            std::string token = msg.readString(MAGIC_TOKEN_LENGTH);
            Character *ptr = new Character(msg);
            ptr->setSpeed(250); // TODO
            gameHandler->addPendingCharacter(token, ptr);
        } break;

        case AGMSG_ACTIVE_MAP:
        {
            int id = msg.readShort();
            MapManager::raiseActive(id);
        } break;

        case AGMSG_REDIRECT_RESPONSE:
        {
            int id = msg.readLong();
            std::string token = msg.readString(MAGIC_TOKEN_LENGTH);
            std::string address = msg.readString();
            int port = msg.readShort();
            gameHandler->completeServerChange(id, token, address, port);
        } break;

        case AGMSG_GET_QUEST_RESPONSE:
        {
            int id = msg.readLong();
            std::string name = msg.readString();
            std::string value = msg.readString();
            recoveredQuestVar(id, name, value);
        } break;

        case CGMSG_CHANGED_PARTY:
        {
            // Party id, 0 for none
            int partyid = msg.readLong();
            // Character DB id
            int charid = msg.readLong();
            gameHandler->updateCharacter(charid, partyid);
        } break;

        case CGMSG_POST_RESPONSE:
        {
            // get the character
            Character *character = postMan->getCharacter(msg.readLong());

            // check character is still valid
            if (!character)
            {
                break;
            }

            // create the message
            MessageOut out(GPMSG_GET_POST_RESPONSE);

            // get all the post for a character
            while (msg.getUnreadLength())
            {
                // write the sender
                out.writeString(msg.readString());

                // write the contents
                out.writeString(msg.readString());

                // read the number of attachments then
                // write the attachments
                for (int i = 0; i < msg.readShort(); ++i)
                {
                    // write the id and amount
                    out.writeShort(msg.readShort());
                    out.writeShort(msg.readShort());
                }
            }

            // send post to character
            gameHandler->sendTo(character, out);
        } break;

        case CGMSG_STORE_POST_RESPONSE:
        {
            // get character
            Character *character = postMan->getCharacter(msg.readLong());

            // check character is valid
            if (!character)
            {
                break;
            }

            // create message and put error inside
            MessageOut out(GPMSG_SEND_POST_RESPONSE);
            out.writeByte(msg.readByte());

            // send message to character
            gameHandler->sendTo(character, out);
        } break;

        default:
            LOG_WARN("Invalid message type");
            break;
    }
}

void AccountConnection::playerReconnectAccount(int id, std::string const &magic_token)
{
    LOG_DEBUG("Send GAMSG_PLAYER_RECONNECT.");
    MessageOut msg(GAMSG_PLAYER_RECONNECT);
    msg.writeLong(id);
    msg.writeString(magic_token, MAGIC_TOKEN_LENGTH);
    send(msg);
}

void AccountConnection::requestQuestVar(Character *ch, std::string const &name)
{
    MessageOut msg(GAMSG_GET_QUEST);
    msg.writeLong(ch->getDatabaseID());
    msg.writeString(name);
    send(msg);
}

void AccountConnection::updateQuestVar(Character *ch, std::string const &name,
                                        std::string const &value)
{
    MessageOut msg(GAMSG_SET_QUEST);
    msg.writeLong(ch->getDatabaseID());
    msg.writeString(name);
    msg.writeString(value);
    send(msg);
}

void AccountConnection::banCharacter(Character *ch, int duration)
{
    MessageOut msg(GAMSG_BAN_PLAYER);
    msg.writeLong(ch->getDatabaseID());
    msg.writeShort(duration);
    send(msg);
}

void AccountConnection::sendStatistics()
{
    MessageOut msg(GAMSG_STATISTICS);
    MapManager::Maps const &maps = MapManager::getMaps();
    for (MapManager::Maps::const_iterator i = maps.begin(),
         i_end = maps.end(); i != i_end; ++i)
    {
        MapComposite *m = i->second;
        if (!m->isActive()) continue;
        msg.writeShort(i->first);
        int nbThings = 0, nbMonsters = 0;
        typedef std::vector< Thing * > Things;
        Things const &things = m->getEverything();
        std::vector< int > players;
        for (Things::const_iterator j = things.begin(),
             j_end = things.end(); j != j_end; ++j)
        {
            Thing *t = *j;
            switch (t->getType())
            {
                case OBJECT_CHARACTER:
                    players.push_back
                        (static_cast< Character * >(t)->getDatabaseID());
                    break;
                case OBJECT_MONSTER:
                    ++nbMonsters;
                    break;
                default:
                    ++nbThings;
            }
        }
        msg.writeShort(nbThings);
        msg.writeShort(nbMonsters);
        msg.writeShort(players.size());
        for (std::vector< int >::const_iterator j = players.begin(),
             j_end = players.end(); j != j_end; ++j)
        {
            msg.writeLong(*j);
        }
    }
    send(msg);
}

void AccountConnection::sendPost(Character *c, MessageIn &msg)
{
    // send message to account server with id of sending player,
    // the id of receiving player, the letter contents, and attachments
    LOG_DEBUG("Sending GCMSG_STORE_POST.");
    MessageOut out(GCMSG_STORE_POST);
    out.writeLong(c->getDatabaseID());
    out.writeString(msg.readString());
    out.writeString(msg.readString());
    while (msg.getUnreadLength())
    {
        // write the item id and amount for each attachment
        out.writeLong(msg.readShort());
        out.writeLong(msg.readShort());
    }
    send(out);
}

void AccountConnection::getPost(Character *c)
{
    // send message to account server with id of retrieving player
    LOG_DEBUG("Sending GCMSG_REQUEST_POST");
    MessageOut out(GCMSG_REQUEST_POST);
    out.writeLong(c->getDatabaseID());
    send(out);
}