#include "Stdafx.h" #include "DnLadderMatchingSystem.h" #include "DNLadderRoom.h" #include "DNLadderRoomRepository.h" #include "DNMasterConnection.h" #include "DNLadderSystemManager.h" #include "DNGameDataManager.h" #if defined(PRE_ADD_DWC) #include "DNDWCSystem.h" #endif using namespace LadderSystem; CMatchingSystem::CMatchingSystem( CRoomRepository* pRepository ) :m_pRoomRepository( pRepository ) ,m_dwLastProcessTick(timeGetTime()) { _ASSERT( static_cast(CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::PvPLadder_MinSampleCount )) >= 2 ); } void CMatchingSystem::Process( DWORD dwCurTick ) { // ProcessTick °Ë»ç if( dwCurTick-m_dwLastProcessTick < 1000 ) return; m_dwLastProcessTick = dwCurTick; // RandomSeed ¼³Á¤ m_Random.srand( dwCurTick ); // RoomState::WaitMatching List ¸¸µé±â std::map> mMatchingRoom; _CreateRoomList( mMatchingRoom, RoomState::WaitMatching, 1000 ); for( std::map>::iterator itor=mMatchingRoom.begin() ; itor!=mMatchingRoom.end() ; ++itor ) { std::map> mListUp; std::vector vData; for( UINT i=0 ; i<(*itor).second.size() ; ++i ) { CRoom* pLadderRoom = (*itor).second[i]; if( pLadderRoom->GetRoomState() != RoomState::WaitMatching ) continue; #if defined(PRE_ADD_DWC) //¸ÅĪ½Ã°£ Á¾·áµÇ¸é Å¥¿¡¼­ »©¹ö¸² if( pLadderRoom->GetMatchType() == LadderSystem::MatchType::_3vs3_DWC || pLadderRoom->GetMatchType() == LadderSystem::MatchType::_3vs3_DWC_PRACTICE ) { if( !g_pDWCTeamManager || !g_pDWCTeamManager->CheckDWCMatchTime(pLadderRoom->GetMatchType()) ) { pLadderRoom->SendLadderMatching( ERROR_DWC_LADDER_MATCH_CLOSED, true ); pLadderRoom->ChangeRoomState( RoomState::WaitUser ); continue; } } #endif bool bForceMatching = false; if( pLadderRoom->bIsForceMatching() ) { for( UINT j=0 ; j<(*itor).second.size() ; ++j ) { CRoom* pOpponentLadderRoom = (*itor).second[j]; if( pLadderRoom == pOpponentLadderRoom || pOpponentLadderRoom->GetRoomState() != RoomState::WaitMatching ) continue; // ¸ÅνÃÅ´ pLadderRoom->ChangeRoomState( RoomState::Matched ); pLadderRoom->SetOpponentRoomIndex( pOpponentLadderRoom->GetRoomIndex() ); pOpponentLadderRoom->ChangeRoomState( RoomState::Matched ); pOpponentLadderRoom->SetOpponentRoomIndex( pLadderRoom->GetRoomIndex() ); bForceMatching = true; break; } } // ÀÏÁ¤½Ã°£ °­Á¦ ¸ÅĪ if( bForceMatching == false ) { if( pLadderRoom->GetRoomStateElapsedTick() >= static_cast(CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::PvPLadder_ForceMatchingSec ))*1000 ) { for( UINT j=0 ; j<(*itor).second.size() ; ++j ) { CRoom* pOpponentLadderRoom = (*itor).second[j]; if( pLadderRoom == pOpponentLadderRoom || pOpponentLadderRoom->GetRoomState() != RoomState::WaitMatching || pOpponentLadderRoom->GetRoomStateElapsedTick() < static_cast(CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::PvPLadder_ForceMatchingSec ))*1000 ) continue; // ¸ÅνÃÅ´ pLadderRoom->ChangeRoomState( RoomState::Matched ); pLadderRoom->SetOpponentRoomIndex( pOpponentLadderRoom->GetRoomIndex() ); pOpponentLadderRoom->ChangeRoomState( RoomState::Matched ); pOpponentLadderRoom->SetOpponentRoomIndex( pLadderRoom->GetRoomIndex() ); bForceMatching = true; break; } } } if( bForceMatching == false ) { pLadderRoom->GetMatchingSection( vData ); for( UINT i=0 ; i>::iterator itor = mListUp.find( vData[i] ); if( itor == mListUp.end() ) { std::list Temp; Temp.push_back( pLadderRoom ); mListUp.insert( std::make_pair(vData[i],Temp) ); } else { (*itor).second.push_back( pLadderRoom ); } } } } for( std::map>::iterator LUitor=mListUp.begin() ; LUitor!=mListUp.end() ; ++LUitor ) { if( (*LUitor).second.size() < static_cast(CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::PvPLadder_MinSampleCount )) ) continue; do { // °¡Àå WaitMatching ÀÌ ¿À·¡µÈ ¹æÀÌ Å°°¡ µÈ´Ù. std::list::iterator LItor = (*LUitor).second.begin(); CRoom* pLadderRoom = (*LItor); (*LUitor).second.remove( pLadderRoom ); if( pLadderRoom->GetRoomState() == RoomState::Matched ) continue; // ·£´ýÇÏ°Ô ÇϳªÀÇ ¹æ ¼±Åà size_t RandVal = m_Random.rand()%(*LUitor).second.size(); LItor = (*LUitor).second.begin(); std::advance( LItor, RandVal ); CRoom* pOpponentLadderRoom = (*LItor); (*LUitor).second.remove( pOpponentLadderRoom ); // ¸ÅνÃÅ´ pLadderRoom->ChangeRoomState( RoomState::Matched ); pLadderRoom->SetOpponentRoomIndex( pOpponentLadderRoom->GetRoomIndex() ); pOpponentLadderRoom->ChangeRoomState( RoomState::Matched ); pOpponentLadderRoom->SetOpponentRoomIndex( pLadderRoom->GetRoomIndex() ); }while((*LUitor).second.size() >= 2 ); } } // RoomState::Matched List ¸¸µé±â mMatchingRoom.clear(); _CreateRoomList( mMatchingRoom, (RoomState::Matched|RoomState::Starting), 1000 ); for( std::map>::iterator itor=mMatchingRoom.begin() ; itor!=mMatchingRoom.end() ; ++itor ) { std::map mSyncingRoom; // Match ½Ã۱â Àü º¯µ¿»çÇ× ÃÖÁ¾ È®ÀÎ for( UINT i=0 ; i<(*itor).second.size() ; ++i ) { CRoom* pLadderRoom = (*itor).second[i]; if( mSyncingRoom.find(pLadderRoom) != mSyncingRoom.end() ) continue; bool bCheck = false; CRoom* pOpponentLadderRoom = m_pRoomRepository->GetRoomPtr( pLadderRoom->GetOpponentRoomIndex() ); if( pOpponentLadderRoom ) { bCheck = pOpponentLadderRoom->bIsValidOpponentRoom( pLadderRoom, static_cast(RoomState::Matched|RoomState::Starting) ); } if( bCheck == false ) { pLadderRoom->ChangeRoomState( RoomState::WaitUser ); continue; } if( pLadderRoom->GetStartMsgCount() > 0 ) pLadderRoom->SetStartMsgCount( pLadderRoom->GetStartMsgCount()-1 ); // ÀÌÀü LadderRoom ¿¡ RoomState °¡ º¯°æµÉ ¼ö ÀÖÀ¸¹Ç·Î Çѹø´õ üũÇÑ´Ù. if( !(pLadderRoom->GetRoomState()&RoomState::Starting) ) continue; if( pLadderRoom->GetStartMsgCount() > 0 || pOpponentLadderRoom->GetStartMsgCount() > 0 ) continue; // ·¡´õ °æ±âÀåÀ¸·Î ÀÔÀå if( g_pMasterConnection && g_pMasterConnection->GetActive() ) { mSyncingRoom[pLadderRoom] = true; mSyncingRoom[pOpponentLadderRoom] = true; int iMapIndex = g_pDataManager->GetRandomLadderMapIndex( pLadderRoom->GetMatchType() ); if( iMapIndex < 0 ) { _ASSERT(0); pLadderRoom->ChangeRoomState( RoomState::WaitUser ); continue; } g_pMasterConnection->SendReqLadderGameID( pLadderRoom, pOpponentLadderRoom, CManager::GetInstance().GetChannelID(), timeGetTime(), iMapIndex ); } } } } void CMatchingSystem::_CreateRoomList( std::map>& mMatchingRoom, int State, DWORD dwElapsedTick/*=0*/ ) { const std::map RoomList = m_pRoomRepository->GetRoomList(); for( std::map::const_iterator itor=RoomList.begin() ; itor!=RoomList.end() ; ++itor ) { CRoom* pRoom = (*itor).second; if( pRoom->GetRoomState()&State && pRoom->GetRoomStateElapsedTick() >= dwElapsedTick ) { if( State&RoomState::WaitMatching ) { if( pRoom->bIsMatchingReady() == false ) continue; } std::map>::iterator itor = mMatchingRoom.find( pRoom->GetMatchType() ); if( itor == mMatchingRoom.end() ) { std::vector vRoom; vRoom.push_back( pRoom ); mMatchingRoom.insert( std::make_pair(pRoom->GetMatchType(),vRoom) ); } else { (*itor).second.push_back( pRoom ); } } } } void CMatchingSystem::AddMatchingTime( MatchType::eCode Type, int iSec ) { std::map>::iterator itor = m_mAvgMatchingTime.find( Type ); if( itor == m_mAvgMatchingTime.end() ) { m_mAvgMatchingTime.insert( std::make_pair( Type, std::make_pair(iSec,1) ) ); } else { (*itor).second.first += iSec; ++(*itor).second.second; } #if defined( _WORK ) std::cout << "[Ladder] MatchType:" << Type << " ¸ÅĪ½Ã°£:" << iSec << "ÃÊ °É¸²" << std::endl; std::cout << "[Ladder] MatchType:" << Type << " Æò±Õ¸ÅĪ½Ã°£:" << GetAvgMatchingTimeSec(Type) << "ÃÊ" << std::endl; #endif // #if defined( _WORK ) } int CMatchingSystem::GetAvgMatchingTimeSec( MatchType::eCode Type ) { std::map>::iterator itor = m_mAvgMatchingTime.find( Type ); if( itor != m_mAvgMatchingTime.end() ) return static_cast((*itor).second.first/(*itor).second.second); return -1; }