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

921 lines
29 KiB
C++

#include "StdAfx.h"
// _NA_005026_20120527_CHAOS_ZONE_BATTLE_GROUND
#include <../Common/PacketStruct_AG_ChaosZoneSystem.h>
#include <ChaosZoneSystem/BattleGroundMatchingSystem.h>
#include <ChaosZoneSystem/BattleGroundManager.h>
#include <AgentParty/AgentPartyManager.h>
#include <AgentParty/AgentParty.h>
#include <UserSessions/UserManager.h>
#include <UserSessions/User.h>
#include <Function/AgentServer.Timer.WorkLoad.h>
#include <BattleGroundInfoParser.h>
#include <../ProgramCommon/PacketStruct_CG.h>
#include <PacketHandler/Handler_FromClient.h>
#include <Zone/ZoneManager.h>
#include <Zone/InstanceDungeon.h>
#include <ServerSessions/ServerSessionManager.h>
#include <AgentParty/AgentPartyOperator.h>
//--------------------------------------------------------------------------------------------------
bool SortFunc( BattleGroundMemberInfo* info_a, BattleGroundMemberInfo* info_b)
{
return (info_a->equip_item_score > info_b->equip_item_score);
}
//--------------------------------------------------------------------------------------------------
void BattleGroundMatchingSystem::Init()
{
matching_group_pool_ = new MatchingGroupPool();
matching_group_pool_->Initialize(60);
update_timer_.SetTimer(1000);
#ifdef _NA_008679_20160202_REWORK_BATTLEGROUND
failed_members_list_.clear();
#endif //_NA_008679_20160202_REWORK_BATTLEGROUND
}
void BattleGroundMatchingSystem::Release()
{
MatchingGroupMap::const_iterator const_itr = matching_groups_map_.begin();
for (; const_itr != matching_groups_map_.end(); ++const_itr)
{
matching_group_pool_->Free(const_itr->second);
}
matching_groups_map_.clear();
SAFE_DELETE(matching_group_pool_);
#ifdef _NA_008679_20160202_REWORK_BATTLEGROUND
failed_members_list_.clear();
#endif //_NA_008679_20160202_REWORK_BATTLEGROUND
}
#ifdef _NA_008679_20160202_REWORK_BATTLEGROUND
bool BattleGroundMatchingSystem::ProcessMatching(const MAPCODE map_code)
{
BattleGroundManager* const battle_ground_manager = BattleGroundManager::Instance();
BattleGroundMemberList* const member_list =
battle_ground_manager->FindStandbyGroupMemberList(map_code);
if (member_list == NULL)
{
return false;
}
// 매칭그룹들 생성
// 그룹에 멤버들 삽입
_ProcessMatching(map_code, member_list);
//매칭그룹에 맞는 InstanceDungeon생성
FOREACH_CONTAINER(MatchingGroupMap::value_type& node, matching_groups_map_, MatchingGroupMap)
{
MatchingGroup* group = node.second;
KEYTYPE group_key = group->group_key;
if (group->matching_state == kStartBattleGround)
{
// 이미 시작된 그룹
continue;
}
//방생성 요청..
if (CreateInstanceRoom(group_key, map_code) == false)
{
// 매칭 취소..
MatchingGroupCancel(group_key);
return false;
}
//BRD.. 매칭그룹에 속한 멤버들에게 1차 매칭이 되었다고 알려줌.
MSG_CG_BATTLE_GROUND_MATCHING_RESULT_BRD brd_msg;
{
brd_msg.result_type = 0;
#ifdef _NA_006620_20130402_GM_BATTLE_GROUND_EVENT_GAME
brd_msg.map_code = group->map_code;
#endif // _NA_006620_20130402_GM_BATTLE_GROUND_EVENT_GAME
}
battle_ground_manager->SendPacketAllMember(&group->matching_group_list,
&brd_msg, sizeof(brd_msg));
}
return true;
}
BOOL BattleGroundMatchingSystem::_ProcessMatching(const MAPCODE map_code,
BattleGroundMemberList* member_list)
{
// 1차 매칭..
if (member_list == NULL)
{
return FALSE;
}
const BattleGroundInfo* const battle_ground_Info = BattleGroundInfoParser::Instance()->FindData(map_code);
BYTE max_team_count = battle_ground_Info->team_max;
BYTE min_team_count = battle_ground_Info->team_min;
BYTE group_members_count = max_team_count;
int number_of_members = member_list->size(); //예약한 플레이어 수
// [매칭그룹들 생성]
_CreateMatchingGroups(map_code, member_list);
// [매칭 실패한 그룹]
_CreateFailedGroup(map_code, member_list);
_RequestMismatchingReward();
return TRUE;
}
BOOL BattleGroundMatchingSystem::_CreateMatchingGroups( const MAPCODE& map_code, BattleGroundMemberList* member_list )
{
const BattleGroundInfo* const battle_ground_Info = BattleGroundInfoParser::Instance()->FindData(map_code);
if (battle_ground_Info == NULL) {
return FALSE;
}
if (member_list->size() == 0) {
return FALSE;
}
BYTE max_team_count = battle_ground_Info->team_max;
BYTE min_team_count = battle_ground_Info->team_min;
int count = max_team_count;
while (count >= min_team_count)
{
int member_count = count * 2; // 그룹에 넣을 인원수
int remained_members = member_list->size();
if (remained_members < member_count)
{
//해당 인원의 매칭그룹을 만들 정도의 인원이 없다
--count;
continue;
}
// [매칭 그룹 생성]
std::stable_sort(member_list->begin(), member_list->end(), SortFunc);
MatchingGroup* matching_group = static_cast<MatchingGroup*>(matching_group_pool_->Alloc());
if (matching_group == NULL) {
return FALSE;
}
for (int man = 0; man < member_count; ++man)
{
BattleGroundMemberInfo* const member_info = *(member_list->begin());
if (member_info == NULL) {
continue;
}
if (BattleGroundManager::Instance()->IsValidReservationMember(member_info->user_guid) == false)
{
continue;
}
member_info->member_state = kStandbyPriority;
matching_group->matching_group_list.push_back(member_info);
BattleGroundManager::Instance()->RemoveMemberStandbyGroup(member_info);
}
const KEYTYPE group_key = _AllocKey();
matching_group->group_key = group_key;
//만들어진 시간 설정
matching_group->matching_time = util::TimeSync::_time64(NULL);
matching_group->matching_state = kWaitCreateRoom;
// 그룹 맵에 넣는다
matching_groups_map_.insert(MatchingGroupMap::value_type(group_key, matching_group));
}
return TRUE;
}
BOOL BattleGroundMatchingSystem::_CreateFailedGroup( const MAPCODE& map_code, const BattleGroundMemberList* member_list )
{
// [매칭 실패한 그룹]
// 최소 인원그룹까지 모두 만들었을 경우
// 더이상 그룹을 만들 수 없는 인원수가 되었을 경우
// 매칭 실패한 멤버들을 리스트에 따로 모아둔다
const BattleGroundInfo* const battle_ground_Info = BattleGroundInfoParser::Instance()->FindData(map_code);
if (battle_ground_Info == NULL) {
return FALSE;
}
BYTE min_team_count = battle_ground_Info->team_min;
int remained_members = member_list->size();
if (remained_members <= 0)
{
return FALSE;
}
// 멤버 리스트 복사
//failed_members_list_.assign(member_list->begin(), member_list->end());
std::copy(member_list->begin(), member_list->end(), std::back_inserter(failed_members_list_));
// 예약 취소 및 클라이언트에게 취소 알림
while(member_list->size() > 0)
{
BattleGroundMemberInfo* const member_info = *(member_list->begin());
User* user = UserManager::Instance()->GetUser(member_info->user_guid);
if (user != NULL)
{
MSG_CG_BATTLE_GROUND_RESERVATION_CANCEL_ACK cmd_msg;
cmd_msg.result_code = BattleGroundManager::Instance()->CancelReservation(user);
user->SendPacket(&cmd_msg, sizeof(cmd_msg));
}
}
return TRUE;
}
VOID BattleGroundMatchingSystem::_RequestMismatchingReward()
{
while (failed_members_list_.size() > 0)
{
BattleGroundMemberList::iterator itr = failed_members_list_.begin();
BattleGroundMemberInfo* info = *itr;
User* user = UserManager::Instance()->GetUser(info->user_guid);
MSG_AG_BATTLE_GROUND_MISMATCHING_REWARD_CMD syn_msg;
syn_msg.user_guid = info->user_guid;
syn_msg.battleground_mapcode = info->map_code;
syn_msg.result_type = eBG_RESULT_MISMATCHING;
user->SendToLinkedServer(&syn_msg, sizeof(syn_msg));
failed_members_list_.erase(itr);
}
}
BOOL BattleGroundMatchingSystem::StartBattleGround()
{
FOREACH_CONTAINER(MatchingGroupMap::value_type& node, matching_groups_map_, MatchingGroupMap)
{
MatchingGroup* group = node.second;
if (group == NULL) {
continue;
}
if (group->matching_state == kStartBattleGround)
{
// 이미 시작한 그룹
continue;
}
// // 그룹의 room이 만들어진 상태이면
if (group->matching_state == kCreatedRoom) // script..
{
// 1. 팀매칭 2. 파티생성
// MoveZone 진행
if (OnTeamMatching(group) == false || // 2차 팀 매칭
OnCreateParty(group) == false || // 팀별로 파티구성
SendMembersToBattleGround(group) == false) // 유저 이동
{
// 매칭 취소
MatchingGroupCancel(group->group_key);
continue;
}
group->matching_state = kStartBattleGround;
}
}
return TRUE;
}
#endif //_NA_008679_20160202_REWORK_BATTLEGROUND
bool BattleGroundMatchingSystem::RemoveMatchigGroup(const KEYTYPE group_key)
{
BattleGroundManager* const battle_ground_manager = BattleGroundManager::Instance();
MatchingGroupMap::iterator itr = matching_groups_map_.find(group_key);
MatchingGroup* const matching_group = itr->second;
BattleGroundMemberList::const_iterator list_itr = matching_group->matching_group_list.begin();
for (;list_itr != matching_group->matching_group_list.end(); ++list_itr)
{
BattleGroundMemberInfo* const member_info = *list_itr;
battle_ground_manager->RemoveReservationMember(member_info->user_guid);
}
_FreeKey(group_key);
matching_group_pool_->Free(itr->second);
matching_groups_map_.erase(itr);
return true;
}
MatchingGroup* BattleGroundMatchingSystem::FindMatchingGroup(const KEYTYPE group_key)
{
MatchingGroupMap::const_iterator const_itr = matching_groups_map_.find(group_key);
if (const_itr == matching_groups_map_.end())
{
return NULL;
}
return const_itr->second;
}
MatchingGroup* BattleGroundMatchingSystem::FindMatchingGroupByZoneKey(const KEYTYPE zone_key)
{
MatchingGroupMap::const_iterator const_itr = matching_groups_map_.begin();
for (; const_itr != matching_groups_map_.end(); ++const_itr)
{
MatchingGroup* const matching_group = const_itr->second;
if (matching_group->zone_key != zone_key)
{
continue;
}
return matching_group;
}
return NULL;
}
bool BattleGroundMatchingSystem::CreateInstanceRoom(const KEYTYPE group_key, const MAPCODE map_code)
{
InstanceDungeon* instance_dungeon = NULL;
const RC::eROOM_RESULT rt = g_ZoneManager.CreateInstanceDungeon( \
0, NULL,
map_code, (InstanceDungeon *&)instance_dungeon,
INDUN_KIND_CHAOS_ZONE, FALSE);
if (!instance_dungeon || rt != RC::RC_ROOM_SUCCESS)
{
return false;
}
instance_dungeon->SetRoomState(eROOMSTATE_GENERNAL);
MatchingGroup* const matching_group = FindMatchingGroup(group_key);
matching_group->matching_state = kCreatedRoom;
matching_group->zone_key = instance_dungeon->GetKey();
matching_group->map_code = instance_dungeon->GetMapCode();
return true;
}
class EquipScoreGreater
{
public:
bool operator () ( BattleGroundMemberInfo *pLeft, BattleGroundMemberInfo *pRight ) const
{
return pLeft->equip_item_score > pRight->equip_item_score;
}
};
namespace SecondTeamMatching
{
bool TeamMatchingRule( \
const BattleGroundMemberInfo* player_left,
const BattleGroundMemberInfo* player_right)
{
if ( player_left->is_healer && !player_right->is_healer)
return false;
if (!player_left->is_healer && player_right->is_healer)
return true;
if ( player_left->is_healer && player_right->is_healer)
return (player_left->equip_item_score < player_right->equip_item_score);
return (player_left->equip_item_score > player_right->equip_item_score);
}
void TeamSetUp(BattleGroundMemberInfo* member_, MatchingGroup* const matching_group, \
ChaosZoneTeam team_)
{
member_->team_division = team_;
member_->group_key = matching_group->group_key;
UserManager* const user_manager = UserManager::Instance();
User* const user = user_manager->GetUser(member_->user_guid);
if (user == NULL) {
return;
}
user->SetTRRoomKey(matching_group->zone_key);
user->SetGroupKey(matching_group->group_key);
user->SetTeam(member_->team_division);
// 상태변경..
;{
user->SetBehaveState(PLAYER_BEHAVE_IDLE_STATE);
MSG_AG_BATTLE_GROUND_STATUS_CHANGE_STATE_CMD cmd_msg;
cmd_msg.behave_sate = PLAYER_BEHAVE_IDLE_STATE;
user->SendToLinkedServer(&cmd_msg, sizeof(cmd_msg));
};
}
};
bool BattleGroundMatchingSystem::OnTeamMatching(MatchingGroup* const matching_group)
{
if (matching_group == NULL) {
return false;
}
const BattleGroundMemberList& matching_group_list = matching_group->matching_group_list;
// 2차 매칭
if (matching_group_list.size()%2 != 0) {
return false;
}
BattleGroundMemberList member_info_list = matching_group_list; // copy
std::stable_sort(member_info_list.begin(), member_info_list.end(), &SecondTeamMatching::TeamMatchingRule);
BattleGroundMemberList::const_iterator it = member_info_list.begin();
while(it != member_info_list.end())
{
std::size_t flag = random(0,1);
SecondTeamMatching::TeamSetUp((*it++), matching_group, (flag ? kRed : kBlue));
SecondTeamMatching::TeamSetUp((*it++), matching_group, (flag ? kBlue : kRed ));
}
return true;
}
bool BattleGroundMatchingSystem::SendMembersToBattleGround(MatchingGroup* const matching_group)
{
if (matching_group == NULL) {
return false;
}
InstanceDungeon* const target_room = \
static_cast<InstanceDungeon*>(g_ZoneManager.FindZone(matching_group->zone_key));
if (target_room == NULL) {
return false;
}
BattleGroundMemberList::const_iterator const_itr = matching_group->matching_group_list.begin();
for (; const_itr != matching_group->matching_group_list.end(); ++const_itr)
{
BattleGroundMemberInfo* const find_member = *const_itr;
User* const user = UserManager::Instance()->GetUser(find_member->user_guid);
if (user == NULL)
{
continue;
}
ZoneInterface* current_zone = g_ZoneManager.FindZone(user->GetZoneKey());
if (current_zone == NULL)
{
SUNLOG(eCRITICAL_LOG, __FUNCTION__ " : Not found zone : %d", user->GetUserGUID());
continue;
}
user->BeginTransaction(TR_LEAVE_FIELD_FOR_INSTANCE);
CheckMoveZonePolicy* const check_move_zone_policy =
MoveZonePolicy<MZTF_STATIC_TO_ROOM_FOR_UCUSER>::AlignInfo(user,
user->GetZoneType(), target_room->GetType(),
user->GetZoneKey(), target_room->GetKey());
RoomArgument argument(eZONEPUBLIC_PUBLIC, NULL);
RC::eROOM_RESULT rt = g_ZoneManager.MoveZone(check_move_zone_policy, RoomArgument::GetEmpty());
//if (rt != RC::RC_ROOM_SUCCESS)
//{
// return false;
//}
}
return true;
}
bool BattleGroundMatchingSystem::OnCreateParty(MatchingGroup* const matching_group)
{
if (matching_group == NULL)
{
return false;
}
ZoneInterface* const zone_interface = g_ZoneManager.FindZone(matching_group->zone_key);
if (zone_interface == NULL)
{
return false;
}
InstanceDungeon* const instance_dungeon = static_cast<InstanceDungeon*>(zone_interface);
BattleGroundMemberList red_team;
BattleGroundMemberList blue_team;
BattleGroundMemberList::const_iterator const_itr = matching_group->matching_group_list.begin();
for (; const_itr != matching_group->matching_group_list.end(); ++const_itr)
{
BattleGroundMemberInfo* member = *const_itr;
if (member->team_division == kBlue)
{
blue_team.push_back(member);
}
else
{
red_team.push_back(member);
}
}
std::stable_sort(red_team.begin(), red_team.end(), EquipScoreGreater());
std::stable_sort(blue_team.begin(), blue_team.end(), EquipScoreGreater());
// 두팀 중 한명도 없는 팀이 존재한다면.. 전장으로 보내지 않는다..
if (red_team.size() == 0 || blue_team.size() == 0) {
return false;
}
// GameServer에 팀 정보 전송.
if (EnterTeam(red_team) == false || EnterTeam(blue_team) == false) {
return false;
}
//red_team << team_key : 1
_CreateBattlegroundParty(instance_dungeon, red_team);
//blue_team << team_key : 2
_CreateBattlegroundParty(instance_dungeon, blue_team);
return true;
}
bool BattleGroundMatchingSystem::EnterTeam(const BattleGroundMemberList member_list)
{
BattleGroundMemberList::const_iterator const_itr = member_list.begin();
if (const_itr == member_list.end())
{
return false;
}
BattleGroundMemberInfo* const master_member = *const_itr;
if (master_member == NULL)
{
return false;
}
MatchingGroup* const matching_group = FindMatchingGroup(master_member->group_key);
if (matching_group == NULL)
{
return false;
}
const BattleGroundInfoParser* const battle_ground_info_parser = \
BattleGroundInfoParser::Instance();
const BattleGroundInfo* const battle_ground_Info = \
battle_ground_info_parser->FindData(matching_group->map_code);
const ZoneInterface* const zone = g_ZoneManager.FindZone(matching_group->zone_key);
if (zone == NULL)
{
SUNLOG(eCRITICAL_LOG, TEXT("[BattleGroundMatchingSystem::EnterTeam] Not exist zone [%d]!!"), matching_group->zone_key);
return false;
}
MSG_AG_BATTLE_GROUND_ENTER_TEAM_CMD send_msg;
send_msg.zone_key = matching_group->zone_key;
send_msg.team_key = (*const_itr)->team_division;
BYTE user_count = 0;
#ifdef _NA_008679_20160202_REWORK_BATTLEGROUND
BYTE _team_index = 1;
#endif //_NA_008679_20160202_REWORK_BATTLEGROUND
for (; const_itr != member_list.end(); ++const_itr)
{
BattleGroundMemberInfo* member = *const_itr;
send_msg.user_key_list[user_count] = member->user_guid;
#ifdef _NA_008679_20160202_REWORK_BATTLEGROUND
member->team_index_ = _team_index;
++_team_index;
send_msg.user_team_index_array[user_count] = member->team_index_;
#endif //_NA_008679_20160202_REWORK_BATTLEGROUND
++user_count;
}
if (user_count > battle_ground_Info->team_max)
{
//팀 최대인원수를 넘겼을 경우
SUNLOG(eCRITICAL_LOG, TEXT("[EnterTeam] BattleGroundTeamCount[%d]!!"), user_count);
}
send_msg.user_count = user_count;
const InstanceDungeon* const instance_dungeon = static_cast<const InstanceDungeon*>(zone);
if (instance_dungeon == NULL)
{
return false;
}
ServerSession* const server_session = instance_dungeon->GetLinkedServer();
if(server_session == NULL || server_session->GetServerType() != BATTLE_SERVER)
{
SUNLOG(eFULL_LOG, "배틀서버가 아닌 세션을 연결하려한다.2\n");
return false;
}
server_session->SendPacket(&send_msg, sizeof(send_msg));
return true;
}
bool BattleGroundMatchingSystem::MatchingGroupCancel(const KEYTYPE group_key)
{
MatchingGroup* const matching_group = FindMatchingGroup(group_key);
if (matching_group == NULL)
{
return false;
}
// 매칭된 멤버들을 대기열로 돌려보낸다.
if (ReturnUserInsertStandbyGroupList(matching_group) == false)
{
return false;
}
// 매칭그룹 제거
if (RemoveMatchigGroup(group_key) == false)
{
return false;
}
return true;
}
bool BattleGroundMatchingSystem::ReturnUserInsertStandbyGroupList(MatchingGroup* const matching_group)
{
BattleGroundMemberList::const_iterator const_itr = matching_group->matching_group_list.begin();
for (; const_itr != matching_group->matching_group_list.end(); ++const_itr)
{
BattleGroundMemberInfo* member = *const_itr;
if (BattleGroundManager::Instance()->ReturnUserInsertStandbyGroupList(member) == false)
{
return false;
}
// 상태변경..
;{
MSG_AG_BATTLE_GROUND_STATUS_CHANGE_STATE_CMD cmd_msg;
cmd_msg.behave_sate = PLAYER_BEHAVE_RESERVATION_BATTLE_GROUND_ZONE;
User* const user = UserManager::Instance()->GetUser(member->user_guid);
if (user)
user->SendToLinkedServer(&cmd_msg, sizeof(cmd_msg));
};
}
return true;
}
bool BattleGroundMatchingSystem::RemoveMemberMatchingGroup(const BattleGroundMemberInfo* member)
{
if (member == NULL)
{
return false;
}
MatchingGroup* const matching_group = FindMatchingGroup(member->group_key);
if (matching_group == NULL)
{
return false;
}
BattleGroundMemberList::iterator itr = matching_group->matching_group_list.begin();
for (;itr != matching_group->matching_group_list.end(); ++itr)
{
if ((*itr)->user_guid == member->user_guid)
{
matching_group->matching_group_list.erase(itr);
return true;
}
}
return false;
}
//--------------------------------------------------------------------------------------------------
/*bool BattleGroundMatchingSystem::CheckMatching(MAPCODE map_code)
{
BattleGroundManager* const battle_ground_manager = BattleGroundManager::Instance();
const BattleGroundMemberList* const member_list = \
battle_ground_manager->FindStandbyGroupMemberList(map_code);
if (member_list == NULL)
{
return false;
}
if (CanCreateMatchingGroup(map_code) == false)
{
return false;
}
if (CreateMatchingGroup(map_code) == false)
{
// 메세지 전달.. 매칭그룹 만들기 실패..
return false;
}
return true;
}*/
VOID BattleGroundMatchingSystem::_CreateBattlegroundParty( InstanceDungeon* instance_dungeon, BattleGroundMemberList& team_list )
{
AgentPartyManager* const party_manager = AgentPartyManager::Instance();
AgentParty* base_party = NULL;
BattleGroundMemberInfo* red_member = NULL;
User* red_user = NULL;
BattleGroundMemberList::const_iterator red_itr = team_list.begin();
for (; red_itr != team_list.end(); ++red_itr)
{
red_member = *red_itr;
red_user = UserManager::Instance()->GetUser(red_member->user_guid);
if (red_user == NULL) {
continue;
}
if (base_party == NULL)
{
base_party = \
static_cast<AgentParty*>(party_manager->CreateParty(red_user->GetPlayerKey(), ePARTY_INSTANCE));
if (base_party == NULL) {
continue;
}
base_party->SetPartySubType(ePARTY_SUB_BATTLEGROUND);
static JoinPartyOperator Opr;
Opr.Init(eUSER_OPERATOR_JOINPARTY, base_party->GetPartyKey());
Opr(red_user);
instance_dungeon->LinkParty(base_party->GetPartyKey());
}
if (base_party) {
party_manager->JoinParty(base_party->GetPartyKey(), red_user);
}
}
}
#ifdef _NA_008679_20160202_REWORK_BATTLEGROUND
#else
void BattleGroundMatchingSystem::Update()
{
if (update_timer_.IsExpired() == false) {
return;
}
CTime current_time = util::TimeSync::_time64(NULL);
const BattleGroundInfoParser* const battle_ground_Info_parser = BattleGroundInfoParser::Instance();
MatchingGroupMap::iterator itr = matching_groups_map_.begin();
while (itr != matching_groups_map_.end())
{
// 매칭그룹
MatchingGroupMap::iterator cur_itr = itr++; //!!!!!
MatchingGroup* const matching_group = cur_itr->second;
if (matching_group == NULL) {
matching_groups_map_.erase(cur_itr);
continue;
}
// 스크립트 데이터
const BattleGroundInfo* battle_ground_Info = \
battle_ground_Info_parser->FindData(matching_group->map_code);
if (battle_ground_Info == NULL)
{
continue;
}
// 전장 출발 시간이 경과하면 출발..
if (matching_group->matching_state == kCreatedRoom &&
current_time >= matching_group->matching_time +
CTimeSpan(0, 0, 0, battle_ground_Info->start_time)) // script..
{
if (OnTeamMatching(matching_group) == false || // 2차 팀 매칭
OnCreateParty(matching_group) == false || // 팀별로 파티구성
SendMembersToBattleGround(matching_group) == false) // 유저 이동
{
// 매칭 취소
MatchingGroupCancel(matching_group->group_key);
continue;
}
matching_group->matching_state = kStartBattleGround;
}
}
}
bool BattleGroundMatchingSystem::ProcessMatching(const MAPCODE map_code)
{
BattleGroundManager* const battle_ground_manager = BattleGroundManager::Instance();
BattleGroundMemberList* const member_list =
battle_ground_manager->FindStandbyGroupMemberList(map_code);
if (member_list == NULL)
{
return false;
}
// 매칭그룹 생성
// 그룹에 멤버들 삽입
MatchingGroup* const matching_group = _ProcessMatching(map_code, member_list);
if (matching_group == NULL)
{
return false;
}
const KEYTYPE group_key = _AllocKey();
matching_group->group_key = group_key;
//만들어진 시간 설정
matching_group->matching_time = util::TimeSync::_time64(NULL);
matching_group->matching_state = kWaitCreateRoom;
matching_groups_map_.insert( \
MatchingGroupMap::value_type(group_key, matching_group));
//방생성 요청..
if (CreateInstanceRoom(group_key, map_code) == false)
{
// 매칭 취소..
MatchingGroupCancel(group_key);
return false;
}
//BRD.. 매칭그룹에 속한 멤버들에게 1차 매칭이 되었다고 알려줌.
MSG_CG_BATTLE_GROUND_MATCHING_RESULT_BRD brd_msg;
{
brd_msg.result_type = 0;
#ifdef _NA_006620_20130402_GM_BATTLE_GROUND_EVENT_GAME
brd_msg.map_code = matching_group->map_code;
#endif // _NA_006620_20130402_GM_BATTLE_GROUND_EVENT_GAME
}
battle_ground_manager->SendPacketAllMember(&matching_group->matching_group_list,
&brd_msg, sizeof(brd_msg));
return true;
}
MatchingGroup* BattleGroundMatchingSystem::_ProcessMatching(const MAPCODE map_code,
const BattleGroundMemberList* member_list)
{
// 1차 매칭..
if (member_list == NULL)
{
return NULL;
}
//인원수가 과반이 안넘으면 매칭 실패
const BattleGroundInfoParser* const battle_ground_info_parser = \
BattleGroundInfoParser::Instance();
const BattleGroundInfo* const battle_ground_Info = battle_ground_info_parser->FindData(map_code);
int extract_list = static_cast<int>(battle_ground_Info->team_max);
if ((extract_list%2) != 0)
extract_list += 1;
if ((int)member_list->size() < extract_list)
{
return NULL;
}
//매칭 그룹 선발
MatchingGroup* matching_group =
static_cast<MatchingGroup*>(matching_group_pool_->Alloc());
if (matching_group == NULL) {
return NULL;
}
// 대기열 인원이 최대인원이 아니고 홀수 일경우..한명을 제외시킨다.
int memeber_size = static_cast<int>(member_list->size());
if (memeber_size%2 != 0)
{
memeber_size -= 1;
}
for (int i = 0; i < memeber_size; ++i) //script..
{
BattleGroundMemberInfo* const member_info = *(member_list->begin());
if (member_info == NULL)
{
continue;
}
if (BattleGroundManager::Instance()->IsValidReservationMember(member_info->user_guid) == false)
{
continue;
}
member_info->member_state = kStandbyPriority;
matching_group->matching_group_list.push_back(member_info);
BattleGroundManager::Instance()->RemoveMemberStandbyGroup(member_info);
}
return matching_group;
}
bool BattleGroundMatchingSystem::CanCreateMatchingGroup(const MAPCODE map_code)
{
BattleGroundManager* const battle_ground_manager = BattleGroundManager::Instance();
const BattleGroundMemberList* const member_list = \
battle_ground_manager->FindStandbyGroupMemberList(map_code);
const BattleGroundInfoParser* const battle_ground_info_parser = \
BattleGroundInfoParser::Instance();
const BattleGroundInfo* const battle_ground_Info = battle_ground_info_parser->FindData(map_code);
int extract_list = static_cast<int>(battle_ground_Info->team_max);
if ((int)member_list->size() < extract_list * 2) //script..
{
return false;
}
return true;
}
#endif //_NA_008679_20160202_REWORK_BATTLEGROUND