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( ¬ifyMsg, 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; }