summaryrefslogblamecommitdiff
path: root/src/chat-server/partyhandler.cpp
blob: c9dcb91dc84876e1094422359557ff65b1960334 (plain) (tree)






























                                                                             
                        
 

                    




































































                                                                                         




                                                           
                               









                                                        








                                                                             

                                           
                                        






                                                    
     

                                                      
         




                                                               

                             
             
         

              
     

               

















                                                     





















                                                                          
                  















                                                   















































                                                                                  
/*
 *  The Mana World Server
 *  Copyright 2008 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
 */

#include "chathandler.hpp"
#include "chatclient.hpp"
#include "party.hpp"

#include "../account-server/dalstorage.hpp"
#include "../account-server/serverhandler.hpp"

#include "../net/messagein.hpp"
#include "../net/messageout.hpp"

#include "../protocol.h"

#include <algorithm>

void updateInfo(ChatClient *client, int partyId)
{
    Character *character = storage->getCharacter(client->characterName);
    GameServerHandler::sendPartyChange(character, partyId);
}

bool ChatHandler::handlePartyJoin(const std::string &invited, const std::string &inviter)
{
    MessageOut out(CPMSG_PARTY_INVITE_RESPONSE);

    // Get inviting client
    ChatClient *c1 = getClient(inviter);
    if (c1)
    {
        // if party doesnt exist, create it
        if (!c1->party)
        {
            c1->party = new Party();
            // tell game server to update info
            updateInfo(c1, c1->party->getId());
        }

        // add inviter to the party
        c1->party->addUser(inviter);

        // Get invited client
        ChatClient *c2 = getClient(invited);
        if (c2)
        {
            // add invited to the party
            c1->party->addUser(invited);
            c2->party = c1->party;
            // was successful so return success to inviter
            out.writeString(invited);
            out.writeByte(ERRMSG_OK);
            c1->send(out);

            // tell everyone a player joined
            informPartyMemberJoined(*c2);

            // tell game server to update info
            updateInfo(c2, c2->party->getId());
            return true;
        }
    }

    // there was an error, return false
    return false;

}

void ChatHandler::handlePartyInvite(ChatClient &client, MessageIn &msg)
{
    //TODO: Handle errors
    MessageOut out(CPMSG_PARTY_INVITED);

    out.writeString(client.characterName);

    std::string invited = msg.readString();
    if (invited == client.characterName)
    {
        return;
    }
    if (invited != "")
    {
        // Get client and send it the invite
        ChatClient *c = getClient(invited);
        if (c)
        {
            ++client.numInvites;

            // TODO: Check number of invites
            // and do something if too many in a short time

            // store the invite
            PartyInvite invite;
            invite.mInvited = invited;
            invite.mInviter = client.characterName;
            if (client.party)
                invite.mPartyId = client.party->getId();
            else
                invite.mPartyId = 0;

            mPartyInvitedUsers.push_back(invite);

            c->send(out);
        }
    }
}

void ChatHandler::handlePartyAcceptInvite(ChatClient &client, MessageIn &msg)
{
    MessageOut out(CPMSG_PARTY_ACCEPT_INVITE_RESPONSE);

    std::string inviter = msg.readString();

    // Check that the player was invited
    std::vector<PartyInvite>::iterator itr, itr_end;
    itr = mPartyInvitedUsers.begin();
    itr_end = mPartyInvitedUsers.end();

    bool found = false;

    while (itr != itr_end)
    {
        if ((*itr).mInvited == client.characterName &&
            (*itr).mInviter == inviter)
        {
            // make them join the party
            if (handlePartyJoin(client.characterName, inviter))
            {
                out.writeByte(ERRMSG_OK);
                mPartyInvitedUsers.erase(itr);
                found = true;
                break;
            }
        }

        ++itr;
    }

    if (!found)
    {
        out.writeByte(ERRMSG_FAILURE);
    }

    client.send(out);
}

void ChatHandler::handlePartyQuit(ChatClient &client)
{
    removeUserFromParty(client);
    MessageOut out(CPMSG_PARTY_QUIT_RESPONSE);
    out.writeByte(ERRMSG_OK);
    client.send(out);

    // tell game server to update info
    updateInfo(&client, 0);
}

void ChatHandler::handlePartyRejection(ChatClient &client, MessageIn &msg)
{
    MessageOut out(CPMSG_PARTY_REJECTED);

    std::string inviter = msg.readString();


    std::vector<PartyInvite>::iterator itr, itr_end;

    itr = mPartyInvitedUsers.begin();
    itr_end = mPartyInvitedUsers.end();
    bool found = false;

    while (itr != itr_end)
    {
        // Check that the player was invited
        if ((*itr).mInvited == client.characterName &&
            (*itr).mInviter == inviter)
        {
            // remove them from invited users list
            mPartyInvitedUsers.erase(itr);
            found = true;
            break;
        }

        ++itr;
    }

    if (!found)
    {
        out.writeByte(ERRMSG_FAILURE);
    }

    // send rejection to inviter
    ChatClient *inviterClient = getClient(inviter);

    inviterClient->send(out);
}

void ChatHandler::removeUserFromParty(ChatClient &client)
{
    if (client.party)
    {
        client.party->removeUser(client.characterName);
        informPartyMemberQuit(client);

        // if theres less than 1 member left, remove the party
        if (client.party->numUsers() < 1)
        {
            delete client.party;
            client.party = 0;
        }
    }
}

void ChatHandler::informPartyMemberQuit(ChatClient &client)
{
    std::map<std::string, ChatClient*>::iterator itr;
    std::map<std::string, ChatClient*>::const_iterator itr_end = mPlayerMap.end();

    for (itr = mPlayerMap.begin(); itr != itr_end; ++itr)
    {
        if (itr->second->party == client.party)
        {
            MessageOut out(CPMSG_PARTY_MEMBER_LEFT);
            out.writeShort(client.characterId);
            itr->second->send(out);
        }
    }
}

void ChatHandler::informPartyMemberJoined(ChatClient &client)
{
    std::map<std::string, ChatClient*>::iterator itr;
    std::map<std::string, ChatClient*>::const_iterator itr_end = mPlayerMap.end();

    for (itr = mPlayerMap.begin(); itr != itr_end; ++itr)
    {
        if (itr->second->party == client.party)
        {
            MessageOut out(CPMSG_PARTY_NEW_MEMBER);
            out.writeShort(client.characterId);
            out.writeString(client.characterName);
            itr->second->send(out);
        }
    }
}