初步修复
This commit is contained in:
parent
8fc4357cc6
commit
e4714f3f0e
46705 changed files with 12004901 additions and 0 deletions
863
Server/DNGameServer/LadderStats.cpp
Normal file
863
Server/DNGameServer/LadderStats.cpp
Normal file
|
|
@ -0,0 +1,863 @@
|
|||
|
||||
#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<LadderKillResult>& vData )
|
||||
{
|
||||
if( m_mKillDeathCount.empty() )
|
||||
return;
|
||||
|
||||
vData.reserve( m_mKillDeathCount.size() );
|
||||
|
||||
for( std::map<int,SKillDeathCount>::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 ; i<pPacket->Data.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<int,SKillDeathCount>::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<int,SKillDeathCount>::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<float,float,float>(1.f,0.4f,0.5f);
|
||||
S_Repository[1] = boost::tuple<float,float,float>(1.f,0.f,0.5f);
|
||||
S_Repository[2] = boost::tuple<float,float,float>(1.f,0.f,0.5f);
|
||||
S_Repository[3] = boost::tuple<float,float,float>(1.f,0.f,0.4f);
|
||||
S_Repository[4] = boost::tuple<float,float,float>(1.f,0.f,0.3f);
|
||||
S_Repository[5] = boost::tuple<float,float,float>(1.f,0.f,-0.5f);
|
||||
|
||||
HiddenS_Repository[0] = boost::tuple<float,float,float>(1.f,0.f,0.5f);
|
||||
HiddenS_Repository[1] = boost::tuple<float,float,float>(1.f,0.f,0.5f);
|
||||
HiddenS_Repository[2] = boost::tuple<float,float,float>(1.f,0.f,0.5f);
|
||||
HiddenS_Repository[3] = boost::tuple<float,float,float>(1.f,0.f,0.5f);
|
||||
HiddenS_Repository[4] = boost::tuple<float,float,float>(1.f,-0.2f,0.5f);
|
||||
HiddenS_Repository[5] = boost::tuple<float,float,float>(1.f,-0.3f,0.5f);
|
||||
|
||||
K_Repository[0] = boost::tuple<float,float,float,float>(60.f,60.f,60.f,60.f);
|
||||
K_Repository[1] = boost::tuple<float,float,float,float>(50.f,50.f,50.f,50.f);
|
||||
K_Repository[2] = boost::tuple<float,float,float,float>(40.f,40.f,40.f,40.f);
|
||||
K_Repository[3] = boost::tuple<float,float,float,float>(30.f,30.f,30.f,30.f);
|
||||
K_Repository[4] = boost::tuple<float,float,float,float>(20.f,20.f,20.f,20.f);
|
||||
K_Repository[5] = boost::tuple<float,float,float,float>(10.f,10.f,10.f,10.f);
|
||||
|
||||
HiddenK_Repository[0] = boost::tuple<float,float,float,float>(120.f,120.f,120.f,120.f);
|
||||
HiddenK_Repository[1] = boost::tuple<float,float,float,float>(100.f,100.f,100.f,100.f);
|
||||
HiddenK_Repository[2] = boost::tuple<float,float,float,float>(80.f,80.f,80.f,80.f);
|
||||
HiddenK_Repository[3] = boost::tuple<float,float,float,float>(60.f,60.f,60.f,60.f);
|
||||
HiddenK_Repository[4] = boost::tuple<float,float,float,float>(40.f,40.f,40.f,40.f);
|
||||
HiddenK_Repository[5] = boost::tuple<float,float,float,float>(20.f,20.f,20.f,20.f);
|
||||
}
|
||||
|
||||
CStatsRepository::~CStatsRepository()
|
||||
{
|
||||
for( std::map<INT64,CStats*>::iterator itor=m_mRepository.begin() ; itor!=m_mRepository.end() ; ++itor )
|
||||
SAFE_DELETE( (*itor).second );
|
||||
}
|
||||
|
||||
bool CStatsRepository::bInitialize()
|
||||
{
|
||||
CDNPvPGameRoom* pPvPGameRoom = static_cast<CDNPvPGameRoom*>(m_pGameRoom);
|
||||
m_MatchType = pPvPGameRoom->GetPvPLadderMatchType();
|
||||
|
||||
#if defined(PRE_ADD_DWC)
|
||||
int iNeedTeamPlayer = LadderSystem::GetNeedTeamCount(m_MatchType);
|
||||
#else
|
||||
int iNeedTeamPlayer = static_cast<int>(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 ; i<m_pGameRoom->GetUserCount() ; ++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<CDNPvPGameRoom*>(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<INT64,CStats*>::iterator itor = m_mRepository.find( pSession->GetCharacterDBID() );
|
||||
if( itor == m_mRepository.end() )
|
||||
return false;
|
||||
|
||||
CStats* pStats = (*itor).second;
|
||||
|
||||
//##############################
|
||||
// 평균평점
|
||||
//##############################
|
||||
|
||||
float Ra = static_cast<float>((pSession->GetTeam() == PvPCommon::Team::A) ? m_iTeamGradePointAvg[PvPCommon::TeamIndex::A] : m_iTeamGradePointAvg[PvPCommon::TeamIndex::B]);
|
||||
float Rb = static_cast<float>((pSession->GetTeam() == PvPCommon::Team::A) ? m_iTeamGradePointAvg[PvPCommon::TeamIndex::B] : m_iTeamGradePointAvg[PvPCommon::TeamIndex::A]);
|
||||
|
||||
//##############################
|
||||
// 래더 평점 보정
|
||||
//##############################
|
||||
|
||||
int iAvgGradePoint = static_cast<int>(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<float>(static_cast<int>(ChangeRa + (ChangeRa > 0.f ? .5f : -.5f) )) / 1.f;
|
||||
ChangeHiddenRa = static_cast<float>(static_cast<int>(ChangeHiddenRa + (ChangeHiddenRa > 0.f ? .5f : -.5f) )) / 1.f;
|
||||
|
||||
//##############################
|
||||
// Query 날리기~
|
||||
//##############################
|
||||
|
||||
CDNDBConnection* pDBCon = pSession->GetDBConnection();
|
||||
if( pDBCon == NULL )
|
||||
return false;
|
||||
|
||||
int iGradePoint = pStats->GetGradePoint()+static_cast<int>(ChangeRa);
|
||||
int iHiddenGradePoint = pStats->GetHiddenGradePoint()+static_cast<int>(ChangeHiddenRa);
|
||||
BYTE cVSJobCode = pStats->GetVSJobCode();
|
||||
std::vector<LadderKillResult> 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<int>(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<CDnMonsterActor*>(hHitter.GetPointer())->GetSummonerPlayerActor();
|
||||
if( hMaster && hMaster->IsPlayerActor() )
|
||||
hHitter = hMaster;
|
||||
}
|
||||
// Valid체크
|
||||
if( !(hActor && hHitter && hActor->IsPlayerActor() && hHitter->IsPlayerActor()) )
|
||||
return;
|
||||
|
||||
CDnPlayerActor* pPlayer = reinterpret_cast<CDnPlayerActor*>(hActor.GetPointer());
|
||||
std::map<INT64,CStats*>::iterator itor = m_mRepository.find( pPlayer->GetCharacterDBID() );
|
||||
if( itor != m_mRepository.end() )
|
||||
(*itor).second->OnDie( hActor, hHitter );
|
||||
|
||||
CDnPlayerActor* pHitter = reinterpret_cast<CDnPlayerActor*>(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<INT64,CStats*>::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<int,std::vector<int>>::iterator Sumitor = m_mGradePointSum.find( iTeam );
|
||||
if( Sumitor == m_mGradePointSum.end() )
|
||||
{
|
||||
std::vector<int> 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<int>(iSum/(*Sumitor).second.size());
|
||||
}
|
||||
|
||||
void CStatsRepository::OnSetPlayState()
|
||||
{
|
||||
// Stats 초기화 검증
|
||||
for( std::map<INT64,CStats*>::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<INT64,CStats*>::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<INT64,SResult>::iterator itor = m_mResult.find( biCharacterDBID );
|
||||
if( itor != m_mResult.end() )
|
||||
return (*itor).second.iAddGradePoint;
|
||||
return 0;
|
||||
}
|
||||
int CStatsRepository::GetResultGradePoint( INT64 biCharacterDBID )
|
||||
{
|
||||
std::map<INT64,SResult>::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<float,float,float>(1.f,0.4f,0.5f);
|
||||
S_Repository[1] = boost::tuple<float,float,float>(1.f,0.f,0.5f);
|
||||
S_Repository[2] = boost::tuple<float,float,float>(1.f,0.f,0.5f);
|
||||
S_Repository[3] = boost::tuple<float,float,float>(1.f,0.f,0.4f);
|
||||
S_Repository[4] = boost::tuple<float,float,float>(1.f,0.f,0.3f);
|
||||
S_Repository[5] = boost::tuple<float,float,float>(1.f,0.f,-0.5f);
|
||||
|
||||
HiddenS_Repository[0] = boost::tuple<float,float,float>(1.f,0.f,0.5f);
|
||||
HiddenS_Repository[1] = boost::tuple<float,float,float>(1.f,0.f,0.5f);
|
||||
HiddenS_Repository[2] = boost::tuple<float,float,float>(1.f,0.f,0.5f);
|
||||
HiddenS_Repository[3] = boost::tuple<float,float,float>(1.f,0.f,0.5f);
|
||||
HiddenS_Repository[4] = boost::tuple<float,float,float>(1.f,-0.2f,0.5f);
|
||||
HiddenS_Repository[5] = boost::tuple<float,float,float>(1.f,-0.3f,0.5f);
|
||||
|
||||
K_Repository[0] = boost::tuple<float,float,float,float>(60.f,60.f,60.f,60.f);
|
||||
K_Repository[1] = boost::tuple<float,float,float,float>(50.f,50.f,50.f,50.f);
|
||||
K_Repository[2] = boost::tuple<float,float,float,float>(40.f,40.f,40.f,40.f);
|
||||
K_Repository[3] = boost::tuple<float,float,float,float>(30.f,30.f,30.f,30.f);
|
||||
K_Repository[4] = boost::tuple<float,float,float,float>(20.f,20.f,20.f,20.f);
|
||||
K_Repository[5] = boost::tuple<float,float,float,float>(10.f,10.f,10.f,10.f);
|
||||
|
||||
HiddenK_Repository[0] = boost::tuple<float,float,float,float>(120.f,120.f,120.f,120.f);
|
||||
HiddenK_Repository[1] = boost::tuple<float,float,float,float>(100.f,100.f,100.f,100.f);
|
||||
HiddenK_Repository[2] = boost::tuple<float,float,float,float>(80.f,80.f,80.f,80.f);
|
||||
HiddenK_Repository[3] = boost::tuple<float,float,float,float>(60.f,60.f,60.f,60.f);
|
||||
HiddenK_Repository[4] = boost::tuple<float,float,float,float>(40.f,40.f,40.f,40.f);
|
||||
HiddenK_Repository[5] = boost::tuple<float,float,float,float>(20.f,20.f,20.f,20.f);
|
||||
}
|
||||
|
||||
bool CDWCStatsRepository::bInitialize()
|
||||
{
|
||||
CDNPvPGameRoom* pPvPGameRoom = static_cast<CDNPvPGameRoom*>(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 ; i<m_pGameRoom->GetUserCount() ; ++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<CDNPvPGameRoom*>(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<float>(static_cast<int>(ChangeRa + (ChangeRa > 0.f ? .5f : -.5f) )) / 1.f;
|
||||
ChangeHiddenRa = static_cast<float>(static_cast<int>(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<int>(ChangeRa);
|
||||
int iHiddenGradePoint = m_DWCStat[i].GetHiddenGradePoint()+static_cast<int>(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<int>(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
|
||||
Loading…
Add table
Add a link
Reference in a new issue