#include "Stdafx.h" #include "LadderStats.h" #include "DNPvPGameRoom.h" #include "DNUserSession.h" #include "DnPlayerActor.h" #include "DNDBConnection.h" #include "PvPGameMode.h" #include "DnMonsterActor.h" #if defined(PRE_ADD_DWC) #include "DNDBConnectionManager.h" #endif using namespace LadderSystem; //############################################################################################################################### // FactoryClass //############################################################################################################################### CStatsRepository* CStatsFactory::CreateRepository( CDNGameRoom* pGameRoom ) { _ASSERT( pGameRoom->bIsLadderRoom() ); CStatsRepository* pStats = new CStatsRepository( pGameRoom ); if( pStats->bInitialize() == false ) { _ASSERT(0); SAFE_DELETE( pStats ); } return pStats; } #if defined(PRE_ADD_DWC) CDWCStatsRepository* CStatsFactory::CreateDWCRepository( CDNGameRoom* pGameRoom ) { _ASSERT( pGameRoom->bIsLadderRoom() ); CDWCStatsRepository* pStats = new CDWCStatsRepository( pGameRoom ); if( pStats->bInitialize() == false ) { _ASSERT(0); SAFE_DELETE( pStats ); } return pStats; } #endif //############################################################################################################################### // CStats //############################################################################################################################### CStats::CStats( CDNUserSession* pSession, MatchType::eCode MatchType ) :m_biCharacterDBID(pSession->GetCharacterDBID()),m_MatchType(MatchType) { m_bInit = false; m_iGradePoint = 0; // 평점 m_iHiddenGradePoint = 0; // 가평점 m_MatchResult = MatchResult::None; // 매치결과 m_iVSJobCode = 0; // MatchType::_1vs1 일경우에만 쓰임 } void CStats::ConvertKillResult( std::vector& vData ) { if( m_mKillDeathCount.empty() ) return; vData.reserve( m_mKillDeathCount.size() ); for( std::map::iterator itor=m_mKillDeathCount.begin() ; itor!=m_mKillDeathCount.end() ; ++itor ) { LadderKillResult Data; Data.cJobCode = (*itor).first; Data.nKillCount = (*itor).second.iKillCount; Data.nDeathCount = (*itor).second.iDeathCount; vData.push_back( Data ); } } void CStats::OnRecvLadderScore( const TAGetListPvPLadderScore* pPacket ) { if( pPacket->nRetCode != ERROR_NONE ) { _ASSERT(0); return; } // 중복초기화들어오면 문제가 있는거다..행여나 발생해도 최신 데이터를 신용한다. if( m_bInit == true ) _ASSERT(0); bool bFound = false; for( int i=0 ; iData.cLadderTypeCount ; ++i ) { if( pPacket->Data.LadderScore[i].cPvPLadderCode == m_MatchType ) { m_iGradePoint = pPacket->Data.LadderScore[i].iPvPLadderGradePoint; // 평점 m_iHiddenGradePoint = pPacket->Data.LadderScore[i].iHiddenPvPLadderGradePoint; // 가평점 bFound = true; break; } } if( bFound == false ) { m_iGradePoint = Stats::InitGradePoint; m_iHiddenGradePoint = Stats::InitGradePoint; } #if defined( _WORK ) std::cout << "[Ladder] CharDBID:" << m_biCharacterDBID << " 평점:" << m_iGradePoint << " 가평점:" << m_iHiddenGradePoint << std::endl; #endif // #if defined( _WORK ) m_bInit = true; } void CStats::OnDie( DnActorHandle hActor, DnActorHandle hHitter ) { if( m_bInit == false ) { _ASSERT(0); return; } if( !hHitter ) return; // DeathCount std::map::iterator itor = m_mKillDeathCount.find( hHitter->OnGetJobClassID() ); if( itor == m_mKillDeathCount.end() ) { m_mKillDeathCount.insert( std::make_pair(hHitter->OnGetJobClassID(),SKillDeathCount(0,1)) ); } else { ++(*itor).second.iDeathCount; } } void CStats::OnKill( DnActorHandle hActor, DnActorHandle hDieActor ) { if( m_bInit == false ) { _ASSERT(0); return; } if( !hDieActor ) return; // KillCount std::map::iterator itor = m_mKillDeathCount.find( hDieActor->OnGetJobClassID() ); if( itor == m_mKillDeathCount.end() ) { m_mKillDeathCount.insert( std::make_pair(hDieActor->OnGetJobClassID(),SKillDeathCount(1,0)) ); } else { ++(*itor).second.iKillCount; } } //############################################################################################################################### // CStatsRepository //############################################################################################################################### CStatsRepository::CStatsRepository( CDNGameRoom* pGameRoom ):m_pGameRoom(pGameRoom),m_MatchType(MatchType::None) { for( int i=0 ; i<_countof(m_iTeamGradePointAvg) ; ++i ) m_iTeamGradePointAvg[i] = 0; //############################################# // 평점 계산용 //############################################# S_Repository[0] = boost::tuple(1.f,0.4f,0.5f); S_Repository[1] = boost::tuple(1.f,0.f,0.5f); S_Repository[2] = boost::tuple(1.f,0.f,0.5f); S_Repository[3] = boost::tuple(1.f,0.f,0.4f); S_Repository[4] = boost::tuple(1.f,0.f,0.3f); S_Repository[5] = boost::tuple(1.f,0.f,-0.5f); HiddenS_Repository[0] = boost::tuple(1.f,0.f,0.5f); HiddenS_Repository[1] = boost::tuple(1.f,0.f,0.5f); HiddenS_Repository[2] = boost::tuple(1.f,0.f,0.5f); HiddenS_Repository[3] = boost::tuple(1.f,0.f,0.5f); HiddenS_Repository[4] = boost::tuple(1.f,-0.2f,0.5f); HiddenS_Repository[5] = boost::tuple(1.f,-0.3f,0.5f); K_Repository[0] = boost::tuple(60.f,60.f,60.f,60.f); K_Repository[1] = boost::tuple(50.f,50.f,50.f,50.f); K_Repository[2] = boost::tuple(40.f,40.f,40.f,40.f); K_Repository[3] = boost::tuple(30.f,30.f,30.f,30.f); K_Repository[4] = boost::tuple(20.f,20.f,20.f,20.f); K_Repository[5] = boost::tuple(10.f,10.f,10.f,10.f); HiddenK_Repository[0] = boost::tuple(120.f,120.f,120.f,120.f); HiddenK_Repository[1] = boost::tuple(100.f,100.f,100.f,100.f); HiddenK_Repository[2] = boost::tuple(80.f,80.f,80.f,80.f); HiddenK_Repository[3] = boost::tuple(60.f,60.f,60.f,60.f); HiddenK_Repository[4] = boost::tuple(40.f,40.f,40.f,40.f); HiddenK_Repository[5] = boost::tuple(20.f,20.f,20.f,20.f); } CStatsRepository::~CStatsRepository() { for( std::map::iterator itor=m_mRepository.begin() ; itor!=m_mRepository.end() ; ++itor ) SAFE_DELETE( (*itor).second ); } bool CStatsRepository::bInitialize() { CDNPvPGameRoom* pPvPGameRoom = static_cast(m_pGameRoom); m_MatchType = pPvPGameRoom->GetPvPLadderMatchType(); #if defined(PRE_ADD_DWC) int iNeedTeamPlayer = LadderSystem::GetNeedTeamCount(m_MatchType); #else int iNeedTeamPlayer = static_cast(m_MatchType); #endif // A 팀 인원수 확인 if( pPvPGameRoom->GetUserCount( PvPCommon::Team::A ) != iNeedTeamPlayer ) { _ASSERT(0); return false; } // B 팀 인원수 확인 if( pPvPGameRoom->GetUserCount( PvPCommon::Team::B ) != iNeedTeamPlayer ) { _ASSERT(0); return false; } for( UINT i=0 ; iGetUserCount() ; ++i ) { CDNUserSession* pSession = m_pGameRoom->GetUserData(i); if( (pSession->GetTeam() == PvPCommon::Team::A || pSession->GetTeam() == PvPCommon::Team::B) == false ) continue; CStats* pStats = new CStats( pSession, m_MatchType ); if( pStats == NULL ) { _ASSERT(0); return false; } m_mRepository.insert( std::make_pair(pSession->GetCharacterDBID(),pStats) ); } if( m_mRepository.size() != iNeedTeamPlayer*2 ) return false; return true; } bool CStatsRepository::QueryUpdateResult( CDNUserSession* pSession, UINT uiWinTeam, PvPCommon::QueryUpdatePvPDataType::eCode Type ) { if( static_cast(m_pGameRoom)->GetPvPGameMode()->GetRemainStartTick() > 0 ) { #if defined( _WORK ) std::cout << "[Ladder] 시작 전에 종료되어서 DB 업뎃안함!!!" << std::endl; #endif // #if defined( _WORK ) return false; } if( bIsValidLadderTeam( pSession->GetTeam() ) == false ) { _ASSERT(0); return false; } std::map::iterator itor = m_mRepository.find( pSession->GetCharacterDBID() ); if( itor == m_mRepository.end() ) return false; CStats* pStats = (*itor).second; //############################## // 평균평점 //############################## float Ra = static_cast((pSession->GetTeam() == PvPCommon::Team::A) ? m_iTeamGradePointAvg[PvPCommon::TeamIndex::A] : m_iTeamGradePointAvg[PvPCommon::TeamIndex::B]); float Rb = static_cast((pSession->GetTeam() == PvPCommon::Team::A) ? m_iTeamGradePointAvg[PvPCommon::TeamIndex::B] : m_iTeamGradePointAvg[PvPCommon::TeamIndex::A]); //############################## // 래더 평점 보정 //############################## int iAvgGradePoint = static_cast(Ra); int iTupleIndex = 0; // 최하유저 if( iAvgGradePoint < 1400 ) iTupleIndex = 0; // 기본 유저 else if( iAvgGradePoint < 1700 ) iTupleIndex = 1; // 일반 유저 else if( iAvgGradePoint < 2000 ) iTupleIndex = 2; // 상위 유저 else if( iAvgGradePoint < 2300 ) iTupleIndex = 3; // 코어 유저 else if( iAvgGradePoint < 2500 ) iTupleIndex = 4; // 안드로 유저 else iTupleIndex = 5; if( iTupleIndex >= MAX_GRADEPOINT_RANGE ) { _ASSERT(0); iTupleIndex = 0; } //############################## // 경기결과 //############################## float S = 0.f; float HiddenS = 0.f; float K = 0.f; float HiddenK = 0.f; MatchResult::eCode Result = MatchResult::Lose; switch( Type ) { case PvPCommon::QueryUpdatePvPDataType::FinishGameMode: { if( uiWinTeam == PvPCommon::Team::Max ) // 무승부 { Result = MatchResult::Draw; S = S_Repository[iTupleIndex].get<2>(); HiddenS = HiddenS_Repository[iTupleIndex].get<2>(); } else if( uiWinTeam == pSession->GetTeam() ) // 승 { Result = MatchResult::Win; S = S_Repository[iTupleIndex].get<0>(); HiddenS = HiddenS_Repository[iTupleIndex].get<0>(); } else // 패 { Result = MatchResult::Lose; S = S_Repository[iTupleIndex].get<1>(); HiddenS = HiddenS_Repository[iTupleIndex].get<1>(); } break; } } switch( m_MatchType ) { case MatchType::_1vs1: { K = K_Repository[iTupleIndex].get<0>(); HiddenK = HiddenK_Repository[iTupleIndex].get<0>(); break; } case MatchType::_2vs2: { K = K_Repository[iTupleIndex].get<1>(); HiddenK = HiddenK_Repository[iTupleIndex].get<1>(); break; } case MatchType::_3vs3: { K = K_Repository[iTupleIndex].get<2>(); HiddenK = HiddenK_Repository[iTupleIndex].get<2>(); break; } case MatchType::_4vs4: { K = K_Repository[iTupleIndex].get<3>(); HiddenK = HiddenK_Repository[iTupleIndex].get<3>(); break; } } //############################## // 예상승률 //############################## float Ea = 1/(1.f+pow(10,(Rb-Ra)/400.f)); //############################## // 평점 변화량 //############################## float ChangeRa = K*(S-Ea); float ChangeHiddenRa = HiddenK*(HiddenS-Ea); //############################## // flaot 반올림 처리 //############################## ChangeRa = static_cast(static_cast(ChangeRa + (ChangeRa > 0.f ? .5f : -.5f) )) / 1.f; ChangeHiddenRa = static_cast(static_cast(ChangeHiddenRa + (ChangeHiddenRa > 0.f ? .5f : -.5f) )) / 1.f; //############################## // Query 날리기~ //############################## CDNDBConnection* pDBCon = pSession->GetDBConnection(); if( pDBCon == NULL ) return false; int iGradePoint = pStats->GetGradePoint()+static_cast(ChangeRa); int iHiddenGradePoint = pStats->GetHiddenGradePoint()+static_cast(ChangeHiddenRa); BYTE cVSJobCode = pStats->GetVSJobCode(); std::vector vData; pStats->ConvertKillResult( vData ); if( iGradePoint < Stats::MinGradePoint ) iGradePoint = Stats::MinGradePoint; if( iHiddenGradePoint < Stats::MinGradePoint ) iHiddenGradePoint = Stats::MinGradePoint; #if defined( _WORK ) std::cout << "[Ladder] CharDBID:" << pSession->GetCharacterDBID() << " 결과:" << Result << std::endl; std::cout << "[Ladder] 평점변화 " << pStats->GetGradePoint() << "->" << iGradePoint << std::endl; std::cout << "[Ladder] 가평점변화 " << pStats->GetHiddenGradePoint() << "->" << iHiddenGradePoint << std::endl; #endif // #if defined( _WORK ) g_Log.Log( LogType::_LADDER, pSession, L"result gradepoint:%d\r\n", iGradePoint ); m_mResult[pSession->GetCharacterDBID()] = SResult(static_cast(ChangeRa),iGradePoint ); return pDBCon->QueryAddPvPLadderResult( pSession, Type, m_MatchType, iGradePoint, iHiddenGradePoint, Result, cVSJobCode, vData ); } void CStatsRepository::OnDie( DnActorHandle hActor, DnActorHandle hHitter ) { //소환물이 kill 한 경우 if( hHitter && hHitter->IsMonsterActor() ) { DnActorHandle hMaster = static_cast(hHitter.GetPointer())->GetSummonerPlayerActor(); if( hMaster && hMaster->IsPlayerActor() ) hHitter = hMaster; } // Valid체크 if( !(hActor && hHitter && hActor->IsPlayerActor() && hHitter->IsPlayerActor()) ) return; CDnPlayerActor* pPlayer = reinterpret_cast(hActor.GetPointer()); std::map::iterator itor = m_mRepository.find( pPlayer->GetCharacterDBID() ); if( itor != m_mRepository.end() ) (*itor).second->OnDie( hActor, hHitter ); CDnPlayerActor* pHitter = reinterpret_cast(hHitter.GetPointer()); itor = m_mRepository.find( pHitter->GetCharacterDBID() ); if( itor != m_mRepository.end() ) (*itor).second->OnKill( hHitter, hActor ); } void CStatsRepository::OnRecvLadderScore( INT64 biCharacterDBID, int iTeam, const TAGetListPvPLadderScore* pPacket ) { std::map::iterator itor = m_mRepository.find( biCharacterDBID ); if( itor == m_mRepository.end() ) { _ASSERT(0); return; } if( bIsValidLadderTeam( iTeam ) == false ) _ASSERT(0); (*itor).second->OnRecvLadderScore( pPacket ); // 팀별 평점 계산 int iGradePoint = (*itor).second->GetGradePoint(); std::map>::iterator Sumitor = m_mGradePointSum.find( iTeam ); if( Sumitor == m_mGradePointSum.end() ) { std::vector vTemp; vTemp.push_back( iGradePoint ); m_mGradePointSum.insert( std::make_pair(iTeam,vTemp) ); } else { (*Sumitor).second.push_back( iGradePoint ); } // 평균 계산 int iSum = 0; Sumitor = m_mGradePointSum.find( iTeam ); for( UINT i=0 ; i<(*Sumitor).second.size() ; ++i ) iSum += (*Sumitor).second[i]; if ((*Sumitor).second.size() <= 0) { _ASSERT(0); return; } m_iTeamGradePointAvg[iTeam-PvPCommon::Team::A] = static_cast(iSum/(*Sumitor).second.size()); } void CStatsRepository::OnSetPlayState() { // Stats 초기화 검증 for( std::map::iterator itor=m_mRepository.begin() ; itor!=m_mRepository.end() ; ++itor ) { CStats* pStats = (*itor).second; if( pStats->bIsInit() == false ) { _ASSERT(0); CDNUserSession* pSession = m_pGameRoom->GetUserSessionByCharDBID( (*itor).first ); if( pSession ) pSession->DetachConnection( L"LadderStats isn't Init" ); } } // 1vs1 인 경우 VSJobCode 설정 작업 if( m_MatchType == MatchType::_1vs1 ) { if( m_pGameRoom->GetUserCount() != 2 ) return; CDNUserSession* pSession = m_pGameRoom->GetUserData(0); CDNUserSession* pSession2 = m_pGameRoom->GetUserData(1); if( pSession && pSession2 ) { std::map::iterator itor = m_mRepository.find( pSession->GetCharacterDBID() ); if( itor != m_mRepository.end() ) (*itor).second->SetVSJobCode( pSession2->GetUserJob() ); itor = m_mRepository.find( pSession2->GetCharacterDBID() ); if( itor != m_mRepository.end() ) (*itor).second->SetVSJobCode( pSession->GetUserJob() ); } } } bool CStatsRepository::bIsValidLadderTeam( int iTeam ) { switch( iTeam ) { case PvPCommon::Team::A: case PvPCommon::Team::B: return true; } return false; } int CStatsRepository::GetAddGradePoint( INT64 biCharacterDBID ) { std::map::iterator itor = m_mResult.find( biCharacterDBID ); if( itor != m_mResult.end() ) return (*itor).second.iAddGradePoint; return 0; } int CStatsRepository::GetResultGradePoint( INT64 biCharacterDBID ) { std::map::iterator itor = m_mResult.find( biCharacterDBID ); if( itor != m_mResult.end() ) return (*itor).second.iResultGradePoint; return 0; } #if defined(PRE_ADD_DWC) void CDWCStats::SetMatchType(MatchType::eCode MatchType) { m_MatchType = MatchType; } void CDWCStats::OnRecvDWCScore(UINT nTeamID, TDWCTeam* Info, UINT nOppositeTeamID) { // 중복초기화들어오면 문제가 있는거다..행여나 발생해도 최신 데이터를 신용한다. if( m_bInit == true ) _ASSERT(0); m_nTeamID = nTeamID; m_nOppositeTeamID = nOppositeTeamID; m_iGradePoint = Info->nDWCPoint; m_iHiddenGradePoint = Info->nHiddenDWCPoint; if(m_iGradePoint <= 0 ) m_iGradePoint = Stats::InitGradePoint; if(m_iHiddenGradePoint <= 0 ) m_iHiddenGradePoint = Stats::InitGradePoint; } CDWCStatsRepository::CDWCStatsRepository( CDNGameRoom* pGameRoom ) :m_pGameRoom(pGameRoom),m_MatchType(MatchType::None) { //############################################# // 평점 계산용 //############################################# S_Repository[0] = boost::tuple(1.f,0.4f,0.5f); S_Repository[1] = boost::tuple(1.f,0.f,0.5f); S_Repository[2] = boost::tuple(1.f,0.f,0.5f); S_Repository[3] = boost::tuple(1.f,0.f,0.4f); S_Repository[4] = boost::tuple(1.f,0.f,0.3f); S_Repository[5] = boost::tuple(1.f,0.f,-0.5f); HiddenS_Repository[0] = boost::tuple(1.f,0.f,0.5f); HiddenS_Repository[1] = boost::tuple(1.f,0.f,0.5f); HiddenS_Repository[2] = boost::tuple(1.f,0.f,0.5f); HiddenS_Repository[3] = boost::tuple(1.f,0.f,0.5f); HiddenS_Repository[4] = boost::tuple(1.f,-0.2f,0.5f); HiddenS_Repository[5] = boost::tuple(1.f,-0.3f,0.5f); K_Repository[0] = boost::tuple(60.f,60.f,60.f,60.f); K_Repository[1] = boost::tuple(50.f,50.f,50.f,50.f); K_Repository[2] = boost::tuple(40.f,40.f,40.f,40.f); K_Repository[3] = boost::tuple(30.f,30.f,30.f,30.f); K_Repository[4] = boost::tuple(20.f,20.f,20.f,20.f); K_Repository[5] = boost::tuple(10.f,10.f,10.f,10.f); HiddenK_Repository[0] = boost::tuple(120.f,120.f,120.f,120.f); HiddenK_Repository[1] = boost::tuple(100.f,100.f,100.f,100.f); HiddenK_Repository[2] = boost::tuple(80.f,80.f,80.f,80.f); HiddenK_Repository[3] = boost::tuple(60.f,60.f,60.f,60.f); HiddenK_Repository[4] = boost::tuple(40.f,40.f,40.f,40.f); HiddenK_Repository[5] = boost::tuple(20.f,20.f,20.f,20.f); } bool CDWCStatsRepository::bInitialize() { CDNPvPGameRoom* pPvPGameRoom = static_cast(m_pGameRoom); m_MatchType = pPvPGameRoom->GetPvPLadderMatchType(); int iNeedTeamPlayer = LadderSystem::GetNeedTeamCount(m_MatchType); #if !defined(_WORK) //워크 버전은 팀원 수 확인 패쓰 // A 팀 인원수 확인 if( pPvPGameRoom->GetUserCount( PvPCommon::Team::A ) != iNeedTeamPlayer ) { _ASSERT(0); return false; } // B 팀 인원수 확인 if( pPvPGameRoom->GetUserCount( PvPCommon::Team::B ) != iNeedTeamPlayer ) { _ASSERT(0); return false; } #endif for( UINT i=0 ; iGetUserCount() ; ++i ) { CDNUserSession* pSession = m_pGameRoom->GetUserData(i); if( (pSession->GetTeam() == PvPCommon::Team::A || pSession->GetTeam() == PvPCommon::Team::B) == false ) continue; } m_DWCStat[0].SetMatchType(m_MatchType); m_DWCStat[1].SetMatchType(m_MatchType); return true; } bool CDWCStatsRepository::bIsValidLadderTeam( int iTeam ) { switch( iTeam ) { case PvPCommon::Team::A: case PvPCommon::Team::B: return true; } return false; } int CDWCStatsRepository::GetAddGradePoint( int iTeam ) { if( iTeam == PvPCommon::Team::A) return m_Result[0].iAddGradePoint; if( iTeam == PvPCommon::Team::B) return m_Result[1].iAddGradePoint; return 0; } int CDWCStatsRepository::GetResultGradePoint( int iTeam ) { if( iTeam == PvPCommon::Team::A) return m_Result[0].iResultGradePoint; if( iTeam == PvPCommon::Team::B) return m_Result[1].iResultGradePoint; return 0; } void CDWCStatsRepository::OnRecvDWCScore(UINT nATeamID, TDWCTeam* ATeamInfo, UINT nBTeamID, TDWCTeam* BTeamInfo) { m_DWCStat[0].OnRecvDWCScore(nATeamID, ATeamInfo, nBTeamID); m_DWCStat[1].OnRecvDWCScore(nBTeamID, BTeamInfo, nATeamID); } bool CDWCStatsRepository::QueryUpdateResult( UINT uiWinTeam, PvPCommon::QueryUpdatePvPDataType::eCode Type ) { if( static_cast(m_pGameRoom)->GetPvPGameMode()->GetRemainStartTick() > 0 ) { #if defined( _WORK ) std::cout << "[Ladder] 시작 전에 종료되어서 DB 업뎃안함!!!" << std::endl; #endif // #if defined( _WORK ) return false; } int nATeamPoint = 0; // A팀 포인트 int nBTeamPoint = 0; // B팀 포인트 for(int nTeam = PvPCommon::Team::A, i = 0 ; nTeam <= PvPCommon::Team::B ; nTeam++, i++) { //############################## // 래더 평점 보정 //############################## int Ra = 0; // 현재팀 int Rb = 0; // 상대팀 UINT nTeamID = 0; UINT nOppositeTeamID = 0; if( nTeam == PvPCommon::Team::A ) { Ra = nATeamPoint; Rb = nBTeamPoint; } else { Ra = nBTeamPoint; Rb = nATeamPoint; } int iTupleIndex = 0; // 최하유저 if( Ra < 1400 ) iTupleIndex = 0; // 기본 유저 else if( Ra < 1700 ) iTupleIndex = 1; // 일반 유저 else if( Ra < 2000 ) iTupleIndex = 2; // 상위 유저 else if( Ra < 2300 ) iTupleIndex = 3; // 코어 유저 else if( Ra < 2500 ) iTupleIndex = 4; // 안드로 유저 else iTupleIndex = 5; if( iTupleIndex >= MAX_GRADEPOINT_RANGE ) { _ASSERT(0); iTupleIndex = 0; } //############################## // 경기결과 //############################## float S = 0.f; float HiddenS = 0.f; float K = 0.f; float HiddenK = 0.f; MatchResult::eCode Result = MatchResult::Lose; switch( Type ) { case PvPCommon::QueryUpdatePvPDataType::FinishGameMode: { if( uiWinTeam == PvPCommon::Team::Max ) // 무승부 { Result = MatchResult::Draw; S = S_Repository[iTupleIndex].get<2>(); HiddenS = HiddenS_Repository[iTupleIndex].get<2>(); } else if( uiWinTeam == nTeam ) // 승 { Result = MatchResult::Win; S = S_Repository[iTupleIndex].get<0>(); HiddenS = HiddenS_Repository[iTupleIndex].get<0>(); } else // 패 { Result = MatchResult::Lose; S = S_Repository[iTupleIndex].get<1>(); HiddenS = HiddenS_Repository[iTupleIndex].get<1>(); } break; } } switch( m_MatchType ) { case MatchType::_3vs3_DWC: case MatchType::_3vs3_DWC_PRACTICE: // 얘는 포인트 줄건지 말건지 확인 { K = K_Repository[iTupleIndex].get<2>(); HiddenK = HiddenK_Repository[iTupleIndex].get<2>(); break; } } //############################## // 예상승률 //############################## float Ea = 1/(1.f+pow(10,(Rb-Ra)/400.f)); //############################## // 평점 변화량 //############################## float ChangeRa = K*(S-Ea); float ChangeHiddenRa = HiddenK*(HiddenS-Ea); //############################## // flaot 반올림 처리 //############################## ChangeRa = static_cast(static_cast(ChangeRa + (ChangeRa > 0.f ? .5f : -.5f) )) / 1.f; ChangeHiddenRa = static_cast(static_cast(ChangeHiddenRa + (ChangeHiddenRa > 0.f ? .5f : -.5f) )) / 1.f; //############################## // Query 날리기~ //############################## BYTE cThreadID; CDNDBConnection* pDBCon = g_pDBConnectionManager->GetDBConnection( cThreadID ); if( pDBCon == NULL ) return false; int iGradePoint = m_DWCStat[i].GetGradePoint()+static_cast(ChangeRa); int iHiddenGradePoint = m_DWCStat[i].GetHiddenGradePoint()+static_cast(ChangeHiddenRa); if( iGradePoint < Stats::MinGradePoint ) iGradePoint = Stats::MinGradePoint; if( iHiddenGradePoint < Stats::MinGradePoint ) iHiddenGradePoint = Stats::MinGradePoint; #if defined( _WORK ) std::cout << "[DWC] TeamID:" << m_DWCStat[i].GetTeamID() << " 결과:" << Result << std::endl; std::cout << "[DWC] 평점변화 " << m_DWCStat[i].GetGradePoint() << "->" << iGradePoint << std::endl; std::cout << "[DWC] 가평점변화 " << m_DWCStat[i].GetHiddenGradePoint() << "->" << iHiddenGradePoint << std::endl; #endif // #if defined( _WORK ) g_Log.Log( LogType::_LADDER, L"[TeamID:(%d)] DWC result gradepoint:%d\r\n", m_DWCStat[i].GetTeamID(), iGradePoint ); m_Result[i] = SResult(static_cast(ChangeRa),iGradePoint ); pDBCon->QueryAddPvPDWCResult(cThreadID, m_pGameRoom->GetWorldSetID(), m_pGameRoom->GetRoomID(), 0, m_DWCStat[i].GetTeamID(), m_DWCStat[i].GetOppositeTeamID(), m_MatchType, Result, iGradePoint, iHiddenGradePoint ); } return true; } #endif