Пример #1
0
uint CGReturnTeamFollowHandler::Execute( CGReturnTeamFollow* pPacket, Player* pPlayer )
{
__ENTER_FUNCTION

	GamePlayer* pGamePlayer = (GamePlayer*)pPlayer;
	Assert( pGamePlayer );

	Obj_Human* pHuman = pGamePlayer->GetHuman();
	Assert( pHuman );
	
	Scene* pScene = pHuman->getScene();
	if( pScene==NULL )
	{
		Assert(FALSE);
		return PACKET_EXE_ERROR;
	}

	//检查线程执行资源是否正确
	Assert( MyGetCurrentThreadID()==pScene->m_ThreadID );

	TeamInfo* pTeamInfo = pHuman->GetTeamInfo();
	if( pTeamInfo->HasTeam() == FALSE )
	{
		Assert(FALSE);
		return PACKET_EXE_CONTINUE;
	}

	const TEAMMEMBER* pLeaderInfo = pTeamInfo->Leader();
	// 这里不对自己是否队长进行检查

	if( pLeaderInfo->m_SceneID != pScene->SceneID() )
	{ // 不在同一个场景
		g_pLog->FastSaveLog( LOG_FILE_1, "CGReturnTeamFollow: GUID=%X is not in the same scene with team leader.", 
			pHuman->GetGUID() );
		return PACKET_EXE_CONTINUE;
	}

	Obj_Human* pLeader = pScene->GetHumanManager()->GetHuman( pLeaderInfo->m_ObjID );
	if( pLeader==NULL )
	{ // 没有找到队长
		g_pLog->FastSaveLog( LOG_FILE_1, "CGReturnTeamFollow: GUID=%X can't find team leader.", 
			pHuman->GetGUID() );
		return PACKET_EXE_CONTINUE;
	}

	// 如果自己正在摆摊,则不允许跟随
	if(pHuman->m_StallBox.GetStallStatus() == ServerStallBox::STALL_OPEN)
	{
		GCTeamFollowErr Msg;
		Msg.SetError( TF_ERROR_STALL_OPEN );

		pGamePlayer->SendPacket( &Msg );

		g_pLog->FastSaveLog( LOG_FILE_1, "CGReturnTeamFollow: GUID=%X can't follow when open stall.", 
			pHuman->GetGUID() );
		return PACKET_EXE_CONTINUE;
	}

	if( pPacket->GetReturn() )
	{ // 同意跟随
		// 检查跟队长之间的距离是否超过 10 米
		if( pHuman->IsInValidRadius(pLeader, (FLOAT)g_Config.m_ConfigInfo.m_nAvailableFollowDist) == FALSE )
		{ // 超过则返回错误信息
			GCTeamFollowErr Msg;
			Msg.SetError( TF_ERROR_TOO_FAR );

			pGamePlayer->SendPacket( &Msg );

			g_pLog->FastSaveLog( LOG_FILE_1, "CGReturnTeamFollow: GUID=%X can't follow for the distance.", 
				pHuman->GetGUID() );
			return PACKET_EXE_CONTINUE;
		}

		// 检查队长是否出于组队跟随状态
		if( pLeader->__GetTeamFollowFlag() == FALSE )
		{ // 队长不处于组队跟随状态,可能队长已经主动取消跟随了
			GCTeamFollowErr Msg;
			Msg.SetError( TF_ERROR_NOT_IN_FOLLOW_MODE );

			pGamePlayer->SendPacket( &Msg );

			g_pLog->FastSaveLog( LOG_FILE_1, "CGReturnTeamFollow: GUID=%X can't follow for not in follow mode.", 
				pHuman->GetGUID() );
			return PACKET_EXE_CONTINUE;
		}

		if ( pHuman->__GetTeamFollowFlag() )
		{ // 如果已经处于此状态,则返回
			return PACKET_EXE_CONTINUE;
		}

		pHuman->__SetTeamFollowFlag( TRUE );

		_FOLLOWEDMEMBER MyInfo;
		MyInfo.m_GUID = pHuman->GetGUID();
		MyInfo.m_pHuman = pHuman;

		// 将新的跟随列表发给可见范围内所有客户端
		// 只有队长有这个列表,这样可以进行优化
		GCTeamFollowList Msg;
		Msg.SetObjID( pLeader->GetID() );

		INT nMaxFollowedCount = pLeader->__GetFollowedMembersCount();

		for( INT i=0; i<nMaxFollowedCount; ++i )
		{ // 所有跟随者加上自己,自己加上每个跟随者
			Obj_Human* pMember;
			const _FOLLOWEDMEMBER* pFollowedMember;

			pFollowedMember = pLeader->__GetFollowedMember(i);

			pMember = pFollowedMember->m_pHuman;
			if( pMember!=NULL )
			{ // 没有断线并且在同一场景
				pMember->__AddFollowedMember( MyInfo );
			}

			pHuman->__AddFollowedMember( *pFollowedMember );
			Msg.AddFollowMember( pFollowedMember->m_GUID );
		}

		pHuman->__AddFollowedMember( MyInfo ); // 自己加上自己
		pHuman->GetHumanAI()->PushCommand_TeamFollow();

		Msg.AddFollowMember( MyInfo.m_GUID );

		//GCNotifyTeamInfo notifyMsg;
		//notifyMsg.SetObjID( pHuman->GetID() );
		//notifyMsg.SetHaveTeamFlag( pTeamInfo->HasTeam() );
		//notifyMsg.SetTeamLeaderFlag( pTeamInfo->IsLeader() );
		//notifyMsg.SetTeamFullFlag( pTeamInfo->IsFull() );
		//notifyMsg.SetTeamFollowFlag( pHuman->__GetTeamFollowFlag() );
		//pScene->BroadCast( &notifyMsg, pHuman );

		pScene->BroadCast( &Msg, pLeader, TRUE ); // 发送跟随列表给所有客户端,以供路线模拟

		GCReturnTeamFollow RetMsg;
		RetMsg.SetReturn( TF_RESULT_ENTER_FOLLOW );
		RetMsg.SetGUID( pHuman->GetGUID() );

		pGamePlayer->SendPacket( &RetMsg ); // 发给自己
		pLeader->GetPlayer()->SendPacket( &RetMsg ); // 发给队长

		// 这里需要通知 world GWEnterTeamFollow
		GWEnterTeamFollow* pMsg = (GWEnterTeamFollow*)g_pPacketFactoryManager->CreatePacket(PACKET_GW_ENTER_TEAMFOLLOW);

		pMsg->SetGUID( pHuman->GetGUID() );

		g_pServerManager->SendPacket( pMsg, INVALID_ID );

		g_pLog->FastSaveLog( LOG_FILE_1, "CGReturnTeamFollow: GUID=%X success.", 
			pHuman->GetGUID() );
		return PACKET_EXE_CONTINUE;
	}
	else
	{ // 不同意跟随
		GCReturnTeamFollow Msg;
		Msg.SetReturn( TF_RESULT_REFUSE_FOLLOW );
		Msg.SetGUID( pHuman->GetGUID() );

		pLeader->GetPlayer()->SendPacket( &Msg );

		g_pLog->FastSaveLog( LOG_FILE_1, "CGReturnTeamFollow: GUID=%X refuse to follow.", 
			pHuman->GetGUID() );
		return PACKET_EXE_CONTINUE;
	}
	return PACKET_EXE_CONTINUE;

__LEAVE_FUNCTION

	return PACKET_EXE_ERROR;
}
UINT WGTeamFollowListHandler::Execute( WGTeamFollowList* pPacket, Player* pPlayer )
{
__ENTER_FUNCTION

    PlayerID_t PlayerID = pPacket->GetPlayerID();
    GamePlayer* pGamePlayer = g_pPlayerPool->GetPlayer(PlayerID);
    if( pGamePlayer==NULL )
    {
        g_pLog->FastSaveLog( LOG_FILE_3, "WGTeamFollowListHandler::Execute pGamePlayer==NULL" );
        return PACKET_EXE_CONTINUE;
    }

    if (pGamePlayer->m_HumanGUID != pPacket->GetGUID())
    {
        g_pLog->FastSaveLog( LOG_FILE_3, "WGTeamFollowListHandler::Execute pGamePlayer->m_HumanGUID[%d] != pPacket->GetGUID()[%d]",pGamePlayer->m_HumanGUID, pPacket->GetGUID());
        return PACKET_EXE_CONTINUE;
    }

    Obj_Human* pHuman = pGamePlayer->GetHuman();
    Assert( pHuman );
    Scene* pScene = pHuman->getScene();
    if( !pScene )
    {
        g_pLog->FastSaveLog( LOG_FILE_3, "WGTeamFollowListHandler::Execute pHuman->getScene() == NULL" );
        return PACKET_EXE_CONTINUE;
    }

    if( pPlayer->IsServerPlayer() )
    {//服务器收到世界服务器发来的数据
        Assert( MyGetCurrentThreadID()==g_pServerManager->m_ThreadID );

        pScene->SendPacket( pPacket, PlayerID );

        g_pLog->FastSaveLog( LOG_FILE_1, "WGTeamFollowListHandler: ServerPlayer (GUID=%X) ",
            pHuman->GetGUID() );

        return PACKET_EXE_NOTREMOVE;
    }
    else if( pPlayer->IsGamePlayer() )
    {//场景收到Cache里的消息
        Assert( MyGetCurrentThreadID()==pScene->m_ThreadID );

        TeamInfo* pTeamInfo = pHuman->GetTeamInfo();
        if( pTeamInfo->HasTeam() == FALSE )
        {
            Assert(FALSE);
            return PACKET_EXE_CONTINUE;
        }

        pHuman->__ClearFollowedMembers(); // 清空旧信息

        _FOLLOWEDMEMBER myInfo;
        myInfo.m_GUID = pHuman->GetGUID();
        myInfo.m_pHuman = pHuman;

        for( INT i=0; i<pPacket->GetMemberCount(); ++i )
        {
            _FOLLOWEDMEMBER info;
            const TEAMMEMBER* pMember;

            info.m_GUID = pPacket->GetFollowMember(i);
            info.m_pHuman = NULL;
            pMember = pTeamInfo->GetTeamMemberByGUID( info.m_GUID );

            if ( pMember->m_SceneID == pScene->SceneID() )
            {
                info.m_pHuman = pScene->GetHumanManager()->GetHuman( pMember->m_ObjID );

                if ( info.m_pHuman!=NULL )
                {
                    if ( info.m_pHuman->GetGUID()!=pMember->m_GUID )
                    { // 宁缺勿滥
                        info.m_pHuman = NULL;
                    }
                    else
                    { // 让跟随队友把自己加进去,以更新 pHuman 指针
                        info.m_pHuman->__AddFollowedMember( myInfo );
                    }
                }
            }

            pHuman->__AddFollowedMember( info );
        }

        if ( pPacket->GetMemberCount()>0 )
        {
            pHuman->__SetTeamFollowFlag( TRUE );

            GCReturnTeamFollow Msg; // 通知客户端进入跟随状态
            Msg.SetGUID( pHuman->GetGUID() );
            Msg.SetReturn( TF_RESULT_FOLLOW_FLAG );
            pGamePlayer->SendPacket( &Msg );
        }
        else
        { // 队长断线退出,World 可能发送一个空的列表过来
            pHuman->__SetTeamFollowFlag( FALSE );
            pHuman->GetHumanAI()->PushCommand_StopTeamFollow();

            GCReturnTeamFollow Msg; // 通知客户端进入跟随状态
            Msg.SetGUID( pHuman->GetGUID() );
            Msg.SetReturn( TF_RESULT_STOP_FOLLOW );
            pGamePlayer->SendPacket( &Msg );
        }

        if ( pTeamInfo->IsLeader() )
        { // 队长
            GCTeamFollowList Msg;
            Msg.SetObjID( pHuman->GetID() );

            for( INT i=1; i<pHuman->__GetFollowedMembersCount(); ++i )
            {
                Obj_Human* pMember;

                pMember = pHuman->__GetFollowedMember(i)->m_pHuman;
                Msg.AddFollowMember( pHuman->__GetFollowedMember(i)->m_GUID );

                if ( pMember!=NULL && pMember->getZoneID()!=INVALID_ID )
                { // 必须进入了场景才跟随
                    pMember->GetHumanAI()->PushCommand_TeamFollow();
                }
            }

            if ( pHuman->getZoneID() != INVALID_ID )
            {
                pScene->BroadCast( &Msg, pHuman, TRUE );
            }
        }
        else if ( pPacket->GetMemberCount()>0 )
        { // 是跟随者
            Obj_Human* pLeader = pHuman->__GetFollowedMember(0)->m_pHuman;

            if ( pLeader!=NULL && pLeader->getZoneID()!=INVALID_ID )
            { // 必须进入了场景才跟随
                pHuman->GetHumanAI()->PushCommand_TeamFollow();
            }
        }

        g_pLog->FastSaveLog( LOG_FILE_1, "WGTeamFollowListHandler: GamePlayer (GUID=%X) ",
            pHuman->GetGUID() );
    }
    else
    {
        Assert(FALSE);
    }

    return PACKET_EXE_CONTINUE;

__LEAVE_FUNCTION

    return PACKET_EXE_ERROR;
}