Files
Sun1602/Server/AgentServer/AgentParty/AgentPartyManager.cpp
T
2022-10-26 12:25:11 +08:00

2709 lines
87 KiB
C++

#include "StdAfx.h"
#include <boost/type_traits/is_same.hpp>
#include "AgentPartyManager.h"
#include "UserSessions/User.h"
#include "AgentPartyOperator.h"
#include "AgentParty.h"
#include <PacketStruct_CG.h>
#include <PacketStruct_AW.h>
#include <PacketStruct_AG.h>
#include <Zone/PortalManager.h>
#include <Zone/InstanceDungeon.h>
//_NA_20110630_BATTLE_ZONE_RENEWAL
#include "MapInfoParser.h"
#include "PartyRoomFinder.h"
#include "PartyRoomList.h"
#include "Party/PartyRoom.h"
#include "BattlezoneMissionTreeParser.h"
#include "BattleOpenTimeManager.h"
#include "PartyRoomWaitingList.h"
#include "PacketHandler/PacketHandler.h"
// _NA_005026_20120527_CHAOS_ZONE_BATTLE_GROUND
#include <ChaosZoneSystem/BattleGroundManager.h>
#include "Zone/DungeonChaosZone.h"
AgentPartyManager::AgentPartyManager()
{
// size 50000 -> 6000으로 수정...
key_generater_.Create(1, 6000);
//_NA_20110630_BATTLE_ZONE_RENEWAL
party_room_finder_ = new PartyRoomFinder;
party_room_list_ = new PartyRoomList;
check_waiting_room_timer_.SetTimer(1000*1);
}
AgentPartyManager::~AgentPartyManager()
{
//_NA_20110630_BATTLE_ZONE_RENEWAL
SAFE_DELETE(party_room_finder_);
SAFE_DELETE(party_room_list_);
}
void
AgentPartyManager::Initialize(DWORD PartyPoolSize)
{
party_pool_router_.Register<AgentParty>(ePARTY_FIELD);
party_pool_router_.Initialize(ePARTY_FIELD, PartyPoolSize, PartyPoolSize/4);
//_NA_20110630_BATTLE_ZONE_RENEWAL
party_pool_router_.Register<AgentParty>(ePARTY_ROOM);
party_pool_router_.Initialize(ePARTY_ROOM, PartyPoolSize, PartyPoolSize/4);
party_pool_router_.Register<AgentParty>(ePARTY_INSTANCE);
party_pool_router_.Initialize(ePARTY_INSTANCE, PartyPoolSize, PartyPoolSize/4);
}
void
AgentPartyManager::Update()
{
PARTY_MAP::iterator end(party_map_.end());
for(PARTY_MAP::iterator it = party_map_.begin(); it != end; ++it)
{
AgentParty* pAgentParty = (AgentParty*)it->second;
pAgentParty->Update();
}
}
BaseParty*
AgentPartyManager::CreateParty(DWORD MasterKey, ePARTY_TYPE party_type)
{
WORD partyKey = (WORD)key_generater_.GetKey();
BaseParty* pBaseParty = BasePartyManager::CreateParty(party_type, partyKey, MasterKey);
if(pBaseParty)
{
MSG_AW_PARTY_MAKE_SYN msgAW;
msgAW.wPartyKey = partyKey;
AgentServer::GetInstance()->SendToWorldServer(&msgAW, sizeof(msgAW));
}
else
{
key_generater_.RestoreKey(partyKey);
}
return pBaseParty;
}
RC::ePARTY_RESULT
AgentPartyManager::DestroyParty(WORD partyKey)
{
BaseParty* pBaseParty = FindEditableParty(partyKey);
if(!pBaseParty)
return RC::RC_PARTY_PARTY_NOTEXIST;
key_generater_.RestoreKey(partyKey);
// 파티해체를 링크된 서버들에게 알린다.
MSG_AG_PARTY_DESTROY_CMD msgAG;
msgAG.m_wPartykey = partyKey;
SendPacketAllLinkedServer(partyKey, &msgAG, sizeof(msgAG));
// 다른 파티원에게 파티가 해체되었음을 알린다.
MSG_CG_PARTY_DESTROY_BRD msgCG;
SendPacketAllMember(partyKey, &msgCG, sizeof(msgCG));
// WorldServer에 파티소멸 알림
MSG_AW_PARTY_DESTROY_SYN msgAW;
msgAW.wPartyKey = partyKey;
AgentServer::GetInstance()->SendToWorldServer(&msgAW, sizeof(msgAW));
// 모든 파티원의 파티상태 초기화
static MemberOperator Opr;
Opr.Init(ePARTY_OPERATOR_INIT, 0, 0);
pBaseParty->For_eachMembers(Opr);
BasePartyManager::DestroyParty(partyKey);
//_NA_20110630_BATTLE_ZONE_RENEWAL
DestroyPartyRoom(partyKey);
return RC::RC_PARTY_SUCCESS;
}
RC::ePARTY_RESULT
AgentPartyManager::CanJoinParty(User* pUser)
{
// 해당 멤버가 다른 파티에 소속되어 있는지 체크
if(pUser->GetPartyState().IsPartyMember())
return RC::RC_PARTY_ALREADY_IS_MEMBEROFPARTY;
// 유저의 상태 체크
if(pUser->GetBehaveState() != PLAYER_BEHAVE_IDLE_STATE)
return RC::RC_PARTY_INVALID_PLAYER_STATE;
// _NA_005026_20120527_CHAOS_ZONE_BATTLE_GROUND
BattleGroundManager* const battle_ground_manager = BattleGroundManager::Instance();
if (battle_ground_manager)
{
// 전장을 예약하고 매칭 대기열에 있는 상태라면
if (battle_ground_manager->IsValidStandbyGroupMember(pUser->GetUserKey()))
{
return RC::RC_PARTY_ALREADY_USE_IN_CHAOS_ZONE;
}
}
return RC::RC_PARTY_SUCCESS;
}
RC::ePARTY_RESULT
AgentPartyManager::JoinParty(WORD partyKey, User* pUser)
{
RC::ePARTY_RESULT result_code = CanJoinParty(pUser);
if (result_code != RC::RC_PARTY_SUCCESS)
{
return result_code;
}
AgentParty* party = static_cast<AgentParty*>(FindEditableParty(partyKey));
if (party == NULL)
{
return RC::RC_PARTY_PARTY_NOTEXIST;
}
BOOST_STATIC_ASSERT(MAX_FIELD_PARTYMEMBER_NUM == MAX_PARTYMEMBER_NUM);
if ((party->GetMemberNum() < MAX_PARTYMEMBER_NUM) == false)
{
if (party->IsClosingUser(pUser) == false)
{
return RC::RC_PARTY_PARTYMEMBER_NUM_FULL;
}
}
static _PARTY_MEMBER_INFO MemberInfo;
pUser->SerializePartyInfo(MemberInfo);
result_code = BasePartyManager::JoinParty(partyKey, MemberInfo);
if(result_code != RC::RC_PARTY_SUCCESS)
{
return result_code;
}
pUser->GetPartyState().JoinParty(0, partyKey);
if (!party->GetSessionMemberMgr().JoinMember(pUser->GetPlayerKey()))
{
SUNLOG(eCRITICAL_LOG,
__FUNCTION__" : Fail SessionMemberMgr().JoinMember()");
}
AddMemberToSession(party, pUser->GetServerSessionIndex(), pUser);
//_NA_20110630_BATTLE_ZONE_RENEWAL
if (party->GetType() == ePARTY_ROOM)
{
const PartyRoom* const party_room = FindPartyRoom(partyKey);
if (party_room == NULL)
{
SUNLOG(eCRITICAL_LOG, __FUNCTION__"Not found party : %d", partyKey);
return RC::RC_PARTY_NOT_FOUND_PARTYROOM;
}
result_code = JoinPartyRoom(pUser, partyKey, party_room->GetPartyRoomType());
if (result_code != RC::RC_PARTY_SUCCESS)
{
return result_code;
}
}
#ifdef _NA_008679_20160202_REWORK_BATTLEGROUND
if (party->GetPartySubType() == ePARTY_SUB_BATTLEGROUND)
{
BattleGroundManager::Instance()->ReInsertAbnormalExitMemberToTotalList(pUser, partyKey);
}
#endif //_NA_008679_20160202_REWORK_BATTLEGROUND
// 조인한 파티원에 파티 전체 정보 알림
_JoinProcess_SendPartyInfo(partyKey, pUser, MemberInfo);
// WorldServer에 파티가입 알림
MSG_AW_PARTY_JOIN_MEMBER_SYN msgAW;
msgAW.wPartyKey = partyKey;
msgAW.m_CharGUID = pUser->GetSelectedCharGuid();
pUser->SendToWorldServer(&msgAW, sizeof(msgAW));
return RC::RC_PARTY_SUCCESS;
}
RC::ePARTY_RESULT
AgentPartyManager::ChangeMaster(WORD partyKey, DWORD nextMasterKey)
{
User* pNextMaster = UserManager::Instance()->GetUserByObjKey(nextMasterKey);
if(!pNextMaster)
return RC::RC_PARTY_NEXTMASTER_NOTEXIST;
RC::ePARTY_RESULT rcResult = BasePartyManager::ChangeMaster(partyKey, nextMasterKey);
if(rcResult != RC::RC_PARTY_SUCCESS)
return rcResult;
// 파티장이 변경되었음을 멤버들이 링크된 서버들에게 알린다.
MSG_AG_PARTY_CHANGE_MASTER_CMD msgAG;
msgAG.m_wPartykey = partyKey;
msgAG.m_dwMemberKey = nextMasterKey; //object_key
SendPacketAllLinkedServer(partyKey, &msgAG, sizeof(msgAG));
// 다른 파티원에게 파티장이 변경되었음을 알린다.
MSG_CG_PARTY_CHANGE_MASTER_BRD msgCGBrd;
msgCGBrd.m_dwObjKey = nextMasterKey; //pNextMaster->GetPlayerKey();
SendPacketAllMember(partyKey, &msgCGBrd, sizeof(msgCGBrd));
//_NA_20110630_BATTLE_ZONE_RENEWAL
const PartyRoom* party_room = FindPartyRoom(partyKey);
if (party_room == NULL)
{
SUNLOG(eCRITICAL_LOG, __FUNCTION__" : Not found party room : %d", partyKey);
return RC::RC_PARTY_NOT_FOUND_PARTYROOM;
}
if (party_room->GetIsMissionStart() == false)
{
ResetPartyRoomReadyState(pNextMaster, partyKey);
}
ChangeMasterOfPartyRoom(pNextMaster);
return RC::RC_PARTY_SUCCESS;
}
RC::ePARTY_RESULT AgentPartyManager::ChangeMaster_inInstanceDungeon( InstanceDungeon* dungeon, User* user )
{
RC::ePARTY_RESULT result = RC::RC_PARTY_UNKNOWN_REASON;
const AgentParty* party = static_cast<const AgentParty*>(FindParty(dungeon->GetLinkParty()));
if (party != NULL)
{
if (party->GetType() != ePARTY_ROOM)
{
User* next_master = dungeon->ChangeSpecialType(false, user);
if (next_master)
{
result = ChangeMaster(next_master->GetPartyState().GetPartyKey(), next_master->GetPlayerKey());
}
}
else {
result = RC::RC_PARTY_INVALID_ROOMTYPE;
}
}
else {
result = RC::RC_PARTY_PARTY_NOTEXIST;
}
return result;
}
RC::ePARTY_RESULT
AgentPartyManager::CanRequestJoin(User* pRequestUser, User* pResponseUser)
{
if(pResponseUser == 0)
return RC::RC_PARTY_PLAYER_NOTEXIST;
RC::ePARTY_RESULT rcResult = CanJoinParty(pResponseUser);
if(rcResult != RC::RC_PARTY_SUCCESS)
return rcResult;
if(PortalManager::CanJoinParty(pRequestUser, pResponseUser) == false)
return RC::RC_PARTY_PORTAL_ENTERANCE_MEMBER;
if(pRequestUser->GetBehaveState() != PLAYER_BEHAVE_IDLE_STATE || pResponseUser->GetBehaveState() != PLAYER_BEHAVE_IDLE_STATE)
return RC::RC_PARTY_INVALID_PLAYER_STATE;
// _NA_005026_20120527_CHAOS_ZONE_BATTLE_GROUND
// 타락한 사원일 경우 파티 허용이 안된다!!.
if (pRequestUser->GetZoneType() == eZONETYPE_INSTANCE)
{
const KEYTYPE zone_key = pRequestUser->GetZoneKey();
InstanceDungeon* const instance_dungeon = \
static_cast<InstanceDungeon*>(g_ZoneManager.FindZone(zone_key));
if (instance_dungeon->GetDungeonType() == INDUN_KIND_SS_QUEST)
{
return RC::RC_PARTY_INVALID_PLAYER_STATE;
}
}
// 다음의 zonetype들에서 파티가 허용된다
if( pRequestUser->GetZoneType() != eZONETYPE_VILLAGE &&
pRequestUser->GetZoneType() != eZONETYPE_DOMINATION_FIELD &&
pRequestUser->GetZoneType() != eZONETYPE_FIELD &&
pRequestUser->GetZoneType() != eZONETYPE_INSTANCE && // 인스턴스 던전에서 파티 허용
pRequestUser->GetZoneType() != eZONETYPE_SPA_FIELD
)
return RC::RC_PARTY_INVALID_PLAYER_STATE;
// _NA_005026_20120527_CHAOS_ZONE_BATTLE_GROUND
BattleGroundManager* const battle_ground_manager = BattleGroundManager::Instance();
if (battle_ground_manager)
{
// 전장을 예약하고 매칭 대기열에 있는 상태라면
if (battle_ground_manager->IsValidReservationMember(pResponseUser->GetUserKey()))
{
return RC::RC_PARTY_ALREADY_USE_IN_CHAOS_ZONE;
}
}
return RC::RC_PARTY_SUCCESS;
}
RC::ePARTY_RESULT
AgentPartyManager::InviteParty(User* pMaster, User* pJoinUser)
{
// 파티요청이 가능한지 체크
RC::ePARTY_RESULT rcResult = CanRequestJoin(pMaster, pJoinUser);
if(rcResult != RC::RC_PARTY_SUCCESS)
return rcResult;
DWORD masterPlayerKey = pMaster->GetPlayerKey();
BaseParty* pBaseParty = FindEditableParty(pMaster->GetPartyState().GetPartyKey());
// 요청자가 파티원이라면
if(pBaseParty)
{
if(pBaseParty->GetMasterKey() != masterPlayerKey)
return RC::RC_PARTY_ISNOT_MASTEROFPARTY;
}
// 파티원이 아니면 파티를 새로 생성한다.
else
{
pBaseParty = CreateParty(masterPlayerKey, ePARTY_FIELD);
if(pBaseParty == 0)
return RC::RC_PARTY_INVALID_ROOMTYPE;
// 파티를 새로 생성할 경우 파티가입 요청자도 파티에 가입시킨다.
JoinParty(pBaseParty->GetPartyKey(), pMaster);
}
//_NA_20110630_BATTLE_ZONE_RENEWAL
WORD join_party_key = pBaseParty->GetPartyKey();
if (pBaseParty->GetType() == ePARTY_ROOM)
{
const PartyRoom* party_room = FindPartyRoom(join_party_key);
if (party_room == NULL)
{
SUNLOG(eCRITICAL_LOG, __FUNCTION__" : Not found party room : %d", join_party_key);
return RC::RC_PARTY_FAIL_JOIN_PARTY_ROOM;
}
if (party_room->GetMapCode() != 0 &&
party_room->CheckLevel(pJoinUser->GetCharLV()) == false)
{
MSG_CG_PARTY_JOIN_ROOM_ACK nak_msg;
nak_msg.result_code_ = RC::RC_PARTY_NOT_MATCHING_USER_LEVEL;
pJoinUser->SendPacket(&nak_msg, nak_msg.GetSize());
return RC::RC_PARTY_NOT_MATCHING_USER_LEVEL;
}
if (party_room->CanJoinPartyRoomByMemberCount() == false)
{
MSG_CG_PARTY_JOIN_ROOM_ACK nak_msg;
nak_msg.result_code_ = RC::RC_PARTY_FAIL_MAX_MEMBER_COUNT;
pJoinUser->SendPacket(&nak_msg, nak_msg.GetSize());
return RC::RC_PARTY_PARTYMEMBER_NUM_FULL;
}
MSG_AG_PARTY_CAN_JOIN_ROOM_SYN syn_msg;
syn_msg.map_code_ = party_room->GetMapCode();
syn_msg.party_room_type_ = party_room->GetZoneType();
syn_msg.join_party_key_ = join_party_key;
pJoinUser->SendToLinkedServer(&syn_msg, sizeof(syn_msg));
return RC::RC_PARTY_SUCCESS;
}
else
{
return JoinParty(join_party_key, pJoinUser);
}
}
RC::ePARTY_RESULT
AgentPartyManager::CanRequestLeave(User* pRequestUser, User* pLeaveUser)
{
// 나가려는 캐릭터가 파티에 소속되어 있는지 체크
BaseParty* pBaseParty = FindEditableParty(pRequestUser->GetPartyState().GetPartyKey());
if(!pBaseParty)
return RC::RC_PARTY_PARTY_NOTEXIST;
if(!pBaseParty->GetMemberInfo(pLeaveUser->GetPlayerKey()))
return RC::RC_PARTY_ISNOT_MEMBEROFPARTY;
// 다른 사람을 내보내려면 파티장이어야 한다.
if(pRequestUser != pLeaveUser)
{
if(pBaseParty->GetMasterKey() != pRequestUser->GetPlayerKey())
return RC::RC_PARTY_ISNOT_MASTEROFPARTY;
}
return RC::RC_PARTY_SUCCESS;
}
RC::ePARTY_RESULT
AgentPartyManager::ForcedExpulsion(User* pMaster, User* pLeaveUser)
{
RC::ePARTY_RESULT rcResult = CanRequestLeave(pMaster, pLeaveUser);
if(rcResult != RC::RC_PARTY_SUCCESS)
return rcResult;
return LeaveParty(pLeaveUser, eREASON_LEAVE_PARTY_BAN);
}
RC::ePARTY_RESULT
AgentPartyManager::SelectTarget(User* pMaster, DWORD dwObjectKey)
{
WORD partyKey = pMaster->GetPartyState().GetPartyKey();
// 파티장인지 체크
BaseParty* pBaseParty = FindEditableParty(partyKey);
if(!pBaseParty)
return RC::RC_PARTY_PARTY_NOTEXIST;
if(pBaseParty->GetMasterKey() != pMaster->GetPlayerKey())
return RC::RC_PARTY_ISNOT_MASTEROFPARTY;
// 파티 타겟을 설정한다.
pBaseParty->SetTargetKey(dwObjectKey);
// 설정된 타겟을 브로드로 알려준다.
MSG_CG_PARTY_SELECT_TARGET_BRD msgCGBrd;
msgCGBrd.m_dwObjectKey = dwObjectKey;
SendPacketAllMember(partyKey, &msgCGBrd, sizeof(msgCGBrd));
return RC::RC_PARTY_SUCCESS;
}
RC::ePARTY_RESULT
AgentPartyManager::SelectMinimap(User* pUser, float PosX, float PosY)
{
WORD partyKey = pUser->GetPartyState().GetPartyKey();
BaseParty* pBaseParty = FindEditableParty(partyKey);
if(!pBaseParty)
return RC::RC_PARTY_PARTY_NOTEXIST;
if(pUser->GetZoneType() == eZONETYPE_VILLAGE)
return RC::RC_PARTY_INVALID_ROOMTYPE;
// 설정된 타겟을 브로드로 알려준다.
MSG_CG_PARTY_MINIMAP_POINTING_BRD msgCGBrd;
msgCGBrd.m_fx = PosX;
msgCGBrd.m_fy = PosY;
SendPacketAllMember(partyKey, &msgCGBrd, sizeof(msgCGBrd), 0, pUser->GetZoneKey());
return RC::RC_PARTY_SUCCESS;
}
RC::ePARTY_RESULT
AgentPartyManager::ChangeDistributionType(User* pUser, eITEM_DISTRIBUTION_TYPE Type)
{
WORD partyKey = pUser->GetPartyState().GetPartyKey();
BaseParty* pBaseParty = FindEditableParty(partyKey);
if(!pBaseParty)
return RC::RC_PARTY_PARTY_NOTEXIST;
if(Type >= eITEM_DISTRIBUTION_MAX)
return RC::RC_PARTY_CHANGE_ITEM_DISTRIBUTION_FAIL;
pBaseParty->SetDistributionType(Type);
MSG_AG_PARTY_ITEM_DISTRIBUTION_CHANGE_CMD msgAG;
msgAG.m_wPartykey = partyKey;
msgAG.m_byItemDistributionType = Type;
SendPacketAllLinkedServer(partyKey, &msgAG, sizeof(msgAG));
MSG_CG_PARTY_ITEM_DISTRIBUTION_CHANGE_BRD msgCGBrd;
msgCGBrd.m_byItemDistributionType = Type;
SendPacketAllMember(partyKey, &msgCGBrd, sizeof(msgCGBrd));
return RC::RC_PARTY_SUCCESS;
}
bool
AgentPartyManager::MemberChangeState(User* pUser)
{
WORD partyKey = pUser->GetPartyState().GetPartyKey();
BaseParty* pBaseParty = FindEditableParty(partyKey);
if(!pBaseParty) return false;
if(!pBaseParty->GetMemberInfo(pUser->GetPlayerKey()))
return false;
static _PARTY_MEMBER_INFO MemberInfo;
pUser->SerializePartyInfo(MemberInfo);
pBaseParty->SetMemberInfo(pUser->GetPlayerKey(), MemberInfo);
return true;
}
void
AgentPartyManager::MemberLevelUp(User* pUser, FLOAT fHPRatio, FLOAT fMPRatio)
{
if(MemberChangeState(pUser))
{
MSG_CG_PARTY_MEMBER_LEVEL_UP_BRD msgCGBrd;
msgCGBrd.m_dwObjKey = pUser->GetPlayerKey();
msgCGBrd.m_wLevel = pUser->GetSelectedCharLV();
msgCGBrd.m_byHPRatio = (BYTE)(fHPRatio*100);
msgCGBrd.m_byMPRatio = (BYTE)(fMPRatio*100);
SendPacketAllMember(pUser->GetPartyState().GetPartyKey(), &msgCGBrd, sizeof(msgCGBrd));
}
}
void
AgentPartyManager::MemberResurrection(User* pUser, FLOAT fHPRatio, FLOAT fMPRatio)
{
if(MemberChangeState(pUser))
{
MSG_CG_PARTY_MEMBER_RESURRECTION_BRD msgCGBrd;
msgCGBrd.m_dwObjKey = pUser->GetPlayerKey();
msgCGBrd.m_byHPRatio = (BYTE)(fHPRatio*100);
msgCGBrd.m_byMPRatio = (BYTE)(fMPRatio*100);
SendPacketAllMember(pUser->GetPartyState().GetPartyKey(), &msgCGBrd, sizeof(msgCGBrd));
}
}
void
AgentPartyManager::MemberChangeChaoState(User* pUser)
{
if(MemberChangeState(pUser))
{
MSG_CG_PARTY_MEMBER_CHAO_STATE_CHANGE_BRD msgCGBrd;
msgCGBrd.m_dwObjKey = pUser->GetPlayerKey();
msgCGBrd.m_byChaoState = pUser->GetSelectedCharChaoState();
SendPacketAllMember(pUser->GetPartyState().GetPartyKey(), &msgCGBrd, sizeof(msgCGBrd));
}
}
void
AgentPartyManager::MemberDead(User* pUser)
{
if(MemberChangeState(pUser))
{
MSG_CG_PARTY_MEMBER_DEAD_BRD msgCGBrd;
msgCGBrd.m_dwObjKey = pUser->GetPlayerKey();
SendPacketAllMember(pUser->GetPartyState().GetPartyKey(), &msgCGBrd, sizeof(msgCGBrd));
}
}
//{__NA001336_090514_PARTY_NAVI_SUPPORT__
void
AgentPartyManager::ChangedMembersInfo(WORD partyKey,
const MSG_AG_PARTY_NAVI_INFO_BRD* navi,
const MSG_AG_STATUS_CHAR_STAT_CHANGE_CMD* hpmp)
{
AgentParty* pAgentParty = (AgentParty*)FindEditableParty(partyKey);
if(pAgentParty == 0)
return;
MSG_CG_PARTY_NAVI_INFO_BRD msgNavi;
MSG_CG_PARTY_MEMBER_HP_CHANGE_BRD msgHP;
MSG_CG_PARTY_MEMBER_MP_CHANGE_BRD msgMP;
#ifdef _NA_006638_20120415_ADD_SHIELD_INFO_IN_TARGET_INFO
MSG_CG_PARTY_MEMBER_SD_CHANGE_BRD msgSD;
#endif // _NA_006638_20120415_ADD_SHIELD_INFO_IN_TARGET_INFO
msgNavi.m_NumberOfNodes = 0;
msgHP.m_NumberOfNodes = 0;
msgMP.m_NumberOfNodes = 0;
#ifdef _NA_006638_20120415_ADD_SHIELD_INFO_IN_TARGET_INFO
msgSD.number_of_nodes = 0;
#endif // _NA_006638_20120415_ADD_SHIELD_INFO_IN_TARGET_INFO
#ifdef _NA_007514_20140828_NEW_CHARACTER_WITCHBLADE
MSG_CG_PARTY_MEMBER_FP_CHANGE_BRD msgFP;
msgFP.number_of_nodes = 0;
#endif //_NA_007514_20140828_NEW_CHARACTER_WITCHBLADE
UserManager* pUserManager = UserManager::Instance(); //나중에 좀 더 개선할 것.
if(navi)
{
msgNavi.m_CodeType = navi->m_CodeType;
const BYTE upperbound = navi->m_NumberOfNodes < _countof(hpmp->m_Nodes)
? navi->m_NumberOfNodes
: _countof(hpmp->m_Nodes);
msgNavi.m_NumberOfNodes = upperbound;
BOOST_STATIC_ASSERT((boost::is_same<MSG_CG_PARTY_NAVI_INFO_BRD::Node,
MSG_AG_PARTY_NAVI_INFO_BRD::Node>::value));
MSG_CG_PARTY_NAVI_INFO_BRD::Node* pDestIt = &msgNavi.m_Nodes[0];
const MSG_AG_PARTY_NAVI_INFO_BRD::Node* pSrcIt = &navi->m_Nodes[0];
CopyMemory(pDestIt, pSrcIt, sizeof(*pDestIt) * upperbound);
#ifdef _NA002676_WORLD_SERVER_RENEWAL
MSG_AW_USER_STADING_POSITION_CMD msg_pos_cmd;
msg_pos_cmd.number_of_nodes = upperbound;
User* pole_user = NULL;
for (uint32_t index = 0; index < msg_pos_cmd.number_of_nodes; ++index)
{
MSG_AW_USER_STADING_POSITION_CMD::Node* dest = &msg_pos_cmd.nodes[index];
const MSG_AG_PARTY_NAVI_INFO_BRD::Node& src = navi->m_Nodes[index];
User* user = pUserManager->GetUserByObjKey(src.objectKey);
dest->user_guid = user ? user->GetUserKey() : 0;
dest->pos_x = src.posX;
dest->pos_y = src.posY;
//
if (pole_user != NULL) {
pole_user = user;
};
};
if (pole_user != NULL) {
pole_user->SendToWorldServer(&msg_pos_cmd, msg_pos_cmd.GetSize());
};
#endif
};
if(hpmp)
{
const BYTE upperbound = hpmp->m_NumberOfNodes < _countof(hpmp->m_Nodes)
? hpmp->m_NumberOfNodes
: _countof(hpmp->m_Nodes);
typedef MSG_AG_STATUS_CHAR_STAT_CHANGE_CMD::uNode StatChangeNode;
const StatChangeNode* pSrcIt = &hpmp->m_Nodes[0],
* pSrcEnd = &hpmp->m_Nodes[upperbound];
MSG_CG_PARTY_MEMBER_HP_CHANGE_BRD::Node* pHpIt = &msgHP.m_Nodes[0];
MSG_CG_PARTY_MEMBER_MP_CHANGE_BRD::Node* pMpIt = &msgMP.m_Nodes[0];
#ifdef _NA_006638_20120415_ADD_SHIELD_INFO_IN_TARGET_INFO
MSG_CG_PARTY_MEMBER_SD_CHANGE_BRD::Node* pSdIt = &msgSD.nodes[0];
#endif // _NA_006638_20120415_ADD_SHIELD_INFO_IN_TARGET_INFO
#ifdef _NA_007514_20140828_NEW_CHARACTER_WITCHBLADE
MSG_CG_PARTY_MEMBER_FP_CHANGE_BRD::Node* pFPIt = &msgFP.nodes[0];
#endif //_NA_007514_20140828_NEW_CHARACTER_WITCHBLADE
for( ; pSrcIt != pSrcEnd; ++pSrcIt)
{
User* pUser = pUserManager->GetUserByObjKey(pSrcIt->m_HP.objectKey);
if(pUser == 0)
continue;
// 나중에 Agent가 HP,MP관리하는 루틴을 제거할 수 있도록 유도하자.
if(pSrcIt->m_HP.event == hpmp->eEvent_ChangedHP)
{
const StatChangeNode::HP& rHP = pSrcIt->m_HP;
if(msgHP.m_NumberOfNodes < _countof(msgHP.m_Nodes))
{
//assert(rHP.maxHP != 0)
pHpIt->objectKey = rHP.objectKey;
pHpIt->ratio = rHP.currentHP ? BYTE(rHP.currentHP * 100 / rHP.maxHP) : 0;
if(pHpIt->ratio == 0 && rHP.currentHP)
pHpIt->ratio = 1;
++msgHP.m_NumberOfNodes;
++pHpIt;
pUser->SetSelectedCharCurHP(rHP.currentHP);
pUser->SetSelectedCharMaxHP(rHP.maxHP);
pUser->SetReservedHP(rHP.reservedHP);
pUser->SetNeedChangedStatus(PlayerStatEvent::eFlag_ChangedHP);
}
}
if(pSrcIt->m_MP.event == hpmp->eEvent_ChangedMP)
{
const StatChangeNode::MP& rMP = pSrcIt->m_MP;
if(msgMP.m_NumberOfNodes < _countof(msgMP.m_Nodes))
{
//assert(rMP.maxMP != 0)
pMpIt->objectKey = rMP.objectKey;
pMpIt->ratio = rMP.currentMP ? BYTE(rMP.currentMP * 100 / rMP.maxMP) : 0;
++msgMP.m_NumberOfNodes;
++pMpIt;
pUser->SetSelectedCharCurMP(rMP.currentMP);
pUser->SetSelectedCharMaxMP(rMP.maxMP);
pUser->SetNeedChangedStatus(PlayerStatEvent::eFlag_ChangedMP);
}
}
if(pSrcIt->m_SD.event == hpmp->eEvent_ChangedSD)
{
#ifdef _NA_006638_20120415_ADD_SHIELD_INFO_IN_TARGET_INFO
const StatChangeNode::SD& rSD = pSrcIt->m_SD;
if(msgSD.number_of_nodes < _countof(msgSD.nodes))
{
pSdIt->object_key = rSD.objectKey;
pSdIt->ratio = rSD.currentSD ? BYTE(rSD.currentSD * 100 / rSD.maxSD) : 0;
++msgSD.number_of_nodes;
++pSdIt;
pUser->SetSelectedCharCurSD(rSD.currentSD);
pUser->SetSelectedCharMaxSD(rSD.maxSD);
pUser->SetNeedChangedStatus(PlayerStatEvent::eFlag_ChangedSD);
}
#else // _NA_006638_20120415_ADD_SHIELD_INFO_IN_TARGET_INFO
const StatChangeNode::SD& rSD = pSrcIt->m_SD;
pUser->SetSelectedCharCurSD(rSD.currentSD);
pUser->SetSelectedCharMaxSD(rSD.maxSD);
pUser->SetNeedChangedStatus(PlayerStatEvent::eFlag_ChangedSD);
#endif // _NA_006638_20120415_ADD_SHIELD_INFO_IN_TARGET_INFO
}
#ifdef _NA_007514_20140828_NEW_CHARACTER_WITCHBLADE
if (pSrcIt->m_FP.event == hpmp->eEvent_ChangedFP)
{
const StatChangeNode::FP& rFP = pSrcIt->m_FP;
if (msgFP.number_of_nodes < _countof(msgFP.nodes))
{
pFPIt->object_key = rFP.objectKey;
++msgFP.number_of_nodes;
++pFPIt;
pUser->SetSelectedCharCurFP(rFP.currentFP);
//FP는 변화가 없으므로 MaxFP를 갱신해줄 필요가 없다
//pUser->SetSelectedCharMaxFP(rFP.maxFP);
pUser->SetNeedChangedStatus(PlayerStatEvent::eFlag_ChangedFP);
}
}
}
}
#endif //_NA_007514_20140828_NEW_CHARACTER_WITCHBLADE
// Special Operator: packet packing control ... 에이~ 일단 나중으로 미루자.
typedef AgentParty::MEMBER_MAP MEMBER_MAP;
const MEMBER_MAP& members = pAgentParty->GetMemberList();
FOREACH_CONTAINER(const MEMBER_MAP::value_type& member, members, MEMBER_MAP)
{
const _PARTY_MEMBER_INFO& memberInfo = member.second;
User* pMember = pUserManager->GetUserByObjKey(memberInfo.m_dwMemberKey);
if (pMember == NULL)
{
SUNLOG(eCRITICAL_LOG, __FUNCTION__" : Not found user : %d", memberInfo.m_dwMemberKey);
continue;
}
#ifdef _NA_007825_20141118_MODIFY_PARTY_CHARACTER_STATUSUPDATE
// 이제 파티상태에서도 '자신'의 상태업데이트는 자신이 하도록 변경한다
#else
DWORD playerKey = pMember->GetPlayerKey();
BYTE statChangedEvent = pMember->GetNeedChangedStatus();
if(statChangedEvent & PlayerStatEvent::eFlag_ChangedHP)
{
MSG_CG_STATUS_CHANGE_HP_BRD msgBRD;
msgBRD.m_dwObjectKey = playerKey;
msgBRD.m_dwTargetHP = pMember->GetSelectedCharCurHP();
msgBRD.m_dwReserveHP = pMember->GetReservedHP();
pMember->SendPacket(&msgBRD, sizeof(msgBRD));
}
if(statChangedEvent & PlayerStatEvent::eFlag_ChangedMP)
{
MSG_CG_STATUS_CHANGE_MP_BRD msgBRD;
msgBRD.m_dwObjectKey = playerKey;
msgBRD.m_dwTargetMP = pMember->GetSelectedCharCurMP();
pMember->SendPacket(&msgBRD, sizeof(msgBRD));
}
if(statChangedEvent & PlayerStatEvent::eFlag_ChangedSD)
{
MSG_CG_STATUS_CHANGE_SD_CMD msgCMD;
msgCMD.m_dwSD = pMember->GetSelectedCharCurSD();
pMember->SendPacket(&msgCMD, sizeof(msgCMD));
}
#ifdef _NA_007514_20140828_NEW_CHARACTER_WITCHBLADE
if (statChangedEvent & PlayerStatEvent::eFlag_ChangedFP)
{
MSG_CG_STATUS_CHANGE_FP_CMD msgCMD;
msgCMD.object_key = playerKey;
msgCMD.m_dwTargetFP = pMember->GetSelectedCharCurFP();
pMember->SendPacket(&msgCMD, sizeof(msgCMD));
}
#endif //_NA_007514_20140828_NEW_CHARACTER_WITCHBLADE
#endif //_NA_007825_20141118_MODIFY_PARTY_CHARACTER_STATUSUPDATE
//
pMember->SetNeedChangedStatus(PlayerStatEvent::eFlag_None);
if(msgNavi.m_NumberOfNodes)
pMember->SendPacket(&msgNavi, msgNavi.GetSize());
if(msgHP.m_NumberOfNodes)
pMember->SendPacket(&msgHP, msgHP.GetSize());
if(msgMP.m_NumberOfNodes)
pMember->SendPacket(&msgMP, msgMP.GetSize());
#ifdef _NA_006638_20120415_ADD_SHIELD_INFO_IN_TARGET_INFO
if(msgSD.number_of_nodes)
pMember->SendPacket(&msgSD, msgSD.GetSize());
#endif // _NA_006638_20120415_ADD_SHIELD_INFO_IN_TARGET_INFO
#ifdef _NA_007514_20140828_NEW_CHARACTER_WITCHBLADE
if (msgFP.number_of_nodes) {
pMember->SendPacket(&msgFP, msgFP.GetSize());
}
#endif //_NA_007514_20140828_NEW_CHARACTER_WITCHBLADE
}
}
//}__NA001336_090514_PARTY_NAVI_SUPPORT__
void
AgentPartyManager::AddMemberToSession(AgentParty* party,
DWORD to_server_index,
User* user)
{
//AgentServer* const agent_server = AgentServer::GetInstance();
if (!party->GetSessionMemberMgr().AddMemberToSession(user->GetPlayerKey(), to_server_index))
{
return;
}
DWORD member_num = party->GetSessionMemberMgr().GetSessionMemberNum(to_server_index);
if (member_num == 1)
{
MSG_AG_PARTY_CREATE_CMD create_msg;
create_msg.m_wPartykey = party->GetPartyKey();
create_msg.m_MasterKey = party->GetMasterKey();
create_msg.m_byItemDistributionType = party->GetDistributionType();
//_NA_20110630_BATTLE_ZONE_RENEWAL
create_msg.m_PartyType = party->GetType();
user->SendToLinkedServer(&create_msg, sizeof(create_msg));
}
MSG_AG_PARTY_JOIN_CMD join_msg;
join_msg.m_wPartykey = party->GetPartyKey();
join_msg.m_MemberInfo = *(party->GetMemberInfo(user->GetPlayerKey()));
join_msg.m_bMaster = party->GetMasterKey() == user->GetPlayerKey() ? true : false;
user->SendToLinkedServer(&join_msg, sizeof(join_msg));
}
void
AgentPartyManager::RemoveMemberToSession(AgentParty* party,
DWORD from_server_index,
DWORD to_server_index,
User* user)
{
//AgentServer* const agent_server = AgentServer::GetInstance();
if (!party->GetSessionMemberMgr().RemoveMemberToSession(user->GetPlayerKey(), to_server_index))
{
return;
}
DWORD member_num = party->GetSessionMemberMgr().GetSessionMemberNum(from_server_index);
if (member_num == 0)
{
MSG_AG_PARTY_DESTROY_CMD destroy_msg;
destroy_msg.m_wPartykey = party->GetPartyKey();
user->SendToLinkedServer(&destroy_msg, sizeof(destroy_msg));
}
else
{
MSG_AG_PARTY_LEAVE_CMD leave_msg;
leave_msg.m_wPartykey = party->GetPartyKey();
leave_msg.m_dwMemberKey = user->GetPlayerKey();
user->SendToLinkedServer(&leave_msg, sizeof(leave_msg));
}
}
void
AgentPartyManager::SendPacketAllLinkedServer(WORD partyKey, MSG_BASE* pMsg, WORD wSize)
{
AgentParty* pAgentParty = (AgentParty*)FindEditableParty(partyKey);
if(!pAgentParty) return;
LinkServerOperator Opr(pMsg, wSize);
pAgentParty->GetSessionMemberMgr().For_eachSessions(Opr);
}
void
AgentPartyManager::SendPacketAllMember(WORD partyKey, MSG_BASE* pMsg, WORD wSize, DWORD ExceptKey, KEYTYPE CheckZoneKey)
{
AgentParty* pAgentParty = (AgentParty*)FindEditableParty(partyKey);
if(!pAgentParty) return;
pAgentParty->SendPacketAll(pMsg, wSize, ExceptKey, CheckZoneKey);
}
bool
AgentPartyManager::IsMaster(User* pUser)
{
AgentParty* pAgentParty = (AgentParty*)FindEditableParty(pUser->GetPartyState().GetPartyKey());
if(!pAgentParty)
return false;
return pAgentParty->GetMasterKey() == pUser->GetPlayerKey() ? true : false;
}
void
AgentPartyManager::AddRelayUser(RoomInterface * pRoom)
{
AgentParty* pAgentParty = (AgentParty*)FindEditableParty(pRoom->GetLinkParty());
if(!pAgentParty)
return;
static MemberOperator Opr;
Opr.Init(ePARTY_OPERATOR_RELAY_USER, 0, 0);
Opr.SetZone(pRoom);
pAgentParty->For_eachMembers(Opr);
//__NA000000_090622_MOB_ABILITY_CONTROL_CHANGE__
BYTE number_of_players = BYTE(pRoom->GetRelayHash().GetDataNum());
pRoom->SetNumberOfExpectedPlayers(number_of_players);
}
DWORD
AgentPartyManager::GetMemberNum(WORD partyKey)
{
AgentParty* pAgentParty = (AgentParty*)FindEditableParty(partyKey);
if(!pAgentParty)
return 0;
return pAgentParty->GetMemberNum();
}
RC::eROOM_RESULT
AgentPartyManager::InstanceDungeonCheck(WORD partyKey, const sMAPINFO* psMAPINFO)
{
AgentParty* pAgentParty = (AgentParty*)FindEditableParty(partyKey);
if(!pAgentParty)
{
// 파티소속이 아니면 입장시켜 준다.
return RC::RC_ROOM_SUCCESS;
}
// 최소, 최대 인원제한 체크
if(pAgentParty->GetMemberNum() < psMAPINFO->byMinUserNum || psMAPINFO->byMaxUserNum < pAgentParty->GetMemberNum())
return RC::RC_ROOM_MISMATCH_NUMBER_IN_PARTY;
// 모든 파티원의 레벨이 입장 가능한 레벨인지 체크
static MemberOperator Opr;
Opr.Init(ePARTY_OPERATOR_FITNESS_LEVEL_CHECK, 0, 0);
Opr.SetFitnessLV(psMAPINFO->minLV, psMAPINFO->maxLV);
pAgentParty->For_eachMembers(Opr);
if(Opr.IsSuccess())
return RC::RC_ROOM_SUCCESS;
else
return RC::RC_ROOM_MISMATCH_LEVEL_IN_PARTY;
}
RC::eROOM_RESULT
AgentPartyManager::TopOfTrialCheck(WORD partyKey)
{
AgentParty* pAgentParty = (AgentParty*)FindEditableParty(partyKey);
if(!pAgentParty)
{
// 파티소속이 아니면 입장시켜 준다.
return RC::RC_ROOM_SUCCESS;
}
static MemberOperator Opr;
/*
// removed a rule by __NA001319_SAME_CLASS_LIMIT_REMOVE__
// 같은 클래스 5명 이상일 수 없음
Opr.Init(ePARTY_OPERATOR_SAME_CLASS_CHECK, 0, 0);
pAgentParty->For_eachMembers(Opr);
if(!Opr.IsSuccess())
return RC::RC_ROOM_MISMATCH_SAME_CLASS_IN_PARTY;
*/
// 파티장과 레벨 10 이상 차이나면 안됨
User* pMaster = UserManager::Instance()->GetUserByObjKey(pAgentParty->GetMasterKey());
if(!pMaster) return RC::RC_ROOM_SUCCESS;
LEVELTYPE MinLevel = pMaster->GetCharLV() < 10 ? 1 : pMaster->GetCharLV() - 10;
LEVELTYPE MaxLevel = pMaster->GetCharLV() + 10;
Opr.Init(ePARTY_OPERATOR_FITNESS_LEVEL_CHECK, 0, 0);
Opr.SetFitnessLV(MinLevel, MaxLevel);
pAgentParty->For_eachMembers(Opr);
if(!Opr.IsSuccess())
return RC::RC_ROOM_MISMATCH_LEVEL_10_WITH_MASTER;
return RC::RC_ROOM_SUCCESS;
}
// implemented by _NA_0_20110210_INVITE_PARTY_BUG
RC::ePARTY_RESULT AgentPartyManager::RequestInviteParty(User* request_user, User* response_user)
{
static uint generated_party_key = 0;
uint current_time = ::GetTickCount();
uint user_party_key = 0;
user_party_key = request_user->GetPartyState().get_invite_party_key();
InvitePartyKeyHashmap::iterator iter_request = invite_party_key_.find(user_party_key);
if (iter_request != invite_party_key_.end())
{
InvitePartyKey& invite_request = iter_request->second;
if ((current_time - invite_request.response_time) > InvitePartyKey::Response_Limit_Time)
invite_party_key_.erase(iter_request);
else
return RC::RC_PARTY_BEING_INVITE_REQUEST;
}
user_party_key = response_user->GetPartyState().get_invite_party_key();
InvitePartyKeyHashmap::iterator iter_response = invite_party_key_.find(user_party_key);
if (iter_response != invite_party_key_.end())
{
InvitePartyKey& invite_response = iter_response->second;
if ((current_time - invite_response.response_time) > InvitePartyKey::Response_Limit_Time)
invite_party_key_.erase(iter_response);
else
return RC::RC_PARTY_BEING_INVITE_RESPONSE;
}
++generated_party_key;
InvitePartyKey party_key;
party_key.request_user_key = request_user->GetPlayerKey();
party_key.response_user_key = response_user->GetPlayerKey();
party_key.response_time = current_time;
invite_party_key_[generated_party_key] = party_key;
request_user->GetPartyState().set_invite_party_key(generated_party_key);
response_user->GetPartyState().set_invite_party_key(generated_party_key);
return RC::RC_PARTY_SUCCESS;
}
RC::ePARTY_RESULT AgentPartyManager::ResponseInviteParty(User* response_user)
{
uint user_party_key = response_user->GetPartyState().get_invite_party_key();
InvitePartyKeyHashmap::iterator iter_request = invite_party_key_.find(user_party_key);
if (iter_request != invite_party_key_.end())
{
RC::ePARTY_RESULT result = RC::RC_PARTY_SUCCESS;
InvitePartyKey& invite_response = iter_request->second;
if ((::GetTickCount() - invite_response.response_time) > InvitePartyKey::Response_Limit_Time)
{
result = RC::RC_PARTY_INVITE_RESPONSE_TIME_OVER;
}
else
{
if (invite_response.response_user_key != response_user->GetPlayerKey())
result = RC::RC_PARTY_INVALID_PLAYER_STATE;
}
// 파티요청자
User* request_user = UserManager::Instance()->GetUserByObjKey(invite_response.request_user_key);
if (request_user)
request_user->GetPartyState().set_invite_party_key(0);
else
result = RC::RC_PARTY_INVALID_PLAYER_STATE;
response_user->GetPartyState().set_invite_party_key(0);
invite_party_key_.erase(iter_request);
return result;
}
return RC::RC_PARTY_WASNOT_REQUEST_PARTY;
}
void
AgentPartyManager::SetOtherMemberKey(User* pRequestUser, User* pResponseUser)
{
// 상대방 UserKey를 서로 등록해 놓는다.
pRequestUser->GetPartyState().SetOtherMemberKey(pResponseUser->GetPlayerKey());
pResponseUser->GetPartyState().SetOtherMemberKey(pRequestUser->GetPlayerKey());
}
void
AgentPartyManager::ResetOtherMemberKey(User* pRequestUser, User* pResponseUser)
{
// 상대방 UserKey를 서로 등록해 놓는다.
pRequestUser->GetPartyState().SetOtherMemberKey(0);
pResponseUser->GetPartyState().SetOtherMemberKey(0);
}
void
AgentPartyManager::Display()
{
PARTY_MAP::iterator it = party_map_.begin(),
end = party_map_.end();
for( ; it != end; ++it)
{
AgentParty* pAgentParty = (AgentParty*)it->second;
pAgentParty->Display();
}
SUNLOG(eCRITICAL_LOG, "TotPartyNum[%d]", party_map_.size());
}
RC::eROOM_RESULT
AgentPartyManager::MigrateToInstanceDungeon(User* pRequestUser, InstanceDungeon* indun)
{
// TODO(WAVERIX) (WARNING) 이것을 사용하는 시점, 각 유저 Transaction상태 검사가 필요하다.
// (차후 이 검사도 여기로 옮겨버리자.)
static MemberQueryResultOperator op;
op.Init(ePARTY_OPERATOR_TOWEROFCURSE_MIGRATE, 0, 0);
op.SetTransaction(TR_LEAVE_FIELD_FOR_INSTANCE);
op.SetZone(indun);
// (WAVERIX) (090906) (CHANGES) 이 함수는 Static이 아니다. AgentPartyManager::Instance제거
WORD partyKey = pRequestUser->GetPartyState().GetPartyKey();
if(partyKey)
For_eachMembers(partyKey, op);
else
op.MigrateTowerOfCurse(pRequestUser);
// migrate operation
KEYTYPE zoneKey = indun->GetKey();
DWORD linkedServerIndex = indun->GetLinkedServerIndex();
eZONETYPE zoneType = indun->GetType();
//UserManager* pUserManager = UserManager::Instance();
typedef MemberQueryResultOperator::UserStateList UserStateList;
typedef MemberQueryResultOperator::UserState UserState;
const UserStateList& stateList = op.GetUserStateList();
FOREACH_CONTAINER(const UserState& state, stateList, UserStateList)
{
if(state.state == 0)
continue;
ZoneInterface* pFromZone = g_ZoneManager.FindZone(state.pUser->GetZoneKey());
if(!pFromZone) // 선행 조건에 의해있으면 안되는 상황이긴 하지만...
continue;
state.pUser->BeginTransaction(TR_LEAVE_FIELD_FOR_INSTANCE);
pFromZone->LeaveUser(state.pUser, eSEND_SYN, zoneType, linkedServerIndex);
state.pUser->SetTRRoomKey(zoneKey);
}
return RC::RC_ROOM_SUCCESS;
}
//_NA_20110630_BATTLE_ZONE_RENEWAL
void AgentPartyManager::FixStringOfPartyRoomInfo(BasePartyRoomInfo* raw_msg)
{
raw_msg->party_room_title_[_countof(raw_msg->party_room_title_) - 1] = '\0';
raw_msg->party_room_password_[_countof(raw_msg->party_room_password_) - 1] = '\0';
}
PartyRoomFinder*
AgentPartyManager::GetPartyRoomFinder()
{
return party_room_finder_;
}
PartyRoomList*
AgentPartyManager::GetPartyRoomList()
{
return party_room_list_;
}
RC::ePARTY_RESULT
AgentPartyManager::FoceLeavePartyRoom(User* request_user, User* leave_user)
{
WORD party_key = request_user->GetPartyState().GetPartyKey();
AgentParty* party = static_cast<AgentParty*>(FindEditableParty(party_key));
if (party == NULL)
{
return RC::RC_PARTY_NOT_EXIST_PARTY;
}
if (party->GetMasterKey() != request_user->GetPlayerKey())
{
return RC::RC_PARTY_ISNOT_MASTEROFPARTY;
}
return LeaveParty(leave_user, eREASON_LEAVE_PARTY_BAN);
}
void
AgentPartyManager::SetMemberReadyState(User* user, bool ready_state)
{
WORD party_key = user->GetPartyState().GetPartyKey();
AgentParty* party = static_cast<AgentParty*>(FindEditableParty(party_key));
if (party == NULL)
{
SUNLOG(eCRITICAL_LOG, __FUNCTION__" : Not found party : %d", party_key);
return;
}
party->SetMemeberReadyState(user->GetPlayerKey(), ready_state);
MSG_AG_PARTY_READY_STATE_SYN cmd_msg;
cmd_msg.ready_state_ = ready_state;
cmd_msg.party_key_ = party_key;
cmd_msg.member_key_ = user->GetPlayerKey();
user->SendToLinkedServer(&cmd_msg, sizeof(cmd_msg));
}
bool
AgentPartyManager::GetMemberReadyState(User* user)
{
WORD party_key = user->GetPartyState().GetPartyKey();
AgentParty* party = static_cast<AgentParty*>(FindEditableParty(party_key));
if (party == NULL)
{
return false;
}
return !!(party->GetMemeberReadyState(user->GetPlayerKey()));
}
void
AgentPartyManager::SetMemberTeam(User* user, BYTE selected_team)
{
WORD party_key = user->GetPartyState().GetPartyKey();
AgentParty* party = static_cast<AgentParty*>(FindEditableParty(party_key));
if (party == NULL)
{
SUNLOG(eCRITICAL_LOG, __FUNCTION__" : Not found party : %d", party_key);
return;
}
party->SetMemeberTeam(user->GetPlayerKey(), selected_team);
}
BYTE
AgentPartyManager::GetMemberTeam(User* user)
{
WORD party_key = user->GetPartyState().GetPartyKey();
AgentParty* party = static_cast<AgentParty*>(FindEditableParty(party_key));
if (party == NULL)
{
SUNLOG(eCRITICAL_LOG, __FUNCTION__" : Not found party : %d", party_key);
return false;
}
return party->GetMemeberTeam(user->GetPlayerKey());
}
RC::ePARTY_RESULT
AgentPartyManager::CanCreatePartyRoom(User* user,
const BasePartyRoomInfo* party_room_info)const
{
if (user->GetBehaveState() != PLAYER_BEHAVE_IDLE_STATE)
{
return RC::RC_PARTY_INVALID_PLAYER_STATE;
}
BattlezoneMissionTreeParser* battle_zone_parser = BattlezoneMissionTreeParser::Instance();
const BattlezoneMissionTreeInfo* parser_info =
battle_zone_parser->FindData(party_room_info->map_code_, party_room_info->party_room_type_);
if (parser_info == NULL)
{
return RC::RC_PARTY_NOT_INCORRECT_MAPCODE;
}
const sMAPINFO* map_info = MapInfoParser::Instance()->FindMapInfo(party_room_info->map_code_);
if (map_info == NULL)
{
return RC::RC_PARTY_NOT_INCORRECT_MAPCODE;
}
if (user->GetSelectedCharLV() < map_info->minLV || user->GetSelectedCharLV() > map_info->maxLV)
{
return RC::RC_PARTY_ISNOT_QUALIFIED_LEVEL;
}
RC::ePARTY_RESULT result_value = CheckTermsByPartyRoomType(user, party_room_info);
if (result_value != RC::RC_PARTY_SUCCESS)
{
return result_value;
}
return RC::RC_PARTY_SUCCESS;
}
RC::ePARTY_RESULT
AgentPartyManager::CheckTermsByPartyRoomType(User* request_user,
const BasePartyRoomInfo* party_room_info)const
{
BattlezoneMissionTreeParser* const parser = BattlezoneMissionTreeParser::Instance();
const eZONETYPE party_zone_type = parser->GetZoneType(party_room_info->map_code_);
switch(party_zone_type)
{
case eZONETYPE_INSTANCE:
{
const sMAPINFO* const map_info =
MapInfoParser::Instance()->FindMapInfo(party_room_info->map_code_);
if (map_info == NULL)
{
return RC::RC_PARTY_NOT_INCORRECT_MAPCODE;
}
const eZONE_RULESET& rule_set = map_info->Ruleset;
static MemberOperator member_operator;
AgentPartyManager* const party_manager = AgentPartyManager::Instance();
member_operator.Init(ePARTY_OPERATOR_MIGRATE_CHECK, 0, 0);
party_manager->For_eachMembers(request_user->GetPartyState().GetPartyKey(), member_operator);
if (member_operator.IsSuccess() == false)
{
return RC::RC_PARTY_CANNOT_JOIN_SOMEONE_MEMBER;
}
if (rule_set.rules & rule_set.ZONE_RULE_INDUN_SHADOW_NOT_PLAYING_MODE)
{
if (request_user->GetCharClass() == eCHAR_SHADOW)
{
return RC::RC_PARTY_CANNOT_JOIN_SOMEONE_MEMBER;
}
member_operator.Init(ePARTY_OPERATOR_SHADOW_CHECK, 0, 0);
party_manager->For_eachMembers(request_user->GetPartyState().GetPartyKey(), member_operator);
if (member_operator.IsSuccess() == false)
{
return RC::RC_PARTY_CANNOT_JOIN_SOMEONE_MEMBER;
}
}
if (party_room_info->party_room_type_ == PartyOfTopOfTrialByNormal)
{
if (!(g_BattleOpenTimeMng.IsOpenDungeon(map_info->wTimeLimit)))
{
return RC::RC_PARTY_NOT_OPEN_TIME;
}
}
}
break;
case eZONETYPE_MISSION:
{
#ifdef _NA_007156_20140703_TOP_OF_TRIAL_LIGHT
const sMAPINFO* const map_info =
MapInfoParser::Instance()->FindMapInfo(party_room_info->map_code_);
if (map_info == NULL) {
return RC::RC_PARTY_NOT_INCORRECT_MAPCODE;
}
const eZONE_RULESET& rule_set = map_info->Ruleset;
static MemberOperator member_operator;
AgentPartyManager* const party_manager = AgentPartyManager::Instance();
member_operator.Init(ePARTY_OPERATOR_MIGRATE_CHECK, 0, 0);
party_manager->For_eachMembers(request_user->GetPartyState().GetPartyKey(), member_operator);
if (member_operator.IsSuccess() == false) {
return RC::RC_PARTY_CANNOT_JOIN_SOMEONE_MEMBER;
}
if (party_room_info->party_room_type_ == PartyOfTopOfTrialLight_normal)
{
if (!(g_BattleOpenTimeMng.IsOpenDungeon(map_info->wTimeLimit))) {
return RC::RC_PARTY_NOT_OPEN_TIME;
}
}
#endif //_NA_007156_20140703_TOP_OF_TRIAL_LIGHT
}
break;
case eZONETYPE_PVP:
break;
case eZONETYPE_FIELD:
break;
default:
SUNLOG(eCRITICAL_LOG,
__FUNCTION__" : Invalid party room type : %d",
party_zone_type);
return RC::RC_PARTY_INVALID_ROOMTYPE;
}
return RC::RC_PARTY_SUCCESS;
}
RC::ePARTY_RESULT
AgentPartyManager::CreatePartyRoom(BasePartyRoomInfo& party_room_info, User* user)
{
RC::ePARTY_RESULT party_result = RC::RC_PARTY_SUCCESS;
MAPCODE map_code = party_room_info.map_code_;
BaseParty* base_party = CreateParty(user->GetPlayerKey() , ePARTY_ROOM);
if (base_party == NULL)
{
return RC::RC_PARTY_INVALID_ROOMTYPE;
}
WORD party_key = base_party->GetPartyKey();
//파티룸 생성 이전에 파티에 소속된 파티장이라면 이전 파티원들에게 초청 메세지를 보낸다.
if (user->GetPartyState().IsPartyMember() == true)
{
WORD previous_party_key = user->GetPartyState().GetPartyKey();
const BaseParty* previous_party = FindParty(previous_party_key);
if (previous_party)
{
if (previous_party->GetMasterKey() == user->GetPlayerKey())
{
//Master
MSG_CG_PARTY_INVITE_PARTY_ROOM_REQ req_msg;
req_msg.invite_party_key_ = party_key;
SendPacketAllMember(previous_party_key,
&req_msg,
sizeof(req_msg),
previous_party->GetMasterKey());
LeaveParty(user, eREASON_LEAVE_PARTY_INTEND);
}
else
{
//Member
LeaveParty(user, eREASON_LEAVE_PARTY_INTEND);
}
}
}
party_room_info.special_type_ = eROOM_SPECIAL_NORMAL;
if (user->CanApplyPCBangBenefit(true))
{
party_room_info.special_type_ = eROOM_SPECIAL_PCBANG_SUPER_ROOM;
}
else if (user->GetItemOwnFlag().FindItemInfo(eITEMTYPE_SUPERMASTER))
{
party_room_info.special_type_ = eROOM_SPECIAL_ITEM1_SUPER_ROOM;
}
#ifdef _NA_004694_20120412_1202_PARTY_ROOM_KEY
WORD room_key = 0;
if (party_room_list_->CreatePartyRoom(party_room_info, base_party->GetPartyKey() ,room_key) == false)
{
return RC::RC_PARTY_FAIL_CREATE_PARTY_ROOM;
}
else
{
MSG_AW_PARTY_ROOM_KEY_SYN message_aw;
message_aw.party_key_ = party_key;
message_aw.room_key_ = room_key;
AgentServer::GetInstance()->SendToWorldServer(&message_aw, sizeof(message_aw));
}
#else
PartyRoomList* party_room_list = GetPartyRoomList();
if (party_room_list->CreatePartyRoom(party_room_info, base_party->GetPartyKey()) == false)
{
return RC::RC_PARTY_FAIL_CREATE_PARTY_ROOM;
}
#endif //_NA_004694_20120412_1202_PARTY_ROOM_KEY
party_result = JoinParty(party_key, user);
if (party_result != RC::RC_PARTY_SUCCESS)
{
DestroyParty(party_key);
return party_result;
}
if (map_code != 0)
{
#ifdef _NA_004706_20120413_1202_SECRET_ROOM_DONOT_SEND_MESSAGE
const bool is_private_room = (strlen(party_room_info.party_room_password_) == 0) ? false : true;
party_room_finder_->UpdateSelectedMapCodeOfParty(0, map_code, party_key,is_private_room);
#else
PartyRoomFinder* party_room_finder = GetPartyRoomFinder();
party_room_finder->UpdateSelectedMapCodeOfParty(0, map_code, party_key);
#endif // _NA_004706_20120413_1202_SECRET_ROOM_DONOT_SEND_MESSAGE
}
return party_result;
}
#ifdef _NA_20111220_CHANGE_DISCONNECTED_USER_PROCESS
RC::ePARTY_RESULT
AgentPartyManager::LeavePartyRoom(User* user, eREASON_LEAVE_PARTY reason_to_leave)
#else
RC::ePARTY_RESULT
AgentPartyManager::LeavePartyRoom(User* user)
#endif
{
WORD party_key = user->GetPartyState().GetPartyKey();
if (party_room_list_->LeavePartyRoom(party_key) == false )
{
return RC::RC_PARTY_FAIL_LEAVE_PARTY_ROOM;
}
AgentParty* party = static_cast<AgentParty*>(FindEditableParty(party_key));
if (party == NULL)
{
return RC::RC_PARTY_NOT_EXIST_PARTY;
}
if (user->GetTeam() != 0)
{
user->SetTeam(0);
}
user->SetIsRecvInvitePartyRoom(true);
MSG_CG_PARTY_LEAVE_ROOM_BRD brd_msg;
#ifdef _NA_20111220_CHANGE_DISCONNECTED_USER_PROCESS
brd_msg.reason_to_leave_ = reason_to_leave;
#endif
brd_msg.member_key_ = user->GetPlayerKey();
party->SendPacketAll(&brd_msg, sizeof(brd_msg));
return RC::RC_PARTY_SUCCESS;
}
void
AgentPartyManager::DestroyPartyRoom(WORD party_key)
{
MAPCODE map_code = party_room_list_->GetMapCodeOfPartyRoom(party_key);
if (map_code != 0)
{
party_room_finder_->DeletePartyKeyFromMissionList(map_code, party_key);
}
party_room_list_->DestroyPartyRoom(party_key);
}
RC::ePARTY_RESULT
AgentPartyManager::JoinPartyRoom(User* user, WORD party_key, PartyZoneType party_room_type)
{
PartyRoomList* room_list = GetPartyRoomList();
if (room_list->JoinPartyRoom(user, party_key) == false)
{
return RC::RC_PARTY_FAIL_JOIN_PARTY_ROOM;
}
if (party_room_type == PartyOfPvPByTeam)
{
SetMemberTeam(user, user->GetTeam());
}
user->SetIsRecvInvitePartyRoom(false);
return RC::RC_PARTY_SUCCESS;
}
void
AgentPartyManager::ResetRoomMissionCode(WORD party_key)
{
const PartyRoom* party_room = FindPartyRoom(party_key);
if (party_room == NULL)
{
SUNLOG(eCRITICAL_LOG, __FUNCTION__" : Not found party room : %d", party_key);
return;
}
MAPCODE map_code = party_room->GetMapCode();
#ifdef _NA_004706_20120413_1202_SECRET_ROOM_DONOT_SEND_MESSAGE
party_room_finder_->UpdateSelectedMapCodeOfParty(map_code, 0,
party_key, party_room->IsPrivateRoom());
#else
party_room_finder_->UpdateSelectedMapCodeOfParty(map_code, 0, party_key);
#endif // _NA_004706_20120413_1202_SECRET_ROOM_DONOT_SEND_MESSAGE
party_room_list_->SetMissionCode(party_key, 0);
}
void
AgentPartyManager::CheckLevelForMission(WORD party_key, MAPCODE map_code)
{
AgentParty* party = static_cast<AgentParty*>(FindEditableParty(party_key));
if (party == NULL)
{
SUNLOG(eCRITICAL_LOG, __FUNCTION__" : Not found party : %d", party_key);
return;
}
const sMAPINFO* map_info = MapInfoParser::Instance()->FindMapInfo(map_code);
if (map_info == NULL)
{
SUNLOG(eCRITICAL_LOG, __FUNCTION__" : Not found map info : %d", map_code);
return;
}
static MemberOperator member_operator;
member_operator.Init(ePARTY_OPERATOR_KICK_USER_AFTER_CHECK_LEVEL, 0, 0);
member_operator.SetFitnessLV(map_info->minLV, map_info->maxLV);
party->For_eachMembers(member_operator);
}
RC::ePARTY_RESULT
AgentPartyManager::ChangePartyRoomOption(User* user, WORD party_key,
const MSG_AG_PARTY_CAN_CHANGE_OPTION_ACK* recv_msg)
{
AgentParty* party = static_cast<AgentParty*>(FindEditableParty(party_key));
if (party == NULL)
{
return RC::RC_PARTY_NOT_EXIST_PARTY;
}
if (party->GetMasterKey() != user->GetPlayerKey())
{
return RC::RC_PARTY_ISNOT_MASTEROFPARTY;
}
const BasePartyRoomInfo& room_info = recv_msg->party_room_info_;
MAPCODE delete_map_code = party_room_list_->GetMapCodeOfPartyRoom(party_key);
#ifdef _NA_004706_20120413_1202_SECRET_ROOM_DONOT_SEND_MESSAGE
bool is_private_room = (strlen(room_info.party_room_password_) == 0) ? false : true;
bool result_value = party_room_finder_->UpdateSelectedMapCodeOfParty(
delete_map_code,
room_info.map_code_,
party_key,
is_private_room
);
#else
bool result_value = party_room_finder_->UpdateSelectedMapCodeOfParty(delete_map_code,
room_info.map_code_,
party_key);
#endif // _NA_004706_20120413_1202_SECRET_ROOM_DONOT_SEND_MESSAGE
if (result_value == false)
{
return RC::RC_PARTY_FAIL_DESTROY_PARTY_LIST;
}
const PartyRoom* party_room = party_room_list_->FindPartyRoom(party_key);
if (party_room == NULL)
{
return RC::RC_PARTY_NOT_FOUND_PARTYROOM;
}
RC::ePARTY_RESULT result_code = CheckTermsByPartyRoomType(user, &(room_info));
if (result_code != RC::RC_PARTY_SUCCESS)
{
return result_code;
}
if (party_room_list_->UpdateBasePartyRoomInfo(room_info, party_key) == false)
{
return RC::RC_PARTY_FAIL_CHANGE_ROOM_OPTION;
}
KickPartyMemberForChangeOption(recv_msg, user);
ResetPartyRoomReadyState(user, party_key);
return RC::RC_PARTY_SUCCESS;
}
KEYTYPE
AgentPartyManager::GetPartyRoomKey(WORD party_key)
{
const PartyRoom* party_room = party_room_list_->FindPartyRoom(party_key);
if (party_room == NULL)
{
SUNLOG(eCRITICAL_LOG, __FUNCTION__" : Not found party : %d", party_key);
return 0;
}
return party_room->GetPartyRoomInfo()->room_key_;
}
const PartyRoomInfo*
AgentPartyManager::GetPartyRoomInfoByMemberKey(DWORD member_key)
{
User* user = UserManager::Instance()->GetUserByObjKey(member_key);
if (user == NULL)
{
SUNLOG(eCRITICAL_LOG, __FUNCTION__" : Not found user");
return NULL;
}
WORD party_key = user->GetPartyState().GetPartyKey();
const PartyRoom* party_room = party_room_list_->FindPartyRoom(party_key);
if (party_room == NULL)
{
SUNLOG(eCRITICAL_LOG, __FUNCTION__" : Not found party room : %d", party_key);
return NULL;
}
return party_room->GetPartyRoomInfo();
}
RC::ePARTY_RESULT
AgentPartyManager::CanStartRoom(User* user)
{
if (user->IsBeginTransaction())
{
return RC::RC_PARTY_ALREADY_DOING_TRANSACTION;
}
WORD party_key = user->GetPartyState().GetPartyKey();
AgentParty* party = static_cast<AgentParty*>(FindEditableParty(party_key));
if (party == NULL)
{
return RC::RC_PARTY_NOT_EXIST_PARTY;
}
if (party->GetType() != ePARTY_ROOM)
{
return RC::RC_PARTY_IS_NOT_PARTY_ROOM;
}
if (IsMaster(user) == false)
{
return RC::RC_PARTY_ISNOT_MASTEROFPARTY;
}
if (user->GetBehaveState() != PLAYER_BEHAVE_IDLE_STATE)
{
return RC::RC_PARTY_INVALID_PLAYER_STATE;
}
if (party->IsReadyToAllMember() == false)
{
return RC::RC_PARTY_NOT_ALLMEMBER_READY;
}
const PartyRoom* party_room = party_room_list_->FindPartyRoom(party_key);
if (party_room == NULL)
{
return RC::RC_PARTY_NOT_FOUND_PARTYROOM;
}
if (party_room->IsStartWaitingRoom() == true)
{
return RC::RC_PARTY_FAIL_CHECK_TERMS;
}
MAPCODE map_code = party_room->GetMapCode();
BattlezoneMissionTreeParser* battle_zone_parser = BattlezoneMissionTreeParser::Instance();
const BattlezoneMissionTreeInfo* parser_info = battle_zone_parser->FindData(map_code);
if (parser_info == NULL)
{
SUNLOG(eCRITICAL_LOG, __FUNCTION__" : Not found battle zone parser info : %d", map_code);
return RC::RC_PARTY_NOT_INCORRECT_MAPCODE;
}
const sMAPINFO* map_info = MapInfoParser::Instance()->FindMapInfo(map_code);
if (map_info == NULL)
{
SUNLOG(eCRITICAL_LOG, __FUNCTION__" : Not found map info parser : %d", map_code);
return RC::RC_PARTY_NOT_INCORRECT_MAPCODE;
}
if (user->GetSelectedCharLV() < map_info->minLV || user->GetSelectedCharLV() > map_info->maxLV)
{
return RC::RC_PARTY_ISNOT_QUALIFIED_LEVEL;
}
return RC::RC_PARTY_SUCCESS;
}
bool
AgentPartyManager::ExceptionProcessByPartyMember(const MSG_AG_ZONE_CAN_CREATE_ROOM_OF_PARTY_ACK* check_msg,
User* request_user)
{
typedef MSG_AG_ZONE_CAN_CREATE_ROOM_OF_PARTY_ACK CheckMsg;
const CheckMsg::MemberInfo* check_members = check_msg->member_info_;
BYTE number_of_partymember = check_msg->number_of_partymember_;
if (number_of_partymember <= 0 || number_of_partymember > _countof(check_msg->member_info_))
{
return false;
}
const CheckMsg::MemberInfo* it_src = check_members;
const CheckMsg::MemberInfo* it_end = &check_members[number_of_partymember];
CheckMsg::MemberInfo member_result_list[_countof(check_msg->member_info_)];
ZeroMemory(&member_result_list, sizeof(member_result_list));
CheckMsg::MemberInfo* it_dest = member_result_list;
typedef AgentParty::MEMBER_MAP MemberList;
WORD party_key = check_msg->party_key_;
AgentParty* party = static_cast<AgentParty*>(FindEditableParty(party_key));
if (party == NULL)
{
SUNLOG(eCRITICAL_LOG, __FUNCTION__" : Not found party : %d", party_key);
return false;
}
const MemberList& memeber_list = party->GetMemberList();
MSG_CG_ZONE_MISSION_CREATE_NAK nak_msg;
DWORD search_number = 0, result_number = 0, valid_number = 0;
BOOLEAN requester_notified = false;
for (; it_src != it_end; ++it_src, ++it_dest)
{
it_dest->object_key_ = it_src->object_key_;
MemberList::const_iterator find_it = memeber_list.find(it_src->object_key_);
const _PARTY_MEMBER_INFO* memeber_info =
(find_it != memeber_list.end()) ? &(find_it->second) : NULL;
User* user = NULL;
if (memeber_info == NULL)
{
it_dest->status_ = check_msg->eStatus_PartialFail;
}
else
{
user = UserManager::Instance()->GetUserByObjKey(memeber_info->m_dwMemberKey);
if (user == NULL)
{
it_dest->status_ = check_msg->eStatus_PartialFail;
}
else
{
it_dest->status_ = it_src->status_;
++result_number;
}
}
++search_number;
if (it_dest->status_ == check_msg->eStatus_PartialOk)
{
if(user->IsBeginTransaction())
it_dest->status_ = check_msg->eStatus_Transaction;
else
++valid_number;
}
if (it_dest->status_ != check_msg->eStatus_PartialOk)
{
switch (it_dest->status_)
{
case CheckMsg::eStatus_PartialFail:
nak_msg.m_dwErrorCode = RC::RC_ROOM_INVALID_PLAYER_STATE;
break;
case CheckMsg::eStatus_Transaction:
nak_msg.m_dwErrorCode = RC::RC_ROOM_ALREADY_DOING_TRANSACTION;
break;
case CheckMsg::eStatus_LevelViolation:
nak_msg.m_dwErrorCode = RC::RC_ROOM_INVALID_LIMITLEVEL_FOR_ME;
break;
case CheckMsg::eStatus_RequireQuestClear:
nak_msg.m_dwErrorCode = RC::RC_ROOM_PREVIOUS_QUEST_CLEAR;
break;
case CheckMsg::eStatus_RequireMissionClear:
nak_msg.m_dwErrorCode = RC::RC_ROOM_NEED2_CLEAR_PRE_MISSION;
break;
}
if (user)
{
requester_notified = user == request_user;
user->SendPacket(&nak_msg, sizeof(nak_msg));
}
}
}
if (search_number == 0 || search_number != result_number || result_number != valid_number)
{
if (requester_notified == false)
{
nak_msg.m_dwErrorCode = RC::RC_ROOM_CANNOT_JOIN_SOMEONE_PARTY_MEMBER;
request_user->SendPacket(&nak_msg, sizeof(nak_msg));
}
return false;
}
return true;
}
void
AgentPartyManager::KickPartyMemberForChangeOption(const MSG_AG_PARTY_CAN_CHANGE_OPTION_ACK* check_msg,
User* master_user)
{
typedef MSG_AG_PARTY_CAN_CHANGE_OPTION_ACK CheckMsg;
const CheckMsg::MemberState* check_members = check_msg->member_state_;
BYTE number_of_partymember = check_msg->number_of_partymember_;
if (number_of_partymember <= 0 || number_of_partymember > _countof(check_msg->member_state_))
{
SUNLOG(eCRITICAL_LOG, __FUNCTION__" : Invalid number of member count : %d",
number_of_partymember);
return;
}
const CheckMsg::MemberState* begin_list = check_members;
const CheckMsg::MemberState* end_list = &check_members[number_of_partymember];
typedef AgentParty::MEMBER_MAP MemberList;
WORD party_key = master_user->GetPartyState().GetPartyKey();
AgentParty* party = static_cast<AgentParty*>(FindEditableParty(party_key));
if (party == NULL)
{
SUNLOG(eCRITICAL_LOG, __FUNCTION__" : Not found party : %d", party_key);
return;
}
const MemberList& memeber_list = party->GetMemberList();
for (; begin_list != end_list; ++begin_list)
{
MemberList::const_iterator find_iterator = memeber_list.find(begin_list->object_key_);
if (find_iterator == memeber_list.end())
{
continue;
}
if (begin_list->status_ != check_msg->eStatus_PartialOk)
{
const UserManager* const user_manager = UserManager::Instance();
User* const kick_user = user_manager->GetUserByObjKey(begin_list->object_key_);
if (kick_user)
{
eREASON_LEAVE_PARTY reason_to_leave;
switch(begin_list->status_)
{
case CheckMsg::eStatus_LevelViolation:
reason_to_leave = eREASON_LEAVE_PARTY_NOT_MATCH_LEVEL;
break;
case CheckMsg::eStatus_RequireMissionClear:
reason_to_leave = eREASON_LEAVE_PARTY_NOT_CLEAR_MISSION;
break;
case CheckMsg::eStatus_RequireQuestClear:
reason_to_leave = eREASON_LEAVE_PARTY_NOT_CLEAR_QUEST;
break;
default:
reason_to_leave = eREASON_LEAVE_PARTY_NOREASON;
break;
}
LeaveParty(kick_user, reason_to_leave);
}
}
}
}
const PartyRoom*
AgentPartyManager::FindPartyRoom(WORD party_key)const
{
const PartyRoom* party_room = party_room_list_->FindPartyRoom(party_key);
if (party_room == NULL)
{
return NULL;
}
return party_room;
}
void
AgentPartyManager::SetIsMissionStart(WORD party_key, bool is_start)
{
PartyRoom* party_room = party_room_list_->_FindEditableNode(party_key);
if (party_room == NULL)
{
SUNLOG(eCRITICAL_LOG, __FUNCTION__" : Not found party room : %d", party_key);
return;
}
party_room->SetIsMissionStart(is_start);
}
void
AgentPartyManager::CreateNoneTypePartyRoom(User* master_user, const BasePartyRoomInfo& base_info)
{
BasePartyRoomInfo copied_party_room_info = base_info;
FixStringOfPartyRoomInfo(&copied_party_room_info);
RC::ePARTY_RESULT result_code = CreatePartyRoom(copied_party_room_info, master_user);
if (result_code != RC::RC_PARTY_SUCCESS)
{
MSG_CG_PARTY_CREATE_ROOM_ACK nak_msg;
nak_msg.result_code_ = result_code;
master_user->SendPacket(&nak_msg, sizeof(nak_msg));
SUNLOG(eFULL_LOG, __FUNCTION__" : CreatePartyRoom() Process Fail : %d", result_code);
return;
}
const PartyRoomInfo* party_room_info = GetPartyRoomInfoByMemberKey(master_user->GetPlayerKey());
if (party_room_info == NULL)
{
SUNLOG(eCRITICAL_LOG, __FUNCTION__" : Not found room info");
return;
}
MSG_CG_PARTY_CREATE_ROOM_ACK ack_msg;
ack_msg.result_code_ = result_code;
ack_msg.party_room_info_ = *(party_room_info);
master_user->SendPacket(&ack_msg, sizeof(ack_msg));
}
void
AgentPartyManager::ResetPartyRoomReadyState(User* master_user, WORD party_key)
{
BaseParty* party = FindEditableParty(party_key);
if (party == NULL)
{
SUNLOG(eCRITICAL_LOG, __FUNCTION__" : Not found party : %d", party_key);
return;
}
party->ResetReadyStateAllMember();
MSG_AG_PARTY_RESET_READY_STATE_CMD cmd_msg;
cmd_msg.master_key_ = master_user->GetPlayerKey();
cmd_msg.party_key_ = party_key;
master_user->SendToLinkedServer(&cmd_msg, sizeof(cmd_msg));
MSG_CG_PARTY_RESET_READY_STATE_CMD brd_msg;
SendPacketAllMember(party_key, &brd_msg, sizeof(brd_msg));
}
void
AgentPartyManager::NotifyMemberMoveArea(User* user, MAPCODE map_code)
{
WORD party_key = user->GetPartyState().GetPartyKey();
DWORD member_key = user->GetPlayerKey();
BaseParty* party = FindEditableParty(party_key);
if (party == NULL)
{
SUNLOG(eCRITICAL_LOG, __FUNCTION__" : Not found party : %d", party_key);
return;
}
party->SetMemberMapCode(member_key, map_code);
MSG_CG_PARTY_PLAYER_MOVE_FIELD_BRD brd_msg;
brd_msg.member_key_ = member_key;
brd_msg.map_code_ = map_code;
SendPacketAllMember(party_key, &brd_msg, sizeof(brd_msg));
}
void
AgentPartyManager::AddPartyRoomToWaitList(WORD party_key)
{
party_room_list_->SetPartyRoomStateForWaitingToStart(party_key);
}
void
AgentPartyManager::StartPartyRoom(User* request_user)
{
WORD party_key = request_user->GetPartyState().GetPartyKey();
const PartyRoom* party_room = FindPartyRoom(party_key);
if (party_room == NULL)
{
SUNLOG(eCRITICAL_LOG,
__FUNCTION__" : Not found party room : Key : %d, User : %s",
party_key, request_user->GetSelectedCharName());
return;
}
eZONETYPE party_room_type = party_room->GetZoneType();
switch(party_room_type)
{
case eZONETYPE_MISSION:
g_ZoneManager.ProcessCreateMissionRoom(request_user);
break;
case eZONETYPE_INSTANCE:
g_ZoneManager.ProcessCreateInstanceDungeonRoom(request_user);
break;
case eZONETYPE_PVP:
g_ZoneManager.ProcessCreatePVPRoom(request_user);
break;
default:
SUNLOG(eCRITICAL_LOG, __FUNCTION__" : Invalid party room type : %d", party_room_type);
return;
}
}
void AgentPartyManager::DoStartToWaitingRoom()
{
if (check_waiting_room_timer_.IsExpired() == true)
{
typedef PartyRoomWaitingList::StartWaitingRoomList WaitRoomLIst;
PartyRoomList* party_room_list = GetPartyRoomList();
PartyRoomWaitingList* wait_room_list = party_room_list->GetStartWaitingRoomList();
WaitRoomLIst* room_list = wait_room_list->GetEditableWaitingRoomList();
WaitRoomLIst::iterator begin_iterator = room_list->begin(),
end_iterator = room_list->end();
while (begin_iterator != end_iterator)
{
const WORD find_party_key = *(begin_iterator);
PartyRoom* party_room = const_cast<PartyRoom*>(FindPartyRoom(find_party_key));
if (party_room && party_room->IsEndRoomForWaitingToStart() == true)
{
const BaseParty* party = FindParty(party_room->GetPartyKey());
if (party == NULL)
{
SUNLOG(eCRITICAL_LOG,
__FUNCTION__" : Not found party : key : %d",
party_room->GetPartyKey());
continue;
}
UserManager* user_manager = UserManager::Instance();
User* master_user = user_manager->GetUserByObjKey(party->GetMasterKey());
if (master_user == NULL)
{
SUNLOG(eCRITICAL_LOG,
__FUNCTION__" : Not found user : key : %d",
party->GetMasterKey());
continue;
}
StartPartyRoom(master_user);
begin_iterator = room_list->erase(begin_iterator);
continue;
}
++begin_iterator;
}
}
}
void
AgentPartyManager::AddClosingUser(User* user, const _PARTY_MEMBER_INFO& member_info)
{
WORD party_key = user->GetPartyState().GetPartyKey();
AgentParty* party = static_cast<AgentParty*>(FindEditableParty(party_key));
if (party == NULL)
{
SUNLOG(
eCRITICAL_LOG,
__FUNCTION__" : Not found party : key : %d",
party->GetPartyKey()
);
return;
}
PartyReturnInfo& party_return_info = user->GetPartyReturnInfo();
ClosingUserList& closing_user_list = party->GetClosingUserList();
closing_user_list.AddClosingUser(user->GetSelectedCharGuid(),
user->GetSelectedCharName(),
party_return_info,
member_info);
}
void
AgentPartyManager::ChangeMasterOfPartyRoom(User* next_party_master)
{
const WORD party_key = next_party_master->GetPartyState().GetPartyKey();
PartyRoom* party_room = party_room_list_->_FindEditableNode(party_key);
if (party_room == NULL)
{
SUNLOG(
eCRITICAL_LOG,
__FUNCTION__" : Not found party room to edit : request char : %s, party key : %d",
next_party_master->GetSelectedCharName(),
party_key
);
return;
}
PartyRoomInfo* party_room_info = party_room->GetEditablePartyRoomInfo();
party_room_info->base_party_room_info.special_type_ = eROOM_SPECIAL_NORMAL;
if (next_party_master->CanApplyPCBangBenefit(true))
{
party_room_info->base_party_room_info.special_type_ = eROOM_SPECIAL_PCBANG_SUPER_ROOM;
}
else if (next_party_master->GetItemOwnFlag().FindItemInfo(eITEMTYPE_SUPERMASTER))
{
party_room_info->base_party_room_info.special_type_ = eROOM_SPECIAL_ITEM1_SUPER_ROOM;
}
}
RC::ePARTY_RESULT
AgentPartyManager::LeaveParty(User* user, eREASON_LEAVE_PARTY reason_to_leave)
{
WORD party_key = user->GetPartyState().GetPartyKey();
AgentParty* party = static_cast<AgentParty*>(FindEditableParty(party_key));
if (party == NULL)
{
return RC::RC_PARTY_PARTY_NOTEXIST;
}
RC::ePARTY_RESULT result_code = RC::RC_PARTY_SUCCESS;
//_NA_20110630_BATTLE_ZONE_RENEWAL
if (party->GetType() == ePARTY_ROOM)
{
#ifdef _NA_20111220_CHANGE_DISCONNECTED_USER_PROCESS
result_code = LeavePartyRoom(user, reason_to_leave);
#else
result_code = LeavePartyRoom(user);
#endif
if (result_code != RC::RC_PARTY_SUCCESS)
{
SUNLOG(
eCRITICAL_LOG,
__FUNCTION__" : Fail leave party room : name : %s, result code : %d",
user->GetSelectedCharName(), result_code
);
return result_code;
}
}
const _PARTY_MEMBER_INFO* member_info = party->GetMemberInfo(user->GetPlayerKey());
if (member_info == NULL)
{
SUNLOG(
eCRITICAL_LOG,
__FUNCTION__" : Not found party member : party key : %d, member name : %s",
party_key, user->GetSelectedCharName()
);
return RC::RC_PARTY_ISNOT_MEMBEROFPARTY;
}
_PARTY_MEMBER_INFO copied_member_info = *(member_info);
result_code = BasePartyManager::LeaveParty(party_key, user->GetPlayerKey());
if (result_code != RC::RC_PARTY_SUCCESS)
{
return result_code;
}
if (reason_to_leave == eREASON_LEAVE_PARTY_ABNORMAL)
{
if (user->IsDead() == true)
{
reason_to_leave = eREASON_LEAVE_PARTY_INTEND;
}
else
{
AddClosingUser(user, copied_member_info);
}
}
else if (reason_to_leave == eREASON_LEAVE_PARTY_INTEND)
{
PortalManager::OnLeaveParty(user);
}
MSG_CG_PARTY_LEAVE_BRD brd_msg;
brd_msg.m_dwObjKey = user->GetPlayerKey();
brd_msg.m_byReason = static_cast<BYTE>(reason_to_leave);
user->SendPacket(&brd_msg, sizeof(brd_msg));
//user->GetPartyState().Init(); // 파티장 위임 전에 초기화 하면 안됨;;
BYTE number_of_member = party->GetActiveMemberCount();
if (number_of_member == 0)
{
user->GetPartyState().Init();
DestroyParty(party_key);
return RC::RC_PARTY_SUCCESS;
}
const _PARTY_MEMBER_INFO* head_member_info = party->GetHeadUser();
if (head_member_info == NULL)
{
user->GetPartyState().Init();
return RC::RC_PARTY_INVALID_PARTY_STATE;
}
UserManager* const user_manager = UserManager::Instance();
User* member_user = user_manager->GetUserByObjKey(head_member_info->m_dwMemberKey);
if (member_user == NULL)
{
user->GetPartyState().Init();
return RC::RC_PARTY_NOT_FOUND_USER;
}
const eZONETYPE zone_type = member_user->GetZoneType();
//_NA_20110630_BATTLE_ZONE_RENEWAL
if (party->GetType() != ePARTY_ROOM && number_of_member == 1 && member_user)
{
//다음의 존타입에서는 파티멤버가 한명뿐일 경우 파티를 해체시킨다
if (zone_type == eZONETYPE_VILLAGE ||
zone_type == eZONETYPE_DOMINATION_FIELD ||
zone_type == eZONETYPE_FIELD ||
zone_type == eZONETYPE_SPA_FIELD
)
{
user->GetPartyState().Init();
DestroyParty(party_key);
return RC::RC_PARTY_SUCCESS;
}
}
RemoveMemberToSession(party, user->GetServerSessionIndex(), -1, user);
SessionMemberMgr& session_member_manager = party->GetSessionMemberMgr();
if (session_member_manager.LeaveMember(user->GetPlayerKey()) == false)
{
SUNLOG(eCRITICAL_LOG,
__FUNCTION__" : Fail session member manager's leave member : name : %s",
user->GetSelectedCharName());
}
SendPacketAllMember(party_key, &brd_msg, sizeof(brd_msg));
MSG_AW_PARTY_WITHDRAW_MEMBER_SYN aw_mag;
aw_mag.wPartyKey = party_key;
aw_mag.m_CharGUID = user->GetSelectedCharGuid();
user->SendToWorldServer(&aw_mag, sizeof(aw_mag));
KEYTYPE zone_key = user->GetZoneKey();
ZoneInterface* zone = g_ZoneManager.FindZone(zone_key);
//파티 마스터가 파티를 탈퇴 했을 경우 처리
if (party->GetMasterKey() == user->GetPlayerKey())
{
if (zone)
{
User* next_master_user =
static_cast<RoomInterface*>(zone)->ChangeSpecialType(false, user);
if (next_master_user)
{
//우선적으로 미션에 존재 하는 인원에게 파티 마스터권한을 준다.
ChangeMaster(party_key, next_master_user->GetPlayerKey());
}
else
{
ChangeMaster(party_key, party->GetHeadUser()->m_dwMemberKey);
}
}
//_NA_20110630_BATTLE_ZONE_RENEWAL
ResetRoomMissionCode(party_key);
}
// 유저의 파티상태 초기화
user->GetPartyState().Init();
//파티 탈퇴시 인원변경에 관한 처리
if (reason_to_leave != eREASON_LEAVE_PARTY_ABNORMAL && zone != NULL)
{
if (PolicymentForRoom::MonsterAbilityChangableRoomsBit & (1 << zone_type))
{
RoomInterface* room = static_cast<RoomInterface*>(zone);
if (room == NULL)
{
return RC::RC_PARTY_NOT_FOUND_PARTYROOM;
}
BYTE number_of_players = room->GetNumberOfExpectedPlayers();
if (number_of_players)
{
room->SetNumberOfExpectedPlayers(--number_of_players);
g_ZoneManager.ChangeBattlePlayersCount(room, number_of_players);
}
}
}
return RC::RC_PARTY_SUCCESS;
}
bool
AgentPartyManager::CanJoinReturnParty(WORD party_key, User* user)
{
if(user->GetPartyState().IsPartyMember() == true)
{
return false;
}
AgentParty* party = static_cast<AgentParty*>(FindEditableParty(party_key));
if (party == NULL)
{
return false;
}
const CHARGUID char_guid = user->GetSelectedCharGuid();
ClosingUserList& closing_user_list = party->GetClosingUserList();
const ClosingUserInfo* closing_user = closing_user_list.FindClosingUser(char_guid);
if (closing_user == NULL)
{
return false;
}
return true;
}
RC::ePARTY_RESULT
AgentPartyManager::AcceptReturnParty(WORD party_key, User* user)
{
if (user->IsBeginTransaction())
{
return RC::RC_PARTY_ALREADY_DOING_TRANSACTION;
}
AgentPartyManager* const party_manager = AgentPartyManager::Instance();
AgentParty* party = static_cast<AgentParty*>(FindEditableParty(party_key));
if (party == NULL)
{
return RC::RC_PARTY_NOT_EXIST_PARTY;
}
ClosingUserList& closing_user_list = party->GetClosingUserList();
const ClosingUserInfo* closing_user_info =
closing_user_list.FindClosingUser(user->GetSelectedCharGuid());
if (closing_user_info == NULL)
{
SUNLOG(
eCRITICAL_LOG,
__FUNCTION__" : Not found closing user : char name : %s, char guid : %d",
user->GetSelectedCharName(),
user->GetSelectedCharGuid()
);
return RC::RC_PARTY_NOT_FOUND_USER;
}
if (closing_user_info->IsStateReturnTransaction() == true)
{
return RC::RC_PARTY_ALREADY_DOING_TRANSACTION;
}
const_cast<ClosingUserInfo*>(closing_user_info)->return_transaction_ = true;
user->SetBehaveState(PLAYER_BEHAVE_IDLE_STATE);
//step 1 : 파티 가입
if (party->GetType() == ePARTY_ROOM)
{
const PartyRoom* party_room = FindPartyRoom(party_key);
if (party_room == NULL)
{
SUNLOG(
eCRITICAL_LOG,
__FUNCTION__" : Not found party room : %d",
party_key
);
return RC::RC_PARTY_FAIL_JOIN_PARTY_ROOM;
}
if (party_room->GetMapCode() != 0 &&
party_room->CheckLevel(user->GetCharLV()) == false)
{
MSG_CG_PARTY_JOIN_ROOM_ACK nak_msg;
nak_msg.result_code_ = RC::RC_PARTY_NOT_MATCHING_USER_LEVEL;
user->SendPacket(&nak_msg, nak_msg.GetSize());
return RC::RC_PARTY_NOT_MATCHING_USER_LEVEL;
}
if (party_room->CanReturnJoinPartyRoomByMemberCount() == false)
{
MSG_CG_PARTY_JOIN_ROOM_ACK nak_msg;
nak_msg.result_code_ = RC::RC_PARTY_FAIL_MAX_MEMBER_COUNT;
user->SendPacket(&nak_msg, nak_msg.GetSize());
return RC::RC_PARTY_PARTYMEMBER_NUM_FULL;
}
MSG_AG_PARTY_CAN_JOIN_ROOM_SYN syn_msg;
syn_msg.map_code_ = party_room->GetMapCode();
syn_msg.party_room_type_ = party_room->GetZoneType();
syn_msg.join_party_key_ = party_key;
user->SendToLinkedServer(&syn_msg, sizeof(syn_msg));
}
else
{
party_manager->JoinParty(party_key, user);
}
//step 2 : 이전 미션으로 복귀 요청
if (closing_user_info->return_zone_type_ == eZONETYPE_MISSION ||
closing_user_info->return_zone_type_ == eZONETYPE_INSTANCE||
closing_user_info->return_zone_type_ == eZONETYPE_EVENT)
{
ZoneInterface* find_zone = g_ZoneManager.FindZone(closing_user_info->return_zone_key_);
if (find_zone == NULL)
{
SUNLOG(
eFULL_LOG,
__FUNCTION__" : Not exist zone to find : find key : %d",
closing_user_info->return_zone_key_
);
return RC::RC_PARTY_NOT_FOUND_ROOM;
}
const ZoneInterface::ZONE_USER_LIST& return_zone_user_list = find_zone->GetUserList();
if (return_zone_user_list.size() == 0)
{
SUNLOG(
eCRITICAL_LOG,
__FUNCTION__" : Not exist party member to room : return member name : %s",
user->GetSelectedCharName()
);
return RC::RC_PARTY_NOT_FOUND_USER;
}
// _NA_005026_20120527_CHAOS_ZONE_BATTLE_GROUND
User* const mission_user = find_zone->FindUser(party->GetMasterKey());
if (mission_user == NULL)
{
SUNLOG(
eCRITICAL_LOG,
__FUNCTION__" : Invalid invite user data : target member name : %s",
user->GetSelectedCharName()
);
return RC::RC_PARTY_NOT_FOUND_USER;
}
user->BeginTransaction(TR_LEAVE_FIELD_FOR_ROOM);
MSG_AG_ZONE_RETURN_TO_ROOM_INFO_SYN syn_msg;
syn_msg.m_dwRequestUserKey = user->GetUserGUID();
syn_msg.m_wPartyKey = party_key;
mission_user->SendToLinkedServer(&syn_msg, sizeof(syn_msg));
}
else
{
party_manager->RemoveClosingUser(party_key, user->GetSelectedCharGuid());
}
return RC::RC_PARTY_SUCCESS;
}
RC::ePARTY_RESULT
AgentPartyManager::RejectReturnParty(WORD party_key, User* user)
{
AgentParty* party = static_cast<AgentParty*>(FindEditableParty(party_key));
if (party == NULL)
{
return RC::RC_PARTY_NOT_EXIST_PARTY;
}
ClosingUserList& closing_members = party->GetClosingUserList();
const CHARGUID char_guid = user->GetSelectedCharGuid();
const ClosingUserInfo* closing_user = closing_members.FindClosingUser(char_guid);
if (closing_user == NULL)
{
return RC::RC_PARTY_NOT_FOUND_USER;
}
MSG_CG_PARTY_RETURN_A2C_MEMBER_REJECT_CMD cmd_msg;
cmd_msg.CopyFrom(closing_user->GetCharName());
SendPacketAllMember(party_key, &cmd_msg, cmd_msg.GetSize(), user->GetPlayerKey());
user->SetBehaveState(PLAYER_BEHAVE_IDLE_STATE);
RemoveClosingUser(party_key, user->GetSelectedCharGuid());
return RC::RC_PARTY_SUCCESS;
}
void
AgentPartyManager::UpdateReturnUser(WORD partyKey, ClosingUserInfo& rCUser)
{
AgentParty* pAgentParty = (AgentParty*)FindEditableParty(partyKey);
if(!pAgentParty)
{
SUNLOG(eCRITICAL_LOG,
__FUNCTION__" : Not found party info : party key : %d",
partyKey);
return;
}
pAgentParty->GetClosingUserList().UpdateChar(rCUser);
}
void
AgentPartyManager::RemoveClosingUser(WORD party_key, const DWORD char_guid)
{
AgentParty* party = static_cast<AgentParty*>(FindEditableParty(party_key));
if (party == NULL)
{
SUNLOG(eCRITICAL_LOG,
__FUNCTION__" : Not found party : party key : %d",
party_key);
return;
}
ClosingUserList& closing_user_list = party->GetClosingUserList();
closing_user_list.RemoveClosingUser(char_guid);
}
void
AgentPartyManager::RemoveClosingUser(WORD party_key, const TCHAR* char_name)
{
AgentParty* party = static_cast<AgentParty*>(FindEditableParty(party_key));
if (party == NULL)
{
SUNLOG(eCRITICAL_LOG,
__FUNCTION__" : Not found party : party key : %d",
party_key);
return;
}
ClosingUserList& closing_user_list = party->GetClosingUserList();
closing_user_list.RemoveClosingUser(char_name);
}
bool
AgentPartyManager::CheckReturnPartyInfo(User* pole_user, User* return_user)
{
if (return_user->closing_user_trans_controller_.IsTransaction())
{
return false;
}
// 현재 유저가 있는 위치에서 마스터유저가 있는 위치로 이동 준비
ZoneInterface * from_zone = g_ZoneManager.FindZone(return_user->GetZoneKey());
ZoneInterface * to_zone = g_ZoneManager.FindZone(pole_user->GetZoneKey());
if (from_zone == NULL || to_zone == NULL)
return false;
if (from_zone->FromZone_Check(CHECK_RETURN_PARTY) == false)
{
SUNLOG(eCRITICAL_LOG, __FUNCTION__" : From zone check fail");
return_user->EndTransaction();
return false;
}
if (to_zone->ToZone_Check(CHECK_RETURN_PARTY) == false)
{
SUNLOG(eCRITICAL_LOG, __FUNCTION__" : To zone check fail");
return_user->EndTransaction();
return false;
}
WORD party_key = pole_user->GetPartyState().GetPartyKey();
AgentParty* party = static_cast<AgentParty*>(FindEditableParty(party_key));
if (party == NULL)
{
return false;
}
const ClosingUserInfo* closing_user =
party->GetClosingUserList().FindClosingUser(return_user->GetSelectedCharGuid());
if (closing_user == NULL)
{
return false;
}
if (pole_user->GetZoneKey() != closing_user->return_zone_key_)
{
return false;
}
ClosingUserTransController& trans_controller = return_user->closing_user_trans_controller_;
bool result = trans_controller.SetClosingUserTransaction(to_zone->GetMapCode(),
closing_user->return_field_code_,
closing_user->return_pos_);
if (result == false)
{
return false;
}
return true;
}
VOID AgentPartyManager::_JoinProcess_SendPartyInfo(WORD partyKey, User* pUser, _PARTY_MEMBER_INFO& member_info)
{
AgentParty* party = static_cast<AgentParty*>(FindEditableParty(partyKey));
// 조인한 파티원에 파티 전체 정보 알림
MSG_CG_PARTY_CREATE_CMD msgCG;
msgCG.m_PartyKey = partyKey;
msgCG.m_MasterKey = party->GetMasterKey();
msgCG.m_TargetKey = party->GetTargetKey();
msgCG.m_DistributionType = party->GetDistributionType();
party->GetMemberInfoAll(msgCG.m_MemberTotalInfo);
#ifdef _NA_008679_20160202_REWORK_BATTLEGROUND
ePARTY_SUB_TYPE party_sub_type = party->GetPartySubType();
if (party_sub_type == ePARTY_SUB_BATTLEGROUND)
{
PARTY_MEMBER_TOTAL_INFO& party_members = msgCG.m_MemberTotalInfo;
for(int count = 0; count < party_members.m_Count; ++count)
{
TCHAR false_name[MAX_CHARNAME_LENGTH+1] = {'\0'};
_PARTY_MEMBER_INFO& info = party_members.m_Slot[count];
User* member_user = UserManager::Instance()->GetUserByObjKey(info.m_dwMemberKey);
if (member_user == NULL) {
continue;
}
BOOL result =
BattleGroundManager::Instance()->GetMemberFalseName(member_user, false_name);
if (result == TRUE)
{
strncpy(info.m_szCharName, false_name, MAX_CHARNAME_LENGTH);
}
}
}
#endif //_NA_008679_20160202_REWORK_BATTLEGROUND
pUser->SendPacket(&msgCG, msgCG.GetSize());
// 기존 파티원에 조인한 파티원 정보 알림
MSG_CG_PARTY_JOIN_BRD msgCGBrd;
msgCGBrd.m_PartyKey = partyKey;
#ifdef _NA_008679_20160202_REWORK_BATTLEGROUND
if (party_sub_type == ePARTY_SUB_BATTLEGROUND)
{
TCHAR false_name[MAX_CHARNAME_LENGTH+1] = {'\0'};
BOOL result =
BattleGroundManager::Instance()->GetMemberFalseName(pUser, false_name);
if (result == TRUE)
{
strncpy(member_info.m_szCharName, false_name, MAX_CHARNAME_LENGTH);
}
}
#endif //_NA_008679_20160202_REWORK_BATTLEGROUND
msgCGBrd.m_NewMemberInfo = member_info;
SendPacketAllMember(partyKey, &msgCGBrd, sizeof(msgCGBrd), pUser->GetPlayerKey());
}