Exemplo n.º 1
0
void WorldSession::LogoutPlayer(bool Save)
{
    Player* pPlayer = GetPlayer();

    if (_loggingOut)
        return;

    _loggingOut = true;

    if (_player != NULL)
    {
        _player->SetFaction(_player->GetInitialFactionId());

        objmgr.RemovePlayer(_player);
        _player->ok_to_remove = true;

        sHookInterface.OnLogout(pPlayer);
        if (_player->DuelingWith)
            _player->DuelingWith->EndDuel(DUEL_WINNER_RETREAT);

        if (_player->m_currentLoot && _player->IsInWorld())
        {
            Object* obj = _player->GetMapMgr()->_GetObject(_player->m_currentLoot);
            if (obj != NULL)
            {
                switch (obj->getObjectTypeId())
                {
                    case TYPEID_UNIT:
                        static_cast <Creature*>(obj)->loot.looters.erase(_player->getGuidLow());
                        break;
                    case TYPEID_GAMEOBJECT:
                        GameObject* go = static_cast<GameObject*>(obj);

                        if (!go->IsLootable())
                            break;

                        GameObject_Lootable* pLGO = static_cast<GameObject_Lootable*>(go);
                        pLGO->loot.looters.erase(_player->getGuidLow());

                        break;
                }
            }
        }

#ifndef GM_TICKET_MY_MASTER_COMPATIBLE
        GM_Ticket* ticket = objmgr.GetGMTicketByPlayer(_player->getGuid());
        if (ticket != NULL)
        {
            // Send status change to gm_sync_channel
            Channel* chn = channelmgr.GetChannel(sWorld.getGmClientChannel().c_str(), _player);
            if (chn)
            {
                std::stringstream ss;
                ss << "GmTicket:" << GM_TICKET_CHAT_OPCODE_ONLINESTATE;
                ss << ":" << ticket->guid;
                ss << ":0";
                chn->Say(_player, ss.str().c_str(), NULL, true);
            }
        }
#endif

        // part channels
        _player->CleanupChannels();

        auto transport = _player->GetTransport();
        if (transport != nullptr)
        {
            transport->RemovePassenger(_player);
        }

        // cancel current spell
        for (uint8_t i = 0; i < CURRENT_SPELL_MAX; ++i)
        {
            if (_player->getCurrentSpell(CurrentSpellType(i)) != nullptr)
                _player->interruptSpellWithSpellType(CurrentSpellType(i));
        }

        _player->Social_TellFriendsOffline();

        // Decrement the global player count
        sWorld.decrementPlayerCount(_player->GetTeam());

        if (_player->m_bgIsQueued)
            BattlegroundManager.RemovePlayerFromQueues(_player);

        // Repop or Resurrect and remove from battlegrounds
        if (_player->m_bg)
        {
            if (pPlayer->getDeathState() == JUST_DIED)
                pPlayer->RemoteRevive();
            if (pPlayer->getDeathState() != ALIVE)
                pPlayer->ResurrectPlayer();
            _player->m_bg->RemovePlayer(_player, true);
        }
        else if (_player->IsDead() && _player->getDeathState() == JUST_DIED)
            _player->RepopRequestedPlayer();

        // Issue a message telling all guild members that this player signed
        // off
#if VERSION_STRING != Cata
        if (_player->IsInGuild())
        {
            Guild* pGuild = _player->m_playerInfo->guild;
            if (pGuild != NULL)
                pGuild->LogGuildEvent(GE_SIGNED_OFF, 1, _player->GetName());
        }
#endif

        _player->GetItemInterface()->EmptyBuyBack();
        _player->GetItemInterface()->removeLootableItems();

        // Save HP/Mana
        _player->load_health = _player->getHealth();
        _player->load_mana = _player->GetPower(POWER_TYPE_MANA);


        _player->summonhandler.RemoveAllSummons();

        _player->DismissActivePets();

        // _player->SaveAuras();

        if (Save)
            _player->SaveToDB(false);

        // Dismounting with RemoveAllAuras may in certain cases add a player
        // aura,
        // which can result in a nice crash during shutdown. Therefore let's
        // dismount on logout.
        // Ofc if the player was mounted on login they will be still mounted
        // ;)
        _player->Dismount();

        _player->RemoveAllAuras();
        if (_player->IsInWorld())
            _player->RemoveFromWorld();

        _player->m_playerInfo->m_loggedInPlayer = NULL;

        if (_player->m_playerInfo->m_Group != NULL)
            _player->m_playerInfo->m_Group->Update();

        // Remove the "player locked" flag, to allow movement on next login
        GetPlayer()->removeUnitFlags(UNIT_FLAG_LOCK_PLAYER);

        // Save Honor Points
        // _player->SaveHonorFields();

        // Update any dirty account_data fields.
        bool dirty = false;

        if (worldConfig.server.useAccountData)
        {
            std::stringstream ss;
            ss << "UPDATE account_data SET ";
            for (uint32 ui = 0; ui < 8; ui++)
            {
                if (sAccountData[ui].bIsDirty)
                {
                    if (dirty)
                        ss << ",";
                    ss << "uiconfig" << ui << "=\"";

                    if (sAccountData[ui].data)
                    {
                        CharacterDatabase.EscapeLongString(sAccountData[ui].data, sAccountData[ui].sz, ss);
                        // ss.write(sAccountData[ui].data,sAccountData[ui].sz);
                    }
                    ss << "\"";
                    dirty = true;
                    sAccountData[ui].bIsDirty = false;
                }
            }
            if (dirty)
            {
                ss << " WHERE acct=" << _accountId << ";";
                CharacterDatabase.ExecuteNA(ss.str().c_str());
            }
        }

        delete _player;
        _player = NULL;

        OutPacket(SMSG_LOGOUT_COMPLETE, 0, NULL);
        LOG_DEBUG("SESSION: Sent SMSG_LOGOUT_COMPLETE Message");
    }
    _loggingOut = false;

    SetLogoutTimer(0);
}
Exemplo n.º 2
0
void WorldSession::LogoutPlayer(bool Save)
{
	Player* pPlayer = GetPlayer();

	if( _loggingOut )
		return;

	_loggingOut = true;

	if( _player != NULL )
	{
		sHookInterface.OnLogout( pPlayer );
		if( _player->DuelingWith )
			_player->EndDuel( DUEL_WINNER_RETREAT );

		if( _player->m_currentLoot && _player->IsInWorld() )
		{
			Object* obj = _player->GetMapMgr()->_GetObject( _player->m_currentLoot );
			if( obj != NULL )
				obj->m_loot.looters.erase(_player->GetLowGUID());
		}

		// part channels
		_player->CleanupChannels();

		if( _player->m_CurrentTransporter != NULL )
			_player->m_CurrentTransporter->RemovePlayer( _player );

		// cancel current spell
		if( _player->m_currentSpell != NULL )
			_player->m_currentSpell->cancel();

		_player->Social_TellFriendsOffline();

		if( _player->GetTeam() == 1 )
		{
			if( sWorld.HordePlayers )
				sWorld.HordePlayers--;
		}
		else
		{
			if( sWorld.AlliancePlayers )
				sWorld.AlliancePlayers--;
		}

		if( _player->m_bg )
			_player->m_bg->RemovePlayer( _player, true );

		if( _player->m_bgIsQueued )
			BattlegroundManager.RemovePlayerFromQueues( _player );

		//Duel Cancel on Leave
		if( _player->DuelingWith != NULL )
			_player->EndDuel( DUEL_WINNER_RETREAT );

		//Issue a message telling all guild members that this player signed off
		if( _player->IsInGuild() )
		{
			Guild* pGuild = _player->m_playerInfo->guild;
			if( pGuild != NULL )
				pGuild->LogGuildEvent( GUILD_EVENT_HASGONEOFFLINE, 1, _player->GetName() );
		}

		_player->GetItemInterface()->EmptyBuyBack();
		
		sLfgMgr.RemovePlayerFromLfgQueues( _player );
		
		// Save HP/Mana
		_player->load_health = _player->GetUInt32Value( UNIT_FIELD_HEALTH );
		_player->load_mana = _player->GetUInt32Value( UNIT_FIELD_POWER1 );
		
		objmgr.RemovePlayer( _player );		
		_player->ok_to_remove = true;

		if( _player->GetSummon() != NULL )
			_player->GetSummon()->Remove( false, true, false );

		//_player->SaveAuras();

		if( Save )
			_player->SaveToDB(false);
		
		_player->RemoveAllAuras();
		if( _player->IsInWorld() )
			_player->RemoveFromWorld();
		
		_player->m_playerInfo->m_loggedInPlayer = NULL;

		if( _player->m_playerInfo->m_Group != NULL )
			_player->m_playerInfo->m_Group->Update();
	  
		// Remove the "player locked" flag, to allow movement on next login
		GetPlayer()->RemoveFlag( UNIT_FIELD_FLAGS, UNIT_FLAG_LOCK_PLAYER );

		// Save Honor Points
		//_player->SaveHonorFields();

		// Update any dirty account_data fields.
		bool dirty = false;
		if( sWorld.m_useAccountData )
		{
			std::stringstream ss;
			ss << "UPDATE account_data SET ";
			for(uint32 ui=0;ui<8;ui++)
			{
				if(sAccountData[ui].bIsDirty)
				{
					if(dirty)
						ss <<",";
					ss << "uiconfig"<< ui <<"=\"";
					if(sAccountData[ui].data)
					{
						CharacterDatabase.EscapeLongString(sAccountData[ui].data, sAccountData[ui].sz, ss);
						//ss.write(sAccountData[ui].data,sAccountData[ui].sz);
					}
					ss << "\"";
					dirty = true;
					sAccountData[ui].bIsDirty = false;
				}
			}			
			if(dirty)
			{
				ss	<<" WHERE acct="<< _accountId <<";";
				CharacterDatabase.ExecuteNA(ss.str().c_str());
			}
		}

		delete _player;
		_player = NULL;

		OutPacket(SMSG_LOGOUT_COMPLETE, 0, NULL);
		DEBUG_LOG( "SESSION: Sent SMSG_LOGOUT_COMPLETE Message" );
	}
	_loggingOut = false;

	SetLogoutTimer(0);
}
Exemplo n.º 3
0
void WorldSession::LogoutPlayer(bool Save)
{
    if(_loggingOut)
        return;

    _loggingOut = true;
    if (_player)
    {
        if(_player->m_currentLoot)
        {
            switch(_player->m_currentLoot->GetTypeId())
            {
            case TYPEID_UNIT:
                ((Creature*)_player->m_currentLoot)->loot.looters.erase(_player);
                break;
            case TYPEID_GAMEOBJECT:
                ((GameObject*)_player->m_currentLoot)->loot.looters.erase(_player);
                break;
            }
        }

        if(_player->m_CurrentTransporter)
            _player->m_CurrentTransporter->RemovePlayer(_player);
        
        for(uint32 x=0;x<4;x++)
        {
            if(_player->m_TotemSlots[x])
                _player->m_TotemSlots[x]->TotemExpire();
            
            if(_player->m_ObjectSlots[x])
                _player->m_ObjectSlots[x]->Expire();
        }

        // cancel current spell
        if(_player->m_currentSpell)
            _player->m_currentSpell->cancel();

        sSocialMgr.LoggedOut(_player);

        // messages
        if(HasPermissions())
        {
            sWorld.BroadcastExtendedMessage(this, "[SM:GMLOGOUT]%s", _player->GetName());
        }

        if(_player->GetTeam() == 1)
            sWorld.HordePlayers--;
        else
            sWorld.AlliancePlayers--;

        // send info
        sWorld.BroadcastExtendedMessage(0, "[SM:INFO:%u:%u]", sWorld.HordePlayers, sWorld.AlliancePlayers);

        //Duel Cancel on Leave
        if(_player->DuelingWith != NULL)
            _player->EndDuel(DUEL_WINNER_RETREAT);

        // wipe our attacker list and target list
        _player->clearAttackers(true);

        //Issue a message telling all guild members that this player signed off
        if(_player->IsInGuild())
        {
            Guild *pGuild = objmgr.GetGuild( _player->GetGuildId() );
            if(pGuild)
            {
                //Update Offline info
                pGuild->GuildMemberLogoff(_player);
                WorldPacket data(SMSG_GUILD_EVENT, 11+strlen(_player->GetName()));
                data << uint8(GUILD_EVENT_HASGONEOFFLINE);
                data << uint8(0x01);
                data << _player->GetName();
                data << _player->GetGUID();
                pGuild->SendMessageToGuild(0,&data,G_MSGTYPE_ALL);
            }
        }

        _player->GetItemInterface()->EmptyBuyBack();
        
        
        // Remove from BG
        if(_player->GetCurrentBattleground() != NULL)
        {
            _player->GetCurrentBattleground()->RemovePlayer(_player, false, false, false);
        }
        
        // Remove ourself from a group
        if (_player->InGroup())
        {
            Group *group = _player->GetGroup();
            if(group)
                group->RemovePlayer(_player);
        }
        
        for(int i=0;i<3;++i)
           {
            if(_player->LfgDungeonId[i] != 0)
                sLfgMgr.RemoveFromLfgQueue(_player,_player->LfgDungeonId[i]);       
        }
        if(Save)
        {
            // Save the player
            _player->SaveToDB();
        }
        
        std::stringstream ss1;
        ss1 << "UPDATE characters SET online = 0 where guid = " << _player->GetGUIDLow();
        sDatabase.Execute(ss1.str().c_str());

        if(_player->IsInWorld()) //hovering in char selection
        {
            // Relocate session to -1 map.
            Relocate(_player->m_mapMgr, NULL);

            sLog.outDebug( "SESSION: removing player from world" );
            _player->RemoveFromWorld();
        }


        // Remove the "player locked" flag, to allow movement on next login
        if ( GetPlayer( )->GetUInt32Value(UNIT_FIELD_FLAGS) & U_FIELD_FLAG_LOCK_PLAYER )
            GetPlayer( )->RemoveFlag( UNIT_FIELD_FLAGS, U_FIELD_FLAG_LOCK_PLAYER );

        _player->RemoveAllAuras();

        if(_player->GetSummon() != NULL)
        {
            _player->GetSummon()->Remove();
        }

        if(_player->critterPet)
        {
            _player->critterPet->m_BeingRemoved = true;
            if(_player->critterPet->IsInWorld())
                _player->critterPet->RemoveFromWorld();
            sObjHolder.Delete<Creature>(_player->critterPet);
            _player->critterPet = NULL;
        }

        // Update any dirty account_data fields.
        /*bool dirty=false;
        std::stringstream ss;
        ss << "UPDATE accounts SET ";
        for(uint32 ui=0;ui<8;ui++)
        {
            if(sAccountData[ui].bIsDirty)
            {
                if(dirty)
                    ss <<",";
                ss << "uiconfig"<< ui <<"=\"";
                if(sAccountData[ui].data)
                    ss.write(sAccountData[ui].data,sAccountData[ui].sz);
                ss << "\"";
                dirty=true;
            }
        }            
        if(dirty)
        {
            ss    <<" WHERE acct="<< _accountId <<";";
            sLogonDatabase.Execute(ss.str().c_str());
        }*/

        sObjHolder.Delete(_player);
        _player = NULL;

        OutPacket(SMSG_LOGOUT_COMPLETE, 0, NULL);
        sLog.outDebug( "SESSION: Sent SMSG_LOGOUT_COMPLETE Message" );
    }
    _loggingOut = false;

    SetLogoutTimer(0);
}