#include "StdAfx.h" #include "Util.h" #include "DNGuildWarManager.h" #include "DNDivisionManager.h" #include "DNVillageConnection.h" #include "MtRandom.h" #include "TimeSet.h" #include "DNExtManager.h" #include "DNPvP.h" CDNGuildWarManager * g_pGuildWarManager = NULL; extern TMasterConfig g_Config; CDNGuildWarManager::CDNGuildWarManager() { memset (m_pWarEventStep, 0x00, sizeof(m_pWarEventStep)); m_pWarEventStep[GUILDWAR_STEP_PREPARATION] = new CDNGuildWarPreparation; m_pWarEventStep[GUILDWAR_STEP_TRIAL] = new CDNGuildWarTrial; m_pWarEventStep[GUILDWAR_STEP_REWARD] = new CDNGuildWarReward; Clear(); } void CDNGuildWarManager::Clear() { // 스텝 초기화 ResetStep(); m_bSendGuildWarInfo = false; m_eSettingStep = REQ_NONE; m_wWinersWeightRate = 0; m_wScheduleID = GUILDWARSCHEDULE_DEF; m_TickCheckGuildWar = 0; memset(&m_GuildWarFinalInfo, 0, sizeof(m_GuildWarFinalInfo)); memset(&m_sGuildWarSchedule, 0, sizeof(m_sGuildWarSchedule)); memset(&m_sGuildWarFinalSchedule, 0, sizeof(m_sGuildWarFinalSchedule)); memset(&m_bTournamentGroup, 0, sizeof(m_bTournamentGroup)); memset(&m_GuildWarOpeningPoints, 0, sizeof(m_GuildWarOpeningPoints)); m_nFinalTeamCount = 0; m_bFinalTeamSetting = false; m_cSecretTeam = 0; m_nSecretRandomSeed = 0; m_bCheatFlag = false; m_nBlueTeamPoint = 0; m_nRedTeamPoint = 0; m_dwPreWinSkillCoolTime = 0; m_bFinalWinGuild = false; m_bResetSchedule = false; m_bFinalStart = false; memset(&m_sGuildWarPointTrialRanking, 0, sizeof(m_sGuildWarPointTrialRanking)); m_wPreWinScheduleID = 0; m_bFrinalProgress = false; m_tRewardExpireDate = 0; m_PreWinGuildUID.Reset(); #if defined(PRE_FIX_75807) m_bFarmForceHarbest = false; #endif //#if defined(PRE_FIX_75807) } CDNGuildWarManager::~CDNGuildWarManager() { CDNGuildWar** pWarEventStep = m_pWarEventStep; for (int j=GUILDWAR_STEP_NONE; jbForce) { m_bWarEvent = false; m_bCheatFlag = true; } if (!pData->bForce && tCurrentTime > pData->EventInfo[GUILDWAR_STEP_REWARD].tEndTime) { // 이미 지난 이벤트이거나 셋팅이 안된거임 //g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] LoadScheduleInfo Failed !!! TimeOut or Schedule empty\n"); #if defined(PRE_FIX_75807) // 여기서 혹시 지난 길드전 우승자의 값이 현재를 안넘었는지 본다. if( pData->tRewardExpireDate > 0 && !GetPreWinGuild().IsSet() ) { __time64_t tCurrentTime; time(&tCurrentTime); if( tCurrentTime < pData->tRewardExpireDate ) { m_tRewardExpireDate = pData->tRewardExpireDate; // 아직 보상 기간이 남아 있으면 우승길드 뽑아오기 m_eSettingStep = REQ_PRE_WIN; SendGuildWarInfoReq(); // 본선 스케쥴 정보 가져오기 요청 g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] Send GetPrewinGuild Schedule Empty!!!\n"); return true; } } else if( pData->tRewardExpireDate == 0 && !m_bFarmForceHarbest ) { // 여기서 게임서버 우승농장 초기화 진행 MAGuildWarPreWinGuild GuildWarPreWinGuild; GuildWarPreWinGuild.GuildUID.Reset(); GuildWarPreWinGuild.bPreWin = false; m_bFarmForceHarbest = true; g_pDivisionManager->SendSetGuildWarPreWinGuildGameServer(&GuildWarPreWinGuild); } m_bSendGuildWarInfo = false; #endif //#if defined(PRE_FIX_75807) return true; } if( pData->tRewardExpireDate > 0) m_tRewardExpireDate = pData->tRewardExpireDate; ////////////////////////////////////////////////////////////////////////////////////////////////// bool bResult = false; m_wWinersWeightRate = pData->wWinersWeightRate; memcpy(m_sGuildWarSchedule, pData->EventInfo, sizeof(m_sGuildWarSchedule)); // 이벤트 진행중이면 if (m_bWarEvent) { // 동일차수에 한해 기간 업데이트 가능 if (m_wScheduleID != pData->wScheduleID) { g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] LoadScheduleInfo Failed !!! Wrong ScheduleID Old(%d)<->New(%d) \n", m_wScheduleID, pData->wScheduleID); return false; } else { bResult = UpdateScheduleGroup(pData->wScheduleID, pData->EventInfo); } } else // 이벤트 진행중이 아니라면 신규 등록 { bResult = RegisterScheduleGroup(pData->wScheduleID, pData->EventInfo); } if (bResult) { // 등록을 하든 업데이트를 하든 여기서 정보를 새로 업데이트한다. m_wScheduleID = pData->wScheduleID; m_eSettingStep = REQ_FINAL_SCHEDULE; SendGuildWarInfoReq(); // 본선 스케쥴 정보 가져오기 요청 SetFinalProgress(pData->bFinalProgress); return true; } return false; } bool CDNGuildWarManager::LoadFinalScheduleInfo(MASetGuildWarFinalSchedule* pData) { __time64_t tCurrentTime; time(&tCurrentTime); ////////////////////////////////////////////////////////////////////////////////////////////////// __time64_t tCheckPeriod = 0; // 이미 본선이 진행중이며 스케쥴이 셋팅되어 있는지 체크.. // 각 시간체크 for( int i=GUILDWAR_FINALPART_MAX-1; i>GUILDWAR_FINALPART_NONE; --i) { if( tCheckPeriod > pData->GuildWarFinalSchedule[i].tBeginTime || pData->GuildWarFinalSchedule[i].tBeginTime > pData->GuildWarFinalSchedule[i].tEndTime ) { g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] LoadFinalScheduleInfo Failed !!! Wrong Time Schedule Begin(%d) End(%d) Check(%d)\n" , pData->GuildWarFinalSchedule[i].tBeginTime, pData->GuildWarFinalSchedule[i].tEndTime, tCheckPeriod); return false; } tCheckPeriod = pData->GuildWarFinalSchedule[i].tBeginTime; } CDNGuildWarReward* pGuildWarReward = (CDNGuildWarReward*)m_pWarEventStep[GUILDWAR_STEP_REWARD]; if( !pGuildWarReward ) { g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] LoadFinalScheduleInfo Failed !!! CDNGuildWarReward Null\n"); return false; } memcpy(m_sGuildWarFinalSchedule, pData->GuildWarFinalSchedule, sizeof(m_sGuildWarFinalSchedule)); pGuildWarReward->SetFinalScheduleInfo(pData); g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] LoadFinalScheduleInfo ScheduleID:%d\n", m_wScheduleID); // 본선 스케쥴 돌아라.. StartStep(); // 전체 스케쥴 보내주기 MASetGuildWarEventTime SetGuildWarEventTime; memset(&SetGuildWarEventTime, 0, sizeof(SetGuildWarEventTime)); memcpy(SetGuildWarEventTime.sGuildWarTime, m_sGuildWarSchedule, sizeof(SetGuildWarEventTime.sGuildWarTime)); memcpy(SetGuildWarEventTime.sFinalPartTime, m_sGuildWarFinalSchedule, sizeof(SetGuildWarEventTime.sFinalPartTime)); SetGuildWarEventTime.bFinalProgress = GetFinalProgress(); g_pDivisionManager->SendSetGuildWarSchedule(&SetGuildWarEventTime); if( (m_cStepIndex != GUILDWAR_STEP_REWARD || !GetFinalStart() ) && m_wScheduleID != 1) // 맨 처음 차수가 아니면. { // 본선이 아니거나 아직 시작을 안했으면 지난 차수 우승팀 가져오기.. m_eSettingStep = REQ_PRE_WIN; SendGuildWarInfoReq(); return true; } else if( m_cStepIndex == GUILDWAR_STEP_TRIAL || m_cStepIndex == GUILDWAR_STEP_REWARD ) { // 예선이거나 본선이면 청팀, 홍팀 포인트 가져오기 m_eSettingStep = REQ_TEAM_POINT; SendGuildWarInfoReq(); return true; } m_bSendGuildWarInfo = false; m_eSettingStep = REQ_ALL_COMPLETE; g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] LoadFinalScheduleInfo REQ_ALL_COMPLETE !!!\n"); return true; } void CDNGuildWarManager::SendGuildWarInfoReq() { // 콜로세움 빌리지한테 요청 CDNVillageConnection* pVillageConnection = g_pDivisionManager->GetVillageConnectionByVillageID( g_pDivisionManager->GetPvPLobbyVillageID() ); if( pVillageConnection == NULL || pVillageConnection->GetActive() == false ) return; if( pVillageConnection ) { switch(m_eSettingStep) { case REQ_NONE : case REQ_SCHEDULE : { pVillageConnection->SendGetGuildWarSchedule(); // 스케쥴 정보 가져오기 요청 m_eSettingStep = REQ_SCHEDULE; } break; case REQ_FINAL_SCHEDULE : { pVillageConnection->SendGetGuildWarFinalSchedule(m_wScheduleID); // 본선 스케쥴 정보 가져오기 요청 } break; case REQ_PRE_WIN : { pVillageConnection->SendGetGuildWarPreWinGuild(); // 우승팀 가져오기 } break; case REQ_TEAM_POINT : { pVillageConnection->SendGetGuildWarPoint(); // 청팀, 홍팀 포인트 가져오기 } break; } m_bSendGuildWarInfo = true; m_TickCheckGuildWar = timeGetTime(); } } void CDNGuildWarManager::SetGuildWarPoint(int nBlueTeam, int nRedTeam) { InterlockedExchange(&m_nBlueTeamPoint, nBlueTeam); InterlockedExchange(&m_nRedTeamPoint, nRedTeam); CalcTeamSecret(); m_bSendGuildWarInfo = false; m_eSettingStep = REQ_ALL_COMPLETE; g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] SetGuildWarPoint REQ_ALL_COMPLETE !!!\n"); } void CDNGuildWarManager::AddGuildWarPoint(char cTeamType, int nAddPoint) { if( cTeamType == GUILDWAR_TEAM_BLUE) InterlockedExchangeAdd(&m_nBlueTeamPoint, nAddPoint); else if( cTeamType == GUILDWAR_TEAM_RED ) InterlockedExchangeAdd(&m_nRedTeamPoint, nAddPoint); CalcTeamSecret(); } void CDNGuildWarManager::SetGuildWarPreWinGuild(TGuildUID GuildUID) { m_PreWinGuildUID = GuildUID; if( m_cStepIndex == GUILDWAR_STEP_TRIAL || m_cStepIndex == GUILDWAR_STEP_REWARD ) { // 예선이거나 본선이면 전이면 청팀, 홍팀 포인트 가져오기 m_eSettingStep = REQ_TEAM_POINT; SendGuildWarInfoReq(); return; } m_bSendGuildWarInfo = false; m_eSettingStep = REQ_ALL_COMPLETE; g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] SetGuildWarPreWinGuild REQ_ALL_COMPLETE !!!\n"); } UINT CDNGuildWarManager::GetGuildDBIDWithFinal(const UINT uiPvPIndex, const WCHAR * pGuildName) { if (pGuildName == NULL) return 0; for( int i=0; i 0 && m_bTournamentGroup[i].BTeam.nTeamNum > 0) { if (wcscmp(m_GuildWarFinalInfo[m_bTournamentGroup[i].ATeam.nTeamNum-1].wszGuildName, pGuildName) == 0 && m_bTournamentGroup[i].unPvPIndex == uiPvPIndex) return m_GuildWarFinalInfo[m_bTournamentGroup[i].ATeam.nTeamNum-1].GuildUID.nDBID; if (wcscmp(m_GuildWarFinalInfo[m_bTournamentGroup[i].BTeam.nTeamNum-1].wszGuildName, pGuildName) == 0 && m_bTournamentGroup[i].unPvPIndex == uiPvPIndex) return m_GuildWarFinalInfo[m_bTournamentGroup[i].BTeam.nTeamNum-1].GuildUID.nDBID; } } return 0; } bool CDNGuildWarManager::IsTrialStats() { if( m_cStepIndex == GUILDWAR_STEP_REWARD) { CDNGuildWarReward* pReward = (CDNGuildWarReward*)m_pWarEventStep[m_cStepIndex]; return pReward->m_bTrialStatsRequest; } return false; } void CDNGuildWarManager::SetTrialStats() { CDNGuildWarReward* pReward = (CDNGuildWarReward*)m_pWarEventStep[GUILDWAR_STEP_REWARD]; pReward->m_bTrialStatsRequest = true; g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] SetTrialStats!!!\n"); } void CDNGuildWarManager::CalcGuildWarTournament(VIMASetGuildWarFinalTeam* pData) { // 자리는 고정입니다요...자세한건 [DN]길드전_본선대진표배치_1_.pptx 참조 int MatchSequence[]={0,8,14,6,4,12,10,2,3,11,13,5,7,15,9,1}; sTournamentGroup Groups[GUILDWAR_TOURNAMENT_GROUP_MAX]; memset(Groups, 0, sizeof(Groups)); for( int i=0; inCount; ++i ) { int nGroupIndex = MatchSequence[i]/2; if( MatchSequence[i]%2 ) Groups[nGroupIndex].BTeam.nTeamNum = i+1; else Groups[nGroupIndex].ATeam.nTeamNum = i+1; } for( int i=0; inTotalPoint[Groups[i].ATeam.nTeamNum-1]; m_GuildWarFinalInfo[i*2].GuildUID = pData->GuidUID[Groups[i].ATeam.nTeamNum-1]; m_GuildWarOpeningPoints[i*2] = pData->nTotalPoint[Groups[i].ATeam.nTeamNum-1]; memcpy(m_GuildWarFinalInfo[i*2].wszGuildName, pData->wszGuildName[Groups[i].ATeam.nTeamNum-1], sizeof(m_GuildWarFinalInfo[Groups[i].ATeam.nTeamNum-1].wszGuildName)); } if( Groups[i].BTeam.nTeamNum ) { //m_bTournamentGroup[i].BTeam.nTeamNum = (i*2)+2; //m_bTournamentGroup[i].BTeam.nOpeningPoint = pData->nTotalPoint[Groups[i].BTeam.nTeamNum-1]; m_GuildWarFinalInfo[(i*2)+1].GuildUID = pData->GuidUID[Groups[i].BTeam.nTeamNum-1]; m_GuildWarOpeningPoints[(i*2)+1] = pData->nTotalPoint[Groups[i].BTeam.nTeamNum-1]; memcpy(m_GuildWarFinalInfo[(i*2)+1].wszGuildName, pData->wszGuildName[Groups[i].BTeam.nTeamNum-1], sizeof(m_GuildWarFinalInfo[Groups[i].BTeam.nTeamNum-1].wszGuildName)); } } m_nFinalTeamCount = pData->nCount; SetGuildWarTournamentGroup(); m_bFinalTeamSetting = true; // 여기서 길드 정보 업데이트 MAChangeGuildInfo ChangeGuildInfo; memset(&ChangeGuildInfo, 0, sizeof(ChangeGuildInfo)); // 본선 진출 횟수 1회 추가~~ ChangeGuildInfo.btGuildUpdate = GUILDUPDATE_TYPE_GUILDWAR; ChangeGuildInfo.Int1 = 1; for(int i=0; iSendChangeGuildInfo(&ChangeGuildInfo); } g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] CalcGuildWarTournament Success TeamCount:%d !!!\n", m_nFinalTeamCount); } void CDNGuildWarManager::DoUpdate(DWORD CurTick) { // Reset 확인 if ( m_bResetSchedule ) { if( g_pGuildWarManager->GetFinalProgress() && g_pGuildWarManager->GetFinalStart() ) { // 본선 진행중이면..이때는 강제 중단으로 여기고 모든 길드전 강제 종료.. g_pDivisionManager->SendGuildWarAllStop(); g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] Emergence GuilWar Stop Process!!!\n"); } g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] Reset Schedule GuilWar Progress:%d, Start:%d\n",g_pGuildWarManager->GetFinalProgress(),g_pGuildWarManager->GetFinalStart() ); Clear(); // 전부 초기화하고 SendGuildWarInfoReq(); // 다시 첨부터 로딩 ㄱㄱ return; } //우승 길드가 셋팅되어 있으면 보상이 지급됐는지 가져오자..대략 1분 마다 한번씩.. DWORD dwTick = timeGetTime(); static DWORD SendTick = 60*1000; if( GetPreWinGuild().IsSet() && !GetFinalWinGuildReward() && SendTick+(60*1000) < dwTick) { //CDNVillageConnection *pVillageConnection = g_pDivisionManager->GetFirstEnableVillageServer(); CDNVillageConnection* pVillageConnection = g_pDivisionManager->GetVillageConnectionByVillageID( g_pDivisionManager->GetPvPLobbyVillageID() ); if( pVillageConnection ) { pVillageConnection->SendGetGuildWarPreWindGuildReward(GetPreWinScheduleID(), GetPreWinGuild().nDBID); } SendTick = dwTick; } if ( m_eSettingStep != REQ_ALL_COMPLETE && (!m_bSendGuildWarInfo || (m_bSendGuildWarInfo && CurTick > m_TickCheckGuildWar+REQ_GUILDWARINFO_TICK_MAX)) ) // 활성화 되어 있지 않고 빌리지에게 정보 요청하지 않은 상태거나 타임오바이면 { SendGuildWarInfoReq(); return; } // 우승길드 해제..제스쳐, 농장 if( m_PreWinGuildUID.IsSet() && m_bFinalWinGuild && m_tRewardExpireDate > 0 ) { __time64_t tCurrentTime; time(&tCurrentTime); if( tCurrentTime > m_tRewardExpireDate ) { // 우승길드 해제 MAGuildWarPreWinGuild pPacket; memset(&pPacket, 0, sizeof(MAGuildWarPreWinGuild)); pPacket.GuildUID = GetPreWinGuild(); pPacket.bPreWin = false; g_pDivisionManager->SendSetGuildWarPreWinGuild(&pPacket); // 전체 게임 및 빌리지에 통보. m_PreWinGuildUID.Reset(); m_tRewardExpireDate = 0; g_pGuildWarManager->SetFinalWinGuild(false); g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] PreWinGuild ExpireDate!!!\n"); } } if (m_bWarEvent && CheckStep(m_cStepIndex) && m_eSettingStep == REQ_ALL_COMPLETE) { CDNGuildWar** pWarEventStep = m_pWarEventStep; CDNGuildWar* pCurrentEvent = pWarEventStep[m_cStepIndex]; if (pCurrentEvent) { // 해당 이벤트객체를 호출하여 처리! pCurrentEvent->Process(); // 모든 이벤트가 끝났을때 다음스텝으로 진행 if (pCurrentEvent->IsFinishPeriod()) NextStep(); } } // 본선 진행일때만.. if( GetFinalProgress() ) { CDNVillageConnection* pVillageCon = g_pDivisionManager->GetVillageConnectionByVillageID( g_pDivisionManager->GetPvPLobbyVillageID() ); if( pVillageCon == NULL || pVillageCon->GetActive() == false ) return; //이거 어케해야함? // 본선이고 방이 만들어진 애들은 시간이 되면 스타트 날려주자.. CDNPvP* pPvP = NULL; VIMAPVP_START Packet; memset(&Packet, 0, sizeof(Packet)); Packet.sCSPVP_START.unCheck = PvPCommon::Check::AllCheck; for( int i=0; i 0) { if( CurTick > m_bTournamentGroup[i].dwStartTick+GUILDWAR_FINAL_ROOMSTRAT_TICK_MAX ) { if( g_pDivisionManager->GetGameConnectionCount() <= 0 ) { g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] StartPvP Failed !!! Not GameConnection \n"); return; } pPvP = g_pDivisionManager->GetPvPRoomByIdx(m_bTournamentGroup[i].unPvPIndex); if( pPvP ) { short wRet = pPvP->StartPvP(pVillageCon, &Packet); if( wRet != ERROR_NONE ) g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] StartPvP Failed !!! %d \n", wRet); else { g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] StartPvP Success PvPIndex:%u !!! \n", m_bTournamentGroup[i].unPvPIndex); m_bTournamentGroup[i].dwStartTick = 0; } } } } } } } CDNGuildWar* CDNGuildWarManager::GetWarEvent(char cStep) { if (!CheckStep(cStep)) return NULL; return m_pWarEventStep[cStep]; } int CDNGuildWarManager::SetGuildTournamentInfo(SGuildTournamentInfo* pGuildTournamentInfo) { // 카운트 셀려고 루프돔.ㅠㅠ int nCount = 0; for( int i=0; i 0) { memcpy(m_GuildWarFinalInfo, pGuildTournamentInfo, sizeof(m_GuildWarFinalInfo)); m_nFinalTeamCount = nCount; SetGuildWarTournamentGroup(); m_bFinalTeamSetting = true; } return nCount; } void CDNGuildWarManager::SetGuildWarPointTrialRanking(const MASetGuildWarPointRunningTotal* pData) { memcpy(m_sGuildWarPointTrialRanking, pData, sizeof(m_sGuildWarPointTrialRanking)); } void CDNGuildWarManager::CalcGuildWarTournamentResult() { for( int i=0; i 0 && m_bTournamentGroup[i].BTeam.nTeamNum > 0) { BYTE ATeamIndex = m_bTournamentGroup[i].ATeam.nTeamNum-1; BYTE BTeamIndex = m_bTournamentGroup[i].BTeam.nTeamNum-1; // 둘다 진 상태로 되어 있으면.. if( ATeamIndex < GUILDWAR_FINALS_TEAM_MAX && BTeamIndex < GUILDWAR_FINALS_TEAM_MAX && !m_GuildWarFinalInfo[ATeamIndex].bWin && !m_GuildWarFinalInfo[BTeamIndex].bWin ) { // 그냥 결판 내버리자.. CalcGuildWarTournamentWin(i); } } } } void CDNGuildWarManager::SetGuildWarTournamentGroup() { memset(m_bTournamentGroup, 0, sizeof(m_bTournamentGroup)); char cCurFinalPart = GetCurFinalPart(); int nCount = 0; int nDefaultWinMax = 0; //부전승 건너띄기 switch(cCurFinalPart) { case GUILDWAR_FINALPART_NONE : case GUILDWAR_FINALPART_16 : nDefaultWinMax = 1; break; case GUILDWAR_FINALPART_8 : nDefaultWinMax = 3; break; case GUILDWAR_FINALPART_4 : nDefaultWinMax = 7; break; case GUILDWAR_FINALPART_FINAL : nDefaultWinMax = 15; break; } for( int i=0; i= GUILDWAR_FINALS_TEAM_MAX ) break; if( !m_GuildWarFinalInfo[i+j].GuildUID.IsSet() ) continue; if( m_GuildWarFinalInfo[i+j].cMatchTypeCode != GUILDWAR_FINALPART_NONE && m_GuildWarFinalInfo[i+j].bWin == false ) continue; // 결승전을 제외하고 왼쪽 팀이 오른쪽 팀과 붙을 일은 없다. if( cCurFinalPart != GUILDWAR_FINALPART_FINAL && i < GUILDWAR_TOURNAMENT_GROUP_MAX && i+j >= GUILDWAR_TOURNAMENT_GROUP_MAX ) break; bDefaltWin = false; break; } if( bDefaltWin ) ++nCount; m_GuildWarFinalInfo[i].cMatchTypeCode = cCurFinalPart; m_GuildWarFinalInfo[i].bWin = false; } else if( m_bTournamentGroup[nCount].BTeam.nTeamNum == 0) { m_bTournamentGroup[nCount].BTeam.nTeamNum = i+1; m_bTournamentGroup[nCount].BTeam.nOpeningPoint = m_GuildWarOpeningPoints[i]; ++nCount; m_GuildWarFinalInfo[i].cMatchTypeCode = cCurFinalPart; m_GuildWarFinalInfo[i].bWin = false; } } g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] SetGuildWarTournamentGroup FinalPart:%d !!!\n", cCurFinalPart); } // 길드전 방 생성 void CDNGuildWarManager::GuildWarCreateRoom() { CDNVillageConnection* pVillageCon = g_pDivisionManager->GetVillageConnectionByVillageID( g_pDivisionManager->GetPvPLobbyVillageID() ); if( pVillageCon == NULL || pVillageCon->GetActive() == false ) return; //이거 어케해야함? CTimeSet CurTime; CurTime.GetMonth(); // MapID 얻어오기 UINT uiMapIndex = g_pExtManager->GetGuildWarMapInfoID((char)CurTime.GetMonth()); if( uiMapIndex == 0 ) { g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] GuildWarCreateRoom Failed !!! GuildWarMapID is Zero\n"); return; } // MapID로 PvPMapTable 얻어오기 const TPvPMapTable* pMapTable = g_pExtManager->GetPvPMapTable(uiMapIndex); if( pMapTable == NULL ) { g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] GuildWarCreateRoom Failed !!! pMapTable is NULL\n"); return; } // PvPMapTable에서 GameMode 정보 가져오기 const TPvPGameModeTable* pPvPGameModeTable = g_pExtManager->GetPvPGameModeTable( pMapTable->vGameModeTableID[0] ); if( pPvPGameModeTable == NULL ) { g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] GuildWarCreateRoom Failed !!! pPvPGameModeTable is NULL\n"); return; } for( int i=0; iSendSetGuildWarFinalResultDB(m_wScheduleID, m_bTournamentGroup[i].ATeam.nTeamNum, m_GuildWarFinalInfo[m_bTournamentGroup[i].ATeam.nTeamNum-1].GuildUID.nDBID, GetCurFinalPart(), true); } else { // 여기서 방만들기.. VIMAPVP_CREATEROOM sCreateRoom; memset(&sCreateRoom, 0, sizeof(sCreateRoom)); sCreateRoom.unVillageChannelID = g_pDivisionManager->GetPvPLobbyChannelID(); sCreateRoom.uiVillageMapIndex = g_pDivisionManager->GetPvPLobbyMapIndex(); sCreateRoom.cGameMode = PvPCommon::GameMode::PvP_GuildWar; sCreateRoom.nGuildDBID[0] = m_GuildWarFinalInfo[m_bTournamentGroup[i].ATeam.nTeamNum-1].GuildUID.nDBID; sCreateRoom.nGuildQualifyingScore[0] = m_GuildWarOpeningPoints[m_bTournamentGroup[i].ATeam.nTeamNum-1]; sCreateRoom.nGuildDBID[1] = m_GuildWarFinalInfo[m_bTournamentGroup[i].BTeam.nTeamNum-1].GuildUID.nDBID; sCreateRoom.nGuildQualifyingScore[1] = m_GuildWarOpeningPoints[m_bTournamentGroup[i].BTeam.nTeamNum-1]; sCreateRoom.sCSPVP_CREATEROOM.uiMapIndex = uiMapIndex; sCreateRoom.sCSPVP_CREATEROOM.uiGameModeTableID = pMapTable->vGameModeTableID[0]; sCreateRoom.sCSPVP_CREATEROOM.uiSelectWinCondition = pPvPGameModeTable->vWinCondition[0]; // 요거 점수인데 에라 모르겠다. sCreateRoom.sCSPVP_CREATEROOM.uiSelectPlayTimeSec = pPvPGameModeTable->vPlayTimeSec[0]; sCreateRoom.sCSPVP_CREATEROOM.cMaxUser = pPvPGameModeTable->uiNumOfPlayersMax; sCreateRoom.sCSPVP_CREATEROOM.cMinUser = 0; sCreateRoom.sCSPVP_CREATEROOM.cRoomPWLen = 0; sCreateRoom.sCSPVP_CREATEROOM.cMinLevel = 1; sCreateRoom.sCSPVP_CREATEROOM.cMaxLevel = 100; sCreateRoom.sCSPVP_CREATEROOM.unRoomOptionBit |= (PvPCommon::RoomOption::BreakInto|PvPCommon::RoomOption::NoRegulation); // 난입,무조정 허용 sCreateRoom.sCSPVP_CREATEROOM.uiEventItemID = 0; #ifdef PRE_ADD_COLOSSEUM_BEGINNER sCreateRoom.sCSPVP_CREATEROOM.cRoomType = PvPCommon::RoomType::regular; #endif //#ifdef PRE_ADD_COLOSSEUM_BEGINNER wsprintf(sCreateRoom.sCSPVP_CREATEROOM.wszBuf, L"%s vs %s", m_GuildWarFinalInfo[m_bTournamentGroup[i].ATeam.nTeamNum-1].wszGuildName, m_GuildWarFinalInfo[m_bTournamentGroup[i].BTeam.nTeamNum-1].wszGuildName); sCreateRoom.sCSPVP_CREATEROOM.cRoomNameLen = (BYTE)wcslen(sCreateRoom.sCSPVP_CREATEROOM.wszBuf); short nRetCode = g_pDivisionManager->CreatePvPRoom( pVillageCon, &sCreateRoom, &m_bTournamentGroup[i].unPvPIndex ); if( nRetCode != ERROR_NONE ) g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] GuildWarCreateRoom Failed !!! CreatePvPRoom %s \n", sCreateRoom.sCSPVP_CREATEROOM.wszBuf); else { m_bTournamentGroup[i].dwStartTick = timeGetTime(); g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] GuildWarCreateRoom !!! CreatePvPRoom PvPIndex:%u %s \n", m_bTournamentGroup[i].unPvPIndex, sCreateRoom.sCSPVP_CREATEROOM.wszBuf); } } } } } void CDNGuildWarManager::SetGuildWarTournamentResult(GAMAPvPGuildWarResult* pGuildWarResult) { char cWinGuildIndex =-1, cLoseGuildIndex = -1; for(char i=0; inWinGuildDBID ) { SetGuildTournamentInfoWin(i, true); cWinGuildIndex = i; continue; } if( m_GuildWarFinalInfo[i].GuildUID.nDBID == pGuildWarResult->nLoseGuildDBID ) { SetGuildTournamentInfoWin(i, false); cLoseGuildIndex = i; continue; } } SendSetGuildWarFinalResult(cWinGuildIndex, cLoseGuildIndex); SendSetGuildWarTournamentWin(cWinGuildIndex, m_GuildWarFinalInfo[cWinGuildIndex].cMatchTypeCode); //결승이면 우승길드로 셋팅해 주자~ if( m_GuildWarFinalInfo[cWinGuildIndex].cMatchTypeCode == GUILDWAR_FINALPART_FINAL ) { SetPreWinGuild( m_GuildWarFinalInfo[cWinGuildIndex].GuildUID); SetPreWinScheduleID(m_wScheduleID); } g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] TournamentResult !!! FinalPart:%d, WinGuildDBID:%d, LosGuildDBID:%d \n", GetCurFinalPart(), pGuildWarResult->nWinGuildDBID, pGuildWarResult->nLoseGuildDBID); } void CDNGuildWarManager::SendSetGuildWarFinalResult(char cWinGuildIndex, char cLoseGuildIndex ) { MAVISetGuildWarFinalResult FinalResult; memset(&FinalResult, 0, sizeof(FinalResult)); FinalResult.cMatchTypeCode = GetCurFinalPart(); FinalResult.cWinGuildIndex = cWinGuildIndex; FinalResult.cLoseGuildIndex = cLoseGuildIndex; g_pDivisionManager->SendSetGuildWarFinalResult(&FinalResult); } void CDNGuildWarManager::SetGuildTournamentInfoWin(char cIndex, bool bWin) { if( cIndex < 0 || cIndex >= GUILDWAR_FINALS_TEAM_MAX ) return; m_GuildWarFinalInfo[cIndex].bWin = bWin; // 만약 결승전 승자 이면.. if( m_GuildWarFinalInfo[cIndex].cMatchTypeCode == GUILDWAR_FINALPART_FINAL && bWin ) { // 여기서 길드 정보 업데이트 MAChangeGuildInfo ChangeGuildInfo; memset(&ChangeGuildInfo, 0, sizeof(ChangeGuildInfo)); // 본선 우승 횟수 1회 추가~~ ChangeGuildInfo.btGuildUpdate = GUILDUPDATE_TYPE_GUILDWAR; ChangeGuildInfo.Int2 = 1; ChangeGuildInfo.GuildUID = m_GuildWarFinalInfo[cIndex].GuildUID; g_pDivisionManager->SendChangeGuildInfo(&ChangeGuildInfo); } } void CDNGuildWarManager::SetGuildWarOpenningPoint(VIMASetGuildWarFinalTeam* pData ) { for( int i=0; inCount; ++i) { for( int j=0; jGuidUID[i] == m_GuildWarFinalInfo[j].GuildUID ) { m_GuildWarOpeningPoints[j] = pData->nTotalPoint[i]; break; } } } } void CDNGuildWarManager::SetGuildWarTournamentPoint(GAMAPvPGuildWarScore* pGuildWarPoint) { for( int i=0; inGuildDBID) { m_bTournamentGroup[i].ATeam.nTournamentPoint = pGuildWarPoint->nScore; break; } if( m_bTournamentGroup[i].BTeam.nTeamNum && m_GuildWarFinalInfo[m_bTournamentGroup[i].BTeam.nTeamNum-1].GuildUID.nDBID == pGuildWarPoint->nGuildDBID) { m_bTournamentGroup[i].BTeam.nTournamentPoint = pGuildWarPoint->nScore; break; } } } void CDNGuildWarManager::SendSetGuildWarTournamentWin(char cWinGuildIndex, char cFinalPart) { if( cWinGuildIndex < 0 || cWinGuildIndex >= GUILDWAR_FINALS_TEAM_MAX ) return; MASetGuildWarTournamentWin SetGuildWarTournamentWin; memset(&SetGuildWarTournamentWin, 0, sizeof(SetGuildWarTournamentWin)); SetGuildWarTournamentWin.cMatchTypeCode = cFinalPart; memcpy(SetGuildWarTournamentWin.wszGuildName, m_GuildWarFinalInfo[cWinGuildIndex].wszGuildName, sizeof(SetGuildWarTournamentWin.wszGuildName) ); g_pDivisionManager->SendSetGuildWarTournamentWin(&SetGuildWarTournamentWin); } char CDNGuildWarManager::GetCurFinalPart() { CDNGuildWarReward* pGuildWarReward = (CDNGuildWarReward*)m_pWarEventStep[GUILDWAR_STEP_REWARD]; if( pGuildWarReward ) return pGuildWarReward->GetCurFinalPart(); return 0; } time_t CDNGuildWarManager::GetCurFinalPartBeginTime() { CDNGuildWarReward* pGuildWarReward = (CDNGuildWarReward*)m_pWarEventStep[GUILDWAR_STEP_REWARD]; if( pGuildWarReward ) return pGuildWarReward->GetCurFinalPartBeginTime(); return 0; } void CDNGuildWarManager::SetDBJobSend(bool bSend) { CDNGuildWar* pGuildWar = m_pWarEventStep[m_cStepIndex]; if( pGuildWar ) pGuildWar->SetDBJobSend(bSend); } void CDNGuildWarManager::SetDBJobSeq(int nJobSeq) { CDNGuildWar* pGuildWar = m_pWarEventStep[m_cStepIndex]; if( pGuildWar ) pGuildWar->SetDBJobSeq(nJobSeq); } void CDNGuildWarManager::SetDBJobSuccess(bool bSuccess) { CDNGuildWar* pGuildWar = m_pWarEventStep[m_cStepIndex]; if( pGuildWar ) pGuildWar->SetDBJobSuccess(bSuccess); } bool CDNGuildWarManager::GetDBJobSuccess() { CDNGuildWar* pGuildWar = m_pWarEventStep[m_cStepIndex]; if( pGuildWar ) return pGuildWar->GetDBJobSuccess(); return false; } // 방이 뽀사지거나 게임서버가 튕겼을때 호출바람.. void CDNGuildWarManager::SetDropTournament(UINT unPvPIndex) { for( int i=0; i= GUILDWAR_TOURNAMENT_GROUP_MAX) return; char cWinGuildIndex = -1, cLoseGuildIndex = -1; // 먼저 중간 점수 보고 if( m_bTournamentGroup[cGroupIndex].ATeam.nTournamentPoint != m_bTournamentGroup[cGroupIndex].BTeam.nTournamentPoint ) { cWinGuildIndex = m_bTournamentGroup[cGroupIndex].ATeam.nTournamentPoint > m_bTournamentGroup[cGroupIndex].BTeam.nTournamentPoint ? m_bTournamentGroup[cGroupIndex].ATeam.nTeamNum-1 : m_bTournamentGroup[cGroupIndex].BTeam.nTeamNum-1; cLoseGuildIndex = m_bTournamentGroup[cGroupIndex].ATeam.nTournamentPoint > m_bTournamentGroup[cGroupIndex].BTeam.nTournamentPoint ? m_bTournamentGroup[cGroupIndex].BTeam.nTeamNum-1 : m_bTournamentGroup[cGroupIndex].ATeam.nTeamNum-1; } // 안되면 예선점수 보고 else if( m_bTournamentGroup[cGroupIndex].ATeam.nOpeningPoint != m_bTournamentGroup[cGroupIndex].BTeam.nOpeningPoint ) { cWinGuildIndex = m_bTournamentGroup[cGroupIndex].ATeam.nOpeningPoint > m_bTournamentGroup[cGroupIndex].BTeam.nOpeningPoint ? m_bTournamentGroup[cGroupIndex].ATeam.nTeamNum-1 : m_bTournamentGroup[cGroupIndex].BTeam.nTeamNum-1; cLoseGuildIndex = m_bTournamentGroup[cGroupIndex].ATeam.nOpeningPoint > m_bTournamentGroup[cGroupIndex].BTeam.nOpeningPoint ? m_bTournamentGroup[cGroupIndex].BTeam.nTeamNum-1 : m_bTournamentGroup[cGroupIndex].ATeam.nTeamNum-1; } else { //이건 운이다..된장.. cWinGuildIndex = m_bTournamentGroup[cGroupIndex].ATeam.nTeamNum-1; cLoseGuildIndex = m_bTournamentGroup[cGroupIndex].BTeam.nTeamNum-1; } char cMatchTypeCode = m_GuildWarFinalInfo[cWinGuildIndex].cMatchTypeCode; SetGuildTournamentInfoWin(cWinGuildIndex, true); //이긴걸로 표시 SetGuildTournamentInfoWin(cLoseGuildIndex, false); //진걸로 표시 SendSetGuildWarFinalResult(cWinGuildIndex, cLoseGuildIndex); // 결과 보내주고.. SendSetGuildWarTournamentWin(cWinGuildIndex, cMatchTypeCode); // 승리 길드 알림. //보상지급해줘야함.. //CDNVillageConnection* pVillage = g_pDivisionManager->GetFirstEnableVillageServer(); CDNVillageConnection* pVillage = g_pDivisionManager->GetVillageConnectionByVillageID( g_pDivisionManager->GetPvPLobbyVillageID() ); if( pVillage ) { //이긴넘 진넘 둘다 DB에 결과 저장 pVillage->SendSetGuildWarFinalResultDB(m_wScheduleID, cWinGuildIndex+1, m_GuildWarFinalInfo[cWinGuildIndex].GuildUID.nDBID, cMatchTypeCode, true); pVillage->SendSetGuildWarFinalResultDB(m_wScheduleID, cLoseGuildIndex+1, m_GuildWarFinalInfo[cLoseGuildIndex].GuildUID.nDBID, cMatchTypeCode, false); } else { // 요건 보상도 못주고 결과 기록도 못함.ㅠㅠ g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] SetDropTournament Failed !!! WinGuildDBID:%d, LosGuildDBID:%d \n", m_GuildWarFinalInfo[cWinGuildIndex].GuildUID.nDBID, m_GuildWarFinalInfo[cLoseGuildIndex].GuildUID.nDBID); } //결승이면 우승길드로 셋팅해 주자~ if( cMatchTypeCode == GUILDWAR_FINALPART_FINAL ) { g_pGuildWarManager->SetPreWinGuild( m_GuildWarFinalInfo[cWinGuildIndex].GuildUID); g_pGuildWarManager->SetPreWinScheduleID(m_wScheduleID); } g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] SetDropTournament !!! WinGuildDBID:%d, LosGuildDBID:%d \n", m_GuildWarFinalInfo[cWinGuildIndex].GuildUID.nDBID, m_GuildWarFinalInfo[cLoseGuildIndex].GuildUID.nDBID); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Private Function bool CDNGuildWarManager::CheckStep(char cStep) { if (GUILDWAR_STEP_NONE < cStep && cStep < GUILDWAR_STEP_END) return true; return false; } void CDNGuildWarManager::ResetStep() { // 스케쥴 ID리셋 m_wScheduleID = GUILDWARSCHEDULE_DEF; // 스텝 초기화 m_cStepIndex = GUILDWAR_STEP_NONE; m_bWarEvent = false; for (int i=GUILDWAR_STEP_NONE; iReset(); } } void CDNGuildWarManager::StartStep() { m_bWarEvent = true; m_cStepIndex = GUILDWAR_STEP_PREPARATION; // 현재 어떤 이벤트가 진행되는지 여기서 맞춰버리자. for( int i=GUILDWAR_STEP_PREPARATION; iProcess(); // 모든 이벤트가 끝났을때 다음스텝으로 진행 if (pWarEventStep[i]->IsFinishPeriod()) NextStep(); } } void CDNGuildWarManager::NextStep() { // 혹시 모르니 타입체크 한번더! if (!CheckStep(m_cStepIndex)) return; char cNextStepIndex = m_cStepIndex + 1; if (cNextStepIndex >= GUILDWAR_STEP_END) { // 다음스텝이 마지막이면 종료한다. FinalStep(); // 다음 차수 가져오기~ m_eSettingStep = REQ_SCHEDULE; SendGuildWarInfoReq(); return; } time_t tNextEvent = m_pWarEventStep[cNextStepIndex]->GetEventTime (GUILDWAR_EVENT_START); time_t tCurrentTime; time(&tCurrentTime); // 다음 이벤트 시간이 현재시각보다 많으면 다음 스텝으로 진행한다. if (tCurrentTime > tNextEvent) m_cStepIndex++; } void CDNGuildWarManager::FinalStep() { Clear(); //ResetStep(); } bool CDNGuildWarManager::RegisterScheduleGroup(short wScheduleID, const TGuildWarEventInfo vEventInfo[]) { ResetStep(); time_t tCheckPeriod = 0; time_t tBeginTime = 0; time_t tEndTime = 0; for (char i=GUILDWAR_STEP_PREPARATION; i= tEndTime) { ResetStep(); // 연속된 기간이 아니라면 에러처리하고 리셋! g_Log.Log(LogType::_FILELOG, L"CDNGuildWarManager::RegisterScheduleGroup Failed !!! Wrong Time Schedule Begin(%d) End(%d) Check(%d)\n", tBeginTime, tEndTime, tCheckPeriod); return false; } m_pWarEventStep[cStep]->UpdateTime(wScheduleID, tBeginTime, tEndTime, m_wWinersWeightRate); // 마지막 시간을 저장해서 다음 기간에 대한 검사조건으로 사용한다. tCheckPeriod = tEndTime; } m_wScheduleID = wScheduleID; g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] RegisterScheduleGroup Success ScheduleID:%d!!!\n", wScheduleID); return true; } bool CDNGuildWarManager::UpdateScheduleGroup(short wScheduleID, const TGuildWarEventInfo vEventInfo[]) { time_t tCurrentTime; time(&tCurrentTime); // 현재시간 // 데이터상의 현재 스텝 char cStepIndex = GUILDWAR_STEP_NONE; time_t tCheckPeriod = 0; time_t tBeginTime = 0; time_t tEndTime = 0; // 본선 진행중일때는 스케쥴 업데이트 하지말자..이럼 Hell 될것 같음. if( m_cStepIndex == GUILDWAR_STEP_REWARD ) { g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] UpdateScheduleGroup Failed !!! Already Reward Step On\n"); return false; } // 데이터 체크 for (char i=GUILDWAR_STEP_PREPARATION; i= tEndTime) { g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] UpdateScheduleGroup Failed !!! Wrong Time Schedule Begin(%d) End(%d) Check(%d)\n", tBeginTime, tEndTime, tCheckPeriod); return false; } // 데이터상 현재 스텝을 구한다. if (tCurrentTime > tBeginTime && tCurrentTime < tEndTime) cStepIndex = i; // 마지막 시간을 저장해서 다음 기간에 대한 검사조건으로 사용한다. tCheckPeriod = tEndTime; } // 현재 스텝과 맞지 않으면 에러처리 if (m_cStepIndex != cStepIndex) { g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] UpdateScheduleGroup Failed !!! Wrong Step Index[%d]<->[%d]\n", m_cStepIndex, cStepIndex); return false; } // 데이터 입력 for (char i=GUILDWAR_STEP_PREPARATION; iUpdateTime(wScheduleID, tBeginTime, tEndTime, m_wWinersWeightRate); else { _DANGER_POINT(); // 위에서 한번 체크했는데 타입체크 실패하면 말이 안됨! return false; } } g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] UpdateScheduleGroup Success ScheduleID:%d!!!\n", wScheduleID); return true; } void CDNGuildWarManager::CalcTeamSecret() { // 블루 : 1 // 레드 : 2 if (m_nBlueTeamPoint == m_nRedTeamPoint) { m_cSecretTeam = 0; return; } BYTE cTeamCode = 0; float fSecretRate = 0.0f; if (m_nBlueTeamPoint > m_nRedTeamPoint) { fSecretRate = (float)m_nRedTeamPoint / (float)m_nBlueTeamPoint; cTeamCode = 2; // 레드팀 혜택 } else { fSecretRate = (float)m_nBlueTeamPoint / (float)m_nRedTeamPoint; cTeamCode = 1; // 블루팀 혜택 } if (fSecretRate < 0) { DN_ASSERT( false, "fSecretRate < 0" ); return; } fSecretRate = 1.0f - fSecretRate; float nSecretStartRate = GUILDWAR_SECRET_SATRT_RATE; float nSecretEndRate = GUILDWAR_SECRET_END_RATE; time_t tCurrentTime; time(&tCurrentTime); time_t tStartTime = m_pWarEventStep[GUILDWAR_STEP_TRIAL]->GetEventTime(GUILDWAR_EVENT_START); time_t tEndTime = m_pWarEventStep[GUILDWAR_STEP_TRIAL]->GetEventTime(GUILDWAR_EVENT_END); //예선 종료 시간 먼저 체크 if( tEndTime - tCurrentTime <= GUILDWAR_SECRET_TERM_SECOND ) // 24시간 이하로 남았으면 비율을 반으로 줄임 { nSecretStartRate = nSecretStartRate*0.5f; nSecretEndRate = nSecretEndRate*0.5f; } else if( tCurrentTime - tStartTime < GUILDWAR_SECRET_TERM_SECOND ) // 시작된지 24시간 안 지났으면 시크릿 발동 안됨. return; if (fSecretRate >= nSecretStartRate) { if (m_cSecretTeam != cTeamCode) { m_cSecretTeam = cTeamCode; // 적용 CMtRandom rand; rand.srand( timeGetTime() ); m_nSecretRandomSeed = rand.rand(); MASetGuildWarSecretMission packet = {0,}; packet.cTeamCode = m_cSecretTeam; packet.nRandomSeed = m_nSecretRandomSeed; g_pDivisionManager->SendSetGuildWarSecretMission(&packet); g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] SecretStart Seed:%d, Team:%d, Rate:%f!!!\n", packet.nRandomSeed, packet.cTeamCode, fSecretRate ); } } else if (fSecretRate <= nSecretEndRate && m_cSecretTeam != 0) { m_cSecretTeam = 0; // 해제 MASetGuildWarSecretMission packet = {0,}; packet.cTeamCode = m_cSecretTeam; packet.nRandomSeed = -1; g_pDivisionManager->SendSetGuildWarSecretMission(&packet); g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] SecretEnd Rate:%f!!!\n", fSecretRate ); } }