6048 lines
No EOL
355 KiB
C++
6048 lines
No EOL
355 KiB
C++
#include "stdafx.h"
|
||
#include "DnGameRoom.h"
|
||
#include "DNUserSession.h"
|
||
#include "TaskManager.h"
|
||
#include "DnGameTask.h"
|
||
#include "DnPvPGameTask.h"
|
||
#include "DnDLGameTask.h"
|
||
#include "DnItemTask.h"
|
||
#include "DnPartyTask.h"
|
||
#include "DnDLPartyTask.h"
|
||
#include "DnGuildTask.h"
|
||
#include "DnPvPPartyTask.h"
|
||
#include "DnSkillTask.h"
|
||
#include "DnWorld.h"
|
||
#include "PerfCheck.h"
|
||
#include "GameListener.h"
|
||
#include "DNGameServerManager.h"
|
||
#include "DNRUDPGameServer.h"
|
||
#include "DNBackGroundLoader.h"
|
||
#include "EtCollisionMng.h"
|
||
#include "GameSendPacket.h"
|
||
#include "DnSkill.h"
|
||
#include "DNUserTcpConnection.h"
|
||
#include "DNIocpManager.h"
|
||
#include "DnWorldSector.h"
|
||
#include "DnWorldActProp.h"
|
||
#include "DNLogConnection.h"
|
||
#include "DNBreakIntoUserSession.h"
|
||
#include "DnBlow.h"
|
||
#include "ExceptionReport.h"
|
||
#include "DnWeapon.h"
|
||
#include "DnParts.h"
|
||
#include "DNServiceConnection.h"
|
||
#include "DnPlayerActor.h"
|
||
#include "NoticeSystem.h"
|
||
#if defined( STRESS_TEST )
|
||
#include "DNDBConnectionManager.h"
|
||
#endif // #if defined( STRESS_TEST )
|
||
#include "DNDBConnectionManager.h"
|
||
#ifdef _USE_VOICECHAT
|
||
#include "DNVoiceChat.h"
|
||
#endif
|
||
#include "DnTaskFactory.hpp"
|
||
#include "DNMissionSystem.h"
|
||
#include "DnMonsterActor.h"
|
||
#include "DNDBConnection.h"
|
||
#include "CloseSystem.h"
|
||
#include "DNFriend.h"
|
||
#if defined( PRE_ADD_NPC_REPUTATION_SYSTEM )
|
||
#include "ReputationSystemRepository.h"
|
||
#include "ReputationSystemEventHandler.h"
|
||
#endif // #if defined( PRE_ADD_NPC_REPUTATION_SYSTEM )
|
||
#include "MasterRewardSystem.h"
|
||
#include "DNMasterConnectionManager.h"
|
||
#include "DNMasterConnection.h"
|
||
#include "DNFarmUserSession.h"
|
||
#if defined (PRE_ADD_BESTFRIEND)
|
||
#include "DNBestFriend.h"
|
||
#endif
|
||
#ifdef PRE_ADD_BEGINNERGUILD
|
||
#include "DNGuildSystem.h"
|
||
#endif //#ifdef PRE_ADD_BEGINNERGUILD
|
||
#include "DNChatTask.h"
|
||
#include "DNChatRoom.h"
|
||
#include "DNTimeEventSystem.h"
|
||
#include "PvPGameMode.h"
|
||
#if defined( PRE_ADD_VIP_FARM )
|
||
#include "DNCashRepository.h"
|
||
#endif // #if defined( PRE_ADD_VIP_FARM )
|
||
#include "DNGameDataManager.h"
|
||
#if defined( _WORK )
|
||
#include <iostream>
|
||
#endif // #if defined( _WORK )
|
||
//rlkt addons
|
||
#include "FarmPVP.h"
|
||
|
||
CDNGameRoom::CDNGameRoom( CDNRUDPGameServer* pServer, unsigned int iRoomID, MAGAReqRoomID* pPacket )
|
||
: CMultiRoom( iRoomID )
|
||
{
|
||
#ifdef PRE_ADD_FRAMEDELAY_LOG
|
||
m_dwProcessElapsedTime = 0;
|
||
#endif //#ifdef PRE_ADD_FRAMEDELAY_LOG
|
||
m_bRoomCrash = false;
|
||
m_lRoomProcessInterLocked = 0;
|
||
|
||
// SmartPtr Manager 들 전부 리셋해줍시다.
|
||
CDnActor::ReleaseClass( this );
|
||
CDnDropItem::ReleaseClass( this );
|
||
CDnWeapon::ReleaseClass( this );
|
||
|
||
CDnParts::DeleteAllObject( this );
|
||
CEtObject::DeleteAllObject( this );
|
||
CDnBlow::DeleteAllObject( this );
|
||
CDnSkill::DeleteAllObject( this );
|
||
CDnWorldProp::DeleteAllObject( this );
|
||
|
||
/////////////////////////////////////////
|
||
m_pGameServer = pServer;
|
||
m_iWorldID = 0;
|
||
|
||
|
||
#if defined( PRE_PARTY_DB )
|
||
m_PartyStructData = pPacket->PartyData;
|
||
#else
|
||
memset(m_wszPartyPass, 0, sizeof(m_wszPartyPass));
|
||
memset(m_wszPartyName, 0, sizeof(m_wszPartyName));
|
||
_wcscpy( m_wszPartyName, _countof(m_wszPartyName), pPacket->wszPartyName, (int)wcslen(pPacket->wszPartyName) );
|
||
m_nUserLvMin = pPacket->cUserLvLimitMin;
|
||
m_nTargetMapIdx = pPacket->nTargetMapIdx;
|
||
m_PartyDifficulty = pPacket->PartyDifficulty;
|
||
m_nMemberMax = pPacket->cMemberMax;
|
||
#endif // #if defined( PRE_PARTY_DB )
|
||
|
||
m_GameTaskType = pPacket->GameTaskType;
|
||
m_cReqGameIDType = pPacket->cReqGameIDType;
|
||
m_InstanceID = pPacket->InstanceID;
|
||
m_iPartMemberCnt = pPacket->cMemberCount;
|
||
m_iMapIdx = pPacket->nMapIndex;
|
||
#if defined(PRE_ADD_RENEW_RANDOM_MAP)
|
||
m_iRootMapIndex = pPacket->nMapIndex;
|
||
#endif
|
||
m_iGateIdx = pPacket->cGateNo;
|
||
m_iGateSelect = pPacket->cGateSelect;
|
||
m_StageDifficulty = pPacket->StageDifficulty;
|
||
m_iRandomSeed = pPacket->nRandomSeed;
|
||
#if defined(PRE_FIX_INITSTATEANDSYNC)
|
||
m_bInitStateAndSyncReserved = false;
|
||
m_nReservedMapIdx = 0;
|
||
m_nReservedGateIdx = 0;
|
||
m_nReservedRandomSeed = 0;
|
||
m_ReservedStageDifficulty = TDUNGEONDIFFICULTY::Easy;
|
||
m_bReservedDirectConnect = false;
|
||
m_bReservedGateSelect = 0;
|
||
#endif
|
||
#if defined( PRE_PARTY_DB )
|
||
#else
|
||
m_ItemLootRule = pPacket->ItemLootRule;
|
||
m_ItemLootRank = pPacket->ItemLootRank;
|
||
#endif
|
||
m_nMeritBonusID = pPacket->nMeritBonusID;
|
||
m_bDirectConnect = pPacket->bDirectConnect;
|
||
m_nChannelID = pPacket->nChannelID;
|
||
|
||
#if defined( PRE_PARTY_DB )
|
||
#else
|
||
m_nUserLvMax = pPacket->cUserLvLimitMax;
|
||
m_cIsJobDice = pPacket->cIsJobDice;
|
||
_wcscpy( m_wszPartyPass, _countof(m_wszPartyPass), pPacket->wszPartyPass, (int)wcslen(pPacket->wszPartyPass) );
|
||
#endif // #if defined( PRE_PARTY_DB )
|
||
|
||
m_nEventRoomIndex = 0;
|
||
|
||
m_nCompleteExperience = 0;
|
||
m_dwDungeonPlayerTime = 0;
|
||
m_nDungeonGateID = 0;
|
||
|
||
memset(m_nKickedMemberList, 0, sizeof(m_nKickedMemberList));
|
||
|
||
//test
|
||
m_ActorSendTick = 0;
|
||
m_ActorTick = DEFAULT_ACTOR_BROADTICK;
|
||
m_nCullingDistance = DEFAULT_PACKETCULLING_DISTANCE;
|
||
|
||
m_pWorld = NULL;
|
||
m_pTaskMng = NULL;
|
||
m_pGameTask = NULL;
|
||
m_pPartyTask = NULL;
|
||
m_pItemTask = NULL;
|
||
m_pSkillTask = NULL;
|
||
m_pGuildTask = NULL;
|
||
m_pCollisionMng = NULL;
|
||
m_iPivotTick = timeGetTime();
|
||
m_iNextGameState = 0;
|
||
m_nCurItemLooterInOrder = 0;
|
||
|
||
if (m_cReqGameIDType == REQINFO_TYPE_FARM)
|
||
m_GameState = _GAME_STATE_FARM_NONE;
|
||
else
|
||
m_GameState = _GAME_STATE_READY2CONNECT;
|
||
|
||
m_pRandom = new CRandom( this );
|
||
_srand( this, timeGetTime() );
|
||
|
||
m_pCollisionMng = new CEtCollisionMng( this );
|
||
|
||
m_VecMember.reserve( PvPCommon::Common::MaxPlayer );
|
||
m_DeleteList.reserve( PvPCommon::Common::MaxPlayer );
|
||
#if defined( PRE_FIX_49129 )
|
||
m_MapFirstPartyMember.clear();
|
||
#endif
|
||
#ifdef _USE_VOICECHAT
|
||
memset(&m_nVoiceChannelID, 0, sizeof(m_nVoiceChannelID));
|
||
m_nTalkingTick = 0;
|
||
if (g_pVoiceChat)
|
||
{
|
||
for (int i = 0; i < PvPCommon::TeamIndex::Max; i++)
|
||
{
|
||
if (pPacket->nVoiceChannelID[i] <= 0) continue;
|
||
if (g_pVoiceChat->CreateVoiceChannel(pPacket->nVoiceChannelID[i]))
|
||
{
|
||
m_nVoiceChannelID[i] = pPacket->nVoiceChannelID[i];
|
||
m_nTalkingTick = timeGetTime();
|
||
}
|
||
else
|
||
_DANGER_POINT();
|
||
}
|
||
}
|
||
#endif // #ifdef _USE_VOICECHAT
|
||
|
||
#if defined( PRE_TRIGGER_LOG )
|
||
// test
|
||
m_dTriggerTime = 0.f;
|
||
m_dProcessTime = 0.f;
|
||
if( pServer )
|
||
{
|
||
#if !defined( _FINAL_BUILD )
|
||
m_bLog = true;
|
||
#else // #if !defined( _FINAL_BUILD )
|
||
m_bLog = (pServer->GetServerID() == 1);
|
||
#endif // #if !defined( _FINAL_BUILD )
|
||
if( m_bLog )
|
||
QueryPerformanceFrequency(&m_liFrequency);
|
||
}
|
||
else
|
||
{
|
||
m_bLog = false;
|
||
}
|
||
#endif // #if defined( PRE_TRIGGER_LOG )
|
||
|
||
_CalcDBConnection( iRoomID );
|
||
|
||
m_cSeqLevel = 0;
|
||
|
||
m_bStageStargLog = false;
|
||
m_bStageEndLog = false;
|
||
m_bGotoVillageFlag = false;
|
||
#if defined( PRE_ADD_DIRECTNBUFF )
|
||
m_DirectPartyBuffItemList.clear();
|
||
#endif
|
||
m_iHackPenalty = 0;
|
||
m_bForceDestroyRoom = false;
|
||
m_bFinalizeRoom = false;
|
||
m_i64RoomLogIndex = (static_cast<INT64>(g_Config.nManagedID)<<32)|((iRoomID&0xFFFF)<<16)|(rand()&0xFFFF);
|
||
#if defined( PRE_PARTY_DB )
|
||
#else
|
||
m_nUpkeepCount = pPacket->cUpkeepCount;
|
||
#endif
|
||
|
||
memset(m_nPartyMemberIndex, 0, sizeof(m_nPartyMemberIndex));
|
||
memset(m_wszInvitedCharacterName, 0, sizeof(m_wszInvitedCharacterName));
|
||
m_nInivitedTime = 0;
|
||
|
||
m_pMasterRewardSystem = new MasterSystem::CRewardSystem( this );
|
||
|
||
m_bCheckTick = false;
|
||
#if defined( PRE_THREAD_ROOMDESTROY )
|
||
m_lRoomDestroyInterLocked = eRoomDestoryStep::None;
|
||
#endif // #if defined( PRE_THREAD_ROOMDESTROY )
|
||
|
||
m_mtRandom.srand(timeGetTime());
|
||
|
||
#if defined( PRE_ADD_36870 )
|
||
m_iDungeonClearRound = 0;
|
||
#endif // #if defined( PRE_ADD_36870 )
|
||
#ifdef _GPK
|
||
m_bGPKCodeFlag = false;
|
||
#endif //#ifdef _GPK
|
||
#if defined( PRE_WORLDCOMBINE_PVP )
|
||
m_eWorldReqRoom = pPacket->eWorldReqType;
|
||
m_nWorldPvPRoomDBIndex = 0;
|
||
m_bWorldPvPRoomStart = 0;
|
||
m_nCreateGMAccountDBID = 0;
|
||
memset(&m_tPvPRoomDBData, 0, sizeof(m_tPvPRoomDBData));
|
||
#endif
|
||
#if defined(PRE_ADD_ACTIVEMISSION)
|
||
m_bIsFirstInitializeDungeon = false;
|
||
#endif
|
||
#if defined( PRE_ALTEIAWORLD_EXPLORE )
|
||
m_bAlteiaWorld = false;
|
||
m_bAlteiaWorldMap = false;
|
||
m_dwAlteiaWorldStartTime = 0;
|
||
m_dwAlteiaWorldPlayTime = 0;
|
||
#endif
|
||
#if defined(PRE_ADD_CP_RANK)
|
||
memset(&m_sLegendClearBest, 0, sizeof(m_sLegendClearBest));
|
||
memset(&m_sMonthlyClearBest, 0, sizeof(m_sMonthlyClearBest));
|
||
#endif //#if defined(PRE_ADD_CP_RANK)
|
||
#if defined( PRE_PVP_GAMBLEROOM )
|
||
m_nGambleRoomDBID = 0;
|
||
#endif
|
||
}
|
||
|
||
CDNGameRoom::~CDNGameRoom()
|
||
{
|
||
SAFE_DELETE( m_pMasterRewardSystem );
|
||
}
|
||
|
||
void CDNGameRoom::FinalizeGameRoom()
|
||
{
|
||
m_bFinalizeRoom = true;
|
||
|
||
#if defined( PRE_PARTY_DB )
|
||
DelPartyDB();
|
||
#endif
|
||
|
||
#if !defined( PRE_PARTY_DB )
|
||
// 파티 종료 로그
|
||
if( GetGameType() == REQINFO_TYPE_PARTY && !GetGoToVillageFlag() )
|
||
{
|
||
BYTE cThreadID;
|
||
CDNDBConnection* pDBCon = g_pDBConnectionManager->GetDBConnection( cThreadID );
|
||
if( pDBCon )
|
||
pDBCon->QueryAddPartyEndLog( cThreadID, GetWorldSetID(), 0, GetPartyLogIndex() );
|
||
}
|
||
#endif
|
||
|
||
// 스테이지 종료 로그
|
||
if( GetStageStartLogFlag() && !GetStageEndLogFlag() )
|
||
{
|
||
BYTE cThreadID;
|
||
CDNDBConnection* pDBCon = g_pDBConnectionManager->GetDBConnection( cThreadID );
|
||
if( pDBCon )
|
||
{
|
||
pDBCon->QueryAddStageEndLog( cThreadID, GetWorldSetID(), 0, GetRoomLogIndex(), static_cast<DBDNWorldDef::WhereToGoCode::eCode>(0) );
|
||
}
|
||
}
|
||
|
||
#if defined( PRE_ALTEIAWORLD_EXPLORE )
|
||
if( bIsAlteiaWorld() )
|
||
{
|
||
GetDBConnection()->QueryAddStageEndLog( GetDBThreadID(), GetWorldSetID(), 0, GetRoomLogIndex(), DBDNWorldDef::WhereToGoCode::Village );
|
||
}
|
||
#endif
|
||
|
||
#if defined( PRE_ADD_58761 )
|
||
if( GetDungeonGateID() > 0 )
|
||
EndDungeonGateTime( GetDungeonGateID() );
|
||
#endif
|
||
|
||
|
||
#ifdef _USE_VOICECHAT
|
||
if (g_pVoiceChat)
|
||
{
|
||
for (int i = 0; i < PvPCommon::TeamIndex::Max; i++)
|
||
{
|
||
if (m_nVoiceChannelID[i] <= 0) continue;
|
||
g_pVoiceChat->DestroyVoiceChannel(m_nVoiceChannelID[i]);
|
||
}
|
||
}
|
||
#endif
|
||
|
||
#if defined( PRE_WORLDCOMBINE_PVP )
|
||
if( bIsWorldPvPRoom() && !bIsWorldPvPRoomStart() )
|
||
{
|
||
GetDBConnection()->QueryDelWorldPvPRoom( GetWorldSetID(), GetWorldPvPRoomDBIndex() );
|
||
}
|
||
#endif
|
||
|
||
std::list<CDNUserSession*>::iterator ii;
|
||
for (ii = m_UserList.begin(); ii != m_UserList.end(); ii++)
|
||
(*ii)->DetachConnection(L"~CDNGameRoom()");
|
||
|
||
FinalizeProcess();
|
||
TcpProcess();
|
||
Process();
|
||
|
||
if( m_pTaskMng )
|
||
m_pTaskMng->RemoveAllTask();
|
||
|
||
SAFE_DELETE( m_pTaskMng );
|
||
SAFE_DELETE( m_pWorld );
|
||
SAFE_DELETE( m_pRandom );
|
||
SAFE_DELETE( m_pCollisionMng );
|
||
SAFE_DELETE_VEC( m_GameListener );
|
||
|
||
for( ii = m_UserList.begin() ; ii != m_UserList.end() ; ++ii )
|
||
{
|
||
delete *ii;
|
||
}
|
||
|
||
#if defined( PRE_TRIGGER_LOG )
|
||
if( m_bLog && m_dProcessTime >= 1.f )
|
||
{
|
||
wchar_t szBuf[MAX_PATH];
|
||
wsprintf( szBuf, L"[Map:%d] Total %.3f ms Trigger %.3f ms rate=%d%%\r\n", m_iMapIdx, m_dProcessTime, m_dTriggerTime, static_cast<int>(m_dTriggerTime/m_dProcessTime*100) );
|
||
g_TriggerLog.Log( LogType::_FILELOG, szBuf );
|
||
}
|
||
#endif // #if defined( PRE_TRIGGER_LOG )
|
||
|
||
//서버 클로징중이 아닌데
|
||
if (bIsFarmRoom())
|
||
{
|
||
//농장이 파괴가 되어진다면, 문제가 있어서 그러는거쉬다 마스터에 알려서 처리되게한다.
|
||
g_pMasterConnectionManager->SendFarmIntendedDestroy(GetWorldSetID(), GetFarmIndex());
|
||
}
|
||
}
|
||
|
||
void CDNGameRoom::_CalcDBConnection( UINT uiRoomID )
|
||
{
|
||
// RootRoom 예외처리
|
||
if( m_pGameServer == NULL )
|
||
{
|
||
m_pDBConnection = NULL;
|
||
m_cDBThreadID = 0;
|
||
return;
|
||
}
|
||
|
||
m_pDBConnection = g_pDBConnectionManager->GetDBConnection( uiRoomID, m_cDBThreadID );
|
||
|
||
if( !m_pDBConnection || !m_pDBConnection->GetActive() )
|
||
{
|
||
// 일정 횟수 동안 랜덤으로 Active 한 DBConnection 을 찾는다.
|
||
for( int i=0 ; i<(int)g_pDBConnectionManager->GetCount()*2 ; ++i )
|
||
{
|
||
m_pDBConnection = g_pDBConnectionManager->GetDBConnection( m_cDBThreadID );
|
||
|
||
// Active 한 DBConnection 을 찾았으면 나간다~~~.
|
||
if( m_pDBConnection && m_pDBConnection->GetActive() )
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
bool CDNGameRoom::bIsBreakIntoUser( CDNUserSession* pGameSession )
|
||
{
|
||
std::list<CDNUserSession*>::iterator itor = std::find( m_BreakIntoUserList.begin(), m_BreakIntoUserList.end(), pGameSession );
|
||
return (itor!=m_BreakIntoUserList.end());
|
||
}
|
||
|
||
void CDNGameRoom::GetBreakIntoUserTeamCount( int& iATeam, int& iBTeam )
|
||
{
|
||
iATeam = 0;
|
||
iBTeam = 0;
|
||
for( std::list<CDNUserSession*>::iterator itor=m_BreakIntoUserList.begin() ; itor!=m_BreakIntoUserList.end() ; ++itor )
|
||
{
|
||
CDNUserSession* pSession = (*itor);
|
||
|
||
// m_VecMember 에 아직 Push 안된애만
|
||
if( GetUserSession( pSession->GetSessionID() ) == NULL )
|
||
{
|
||
if( pSession->GetTeam() == PvPCommon::Team::A )
|
||
++iATeam;
|
||
else if( pSession->GetTeam() == PvPCommon::Team::B )
|
||
++iBTeam;
|
||
}
|
||
}
|
||
}
|
||
|
||
CDNUserSession* CDNGameRoom::CreateBreakIntoGameSession( WCHAR* wszAccountName, const WCHAR * pwszChracterName, UINT nAccountDBID, UINT nSessionID, INT64 biCharacterDBID, int iTeam, int nWorldID, int nVillageID,
|
||
#if defined(PRE_ADD_MULTILANGUAGE)
|
||
bool bAdult, char cPCBangGrade, int BreakIntoType, char cSelectedLanguage )
|
||
#else //#if defined(PRE_ADD_MULTILANGUAGE)
|
||
bool bAdult, char cPCBangGrade, int BreakIntoType )
|
||
#endif //#if defined(PRE_ADD_MULTILANGUAGE)
|
||
{
|
||
CDNUserSession* pSession = NULL;
|
||
// 난입은 _GAME_STATE_PLAY 상태에서만 가능하다.
|
||
if( m_GameState == _GAME_STATE_PLAY )
|
||
{
|
||
#if defined( PRE_PARTY_DB )
|
||
if (GetGameType() == REQINFO_TYPE_PARTY && GetPartyIndex() > 0 && (BreakIntoType==BreakInto::Type::WorldZoneParty || BreakIntoType==BreakInto::Type::PartyJoin) )
|
||
#else
|
||
if (GetGameType() == REQINFO_TYPE_PARTY && GetPartyIndex() > 0 && BreakIntoType==BreakInto::Type::WorldZoneParty )
|
||
#endif // #if defined( PRE_PARTY_DB )
|
||
{
|
||
//혹시나 스텝이 꼬여서 들어올 경우를 막아보자꾸나~
|
||
if ((int)m_VecMember.size() >= GetPartyMemberMax())
|
||
return NULL; //맥스카운트보다 더들어올려고 하는 경우
|
||
|
||
#if defined( PRE_PARTY_DB )
|
||
if ((int)(m_VecMember.size()+m_BreakIntoUserList.size()) >= GetPartyMemberMax())
|
||
return NULL; //난입하는 유저 포함 맥스카운트보다 더들어올려고 하는 경우
|
||
#endif // #if defined( PRE_PARTY_DB )
|
||
if ( (BreakIntoType==BreakInto::Type::WorldZoneParty) && IsInvitingUser(pwszChracterName) == false)
|
||
return NULL; //초대한 사람이 아니면 안데지잉~
|
||
|
||
//지금 월드존인지까지 한번 확인
|
||
if (CDnWorld::GetInstance(this).GetMapType() != GlobalEnum::eMapTypeEnum::MAP_WORLDMAP)
|
||
return NULL;
|
||
}
|
||
|
||
if( bIsFarmRoom() )
|
||
pSession = new CDNFarmUserSession( nSessionID, m_pGameServer, this );
|
||
else
|
||
pSession = new IBoostPoolDNBreakIntoUserSession( nSessionID, m_pGameServer, this );
|
||
if( pSession )
|
||
{
|
||
pSession->SetDBConInfo( m_pDBConnection, m_cDBThreadID );
|
||
#if defined(PRE_ADD_MULTILANGUAGE)
|
||
pSession->PreInitializeUser( wszAccountName, nAccountDBID, nSessionID, biCharacterDBID, iTeam, nWorldID, nVillageID, false, bAdult, cPCBangGrade, cSelectedLanguage );
|
||
#else //#if defined(PRE_ADD_MULTILANGUAGE)
|
||
pSession->PreInitializeUser( wszAccountName, nAccountDBID, nSessionID, biCharacterDBID, iTeam, nWorldID, nVillageID, false, bAdult, cPCBangGrade );
|
||
#endif //#if defined(PRE_ADD_MULTILANGUAGE)
|
||
}
|
||
else
|
||
return pSession;
|
||
|
||
m_BreakIntoUserList.push_back( pSession );
|
||
m_UserList.push_back(pSession);
|
||
}
|
||
else
|
||
g_Log.Log(LogType::_ERROR, nWorldID, nAccountDBID, biCharacterDBID, nSessionID, _T("Connect|GameStart Flow err [state:addmember]\n"));
|
||
|
||
return pSession;
|
||
}
|
||
|
||
void CDNGameRoom::OnSendPartyMemberInfo( CDNUserSession* pBreakIntoSession )
|
||
{
|
||
if( !pBreakIntoSession )
|
||
return;
|
||
|
||
SCROOM_SYNC_MEMBERINFO TxPacket;
|
||
memset( &TxPacket, 0, sizeof(TxPacket) );
|
||
|
||
TxPacket.bIsStart = true;
|
||
TxPacket.bIsBreakInto = true;
|
||
|
||
UINT uiSendCount = 0;
|
||
|
||
for( UINT i=0 ; i<m_VecMember.size() ; ++i )
|
||
{
|
||
m_VecMember[i].pSession->GetPartyMemberInfo( TxPacket.Member[i-uiSendCount] );
|
||
++TxPacket.nCount;
|
||
|
||
// Page완성
|
||
if( TxPacket.nCount%_countof(TxPacket.Member) == 0 )
|
||
{
|
||
pBreakIntoSession->AddSendData( SC_ROOM, eRoom::SC_SYNC_MEMBERINFO, reinterpret_cast<char*>(&TxPacket), sizeof(TxPacket) );
|
||
|
||
uiSendCount += _countof(TxPacket.Member);
|
||
TxPacket.nCount = 0;
|
||
TxPacket.bIsStart = false;
|
||
}
|
||
}
|
||
|
||
if( TxPacket.nCount > 0 )
|
||
{
|
||
int iSize = sizeof(TxPacket)-sizeof(TxPacket.Member)+TxPacket.nCount*sizeof(TxPacket.Member[0]);
|
||
|
||
pBreakIntoSession->AddSendData( SC_ROOM, eRoom::SC_SYNC_MEMBERINFO, reinterpret_cast<char*>(&TxPacket), iSize );
|
||
}
|
||
}
|
||
|
||
void CDNGameRoom::OnSetLoad2SyncState( const int iCurTick )
|
||
{
|
||
SendConnectedResult();
|
||
|
||
#if defined(_HSHIELD)
|
||
SendMakeReq(); // CRC 요청
|
||
#endif //#elif defined(_GPK)
|
||
|
||
m_GameState = _GAME_STATE_LOAD2SYNC; //다음 스테이트로 이동합니다.
|
||
m_iNextGameState = iCurTick + WAIT_FOR_LOAD_TIME_LIMIT;
|
||
}
|
||
|
||
// On 으로 시작하는 함수는 가상함수임.
|
||
void CDNGameRoom::SetSync2SyncStateTemplateMethod( const int iCurTick, CDNUserSession* pBreakIntoSession/*=NULL*/)
|
||
{
|
||
InitRoomState( pBreakIntoSession );
|
||
OnSendPartyMemberInfo( pBreakIntoSession );
|
||
OnSendTeamData( pBreakIntoSession ); // 관전 모드 때문에 제일 상단에서 팀정보 보내준다.
|
||
SendEquipData( pBreakIntoSession );
|
||
SendSkillData( pBreakIntoSession );
|
||
SendEtcData( pBreakIntoSession );
|
||
SendSecondAuthInfo( pBreakIntoSession );
|
||
SendMaxLevelCharacterCount( pBreakIntoSession );
|
||
SendHPSP( pBreakIntoSession );
|
||
SendBattleMode( pBreakIntoSession );
|
||
#if !defined( PRE_FIX_BREAKINTO_BLOW_SYNC )
|
||
SendAddStateEffect( pBreakIntoSession );
|
||
#endif // #if !defined( PRE_FIX_BREAKINTO_BLOW_SYNC )
|
||
SendGuildData( pBreakIntoSession );
|
||
SendMasterSystemSimpleInfo( pBreakIntoSession );
|
||
SendMasterSystemCountInfo( pBreakIntoSession );
|
||
#if defined( PRE_ADD_NPC_REPUTATION_SYSTEM )
|
||
SendReputationList( pBreakIntoSession );
|
||
#endif // #if defined( PRE_ADD_NPC_REPUTATION_SYSTEM )
|
||
#if defined (PRE_ADD_BESTFRIEND)
|
||
SendBestFriendData( pBreakIntoSession );
|
||
#endif
|
||
#if defined( PRE_PARTY_DB )
|
||
AddPartyDB( pBreakIntoSession );
|
||
#endif
|
||
#if defined( PRE_ADD_NAMEDITEM_SYSTEM )
|
||
SendPartyEffectSkillItemData(pBreakIntoSession);
|
||
#endif
|
||
#if defined( PRE_ADD_NEWCOMEBACK )
|
||
ApplyJoinMemberAppellation( pBreakIntoSession );
|
||
#endif
|
||
SendCompleteGameReady( pBreakIntoSession ); // 이거 반드시 마지막에 콜해줘야해요.
|
||
if( !pBreakIntoSession )
|
||
{
|
||
m_GameState = bIsFarmRoom() ? _GAME_STATE_FARM_READY2LOAD : _GAME_STATE_SYNC2SYNC;
|
||
|
||
m_iNextGameState = iCurTick + GOGO_SING_TO_PLAY_FOR_WAIT_TIME_LIMIT;
|
||
}
|
||
else
|
||
{
|
||
pBreakIntoSession->SendSeqLevel(m_cSeqLevel);
|
||
}
|
||
}
|
||
|
||
void CDNGameRoom::SetSync2PvPModeStateTemplateMethod(const int iCurTick)
|
||
{
|
||
if (m_VecMember.empty()) //유저가 없을 경우에만 일루 바로 넘어온다
|
||
m_GameState = _GAME_STATE_PVP_SYNC2GAMEMODE;
|
||
}
|
||
|
||
void CDNGameRoom::OnSetPlayState()
|
||
{
|
||
if (m_GameState == _GAME_STATE_DESTROYED) return;
|
||
|
||
m_pGameTask->SetSyncComplete( true );
|
||
m_pPartyTask->RequestPartyMember();
|
||
m_pPartyTask->RequestSyncStart();
|
||
|
||
//g_Log.LogA( _GREEN, "Member : %d\r\n", m_VecMember.size() );
|
||
|
||
__time64_t _tNow, _tOderedTime, _tCloseTime;
|
||
if (g_pCloseSystem)
|
||
{
|
||
_tNow = 0;
|
||
if (g_pCloseSystem->IsClosing(_tOderedTime, _tCloseTime))
|
||
time(&_tNow);
|
||
}
|
||
|
||
TNoticeInfo Notice;
|
||
memset(&Notice, 0, sizeof(Notice));
|
||
|
||
if (g_pNoticeSystem)
|
||
g_pNoticeSystem->GetNotice(0, 0, Notice);
|
||
|
||
for( DNVector(PartyStruct)::iterator itor=m_VecMember.begin() ; itor!=m_VecMember.end() ; ++itor )
|
||
{
|
||
if( (*itor).pSession->GetState() != SESSION_STATE_READY_TO_PLAY )
|
||
continue;
|
||
|
||
(*itor).pSession->SetLoadingComplete( true );
|
||
if( (*itor).pSession->IsConnected() )
|
||
{
|
||
(*itor).pSession->SetSessionState( SESSION_STATE_GAME_PLAY );
|
||
(*itor).pSession->SetSecurityUpdateFlag( true );
|
||
|
||
if (Notice.nCreateTime > 0)
|
||
(*itor).pSession->SendNotice(Notice.wszMsg, (int)wcsnlen(Notice.wszMsg, CHATLENMAX), Notice.TypeInfo.nSlideShowSec);
|
||
|
||
if (_tNow > 0)
|
||
(*itor).pSession->SendCloseService(_tNow, _tOderedTime, _tCloseTime);
|
||
#if defined(PRE_ADD_MISSION_COUPON)
|
||
if( (*itor).pSession->GetExpiredPetID() )
|
||
{
|
||
(*itor).pSession->GetEventSystem()->OnEvent( EventSystem::OnPetExpired, 1, EventSystem::ItemID, (*itor).pSession->GetExpiredPetID() );
|
||
(*itor).pSession->SetExpiredPetID(0);
|
||
}
|
||
#endif
|
||
#if defined(_WORK)
|
||
wstring wszString = FormatW(L"맵 이동 -> ID:[%d]\r\n", (*itor).pSession->GetStatusData()->nMapIndex);
|
||
(*itor).pSession->SendChat(CHATTYPE_NORMAL, (int)wszString.size()*sizeof(WCHAR), L"", (WCHAR*)wszString.c_str());
|
||
#endif
|
||
}
|
||
}
|
||
#ifdef _GPK
|
||
SendGPKCode();
|
||
#endif //#ifdef _GPK
|
||
|
||
#ifdef _USE_PEERCONNECT
|
||
ConnectPeerRequest(); //Peer Connect Request
|
||
#endif
|
||
|
||
UpdateAppliedEventValue();
|
||
|
||
m_GameState = _GAME_STATE_PLAY;
|
||
m_iNextGameState = 0;
|
||
#if defined( STRESS_TEST )
|
||
m_iNextGameState = timeGetTime();
|
||
#endif
|
||
|
||
if( GetMasterRewardSystem() )
|
||
GetMasterRewardSystem()->RequestRefresh();
|
||
|
||
#if defined(PRE_ADD_ACTIVEMISSION)
|
||
if(GetIsFirstInitializeDungeon())
|
||
InitActiveMission();
|
||
#endif
|
||
|
||
#if defined( PRE_WORLDCOMBINE_PVP )
|
||
if(m_nCreateGMAccountDBID > 0)
|
||
{
|
||
int nPvPIndex = (GetWorldPvPRoomDBIndex() % 100) + WorldPvPMissionRoom::Common::GMWorldPvPRoomStartIndex;
|
||
g_pMasterConnectionManager->SendWorldPvPRoomGMCreateResult( GetWorldSetID(), ERROR_NONE, m_nCreateGMAccountDBID, &m_tPvPRoomDBData, nPvPIndex );
|
||
}
|
||
#endif
|
||
|
||
// 패킷을 쌓아두었다 보낼때는 GenerateMonster와 SC_Slave_OF 를 동시에 보내면 , SC_SLAVE_OF 는 바로 보내기때문에 동기가 틀어질수 있다
|
||
// 그래서 올바르게 보낼수있는 시점에 소환수 패킷을 보내도록 설정합니다.
|
||
for( DWORD i=0; i<GetUserCount(); i++ )
|
||
{
|
||
CDNGameRoom::PartyStruct* pPartyMember = GetPartyData( i );
|
||
CDnPlayerActor* pPlayerActor = pPartyMember->pSession->GetPlayerActor();
|
||
if( pPlayerActor )
|
||
pPlayerActor->OnInitializeNextStageFinished();
|
||
}
|
||
}
|
||
|
||
void CDNGameRoom::OnDie( DnActorHandle hActor, DnActorHandle hHitter )
|
||
{
|
||
if (!hActor || !hActor->IsPlayerActor())
|
||
return;
|
||
|
||
// 갖고 있는 스킬들의 쿨타임을 0으로 초기화. (이슈번호 #2422)
|
||
if( hActor )
|
||
hActor->ResetSkillCoolTime();
|
||
|
||
bool bCallMissionEvent = false;
|
||
|
||
// 미션처리
|
||
if( hHitter && hHitter->IsMonsterActor() )
|
||
{
|
||
CDnMonsterActor* pMonster = (CDnMonsterActor *)hHitter.GetPointer();
|
||
|
||
if( hActor )
|
||
{
|
||
CDNUserSession* pSession = GetUserSession( hActor->GetSessionID() );
|
||
if( pSession )
|
||
{
|
||
pSession->GetEventSystem()->OnEvent( EventSystem::OnDie, 1, EventSystem::MonsterID, pMonster->GetMonsterClassID() );
|
||
bCallMissionEvent = true;
|
||
}
|
||
}
|
||
}
|
||
|
||
if( bCallMissionEvent == false && hActor->IsPlayerActor() )
|
||
{
|
||
CDnPlayerActor* pPlayerActor = static_cast<CDnPlayerActor*>(hActor.GetPointer());
|
||
if( pPlayerActor->GetUserSession() )
|
||
pPlayerActor->GetUserSession()->GetEventSystem()->OnEvent( EventSystem::OnDie );
|
||
}
|
||
|
||
//rlkt farm pvp!
|
||
FarmPVP::GetInstance().OnDie(hActor,hHitter);
|
||
|
||
}
|
||
|
||
void CDNGameRoom::OnSuccessBreakInto( CDNUserSession* pGameSession )
|
||
{
|
||
if( !pGameSession )
|
||
return;
|
||
|
||
DnActorHandle hActor = pGameSession->GetActorHandle();
|
||
if( !hActor )
|
||
return;
|
||
|
||
if( pGameSession->bIsGMTrace() )
|
||
{
|
||
hActor->CmdAddStateEffect( NULL, STATE_BLOW::BLOW_071, -1, NULL, true ); // 행동 불가
|
||
}
|
||
|
||
GetWorld()->OnTriggerEventCallback( "CPvPGameMode::OnSuccessBreakInto", 0, 0 );
|
||
}
|
||
|
||
void CDNGameRoom::OnSuccessBreakInto( std::list<CDNUserSession*>::iterator& itor )
|
||
{
|
||
itor = m_BreakIntoUserList.erase( itor );
|
||
}
|
||
|
||
void CDNGameRoom::_BreakIntoProcess()
|
||
{
|
||
if( m_BreakIntoUserList.empty() )
|
||
return;
|
||
|
||
for( std::list<CDNUserSession*>::iterator itor=m_BreakIntoUserList.begin() ; itor!=m_BreakIntoUserList.end() ; )
|
||
{
|
||
if( (*itor)->BreakIntoProcess() )
|
||
{
|
||
OnSuccessBreakInto( itor );
|
||
}
|
||
else
|
||
++itor;
|
||
}
|
||
}
|
||
|
||
void CDNGameRoom::InitEvent()
|
||
{
|
||
m_EventList.clear();
|
||
if( g_pEvent )
|
||
g_pEvent->GetEvent(m_iWorldID, m_iMapIdx, &m_EventList);
|
||
}
|
||
|
||
void CDNGameRoom::OnGameStatePlay(ULONG iCurTick)
|
||
{
|
||
// 난입 프로세스
|
||
UINT uiTick = timeGetTime();
|
||
PROFILE_TIME_TEST( _BreakIntoProcess() );
|
||
if( timeGetTime()-uiTick >= 80 )
|
||
{
|
||
if( GetGameServer()->bIsFrameAlert() )
|
||
{
|
||
g_Log.Log(LogType::_GAMESERVERDELAY, L"[%d] OnGameStatePlay::_BreakIntoProcess() Delay RoomID:%d MapIndex=%d Delay=%d UserCount=%d\n", g_Config.nManagedID, GetRoomID(), m_iMapIdx, timeGetTime()-uiTick, m_BreakIntoUserList.size() );
|
||
if (g_pServiceConnection)
|
||
{
|
||
WCHAR wszBuf[GAMEDELAYSIZE] = {0,};
|
||
wsprintf( wszBuf, L"[%d] OnGameStatePlay::_BreakIntoProcess() Delay RoomID:%d MapIndex=%d Delay=%d UserCount=%d", g_Config.nManagedID, GetRoomID(), m_iMapIdx, timeGetTime()-uiTick, m_BreakIntoUserList.size() );
|
||
g_pServiceConnection->SendGameDelayedReport(wszBuf);
|
||
}
|
||
|
||
// 유저 로그 찍는다
|
||
for( std::list<CDNUserSession*>::iterator itor=m_BreakIntoUserList.begin() ; itor!=m_BreakIntoUserList.end() ; ++itor )
|
||
{
|
||
CDNUserSession* pSession = (*itor);
|
||
if( pSession )
|
||
{
|
||
g_Log.Log(LogType::_GAMESERVERDELAY, L"[%d] OnGameStatePlay::_BreakIntoProcess() Delay RoomID:%d MapIndex=%d CharName=%s JobID=%d UserState=%d\n", g_Config.nManagedID, GetRoomID(), m_iMapIdx, pSession->GetCharacterName(), (int)pSession->GetUserJob(), pSession->GetState() );
|
||
if (g_pServiceConnection)
|
||
{
|
||
WCHAR wszBuf[GAMEDELAYSIZE] = {0,};
|
||
wsprintf( wszBuf, L"[%d] OnGameStatePlay::_BreakIntoProcess() Delay RoomID:%d MapIndex=%d CharName=%s JobID=%d UserState=%d", g_Config.nManagedID, GetRoomID(), m_iMapIdx, pSession->GetCharacterName(), (int)pSession->GetUserJob(), pSession->GetState());
|
||
g_pServiceConnection->SendGameDelayedReport(wszBuf);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// TaskMng 프로세스
|
||
if( m_pTaskMng )
|
||
{
|
||
bool bResult;
|
||
PROFILE_TIME_TEST_BLOCK_START( "m_pTaskMng->Excute()" );
|
||
bResult = m_pTaskMng->Excute();
|
||
PROFILE_TIME_TEST_BLOCK_END();
|
||
if( !bResult )
|
||
OutputDebug( "Finalize Task\n" );
|
||
}
|
||
if( !m_vChangeMapQueue.empty() )
|
||
{
|
||
int iMapIndex = m_vChangeMapQueue.begin()->first;
|
||
int iGateNo = m_vChangeMapQueue.begin()->second;
|
||
m_vChangeMapQueue.clear();
|
||
m_pGameTask->RequestChangeMap( iMapIndex, static_cast<char>(iGateNo) );
|
||
}
|
||
FarmUpdate();
|
||
}
|
||
|
||
#ifdef _USE_VOICECHAT
|
||
void CDNGameRoom::OnInitVoice()
|
||
{
|
||
for( UINT i=0 ; i<m_VecMember.size() ; ++i )
|
||
{
|
||
if (m_VecMember[i].pSession->IsConnected())
|
||
m_VecMember[i].pSession->MakeMute();
|
||
}
|
||
}
|
||
#endif
|
||
|
||
void CDNGameRoom::OnDelPartyMember( UINT iDelMemberSessionID, char cKickKind )
|
||
{
|
||
// 운영자 난입했을 경우엔 REQINFO_TYPE_SINGLE 이지만 OnDelPartyMember() 호출된다.
|
||
// SwapLeader 에서 필터링 되므로 아래 주석처리 함. by 김밥
|
||
//if (m_cReqGameIDType == REQINFO_TYPE_SINGLE) return; //싱글이면 보내면 안데요.
|
||
|
||
UINT nNewLeaderSessionID = 0;
|
||
if (m_cReqGameIDType == REQINFO_TYPE_PARTY) //파티인경우에만 새로운리더가 필요함
|
||
{
|
||
bool bRet = SwapLeader( iDelMemberSessionID, nNewLeaderSessionID );
|
||
if (bRet == false) return; //이미 나가신 분입니다.
|
||
}
|
||
|
||
if( m_pTaskMng )
|
||
{
|
||
CDnPartyTask* pPartyTask = (CDnPartyTask*)(m_pTaskMng->GetTask("PartyTask"));
|
||
if( pPartyTask )
|
||
pPartyTask->OutPartyMember( iDelMemberSessionID, nNewLeaderSessionID, cKickKind );
|
||
}
|
||
}
|
||
|
||
void CDNGameRoom::OnRequestSyncStartMsg( CDNUserSession* pGameSession )
|
||
{
|
||
SendGameSyncStart( pGameSession );
|
||
if( pGameSession && pGameSession->GetTimeEventSystem() )
|
||
pGameSession->GetTimeEventSystem()->RequestSyncTimeEvent();
|
||
}
|
||
|
||
|
||
#if defined( STRESS_TEST )
|
||
|
||
void CDNGameRoom::OrgProcess()
|
||
{
|
||
#ifdef _FINAL_BUILD
|
||
__try {
|
||
#endif
|
||
|
||
//게임룸의 메인프로세스! 게임룸단에서 프로세스 호출시에는 동기화 없음!
|
||
unsigned long iCurTick = GetGameTick();
|
||
|
||
UserUpdate( iCurTick );
|
||
CheckRemovedMember();
|
||
CheckRudpDisconnectedMember();
|
||
|
||
switch (m_GameState)
|
||
{
|
||
case _GAME_STATE_READY2CONNECT:
|
||
{
|
||
int iConnectedCnt = 0;
|
||
|
||
/*PartyStruct * pStruct = &m_VecMember[100];
|
||
TUserData * pData = pStruct->pSession->GetUserData();
|
||
pData->Attribute.nExp = 1000;*/
|
||
|
||
for( UINT i=0 ; i<m_VecMember.size() ; ++i )
|
||
if (m_VecMember[i].pSession->IsConnected())
|
||
iConnectedCnt++;
|
||
|
||
if (m_iPartMemberCnt == iConnectedCnt)
|
||
{
|
||
m_GameState = _GAME_STATE_CONNECT2LOAD; //다음 스테이트로 이동합니다.
|
||
m_iNextGameState = 0;
|
||
break;
|
||
}
|
||
|
||
#if defined( PRE_WORLDCOMBINE_PARTY )
|
||
#if defined( PRE_WORLDCOMBINE_PVP )
|
||
if (iConnectedCnt == 0 && bIsWorldCombineParty() == false && bIsWorldPvPRoom() == false )
|
||
#else // #if defined( PRE_WORLDCOMBINE_PVP )
|
||
if (iConnectedCnt == 0 && bIsWorldCombineParty() == false )
|
||
#endif // #if defined( PRE_WORLDCOMBINE_PVP )
|
||
#else // #if defined( PRE_WORLDCOMBINE_PARTY )
|
||
if (iConnectedCnt == 0)
|
||
#endif // #if defined( PRE_WORLDCOMBINE_PARTY )
|
||
{
|
||
if (iCurTick > (GetPartyIndex() <= 0 ? RUDP_CONNECT_TIME_LIMIT_FOR_SINGLE : RUDP_CONNECT_TIME_LIMIT_FOR_PARTY))
|
||
{
|
||
g_Log.Log(LogType::_NORMAL, L"Destroy|READY2CONNECT\n");
|
||
//정상적인 인원이 전혀없고 리밋타임이 넘어가면 방은 삭제상태로 된다 (상위프로세스에서 삭제됨)
|
||
DestroyGameRoom();
|
||
}
|
||
break;
|
||
}
|
||
|
||
if (m_iNextGameState == 0) //한명이라도 접속이 되었다. 일정 시간동안 기다린다.
|
||
m_iNextGameState = iCurTick + WAIT_FOR_ANOTHER_USER_TIME_LIMIT;
|
||
|
||
if (iConnectedCnt != 0 && iCurTick > m_iNextGameState)
|
||
{
|
||
m_GameState = _GAME_STATE_CONNECT2LOAD; //다음 스테이트로 이동합니다.
|
||
m_iNextGameState = 0;
|
||
}
|
||
break;
|
||
}
|
||
|
||
case _GAME_STATE_CONNECT2LOAD:
|
||
{
|
||
if (m_iNextGameState == 0)
|
||
{
|
||
for( UINT i=0 ; i<m_VecMember.size() ; ++i )
|
||
{
|
||
if (m_VecMember[i].pSession->IsConnected() == false)
|
||
{
|
||
g_Log.Log(LogType::_ERROR, m_VecMember[i].pSession, L"Connect|Connection Fail AID[%d] SID[%d] CID[%I64d]\n", m_VecMember[i].pSession->GetAccountDBID(), m_VecMember[i].pSession->GetSessionID(), m_VecMember[i].pSession->GetCharacterDBID());
|
||
m_VecMember[i].pSession->DetachConnection( L"" ); //아직까지 연결되지 않은 청년들은 짤라줍니다.
|
||
}
|
||
}
|
||
|
||
CheckRemovedMember();
|
||
OnInitGameRoomUser();
|
||
m_iNextGameState = iCurTick + WAIT_FOR_LOAD_TIME_LIMIT;
|
||
}
|
||
|
||
int iLoadedUser = 0;
|
||
for( UINT i=0 ; i<m_VecMember.size() ; ++i )
|
||
if (m_VecMember[i].pSession->GetState() == SESSION_STATE_LOADED)
|
||
iLoadedUser++;
|
||
|
||
if (m_iPartMemberCnt == iLoadedUser)
|
||
{
|
||
OnSetLoad2SyncState( iCurTick );
|
||
break;
|
||
}
|
||
|
||
#if defined( PRE_WORLDCOMBINE_PARTY )
|
||
#if defined( PRE_WORLDCOMBINE_PVP )
|
||
if (iLoadedUser == 0 && bIsWorldCombineParty() == false && bIsWorldPvPRoom() == false )
|
||
#else // #if defined( PRE_WORLDCOMBINE_PVP )
|
||
if (iLoadedUser == 0 && bIsWorldCombineParty() == false )
|
||
#endif // #if defined( PRE_WORLDCOMBINE_PVP )
|
||
#else
|
||
if (iLoadedUser == 0)
|
||
#endif
|
||
{
|
||
if (iCurTick > m_iNextGameState)
|
||
{
|
||
g_Log.Log(LogType::_ERROR, L"Destroy|CONNECT2LOAD\n");
|
||
//정상적인 인원이 전혀없고 리밋타임이 넘어가면 방은 삭제상태로 된다 (상위프로세스에서 삭제됨)
|
||
DestroyGameRoom();
|
||
}
|
||
break;
|
||
}
|
||
|
||
if (iLoadedUser != 0 && iCurTick > m_iNextGameState)
|
||
{
|
||
for( UINT i=0 ; i<m_VecMember.size() ; ++i )
|
||
{
|
||
if (m_VecMember[i].pSession->GetState() != SESSION_STATE_LOADED)
|
||
{
|
||
g_Log.Log(LogType::_ERROR, m_VecMember[i].pSession, L"Connect|Load Fail AID[%d] SID[%d] CID[%I64d]\n", m_VecMember[i].pSession->GetAccountDBID(), m_VecMember[i].pSession->GetSessionID(), m_VecMember[i].pSession->GetCharacterDBID());
|
||
m_VecMember[i].pSession->DetachConnection( L"" ); //아직까지 연결되지 않은 청년들은 짤라줍니다.
|
||
}
|
||
}
|
||
|
||
OnSetLoad2SyncState( iCurTick );
|
||
}
|
||
break;
|
||
}
|
||
|
||
case _GAME_STATE_LOAD2SYNC:
|
||
{
|
||
int iReadyUserCnt = 0;
|
||
for( UINT i=0 ; i<m_VecMember.size() ; ++i )
|
||
if (m_VecMember[i].pSession->GetState() == SESSION_STATE_READY_TO_SYNC)
|
||
iReadyUserCnt++;
|
||
|
||
if (m_iPartMemberCnt == iReadyUserCnt)
|
||
{
|
||
SetSync2SyncStateTemplateMethod( iCurTick );
|
||
break;
|
||
}
|
||
|
||
#if defined( PRE_WORLDCOMBINE_PARTY )
|
||
#if defined( PRE_WORLDCOMBINE_PVP )
|
||
if (iReadyUserCnt == 0 && bIsWorldCombineParty() == false && bIsWorldPvPRoom() == false )
|
||
#else // #if defined( PRE_WORLDCOMBINE_PVP )
|
||
if (iReadyUserCnt == 0 && bIsWorldCombineParty() == false )
|
||
#endif // #if defined( PRE_WORLDCOMBINE_PVP )
|
||
#else
|
||
if (iReadyUserCnt == 0)
|
||
#endif
|
||
{
|
||
if (iCurTick > m_iNextGameState)
|
||
{
|
||
g_Log.Log(LogType::_ERROR, L"Destroy|LOAD2SYNC\n");
|
||
//정상적인 인원이 전혀없고 리밋타임이 넘어가면 방은 삭제상태로 된다 (상위프로세스에서 삭제됨)
|
||
DestroyGameRoom();
|
||
}
|
||
break;
|
||
}
|
||
|
||
if (iReadyUserCnt != 0 && iCurTick > m_iNextGameState)
|
||
{
|
||
for( UINT i=0 ; i<m_VecMember.size() ; ++i )
|
||
{
|
||
if (m_VecMember[i].pSession->GetState() != SESSION_STATE_READY_TO_SYNC)
|
||
{
|
||
g_Log.Log(LogType::_ERROR, m_VecMember[i].pSession, L"Connect|Load Sync Fail AID[%d] SID[%d] CID[%I64d]\n", m_VecMember[i].pSession->GetAccountDBID(), m_VecMember[i].pSession->GetSessionID(), m_VecMember[i].pSession->GetCharacterDBID());
|
||
m_VecMember[i].pSession->DetachConnection( L"" ); //아직까지 연결되지 않은 청년들은 짤라줍니다.
|
||
}
|
||
}
|
||
|
||
//요 타이밍에 로드쓰레드와의 간섭이 발생할 수 있으므로 체킹해서 진짜로 자른뒤에 로드 시작하자
|
||
CheckRemovedMember();
|
||
if (m_GameState != _GAME_STATE_DESTROYED) //혹시나 하는 마음에...
|
||
SetSync2SyncStateTemplateMethod( iCurTick );
|
||
else
|
||
_DANGER_POINT();
|
||
}
|
||
break;
|
||
}
|
||
|
||
case _GAME_STATE_SYNC2SYNC:
|
||
{
|
||
if (g_pBackLoader->IsLoaded(m_iRoomID) == true)
|
||
{
|
||
if (g_pBackLoader->LoadConfirm(m_iRoomID) == false)
|
||
{
|
||
g_Log.Log(LogType::_ERROR, L"Destroy|DataLoad Failed CheckOut ResourceData roomID [%d]\n", m_iRoomID);
|
||
DestroyGameRoom();
|
||
break;
|
||
}
|
||
|
||
SyncProp( NULL );
|
||
|
||
m_pWorld->EnableTriggerEventCallback(true);
|
||
m_pWorld->OnTriggerEventCallback( "CDnGameTask::PostInitializeStage", 0, 0.f, false );
|
||
m_pWorld->EnableTriggerEventCallback(false);
|
||
|
||
m_GameState = _GAME_STATE_SYNC2PLAY;
|
||
break;
|
||
}
|
||
|
||
if (iCurTick > m_iNextGameState)
|
||
{
|
||
g_Log.Log(LogType::_ERROR, L"Destroy|Delay Load SYNC2SYNC\n");
|
||
//정상적인 인원이 전혀없고 리밋타임이 넘어가면 방은 삭제상태로 된다 (상위프로세스에서 삭제됨)
|
||
DestroyGameRoom();
|
||
m_iNextGameState = 0;
|
||
break;
|
||
}
|
||
break;
|
||
}
|
||
|
||
case _GAME_STATE_SYNC2PLAY:
|
||
{
|
||
int iConnectedCnt = 0;
|
||
for( UINT i=0 ; i<m_VecMember.size() ; ++i )
|
||
{
|
||
if (m_VecMember[i].pSession->IsConnected() && m_VecMember[i].pSession->GetState() == SESSION_STATE_SYNC_READY_2_DELAY)
|
||
{
|
||
m_VecMember[i].pSession->FlushStoredPacket();
|
||
m_VecMember[i].pSession->FlushPacketQueue();
|
||
for( UINT i2=0 ; i2<m_VecMember.size() ; ++i2 )
|
||
SendGameSyncWait( m_VecMember[i2].pSession, m_VecMember[i2].pSession->GetSessionID() );
|
||
m_VecMember[i].pSession->SetSessionState(SESSION_STATE_READY_TO_PLAY);
|
||
}
|
||
|
||
if (m_VecMember[i].pSession->IsConnected() && m_VecMember[i].pSession->GetState() == SESSION_STATE_READY_TO_PLAY)
|
||
iConnectedCnt++;
|
||
}
|
||
|
||
if (m_iPartMemberCnt == iConnectedCnt)
|
||
{
|
||
OnSetPlayState();
|
||
break;
|
||
}
|
||
|
||
#if defined( PRE_WORLDCOMBINE_PARTY )
|
||
#if defined( PRE_WORLDCOMBINE_PVP )
|
||
if (iConnectedCnt == 0 && bIsWorldCombineParty() == false && bIsWorldPvPRoom() == false )
|
||
#else // #if defined( PRE_WORLDCOMBINE_PVP )
|
||
if (iConnectedCnt == 0 && bIsWorldCombineParty() == false )
|
||
#endif // #if defined( PRE_WORLDCOMBINE_PVP )
|
||
#else
|
||
if (iConnectedCnt == 0)
|
||
#endif
|
||
{
|
||
if (iCurTick > m_iNextGameState)
|
||
{
|
||
g_Log.Log(LogType::_ERROR, L"Destroy|SYNC2PLAY\n");
|
||
//정상적인 인원이 전혀없고 리밋타임이 넘어가면 방은 삭제상태로 된다 (상위프로세스에서 삭제됨)
|
||
DestroyGameRoom();
|
||
}
|
||
break;
|
||
}
|
||
|
||
if (iCurTick > m_iNextGameState)
|
||
{
|
||
for( UINT i=0 ; i<m_VecMember.size() ; ++i )
|
||
{
|
||
if (m_VecMember[i].pSession->GetState() != SESSION_STATE_READY_TO_PLAY)
|
||
{
|
||
g_Log.Log(LogType::_ERROR, m_VecMember[i].pSession, L"Connect|Sync Fail AID[%d] SID[%d] CID[%I64d]\n", m_VecMember[i].pSession->GetAccountDBID(), m_VecMember[i].pSession->GetSessionID(), m_VecMember[i].pSession->GetCharacterDBID());
|
||
m_VecMember[i].pSession->DetachConnection( L"" ); //아직까지 처리되지 않은 청년들은 짤라줍니다.
|
||
}
|
||
}
|
||
|
||
CheckRemovedMember();
|
||
OnSetPlayState();
|
||
break;
|
||
}
|
||
break;
|
||
}
|
||
|
||
case _GAME_STATE_CANCEL_LOADING:
|
||
{
|
||
if (g_pBackLoader->LoadCancel(m_iRoomID))
|
||
m_GameState = _GAME_STATE_DESTROYED;
|
||
break;
|
||
}
|
||
|
||
case _GAME_STATE_PLAY:
|
||
{
|
||
OnGameStatePlay(iCurTick);
|
||
break;
|
||
}
|
||
}
|
||
|
||
/*
|
||
Windows SEH 까지 예외로 받을수 있도록
|
||
Enable C++ Exceptions 항목을 /EHa 옵션으로 컴파일 하도록 한다.
|
||
*/
|
||
#ifdef _FINAL_BUILD
|
||
} // __try {
|
||
__except(CExceptionReport::GetInstancePtr()->Proc(GetExceptionInformation(), MiniDumpNormal)) {
|
||
{
|
||
// 룸 process 시 예외가 발생 하면 게임룸만 닫도록 처리 한다.
|
||
g_Log.Log(LogType::_ROOMCRASH, L"[%d] Destroy|Process Crash RoomID=%d RoomState=%d\n", g_Config.nManagedID, m_iRoomID, m_GameState );
|
||
if (g_pBackLoader)
|
||
{
|
||
//for( UINT i=0 ; i<m_VecMember.size() ; ++i )
|
||
// m_VecMember[i].pSession->SetSessionState(SESSION_STATE_CRASH);
|
||
DestroyGameRoom();
|
||
}
|
||
|
||
//예외가 발생하면 SM에게 예외발생을 알린다.
|
||
#if !defined (_TH)
|
||
if (g_pServiceConnection)
|
||
g_pServiceConnection->SendDetectException(_EXCEPTIONTYPE_ROOMCRASH);
|
||
#endif // #if !defined (_TH)
|
||
}
|
||
#endif
|
||
}
|
||
|
||
#endif
|
||
|
||
void CDNGameRoom::DestroyGameRoom(bool bForce/* = false*/)
|
||
{
|
||
if (g_pBackLoader->LoadCancel(m_iRoomID) == false)
|
||
m_GameState = _GAME_STATE_CANCEL_LOADING;
|
||
else
|
||
{
|
||
if (bForce == false) //강제가 아니면 체크해본다
|
||
{
|
||
// 난입하는 유저가 있다면 방을 파괴하지 않는다.
|
||
//룸크래쉬면 난입있어도 죽인다
|
||
if( IsRoomCrash() == false && bIsExistBreakIntoUser() )
|
||
return;
|
||
}
|
||
|
||
m_GameState = _GAME_STATE_DESTROYED;
|
||
}
|
||
}
|
||
|
||
void CDNGameRoom::FinalizeProcess()
|
||
{
|
||
for( UINT i=0 ; i<m_VecMember.size() ; ++i )
|
||
{
|
||
#ifdef _FINAL_BUILD
|
||
__try
|
||
{
|
||
#endif // #ifdef _FINAL_BUILD
|
||
|
||
m_VecMember[i].pSession->FinalUser();
|
||
GetGameServer()->RemoveConnection(GetRoomID(), m_VecMember[i].pSession->GetNetID(), m_VecMember[i].pSession->GetAccountDBID(), m_VecMember[i].pSession->GetSessionID());
|
||
|
||
m_VecMember[i].ReleaseEquipInventory();
|
||
|
||
#ifdef _FINAL_BUILD
|
||
} // __try {
|
||
__except(CExceptionReport::GetInstancePtr()->Proc(GetExceptionInformation(), MiniDumpNormal))
|
||
{
|
||
m_bRoomCrash = true;
|
||
m_VecMember[i].pSession->SetSessionState(SESSION_STATE_DISCONNECTED);
|
||
g_Log.Log( LogType::_ROOMFINALIZECRASH, L"[%d] FinalizeProcess Crash RoomID=%d\n", g_Config.nManagedID, m_iRoomID );
|
||
}
|
||
#endif // #ifdef _FINAL_BUILD
|
||
}
|
||
|
||
m_DeleteList.clear();
|
||
m_VecMember.clear();
|
||
#if defined( PRE_FIX_49129 )
|
||
m_MapFirstPartyMember.clear();
|
||
#endif
|
||
}
|
||
|
||
void CDNGameRoom::_DeleteSession()
|
||
{
|
||
for( UINT i=0 ; i<m_vDeleteSession.size() ; ++i )
|
||
{
|
||
SAFE_DELETE( m_vDeleteSession[i] );
|
||
}
|
||
m_vDeleteSession.clear();
|
||
}
|
||
|
||
void CDNGameRoom::Process()
|
||
{
|
||
//#ifdef _FINAL_BUILD
|
||
__try {
|
||
//#endif
|
||
|
||
#if defined( STRESS_TEST )
|
||
if( m_cReqGameIDType == REQINFO_TYPE_PARTY )
|
||
return OrgProcess();
|
||
#endif
|
||
|
||
//게임룸의 메인프로세스! 게임룸단에서 프로세스 호출시에는 동기화 없음!
|
||
unsigned long iCurTick = GetGameTick();
|
||
unsigned long iCurTick2 = timeGetTime();
|
||
|
||
_DeleteSession();
|
||
UserUpdate( iCurTick2 );
|
||
CheckRemovedMember();
|
||
CheckRudpDisconnectedMember();
|
||
#ifdef _USE_VOICECHAT
|
||
TalkingUpdate(iCurTick2);
|
||
#endif
|
||
if (bIsGuildWarSystem() && m_VecMember.empty())
|
||
{
|
||
if (GetPvPGameMode() && GetPvPGameMode()->bIsFinishFlag())
|
||
DestroyGameRoom();
|
||
}
|
||
|
||
if (m_nEventRoomIndex > 0 &&
|
||
(iCurTick > 1000 * 60 * 60) && // 1시간 초과시
|
||
!m_bCheckTick)
|
||
{
|
||
m_bCheckTick = true;
|
||
g_Log.Log(LogType::_PVPROOM, L"PVP OverTime [Index:%d][Room:%d][Event:%d][User:%d][Break:%d][Vec:%d][MID:%d][State:%d] \r\n",
|
||
GetPvPIndex(), GetRoomID(), m_nEventRoomIndex, m_UserList.size(), m_BreakIntoUserList.size(), m_VecMember.size(), g_Config.nManagedID, m_GameState);
|
||
|
||
for( m_ItorSession=m_BreakIntoUserList.begin() ; m_ItorSession!=m_BreakIntoUserList.end() ; ++m_ItorSession )
|
||
{
|
||
CDNUserSession* pSession = (*m_ItorSession);
|
||
if (pSession)
|
||
g_Log.Log(LogType::_PVPROOM, L"PVP OverTime MemberInfo [CHRID:%d][State:%d]\r\n", pSession->GetCharacterDBID(), pSession->GetState());
|
||
}
|
||
|
||
m_GameState = _GAME_STATE_DESTROYED; // 방파괴를 진행합니다.
|
||
}
|
||
|
||
switch (m_GameState)
|
||
{
|
||
case _GAME_STATE_READY2CONNECT:
|
||
{
|
||
int iConnectedCnt = 0;
|
||
|
||
/*PartyStruct * pStruct = &m_VecMember[100];
|
||
TUserData * pData = pStruct->pSession->GetUserData();
|
||
pData->Attribute.nExp = 1000;*/
|
||
|
||
for( UINT i=0 ; i<m_VecMember.size() ; ++i )
|
||
if (m_VecMember[i].pSession->IsConnected())
|
||
iConnectedCnt++;
|
||
|
||
#if defined( STRESS_TEST )
|
||
if(true)
|
||
#else
|
||
if (m_iPartMemberCnt == iConnectedCnt)
|
||
#endif
|
||
{
|
||
m_GameState = _GAME_STATE_CONNECT2CHECKAUTH; //다음 스테이트로 이동합니다.
|
||
m_iNextGameState = timeGetTime();
|
||
#ifdef _USE_VOICECHAT
|
||
OnInitVoice();
|
||
#endif
|
||
break;
|
||
}
|
||
|
||
#if defined( PRE_WORLDCOMBINE_PARTY )
|
||
#if defined( PRE_WORLDCOMBINE_PVP )
|
||
if (iConnectedCnt == 0 && bIsWorldCombineParty() == false && bIsWorldPvPRoom() == false )
|
||
#else // #if defined( PRE_WORLDCOMBINE_PVP )
|
||
if (iConnectedCnt == 0 && bIsWorldCombineParty() == false )
|
||
#endif // #if defined( PRE_WORLDCOMBINE_PVP )
|
||
#else // #if defined( PRE_WORLDCOMBINE_PARTY )
|
||
if (iConnectedCnt == 0)
|
||
#endif // #if defined( PRE_WORLDCOMBINE_PARTY )
|
||
{
|
||
if (iCurTick > (GetPartyIndex() <= 0 ? RUDP_CONNECT_TIME_LIMIT_FOR_SINGLE : RUDP_CONNECT_TIME_LIMIT_FOR_PARTY))
|
||
{
|
||
g_Log.Log(LogType::_NORMAL, L"Destroy|READY2CONNECT\n");
|
||
//정상적인 인원이 전혀없고 리밋타임이 넘어가면 방은 삭제상태로 된다 (상위프로세스에서 삭제됨)
|
||
DestroyGameRoom();
|
||
}
|
||
break;
|
||
}
|
||
|
||
if (m_iNextGameState == 0) //한명이라도 접속이 되었다. 일정 시간동안 기다린다.
|
||
m_iNextGameState = iCurTick + WAIT_FOR_ANOTHER_USER_TIME_LIMIT;
|
||
|
||
if (iConnectedCnt != 0 && iCurTick > m_iNextGameState)
|
||
{
|
||
m_GameState = _GAME_STATE_CONNECT2CHECKAUTH; //다음 스테이트로 이동합니다.
|
||
m_iNextGameState = timeGetTime();
|
||
|
||
#ifdef _USE_VOICECHAT
|
||
OnInitVoice();
|
||
#endif
|
||
|
||
//다음스테이트 이동전에 한번 걸러내 줍니다.
|
||
for( UINT i=0 ; i<m_VecMember.size() ; ++i )
|
||
{
|
||
if (m_VecMember[i].pSession->IsConnected() == false)
|
||
{
|
||
g_Log.Log(LogType::_GAMECONNECTLOG, m_VecMember[i].pSession, L"Connect|Connection Fail\n" );
|
||
g_Log.Log(LogType::_ERROR, m_VecMember[i].pSession, L"Connect|Connection Fail AID[%d] SID[%d] CID[%I64d]\n", m_VecMember[i].pSession->GetAccountDBID(), m_VecMember[i].pSession->GetSessionID(), m_VecMember[i].pSession->GetCharacterDBID());
|
||
m_VecMember[i].pSession->DetachConnection(L"_GAME_STATE_READY2CONNECT"); //아직까지 연결되지 않은 청년들은 짤라줍니다.
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
|
||
case _GAME_STATE_CONNECT2CHECKAUTH:
|
||
{
|
||
int iCertifiedCnt = 0;
|
||
|
||
for( UINT i=0 ; i<m_VecMember.size() ; ++i ) {
|
||
if (false == m_VecMember[i].pSession->IsConnected()) {
|
||
continue;
|
||
}
|
||
if (true == m_VecMember[i].pSession->IsCertified()) {
|
||
++iCertifiedCnt;
|
||
}
|
||
}
|
||
|
||
#if defined( STRESS_TEST )
|
||
if( true ) {
|
||
#else
|
||
if (m_iPartMemberCnt == iCertifiedCnt) {
|
||
#endif
|
||
m_GameState = _GAME_STATE_CONNECT2LOAD; //다음 스테이트로 이동합니다.
|
||
m_iNextGameState = 0;
|
||
break;
|
||
}
|
||
|
||
#if defined( PRE_WORLDCOMBINE_PARTY )
|
||
#if defined( PRE_WORLDCOMBINE_PVP )
|
||
if (0 == iCertifiedCnt && bIsWorldCombineParty() == false && bIsWorldPvPRoom() == false) {
|
||
#else // #if defined( PRE_WORLDCOMBINE_PVP )
|
||
if (0 == iCertifiedCnt && bIsWorldCombineParty() == false ) {
|
||
#endif // #if defined( PRE_WORLDCOMBINE_PVP )
|
||
#else // #if defined( PRE_WORLDCOMBINE_PARTY )
|
||
if (0 == iCertifiedCnt) {
|
||
#endif // #if defined( PRE_WORLDCOMBINE_PARTY )
|
||
if (CHECKAUTHLIMITTERM < GetTickTerm(m_iNextGameState, iCurTick2)) {
|
||
g_Log.Log(LogType::_NORMAL, L"Destroy|CONNECT2CHECKAUTH\n");
|
||
//정상적인 인원이 전혀없고 리밋타임이 넘어가면 방은 삭제상태로 된다 (상위프로세스에서 삭제됨)
|
||
DestroyGameRoom();
|
||
}
|
||
break;
|
||
}
|
||
|
||
if (0 < iCertifiedCnt &&
|
||
CHECKAUTHLIMITTERM < GetTickTerm(m_iNextGameState, iCurTick2))
|
||
{
|
||
//다음스테이트로 이동전에 인증처리 안된녀석을 잘라주는 처리 추가
|
||
for( UINT i=0 ; i<m_VecMember.size() ; ++i )
|
||
{
|
||
if (m_VecMember[i].pSession->IsCertified() != true)
|
||
{
|
||
g_Log.Log(LogType::_ERROR, m_VecMember[i].pSession, L"Connect|Certified Fail AID[%d] SID[%d] CID[%I64d]\n", m_VecMember[i].pSession->GetAccountDBID(), m_VecMember[i].pSession->GetSessionID(), m_VecMember[i].pSession->GetCharacterDBID());
|
||
m_VecMember[i].pSession->DetachConnection(L"_GAME_STATE_CONNECT2CHECKAUTH"); //아직까지 인즐처리 되지 않은 친구들은 잘라줍니다.
|
||
}
|
||
}
|
||
|
||
m_GameState = _GAME_STATE_CONNECT2LOAD; //다음 스테이트로 이동합니다.
|
||
m_iNextGameState = 0;
|
||
}
|
||
break;
|
||
}
|
||
break;
|
||
|
||
case _GAME_STATE_CONNECT2LOAD:
|
||
{
|
||
if (m_iNextGameState == 0)
|
||
{
|
||
#if !defined( STRESS_TEST )
|
||
for( UINT i=0 ; i<m_VecMember.size() ; ++i )
|
||
{
|
||
if (m_VecMember[i].pSession->IsConnected() == false)
|
||
{
|
||
g_Log.Log(LogType::_ERROR, m_VecMember[i].pSession, L"Connect|Connection Fail AID[%d] SID[%d] CID[%I64d]\n", m_VecMember[i].pSession->GetAccountDBID(), m_VecMember[i].pSession->GetSessionID(), m_VecMember[i].pSession->GetCharacterDBID());
|
||
m_VecMember[i].pSession->DetachConnection(L"_GAME_STATE_CONNECT2LOAD"); //아직까지 연결되지 않은 청년들은 짤라줍니다.
|
||
}
|
||
}
|
||
#endif
|
||
|
||
CheckRemovedMember();
|
||
OnInitGameRoomUser();
|
||
m_iNextGameState = iCurTick + WAIT_FOR_LOAD_TIME_LIMIT;
|
||
}
|
||
|
||
int iLoadedUser = 0;
|
||
for( UINT i=0 ; i<m_VecMember.size() ; ++i )
|
||
if (m_VecMember[i].pSession->GetState() == SESSION_STATE_LOADED)
|
||
iLoadedUser++;
|
||
|
||
#if defined( STRESS_TEST )
|
||
if( true )
|
||
#else
|
||
if (m_iPartMemberCnt == iLoadedUser)
|
||
#endif
|
||
{
|
||
OnSetLoad2SyncState( iCurTick );
|
||
break;
|
||
}
|
||
|
||
#if defined( PRE_WORLDCOMBINE_PARTY )
|
||
#if defined( PRE_WORLDCOMBINE_PVP )
|
||
if (iLoadedUser == 0 && bIsWorldCombineParty() == false && bIsWorldPvPRoom() == false )
|
||
#else // #if defined( PRE_WORLDCOMBINE_PVP )
|
||
if (iLoadedUser == 0 && bIsWorldCombineParty() == false )
|
||
#endif // #if defined( PRE_WORLDCOMBINE_PVP )
|
||
#else // #if defined( PRE_WORLDCOMBINE_PARTY )
|
||
if (iLoadedUser == 0)
|
||
#endif // #if defined( PRE_WORLDCOMBINE_PARTY )
|
||
{
|
||
if (iCurTick > m_iNextGameState)
|
||
{
|
||
g_Log.Log(LogType::_NORMAL, L"Destroy|CONNECT2LOAD\n");
|
||
//정상적인 인원이 전혀없고 리밋타임이 넘어가면 방은 삭제상태로 된다 (상위프로세스에서 삭제됨)
|
||
DestroyGameRoom();
|
||
}
|
||
break;
|
||
}
|
||
|
||
if (iLoadedUser != 0 && iCurTick > m_iNextGameState)
|
||
{
|
||
for( UINT i=0 ; i<m_VecMember.size() ; ++i )
|
||
{
|
||
if (m_VecMember[i].pSession->GetState() != SESSION_STATE_LOADED)
|
||
{
|
||
g_Log.Log(LogType::_ERROR, m_VecMember[i].pSession, L"Connect|Load Fail AID[%d] SID[%d] CID[%I64d]\n", m_VecMember[i].pSession->GetAccountDBID(), m_VecMember[i].pSession->GetSessionID(), m_VecMember[i].pSession->GetCharacterDBID());
|
||
m_VecMember[i].pSession->DetachConnection(L"_GAME_STATE_CONNECT2LOAD"); //아직까지 연결되지 않은 청년들은 짤라줍니다.
|
||
}
|
||
}
|
||
|
||
OnSetLoad2SyncState( iCurTick );
|
||
}
|
||
break;
|
||
}
|
||
|
||
case _GAME_STATE_LOAD2SYNC:
|
||
{
|
||
int iReadyUserCnt = 0;
|
||
for( UINT i=0 ; i<m_VecMember.size() ; ++i )
|
||
if (m_VecMember[i].pSession->GetState() == SESSION_STATE_READY_TO_SYNC)
|
||
iReadyUserCnt++;
|
||
|
||
#if defined( STRESS_TEST )
|
||
if( true )
|
||
#else
|
||
if (m_iPartMemberCnt == iReadyUserCnt)
|
||
#endif
|
||
{
|
||
SetSync2SyncStateTemplateMethod( iCurTick );
|
||
break;
|
||
}
|
||
|
||
#if defined( PRE_WORLDCOMBINE_PARTY )
|
||
#if defined( PRE_WORLDCOMBINE_PVP )
|
||
if (iReadyUserCnt == 0 && bIsWorldCombineParty() == false && bIsWorldPvPRoom() == false)
|
||
#else // #if defined( PRE_WORLDCOMBINE_PVP )
|
||
if (iReadyUserCnt == 0 && bIsWorldCombineParty() == false )
|
||
#endif // #if defined( PRE_WORLDCOMBINE_PVP )
|
||
#else // #if defined( PRE_WORLDCOMBINE_PARTY )
|
||
if (iReadyUserCnt == 0)
|
||
#endif // #if defined( PRE_WORLDCOMBINE_PARTY )
|
||
{
|
||
if (iCurTick > m_iNextGameState)
|
||
{
|
||
g_Log.Log(LogType::_NORMAL, L"Destroy|LOAD2SYNC\n");
|
||
//정상적인 인원이 전혀없고 리밋타임이 넘어가면 방은 삭제상태로 된다 (상위프로세스에서 삭제됨)
|
||
DestroyGameRoom();
|
||
}
|
||
break;
|
||
}
|
||
|
||
if (iReadyUserCnt != 0 && iCurTick > m_iNextGameState)
|
||
{
|
||
for( UINT i=0 ; i<m_VecMember.size() ; ++i )
|
||
{
|
||
if (m_VecMember[i].pSession->GetState() != SESSION_STATE_READY_TO_SYNC)
|
||
{
|
||
g_Log.Log(LogType::_ERROR, m_VecMember[i].pSession, L"Connect|Load Sync Fail AID[%d] SID[%d] CID[%I64d]\n", m_VecMember[i].pSession->GetAccountDBID(), m_VecMember[i].pSession->GetSessionID(), m_VecMember[i].pSession->GetCharacterDBID());
|
||
m_VecMember[i].pSession->DetachConnection(L"_GAME_STATE_LOAD2SYNC"); //아직까지 연결되지 않은 청년들은 짤라줍니다.
|
||
}
|
||
}
|
||
|
||
//요 타이밍에 로드쓰레드와의 간섭이 발생할 수 있으므로 체킹해서 진짜로 자른뒤에 로드 시작하자
|
||
CheckRemovedMember();
|
||
if (m_GameState != _GAME_STATE_DESTROYED) //혹시나 하는 마음에...
|
||
SetSync2SyncStateTemplateMethod( iCurTick );
|
||
else
|
||
_DANGER_POINT();
|
||
}
|
||
break;
|
||
}
|
||
|
||
case _GAME_STATE_SYNC2SYNC:
|
||
{
|
||
if (g_pBackLoader->IsLoaded(m_iRoomID) == true)
|
||
{
|
||
if (g_pBackLoader->LoadConfirm(m_iRoomID) == false)
|
||
{
|
||
g_Log.Log(LogType::_ERROR, L"[%d] Destroy|DataLoad Failed CheckOut ResourceData roomID [%d]\n", g_Config.nManagedID, m_iRoomID);
|
||
DestroyGameRoom();
|
||
break;
|
||
}
|
||
|
||
// UpdateRoomCountInfo GameThread 로 옮김.
|
||
if( m_pGameServer && m_pGameServer->GetServerManager() )
|
||
m_pGameServer->GetServerManager()->UpdateRoomCountInfo( GetRoomID(), m_iMapIdx );
|
||
|
||
SyncProp( NULL );
|
||
OnSync2Sync( NULL );
|
||
|
||
m_pWorld->EnableTriggerEventCallback(true);
|
||
m_pWorld->OnTriggerEventCallback( "CDnGameTask::PostInitializeStage", 0, 0.f, false );
|
||
m_pWorld->EnableTriggerEventCallback(false);
|
||
|
||
m_GameState = _GAME_STATE_SYNC2PLAY;
|
||
break;
|
||
}
|
||
|
||
if (iCurTick > m_iNextGameState)
|
||
{
|
||
g_Log.Log(LogType::_NORMAL, L"Destroy|Delay Load SYNC2SYNC\n");
|
||
//정상적인 인원이 전혀없고 리밋타임이 넘어가면 방은 삭제상태로 된다 (상위프로세스에서 삭제됨)
|
||
DestroyGameRoom();
|
||
m_iNextGameState = 0;
|
||
break;
|
||
}
|
||
break;
|
||
}
|
||
|
||
case _GAME_STATE_SYNC2PLAY:
|
||
{
|
||
int iConnectedCnt = 0;
|
||
#if !defined( STRESS_TEST )
|
||
for( UINT i=0 ; i<m_VecMember.size() ; ++i )
|
||
{
|
||
if (m_VecMember[i].pSession->IsConnected() && m_VecMember[i].pSession->GetState() == SESSION_STATE_SYNC_READY_2_DELAY)
|
||
{
|
||
m_VecMember[i].pSession->FlushStoredPacket();
|
||
m_VecMember[i].pSession->FlushPacketQueue();
|
||
for( UINT i2=0 ; i2<m_VecMember.size() ; ++i2 )
|
||
SendGameSyncWait( m_VecMember[i2].pSession, m_VecMember[i].pSession->GetSessionID() );
|
||
m_VecMember[i].pSession->SetSessionState(SESSION_STATE_READY_TO_PLAY);
|
||
}
|
||
|
||
if (m_VecMember[i].pSession->IsConnected() && m_VecMember[i].pSession->GetState() == SESSION_STATE_READY_TO_PLAY)
|
||
iConnectedCnt++;
|
||
}
|
||
#endif
|
||
|
||
#if defined( STRESS_TEST )
|
||
if( true )
|
||
#else
|
||
if (m_iPartMemberCnt == iConnectedCnt)
|
||
#endif
|
||
{
|
||
OnSetPlayState();
|
||
break;
|
||
}
|
||
|
||
#if defined( PRE_WORLDCOMBINE_PARTY )
|
||
#if defined( PRE_WORLDCOMBINE_PVP )
|
||
if (iConnectedCnt == 0 && bIsWorldCombineParty() == false && bIsWorldPvPRoom() == false)
|
||
#else // #if defined( PRE_WORLDCOMBINE_PVP )
|
||
if (iConnectedCnt == 0 && bIsWorldCombineParty() == false )
|
||
#endif // #if defined( PRE_WORLDCOMBINE_PVP )
|
||
#else // #if defined( PRE_WORLDCOMBINE_PARTY )
|
||
if (iConnectedCnt == 0)
|
||
#endif // #if defined( PRE_WORLDCOMBINE_PARTY )
|
||
{
|
||
if (iCurTick > m_iNextGameState)
|
||
{
|
||
g_Log.Log(LogType::_NORMAL, L"Destroy|SYNC2PLAY\n");
|
||
//정상적인 인원이 전혀없고 리밋타임이 넘어가면 방은 삭제상태로 된다 (상위프로세스에서 삭제됨)
|
||
DestroyGameRoom();
|
||
}
|
||
break;
|
||
}
|
||
|
||
if (iCurTick > m_iNextGameState)
|
||
{
|
||
for( UINT i=0 ; i<m_VecMember.size() ; ++i )
|
||
{
|
||
if (m_VecMember[i].pSession->GetState() != SESSION_STATE_READY_TO_PLAY)
|
||
{
|
||
g_Log.Log(LogType::_ERROR, m_VecMember[i].pSession, L"Connect|Sync Fail AID[%d] SID[%d] CID[%I64d]\n", m_VecMember[i].pSession->GetAccountDBID(), m_VecMember[i].pSession->GetSessionID(), m_VecMember[i].pSession->GetCharacterDBID());
|
||
m_VecMember[i].pSession->DetachConnection(L"_GAME_STATE_SYNC2PLAY"); //아직까지 처리되지 않은 청년들은 짤라줍니다.
|
||
}
|
||
}
|
||
|
||
CheckRemovedMember();
|
||
OnSetPlayState();
|
||
break;
|
||
}
|
||
break;
|
||
}
|
||
|
||
case _GAME_STATE_FARM_READY2LOAD:
|
||
{
|
||
if (m_cReqGameIDType != REQINFO_TYPE_FARM)
|
||
{
|
||
_DANGER_POINT();
|
||
DestroyGameRoom();
|
||
break;
|
||
}
|
||
|
||
if (g_pBackLoader->IsLoaded(m_iRoomID) == true)
|
||
{
|
||
if (g_pBackLoader->LoadConfirm(m_iRoomID) == false)
|
||
{
|
||
g_Log.Log(LogType::_FARM, L"[%d] Destroy|DataLoad Failed CheckOut ResourceData roomID [%d]\n", g_Config.nManagedID, m_iRoomID);
|
||
DestroyGameRoom();
|
||
break;
|
||
}
|
||
|
||
QueryGetListField();
|
||
}
|
||
break;
|
||
}
|
||
|
||
case _GAME_STATE_FARM_LOAD2PLAY:
|
||
{
|
||
// 농장인 경우만 들어옴
|
||
if (iCurTick > m_iNextGameState)
|
||
{
|
||
// 쿼리 보내고 일정 시간이 지난 경우에 다시 보내기
|
||
QueryGetListField();
|
||
}
|
||
}
|
||
break;
|
||
case _GAME_STATE_CANCEL_LOADING:
|
||
{
|
||
if (g_pBackLoader->LoadCancel(m_iRoomID))
|
||
{
|
||
// 난입하는 유저가 있다면 방을 파괴하지 않는다.
|
||
if( bIsExistBreakIntoUser() )
|
||
break;
|
||
m_GameState = _GAME_STATE_DESTROYED;
|
||
}
|
||
break;
|
||
}
|
||
|
||
case _GAME_STATE_PLAY:
|
||
{
|
||
#if defined( PRE_TRIGGER_LOG )
|
||
if( m_bLog )
|
||
QueryPerformanceCounter(&m_liStartTime);
|
||
#endif // #if defined( PRE_TRIGGER_LOG )
|
||
|
||
OnGameStatePlay(iCurTick);
|
||
|
||
#if defined( PRE_TRIGGER_LOG )
|
||
if( m_bLog )
|
||
{
|
||
QueryPerformanceCounter(&m_liCurTime);
|
||
double dElapsed = (1000 * ( m_liCurTime.QuadPart - m_liStartTime.QuadPart ) / static_cast<double>( m_liFrequency.QuadPart ));
|
||
|
||
m_dProcessTime += dElapsed;
|
||
}
|
||
#endif // #if defined( PRE_TRIGGER_LOG )
|
||
|
||
#if defined( STRESS_TEST )
|
||
if( m_iRandomSeed > 0 )
|
||
{
|
||
if( timeGetTime()-m_iNextGameState >= static_cast<UINT>(m_iRandomSeed) )
|
||
{
|
||
if( m_VecMember[0].pSession )
|
||
m_VecMember[0].pSession->ChangeServerUserData();
|
||
DestroyGameRoom();
|
||
}
|
||
}
|
||
/*
|
||
else
|
||
{
|
||
if( timeGetTime()-m_iNextGameState >= 500 )
|
||
{
|
||
g_pDBConnectionManager->QueryLevelExp( m_VecMember[0].pSession->GetWorldSetID(), m_VecMember[0].pSession->GetCharacterDBID(), 1, 0 );
|
||
m_iNextGameState = timeGetTime();
|
||
}
|
||
}
|
||
*/
|
||
#endif
|
||
break;
|
||
}
|
||
}
|
||
|
||
#if defined(PRE_FIX_INITSTATEANDSYNC)
|
||
if(m_bInitStateAndSyncReserved)
|
||
InitStateAndSync();
|
||
#endif
|
||
|
||
/*
|
||
Windows SEH 까지 예외로 받을수 있도록
|
||
Enable C++ Exceptions 항목을 /EHa 옵션으로 컴파일 하도록 한다.
|
||
*/
|
||
//#ifdef _FINAL_BUILD
|
||
} // __try {
|
||
__except(CExceptionReport::GetInstancePtr()->Proc(GetExceptionInformation(), MiniDumpNormal))
|
||
{
|
||
// 룸 process 시 예외가 발생 하면 게임룸만 닫도록 처리 한다.
|
||
g_Log.Log(LogType::_ROOMCRASH, L"[%d] Destroy|Process Crash RoomID=%d RoomState=%d\n", g_Config.nManagedID, m_iRoomID, m_GameState );
|
||
|
||
if (g_pBackLoader)
|
||
{
|
||
for( UINT i=0 ; i<m_VecMember.size() ; ++i )
|
||
{
|
||
// GameRoom 예외 발생시 피로도 감소 하지 않게 설정
|
||
m_VecMember[i].pSession->SetDecreaseFatigue(0);
|
||
//m_VecMember[i].pSession->SetSessionState(SESSION_STATE_CRASH);
|
||
}
|
||
m_bRoomCrash = true;
|
||
DestroyGameRoom();
|
||
}
|
||
|
||
//예외가 발생하면 SM에게 예외발생을 알린다.
|
||
#if !defined (_TH)
|
||
if (g_pServiceConnection)
|
||
g_pServiceConnection->SendDetectException(_EXCEPTIONTYPE_ROOMCRASH);
|
||
#endif
|
||
if (g_pMasterConnectionManager && bIsPvPRoom())
|
||
{
|
||
if (bIsPvPRoom() && bIsGuildWarSystem())
|
||
g_pMasterConnectionManager->SendPvPDetectCrash(GetWorldSetID(), GetRoomID(), GetPvPIndex());
|
||
}
|
||
}
|
||
//#endif
|
||
}
|
||
|
||
void CDNGameRoom::TcpProcess()
|
||
{
|
||
DNVector(PartyStruct)::iterator ii;
|
||
for (ii = m_VecMember.begin(); ii != m_VecMember.end(); ii++)
|
||
if ((*ii).pSession->GetTcpConnection() != NULL && (*ii).pSession->GetTcpConnection()->GetDelete() != true && (*ii).pSession->GetTcpConnection()->IsAttachedToSession() )
|
||
if ((*ii).pSession->GetTcpConnection()->FlushRecvData(0) == false)
|
||
RemoveMember((*ii).pSession, L"TcpProcess()");
|
||
}
|
||
|
||
void CDNGameRoom::InitRoomState( CDNUserSession* pBreakIntoSession )
|
||
{
|
||
if( pBreakIntoSession )
|
||
return;
|
||
|
||
OutputDebug( "InitSession\n" );
|
||
|
||
// Task Initialize
|
||
if( m_pTaskMng ) m_pTaskMng->RemoveAllTask();
|
||
SAFE_DELETE( m_pTaskMng );
|
||
m_pTaskMng = new CTaskManager(this);
|
||
|
||
m_pWorld = new CDnWorld(this);
|
||
|
||
// 파티 셋팅
|
||
m_pPartyTask = CDnTaskFactory::CreatePartyTask( m_GameTaskType, this );
|
||
m_pPartyTask->Initialize();
|
||
CTaskManager::GetInstance(this).AddTask( m_pPartyTask, "PartyTask", -1 );
|
||
|
||
// 아이템
|
||
m_pItemTask = new CDnItemTask( this );
|
||
m_pItemTask->Initialize();
|
||
CTaskManager::GetInstance(this).AddTask( m_pItemTask, "ItemTask", -1 );
|
||
// 인벤토리 셋팅해준다.
|
||
|
||
// 스킬 태스크
|
||
m_pSkillTask = new CDnSkillTask( this );
|
||
m_pSkillTask->Initialize();
|
||
CTaskManager::GetInstance(this).AddTask( m_pSkillTask, "SkillTask", -1 );
|
||
|
||
// 겜 타숙후
|
||
m_pGameTask = CDnTaskFactory::CreateGameTask( m_GameTaskType, this );
|
||
m_pGameTask->Initialize();
|
||
CTaskManager::GetInstance(this).AddTask( m_pGameTask, "GameTask", -1 );
|
||
|
||
m_pGuildTask = new CDnGuildTask( this );
|
||
m_pGuildTask->Initialize();
|
||
CTaskManager::GetInstance(this).AddTask( m_pGuildTask, "GuildTask", -1 );
|
||
|
||
m_pChatTask = new CDnChatTask( this );
|
||
m_pChatTask->Initialize();
|
||
CTaskManager::GetInstance(this).AddTask( m_pChatTask, "ChatTask", -1 );
|
||
|
||
AddGameListener( m_pPartyTask );
|
||
AddGameListener( m_pItemTask );
|
||
AddGameListener( m_pGameTask );
|
||
AddGameListener( m_pSkillTask );
|
||
AddGameListener( m_pGuildTask );
|
||
AddGameListener( m_pChatTask );
|
||
|
||
// 나중에 셋팅하게 해준다.
|
||
|
||
if (g_pBackLoader != NULL)
|
||
{
|
||
InitEvent();
|
||
if (g_pBackLoader->PushToLoadProcess( this ) == false)
|
||
{
|
||
//이럼 안덴다!시작도 하지 않았지만 그냥 방만 죽이자
|
||
g_Log.Log(LogType::_ERROR, L"Destroy|OnInitRoomState LoadError\n");
|
||
DestroyGameRoom();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
g_Log.Log(LogType::_ERROR, L"Destroy|BackLoader Not Found\n");
|
||
DestroyGameRoom();
|
||
}
|
||
|
||
for( UINT i=0 ; i<m_VecMember.size() ; ++i )
|
||
{
|
||
if( !m_VecMember[i].pSession )
|
||
continue;
|
||
m_VecMember[i].pSession->SetLoadingComplete( false );
|
||
}
|
||
}
|
||
|
||
void CDNGameRoom::SendSeqLevel()
|
||
{
|
||
m_cSeqLevel++; //이동시 스컨싱레벨을 올린다. 레벨을 올리게되면 사이값은 무시되어진다.(일단 액터관련 패킷만 무시합니다.)
|
||
for( DWORD i=0; i<GetUserCount(); i++ )
|
||
GetUserData(i)->SendSeqLevel(m_cSeqLevel);
|
||
}
|
||
|
||
// GameRoom 의 프로세스가 도는 도중에 InitStateAndSync 호출될 경우(ex:트리거 호출시) 발생하는 동기화 문제를 해결하기 위해
|
||
// ReserveInitStateAndSync 를 두어 정보 저장후 GameRoom 프로세스 종료단 에서 정보를 확인,처리 하는 프로세스로 변경
|
||
#if defined(PRE_FIX_INITSTATEANDSYNC)
|
||
void CDNGameRoom::ReserveInitStateAndSync(int iMapIdx, int iGateIdx, int iRandomSeed, TDUNGEONDIFFICULTY StageDifficulty, bool bDirectConnect, int iGateSelect)
|
||
{
|
||
m_bInitStateAndSyncReserved = true;
|
||
m_nReservedMapIdx = iMapIdx;
|
||
m_nReservedGateIdx = iGateIdx;
|
||
m_nReservedRandomSeed = iRandomSeed;
|
||
m_ReservedStageDifficulty = StageDifficulty;
|
||
m_bReservedDirectConnect = bDirectConnect;
|
||
m_bReservedGateSelect = iGateSelect;
|
||
}
|
||
|
||
void CDNGameRoom::ResetReservedStateAndSyncData()
|
||
{
|
||
m_bInitStateAndSyncReserved = false;
|
||
m_nReservedMapIdx = 0;
|
||
m_nReservedGateIdx = 0;
|
||
m_nReservedRandomSeed = 0;
|
||
m_ReservedStageDifficulty =TDUNGEONDIFFICULTY::Easy;
|
||
m_bReservedDirectConnect = false;
|
||
m_bReservedGateSelect = 0;
|
||
}
|
||
|
||
void CDNGameRoom::InitStateAndSync()
|
||
{
|
||
if (g_pBackLoader != NULL)
|
||
{
|
||
if (GetFarmIndex() > 0)
|
||
{
|
||
_DANGER_POINT();
|
||
return ;
|
||
}
|
||
|
||
DNTableFileFormat *pSox = GetDNTable( CDnTableDB::TMAP );
|
||
if( pSox && !pSox->IsExistItem( m_nReservedMapIdx ) ) {
|
||
DestroyGameRoom();
|
||
return;
|
||
}
|
||
|
||
InitEvent();
|
||
#if defined(PRE_ADD_WORLD_EVENT)
|
||
TEvent * pEvent = GetApplyEventType(WorldEvent::EVENT5);
|
||
#else
|
||
TEvent * pEvent = GetApplyEvent(_EVENT_1_DROPITEM);
|
||
#endif //#if defined(PRE_ADD_WORLD_EVENT)
|
||
|
||
for( DWORD i=0; i<GetUserCount(); i++ ) {
|
||
GetUserData(i)->SetMapIndex( m_nReservedMapIdx );
|
||
GetUserData(i)->SendStartStage( m_bReservedDirectConnect, m_nReservedMapIdx, m_nReservedGateIdx, m_nReservedRandomSeed, m_ReservedStageDifficulty, pEvent == NULL ? 0 : pEvent->nAtt1 );
|
||
GetUserData(i)->ChangeStageUserData();
|
||
GetUserData(i)->SetLoadingComplete(false);
|
||
|
||
//게임도중 게이트이동시 클라이언트단에서 씹힐수 있으므로 게임도중 로딩시 핵쉴드관련 보내지 않음 -2hogi
|
||
GetUserData(i)->SetSecurityUpdateFlag(false);
|
||
// GetUserData(i)->UpdateUserData();
|
||
}
|
||
|
||
m_iMapIdx = m_nReservedMapIdx;
|
||
m_iGateIdx = m_nReservedGateIdx;
|
||
m_iGateSelect = m_bReservedGateSelect;
|
||
m_StageDifficulty = m_ReservedStageDifficulty;
|
||
m_iRandomSeed = m_nReservedRandomSeed;
|
||
m_bDirectConnect = m_bReservedDirectConnect;
|
||
|
||
if (g_pBackLoader->PushToLoadProcess( this, true ) == false)
|
||
{
|
||
//이럼 안덴다!시작도 하지 않았지만 그냥 방만 죽이자
|
||
g_Log.Log(LogType::_ERROR, L"Destroy|InitStateAndSync LoadError\n");
|
||
DestroyGameRoom();
|
||
}
|
||
else
|
||
{
|
||
m_GameState = _GAME_STATE_SYNC2SYNC;
|
||
m_iNextGameState = GetGameTick() + GOGO_SING_TO_PLAY_FOR_WAIT_TIME_LIMIT;
|
||
}
|
||
|
||
SendSeqLevel();
|
||
}
|
||
else
|
||
{
|
||
g_Log.Log(LogType::_ERROR, L"Destroy|BackLoader Not Found\n");
|
||
DestroyGameRoom();
|
||
}
|
||
|
||
ResetReservedStateAndSyncData();
|
||
}
|
||
|
||
#else //#if defined(PRE_FIX_INITSTATEANDSYNC)
|
||
// 마을 -> 게임 서버 이동시에만 사용할때 필요한 iGateSelect값입니다.
|
||
// 게임서버내 월드존, 던젼, 치트 그리고 트리거로 이동할 때, 게이트 선택사항이 없어 기본값(0)으로 처리합니다.
|
||
void CDNGameRoom::InitStateAndSync(int iMapIdx, int iGateIdx, int iRandomSeed, TDUNGEONDIFFICULTY StageDifficulty, bool bDirectConnect, int iGateSelect)
|
||
{
|
||
if (g_pBackLoader != NULL)
|
||
{
|
||
if (GetFarmIndex() > 0)
|
||
{
|
||
_DANGER_POINT();
|
||
return ;
|
||
}
|
||
|
||
DNTableFileFormat *pSox = GetDNTable( CDnTableDB::TMAP );
|
||
if( pSox && !pSox->IsExistItem( iMapIdx ) ) {
|
||
DestroyGameRoom();
|
||
return;
|
||
}
|
||
|
||
InitEvent();
|
||
#if defined(PRE_ADD_WORLD_EVENT)
|
||
TEvent * pEvent = GetApplyEventType(WorldEvent::EVENT5);
|
||
#else
|
||
TEvent * pEvent = GetApplyEvent(_EVENT_1_DROPITEM);
|
||
#endif //#if defined(PRE_ADD_WORLD_EVENT)
|
||
|
||
for( DWORD i=0; i<GetUserCount(); i++ ) {
|
||
GetUserData(i)->SetMapIndex( iMapIdx );
|
||
GetUserData(i)->SendStartStage( bDirectConnect, iMapIdx, iGateIdx, iRandomSeed, StageDifficulty, pEvent == NULL ? 0 : pEvent->nAtt1 );
|
||
GetUserData(i)->ChangeStageUserData();
|
||
GetUserData(i)->SetLoadingComplete(false);
|
||
|
||
//게임도중 게이트이동시 클라이언트단에서 씹힐수 있으므로 게임도중 로딩시 핵쉴드관련 보내지 않음 -2hogi
|
||
GetUserData(i)->SetSecurityUpdateFlag(false);
|
||
// GetUserData(i)->UpdateUserData();
|
||
}
|
||
|
||
m_iMapIdx = iMapIdx;
|
||
m_iGateIdx = iGateIdx;
|
||
m_iGateSelect = iGateSelect;
|
||
m_StageDifficulty = StageDifficulty;
|
||
m_iRandomSeed = iRandomSeed;
|
||
m_bDirectConnect = bDirectConnect;
|
||
|
||
if (g_pBackLoader->PushToLoadProcess( this, true ) == false)
|
||
{
|
||
//이럼 안덴다!시작도 하지 않았지만 그냥 방만 죽이자
|
||
g_Log.Log(LogType::_ERROR, L"Destroy|InitStateAndSync LoadError\n");
|
||
DestroyGameRoom();
|
||
}
|
||
else
|
||
{
|
||
m_GameState = _GAME_STATE_SYNC2SYNC;
|
||
m_iNextGameState = GetGameTick() + GOGO_SING_TO_PLAY_FOR_WAIT_TIME_LIMIT;
|
||
}
|
||
|
||
SendSeqLevel();
|
||
}
|
||
else
|
||
{
|
||
g_Log.Log(LogType::_ERROR, L"Destroy|BackLoader Not Found\n");
|
||
DestroyGameRoom();
|
||
}
|
||
}
|
||
#endif //#if defined(PRE_FIX_INITSTATEANDSYNC)
|
||
|
||
bool CDNGameRoom::LoadData(bool bContinue)
|
||
{//외부에서 호출되며, 동기화를 잡고 있지 않습니다 (잡지 않도록 해주세요 수정시) 변경시 살짝 주의 요망
|
||
bool bResult;
|
||
if (bContinue == false)
|
||
{
|
||
PROFILE_TICK_TEST_BLOCK_START( "LoadData" );
|
||
m_pItemTask->InitializePlayerItem();
|
||
bResult = m_pGameTask->InitializeStage( m_iMapIdx, m_iGateIdx, m_StageDifficulty, m_iRandomSeed, bContinue, m_bDirectConnect, m_iGateSelect );
|
||
if( !bResult )
|
||
{
|
||
g_Log.Log(LogType::_REMAINEDACTOR, _T("m_pGameTask->InitializeStage Failed\n"));
|
||
return false;
|
||
}
|
||
|
||
bResult = m_pGameTask->InitializePlayerActor();
|
||
if( !bResult )
|
||
{
|
||
g_Log.Log(LogType::_REMAINEDACTOR, _T("m_pGameTask->InitializePlayerActor Failed\n"));
|
||
return false;
|
||
}
|
||
bResult = m_pGameTask->PostInitializeStage( m_iRandomSeed );
|
||
if( !bResult )
|
||
{
|
||
g_Log.Log(LogType::_REMAINEDACTOR, _T("m_pGameTask->PostInitializeStage Failed\n"));
|
||
return false;
|
||
}
|
||
PROFILE_TICK_TEST_BLOCK_END();
|
||
}
|
||
else {
|
||
PROFILE_TICK_TEST_BLOCK_START( "LoadData" );
|
||
bResult = m_pGameTask->InitializeStage( m_iMapIdx, m_iGateIdx, m_StageDifficulty, m_iRandomSeed, bContinue, m_bDirectConnect, m_iGateSelect );
|
||
if( !bResult ){
|
||
g_Log.Log(LogType::_REMAINEDACTOR, _T("m_pGameTask->InitializeStage(bContinue==true) Failed\n"));
|
||
return false;
|
||
}
|
||
PROFILE_TICK_TEST_BLOCK_END();
|
||
}
|
||
return true;
|
||
}
|
||
|
||
CDNUserSession * CDNGameRoom::CreateGameSession(WCHAR * wszAccountName, UINT nAccountDBID, UINT nSessionID, INT64 biCharacterDBID, int iTeam, int nWorldID, int nVillageID, bool bIsMaster, bool bTutorial, bool bAdult,
|
||
#if defined(PRE_ADD_MULTILANGUAGE)
|
||
char cPCBangGrade, char cSelectedLanguage, TMemberVoiceInfo * pInfo)
|
||
#else //#if defined(PRE_ADD_MULTILANGUAGE)
|
||
char cPCBangGrade, TMemberVoiceInfo * pInfo)
|
||
#endif //#if defined(PRE_ADD_MULTILANGUAGE)
|
||
{
|
||
CDNUserSession * pSession = NULL;
|
||
if (m_GameState == _GAME_STATE_READY2CONNECT)
|
||
{//지금은 대기상태에서만 세션생성하고 컨넥트 가능합니다. 차후에 파티인녀석은 다시 들어오거나 그런것 조정합시다.(세션객체는 유지방향으로)
|
||
pSession = new IBoostPoolDNGameSession( nSessionID, m_pGameServer, this );
|
||
|
||
if (pSession)
|
||
{
|
||
#if defined(PRE_ADD_MULTILANGUAGE)
|
||
pSession->PreInitializeUser(wszAccountName, nAccountDBID, nSessionID, biCharacterDBID, iTeam, nWorldID, nVillageID, bTutorial, bAdult, cPCBangGrade, cSelectedLanguage, pInfo);
|
||
#else //#if defined(PRE_ADD_MULTILANGUAGE)
|
||
pSession->PreInitializeUser(wszAccountName, nAccountDBID, nSessionID, biCharacterDBID, iTeam, nWorldID, nVillageID, bTutorial, bAdult, cPCBangGrade, pInfo);
|
||
#endif //#if defined(PRE_ADD_MULTILANGUAGE)
|
||
}
|
||
else
|
||
return pSession;
|
||
|
||
#if defined( STRESS_TEST )
|
||
PartyStruct Party;
|
||
Party.pSession = pSession;
|
||
Party.bLeader = bIsMaster;
|
||
|
||
if( nAccountDBID == 0 )
|
||
{
|
||
for( UINT i=0 ; i<4 ; ++i )
|
||
m_VecMember.push_back(Party);
|
||
}
|
||
else
|
||
{
|
||
m_VecMember.push_back(Party);
|
||
}
|
||
#else
|
||
AddPartyStruct( pSession, bIsMaster );
|
||
#endif
|
||
m_UserList.push_back(pSession);
|
||
}
|
||
else
|
||
g_Log.Log(LogType::_ERROR, nWorldID, nAccountDBID, biCharacterDBID, 0, _T("Connect|GameStart Flow err [state:addmember]\n"));
|
||
|
||
return pSession;
|
||
}
|
||
|
||
bool CDNGameRoom::VerifyMember(CDNUserSession * pSession)
|
||
{//마스터에서 멤버추가 요청시에
|
||
for (unsigned int i = 0; i < m_VecMember.size(); i ++)
|
||
if (m_VecMember[i].pSession == pSession)
|
||
return true;
|
||
return false;
|
||
}
|
||
|
||
void CDNGameRoom::RemoveMember(CDNUserSession * pSession, wchar_t * pwszIdent)
|
||
{//멤버 삭제 다 나가면 데스트로이 상태로 변경 하자
|
||
m_DeleteList.push_back(pSession->GetSessionID());
|
||
OnLeaveUser(pSession->GetSessionID());
|
||
|
||
g_Log.Log(LogType::_NORMAL, pSession, L"[%d] RemoveMember(%s) SessionState=%d RoomState=%d\r\n", g_Config.nManagedID, pwszIdent == NULL ? L"NULL" : pwszIdent, pSession->GetState(), GetRoomState());
|
||
}
|
||
|
||
void CDNGameRoom::CheckRemovedMember()
|
||
{
|
||
#ifdef STRESS_TEST
|
||
return;
|
||
#endif
|
||
if (m_DeleteList.empty() )
|
||
return;
|
||
|
||
// BackGround 쓰레드랑 동기 이슈때문에 이때는 기다렸다가 유저 정리한다.
|
||
//if( m_GameState == _GAME_STATE_SYNC2SYNC || m_GameState == _GAME_STATE_LOAD2SYNC )
|
||
if( g_pBackLoader && g_pBackLoader->IsLoading( GetRoomID() ) )
|
||
return;
|
||
|
||
DNVector(PartyStruct)::iterator ii;
|
||
for (int i = 0; i < (int)m_DeleteList.size(); i++)
|
||
{
|
||
bool bDelFalg = false; // m_VecMember.erase() 했는지 Flag
|
||
// m_VecMember 에 pushback 하기 전에 disconnect 된 session 처리
|
||
CDNUserSession* pDeleteSession = NULL;
|
||
|
||
// 난입유저 Disconnect 처리
|
||
for( std::list<CDNUserSession*>::iterator bi=m_BreakIntoUserList.begin() ; bi!=m_BreakIntoUserList.end() ; )
|
||
{
|
||
if( (*bi)->GetSessionID() == m_DeleteList[i] )
|
||
{
|
||
pDeleteSession = (*bi);
|
||
bi = m_BreakIntoUserList.erase( bi );
|
||
break;
|
||
}
|
||
else
|
||
++bi;
|
||
}
|
||
|
||
for (ii = m_VecMember.begin(); ii != m_VecMember.end(); ii++)
|
||
{
|
||
if ((*ii).pSession->GetSessionID() == m_DeleteList[i])
|
||
{
|
||
#ifndef _FINAL_BUILD
|
||
// 어디선가 지워진걸 또 지우는게 있어서 검증때립니다.
|
||
for( int j=EQUIP_FACE; j<=EQUIP_RING2; j++ ) {
|
||
if( !(*ii).pEquip[j] ) continue;
|
||
for( int k=0; k<INVENTORYMAX; k++ ) {
|
||
if( !(*ii).pInventory[k] ) continue;
|
||
if( (*ii).pEquip[j] == (*ii).pInventory[k] ) {
|
||
_ASSERT(0&&"씨바를 불러줘 제발!!");
|
||
}
|
||
}
|
||
}
|
||
/////////////////////////////////////////////////////
|
||
#endif
|
||
pDeleteSession = NULL;
|
||
|
||
m_vDeleteSession.push_back( (*ii).pSession );
|
||
m_UserList.remove( (*ii).pSession );
|
||
(*ii).pSession->FinalUser();
|
||
GetGameServer()->RemoveConnection(GetRoomID(), (*ii).pSession->GetNetID(), (*ii).pSession->GetAccountDBID(), (*ii).pSession->GetSessionID());
|
||
|
||
(*ii).ReleaseEquipInventory();
|
||
|
||
CheckCurrentItemLooterIdx( &(*ii) );
|
||
std::map<INT64,CDNUserSession*>::iterator itor = m_mCharDBIDMember.find( (*ii).pSession->GetCharacterDBID() );
|
||
if( itor != m_mCharDBIDMember.end() )
|
||
m_mCharDBIDMember.erase( itor );
|
||
m_VecMember.erase(ii);
|
||
bDelFalg = true;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if( bDelFalg && GetMasterRewardSystem() )
|
||
GetMasterRewardSystem()->RequestRefresh();
|
||
|
||
if( bDelFalg == false && pDeleteSession == NULL )
|
||
{
|
||
for( std::list<CDNUserSession*>::iterator itor=m_UserList.begin() ; itor!=m_UserList.end() ; ++itor )
|
||
{
|
||
CDNUserSession* pZombieSession = (*itor);
|
||
if( pZombieSession )
|
||
{
|
||
if( pZombieSession->GetSessionID() == m_DeleteList[i] )
|
||
{
|
||
g_Log.Log( LogType::_ZOMBIEUSER, pZombieSession, L"[%d] RoomID:%d", g_Config.nManagedID, GetRoomID() );
|
||
pZombieSession->FinalUser();
|
||
GetGameServer()->RemoveConnection(GetRoomID(), pZombieSession->GetNetID(), pZombieSession->GetAccountDBID(), pZombieSession->GetSessionID());
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if( pDeleteSession )
|
||
{
|
||
m_UserList.remove( pDeleteSession );
|
||
pDeleteSession->FinalUser();
|
||
GetGameServer()->RemoveConnection(GetRoomID(), pDeleteSession->GetNetID(), pDeleteSession->GetAccountDBID(), pDeleteSession->GetSessionID());
|
||
}
|
||
}
|
||
m_DeleteList.clear();
|
||
|
||
if( m_VecMember.empty() )
|
||
{
|
||
//일단 농장이라면 유저가 나가더라도 방폭은 없다
|
||
#if defined( PRE_WORLDCOMBINE_PARTY )
|
||
if (bIsFarmRoom() == false && CheckDestroyWorldCombineParty() == true )
|
||
#else
|
||
if (bIsFarmRoom() == false)
|
||
#endif // #if defined( PRE_WORLDCOMBINE_PARTY )
|
||
{
|
||
bool bDestroy = true;
|
||
if (bIsPvPRoom())
|
||
{
|
||
if (bIsGuildWarSystem() && m_bForceDestroyRoom == false)
|
||
{
|
||
if (GetPvPGameMode() && GetPvPGameMode()->bIsFinishFlag() == false)
|
||
bDestroy = false;
|
||
}
|
||
#if defined( PRE_WORLDCOMBINE_PVP )
|
||
if( bIsWorldPvPRoom() && bIsWorldPvPRoomStart() == false && GetWorldPvPRoomReqType() != WorldPvPMissionRoom::Common::GMRoom )
|
||
bDestroy =false;
|
||
#endif
|
||
}
|
||
|
||
if (bDestroy)
|
||
DestroyGameRoom();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (m_pTaskMng)
|
||
{
|
||
CDnPartyTask * pPartyTask = (CDnPartyTask*)m_pTaskMng->GetTask("PartyTask");
|
||
if (pPartyTask)
|
||
pPartyTask->UpdateGateInfo();
|
||
else _DANGER_POINT();
|
||
}
|
||
|
||
#if defined( PRE_PARTY_DB )
|
||
if( GetUserCount() <= 1 ) m_PartyStructData.iUpkeepCount = 0;
|
||
#else
|
||
if( GetUserCount() <= 1 ) m_nUpkeepCount = 0;
|
||
#endif
|
||
UpdateAppliedEventValue();
|
||
}
|
||
}
|
||
|
||
void CDNGameRoom::CheckRudpDisconnectedMember()
|
||
{
|
||
//tcp는 콘넥되어 있는데 rudp만 끊긴녀석들에게 재연결을 유도했습니다. 일정시간동안 연결을 못하는 친구들을 잘라 줍니다.
|
||
DNVector(PartyStruct)::iterator ii;
|
||
for (ii = m_VecMember.begin(); ii != m_VecMember.end(); ii++)
|
||
if ((*ii).pSession->IsRudpDisconnected() && GetGameTick() - (*ii).pSession->GetRudpDisconnectedTick() > (5*1000)) //한 5초?
|
||
(*ii).pSession->DetachConnection(L"CheckRudpDisconnectedMember");
|
||
}
|
||
|
||
void CDNGameRoom::UserUpdate( DWORD dwCurTick )
|
||
{
|
||
#ifdef PRE_MOD_INDUCE_TCPCONNECT
|
||
if (m_GameState == _GAME_STATE_SYNC2PLAY || m_GameState == _GAME_STATE_PLAY || \
|
||
m_GameState == _GAME_STATE_READY2CONNECT || m_GameState == _GAME_STATE_CONNECT2CHECKAUTH)
|
||
#else //#ifdef PRE_MOD_INDUCE_TCPCONNECT
|
||
if (m_GameState == _GAME_STATE_SYNC2PLAY || m_GameState == _GAME_STATE_PLAY)
|
||
#endif //#ifdef PRE_MOD_INDUCE_TCPCONNECT
|
||
{
|
||
for( UINT i=0 ; i<m_VecMember.size() ; ++i )
|
||
{
|
||
CDNUserSession* pSession = m_VecMember[i].pSession;
|
||
if( pSession )
|
||
pSession->DoUpdate( dwCurTick );
|
||
}
|
||
}
|
||
|
||
if (m_nInivitedTime > 0 && m_nInivitedTime + (GAMEINVITEWAITTIME) < timeGetTime())
|
||
{
|
||
ResetInvite(ERROR_PARTY_INVITEFAIL);
|
||
}
|
||
}
|
||
|
||
void CDNGameRoom::AddGameListener(CGameListener * pListener)
|
||
{
|
||
m_GameListener.push_back(pListener);
|
||
}
|
||
|
||
void CDNGameRoom::RemoveGameListener(CGameListener * pListener)
|
||
{
|
||
std::vector <CGameListener*>::iterator ii;
|
||
for (ii = m_GameListener.begin(); ii != m_GameListener.end(); ii++)
|
||
{
|
||
if ((*ii) == pListener)
|
||
{
|
||
m_GameListener.erase(ii);
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
|
||
void CDNGameRoom::_AddPacketQueue( CDNUserSession* pSession, const DWORD dwUniqueID, const BYTE cSubCmd, const BYTE* pBuffer, const int iSize, const int iPrior )
|
||
{
|
||
for( UINT i=0 ; i<m_VecMember.size() ; ++i )
|
||
{
|
||
if( m_VecMember[i].pSession == pSession )
|
||
continue;
|
||
|
||
if( bIsFarmRoom() )
|
||
{
|
||
// 농장세션은 낚시 관련 Actor 패킷이 너무 많아서 unreachable 걸리는게 아닌가 싶어서 SESSION_STATE_GAME_PLAY 일때만 보낸다.
|
||
if( m_VecMember[i].pSession->GetState() != SESSION_STATE_GAME_PLAY )
|
||
{
|
||
bool bSkip = false;
|
||
switch( cSubCmd )
|
||
{
|
||
case eActor::CS_FISHINGROD_CAST:
|
||
case eActor::CS_FISHINGROD_LIFT:
|
||
case eActor::CS_FISHINGROD_HIDE:
|
||
{
|
||
bSkip = true;
|
||
}
|
||
}
|
||
|
||
if( bSkip )
|
||
continue;
|
||
}
|
||
}
|
||
|
||
//#ifdef PRE_ADD_PACKETSIZE_CHECKER
|
||
// m_VecMember[i].pSession->AddPacketQueue( dwUniqueID, cSubCmd, pBuffer, iSize, iPrior, true );
|
||
//#else //#ifdef PRE_ADD_PACKETSIZE_CHECKER
|
||
m_VecMember[i].pSession->AddPacketQueue( dwUniqueID, cSubCmd, pBuffer, iSize, iPrior );
|
||
//#endif //#ifdef PRE_ADD_PACKETSIZE_CHECKER
|
||
}
|
||
}
|
||
|
||
int CDNGameRoom::OnDispatchMessage(CDNUserSession * pSession, int iMainCmd, int iSubCmd, char * pData, int iLen, BYTE cSeqLevel)
|
||
{
|
||
#ifdef _FINAL_BUILD
|
||
__try {
|
||
#endif
|
||
|
||
/*
|
||
if( g_pBackLoader && g_pBackLoader->IsLoading( GetRoomID() ) )
|
||
{
|
||
if( !(iMainCmd == CS_ACTOR && iSubCmd == eActor::CS_CMDSTOP) )
|
||
g_Log.Log( LogType::_ERROR, pSession, L"[%d] BackGroundLoading MCMD[%d] SCMD[%d]\n", g_Config.nManagedID, iMainCmd, iSubCmd );
|
||
}
|
||
*/
|
||
|
||
if (m_GameState == _GAME_STATE_DESTROYED) return ERROR_NONE;
|
||
if (m_GameState == _GAME_STATE_SYNC2SYNC)
|
||
{
|
||
bool bSkip = true;
|
||
switch( iMainCmd )
|
||
{
|
||
case CS_ROOM:
|
||
case CS_SYSTEM:
|
||
{
|
||
bSkip = false;
|
||
break;
|
||
}
|
||
case CS_ITEM:
|
||
{
|
||
if( iSubCmd == eItem::SC_REFRESHINVEN )
|
||
bSkip = false;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if( bSkip )
|
||
{
|
||
//이타이밍에 어떤 메세지가 들어오는지 확인용
|
||
//이부분을 패쓰 하는게 필요한 경우 명재에게 알려주세요.
|
||
#ifndef _FINAL_BUILD
|
||
// if( !(iMainCmd == CS_ACTOR && iSubCmd == eActor::CS_CMDSTOP) )
|
||
// g_Log.Log( LogType::_ERROR, pSession, L"MapIndex[%d] MCMD[%d] SCMD[%d]\n", pSession->GetMapIndex(), iMainCmd, iSubCmd);
|
||
#endif
|
||
return ERROR_NONE;
|
||
}
|
||
}
|
||
|
||
if (iMainCmd == CS_ACTOR || iMainCmd == CS_ACTORBUNDLE)
|
||
{
|
||
//액터메세지는 플레이상태에서만 처리합니다. 이동 또는 받지 않아야할 타이밍에 받아서 위치가 틀어지는 문제가 있습니다.
|
||
if ((m_GameState != _GAME_STATE_PLAY) || cSeqLevel != m_cSeqLevel)
|
||
return ERROR_NONE;
|
||
}
|
||
|
||
switch (iMainCmd)
|
||
{
|
||
case CS_SYSTEM: return pSession->OnRecvSystemMessage(iSubCmd, pData, iLen);
|
||
case CS_FRIEND: return pSession->OnRecvFriendMessage(iSubCmd, pData, iLen);
|
||
case CS_ISOLATE: return pSession->OnRecvIsolateMessage(iSubCmd, pData, iLen);
|
||
case CS_GAMEOPTION: return pSession->OnRecvGameOptionMessage(iSubCmd, pData, iLen);
|
||
case CS_RADIO: return pSession->OnRecvRadioMessage(iSubCmd, pData, iLen);
|
||
case CS_ETC: return pSession->OnRecvEtcMessage(iSubCmd, pData, iLen);
|
||
// case CS_GUILD: return pSession->OnRecvGuildMessage(iSubCmd, pData, iLen); // 게임서버의 길드 메시지 처리는 CDnGuildTask::OnRecvGuildMessage(...) 에서 처리 (20100210 b4nfter)
|
||
#ifdef _USE_VOICECHAT
|
||
case CS_VOICECHAT: return pSession->OnRecvVoiceChatMessage(iSubCmd, pData, iLen);
|
||
#endif
|
||
#if defined( PRE_ADD_NPC_REPUTATION_SYSTEM )
|
||
case CS_REPUTATION: return pSession->OnRecvReputationMessage( iSubCmd, pData, iLen );
|
||
#endif // #if defined( PRE_ADD_NPC_REPUTATION_SYSTEM )
|
||
case CS_MASTERSYSTEM: return pSession->OnRecvMasterSystemMessage( iSubCmd, pData, iLen );
|
||
#if defined( PRE_ADD_SECONDARY_SKILL )
|
||
case CS_SECONDARYSKILL: return pSession->OnRecvSecondarySkillMessage( iSubCmd, pData, iLen );
|
||
#endif // #if defined( PRE_ADD_SECONDARY_SKILL )
|
||
#if defined( PRE_PRIVATECHAT_CHANNEL )
|
||
case CS_PRIVATECHAT_CHANNEL: return pSession->OnRecvPrivateChatChannelMessage( iSubCmd, pData, iLen );
|
||
#endif
|
||
#if defined( PRE_ALTEIAWORLD_EXPLORE )
|
||
case CS_ALTEIAWORLD: return pSession->OnRecvWorldAlteiaMessage( iSubCmd, pData, iLen );
|
||
#endif
|
||
#if defined(PRE_ADD_CHAT_MISSION)
|
||
case CS_MISSION: return pSession->OnRecvMissionMessage(iSubCmd, pData, iLen);
|
||
#endif
|
||
case CS_ACTOR:
|
||
{
|
||
CSActorMessage * pActorMsg = reinterpret_cast<CSActorMessage*>(pData);
|
||
|
||
/*if (sizeof(CSActorMessage) - sizeof(pActorMsg->cBuf) + pActorMsg->cSize != iLen)
|
||
return ERROR_INVALIDPACKET;*/
|
||
|
||
_AddPacketQueue( pSession, pActorMsg->nSessionID, iSubCmd, reinterpret_cast<const BYTE*>(pActorMsg->cBuf), iLen, _FAST );
|
||
break;
|
||
}
|
||
case CS_ACTORBUNDLE:
|
||
{
|
||
CSActorBundleMessage *pBundlePacket = reinterpret_cast<CSActorBundleMessage*>(pData);
|
||
|
||
/*if (sizeof(CSActorBundleMessage) - sizeof(pBundlePacket->cBuf) + (pBundlePacket->cSize) != iLen)
|
||
return ERROR_INVALIDPACKET;*/
|
||
|
||
int nOffset = 0;
|
||
DWORD dwUniqueID;
|
||
BYTE cSubCmd;
|
||
WORD wSize;
|
||
void* pLocalData;
|
||
|
||
int iDataLen = iLen-sizeof(pBundlePacket->nSessionID);
|
||
if( iDataLen < 0 )
|
||
return ERROR_INVALIDPACKET;
|
||
|
||
for( int i=0; i<iSubCmd; ++i )
|
||
{
|
||
if( iDataLen < sizeof(DWORD) )
|
||
return ERROR_INVALIDPACKET;
|
||
memcpy( &dwUniqueID, pBundlePacket->cBuf+nOffset, sizeof(DWORD) ); nOffset += sizeof(DWORD);
|
||
iDataLen -= sizeof(DWORD);
|
||
|
||
if( iDataLen < sizeof(BYTE) )
|
||
return ERROR_INVALIDPACKET;
|
||
memcpy( &cSubCmd, pBundlePacket->cBuf+nOffset, sizeof(BYTE) ); nOffset += sizeof(BYTE);
|
||
iDataLen -= sizeof(BYTE);
|
||
|
||
if( iDataLen < sizeof(WORD) )
|
||
return ERROR_INVALIDPACKET;
|
||
memcpy( &wSize, pBundlePacket->cBuf+nOffset, sizeof(WORD) ); nOffset += sizeof(WORD);
|
||
iDataLen -= sizeof(WORD);
|
||
|
||
if( iDataLen < wSize )
|
||
return ERROR_INVALIDPACKET;
|
||
pLocalData = pBundlePacket->cBuf + nOffset; nOffset += wSize;
|
||
iDataLen -= wSize;
|
||
|
||
_AddPacketQueue( pSession, dwUniqueID, cSubCmd, static_cast<const BYTE*>(pLocalData), wSize, _FAST );
|
||
}
|
||
|
||
break;
|
||
}
|
||
}
|
||
|
||
for (int i = 0; i < (int)m_GameListener.size(); i++)
|
||
m_GameListener[i]->OnDispatchMessage(pSession, iMainCmd, iSubCmd, pData, iLen);
|
||
|
||
/*
|
||
Windows SEH 까지 예외로 받을수 있도록
|
||
Enable C++ Exceptions 항목을 /EHa 옵션으로 컴파일 하도록 한다.
|
||
*/
|
||
#ifdef _FINAL_BUILD
|
||
} // __try {
|
||
__except(CExceptionReport::GetInstancePtr()->Proc(GetExceptionInformation(), MiniDumpNormal))
|
||
{
|
||
// 유저가 패킷 관련 처리 하다가 예외가 발생하면 여기서 접속을 끊어준다.
|
||
g_Log.Log(LogType::_SESSIONCRASH, L"[%d] Session Crash! RoomID=%d\n", g_Config.nManagedID, m_iRoomID );
|
||
pSession->SetDecreaseFatigue(0);
|
||
//pSession->SetSessionState(SESSION_STATE_CRASH);
|
||
pSession->DetachConnection(L"SESSION_STATE_CRASH");//L"SESSION_STATE_CRASH");
|
||
|
||
//예외가 발생하면 SM에게 예외발생을 알린다.
|
||
#if !defined (_TH)
|
||
if (g_pServiceConnection)
|
||
g_pServiceConnection->SendDetectException(_EXCEPTIONTYPE_SESSIONCRASH);
|
||
#endif
|
||
}
|
||
|
||
#endif
|
||
return ERROR_NONE;
|
||
}
|
||
|
||
CDNUserSession * CDNGameRoom::GetUserData(DWORD dwIndex)
|
||
{
|
||
if( dwIndex >= (DWORD)m_VecMember.size() )
|
||
return NULL;
|
||
return m_VecMember[dwIndex].pSession;
|
||
}
|
||
|
||
CDNUserSession * CDNGameRoom::GetUserSession(UINT nSessionID)
|
||
{
|
||
DNVector(PartyStruct)::iterator ii;
|
||
for (ii = m_VecMember.begin(); ii != m_VecMember.end(); ii++)
|
||
if ((*ii).pSession->GetSessionID() == nSessionID)
|
||
return (*ii).pSession;
|
||
return NULL;
|
||
}
|
||
|
||
|
||
//PartyData
|
||
bool CDNGameRoom::AddPartyStruct( CDNUserSession* pSession, bool bLeader)
|
||
{
|
||
if( bIsFarmRoom() == false )
|
||
{
|
||
UINT uiMax = bIsPvPRoom() ? PvPCommon::Common::MaxPlayer : PARTYCOUNTMAX;
|
||
|
||
if (pSession->bIsGMTrace())
|
||
uiMax = PARTYMAX;
|
||
|
||
if( m_VecMember.size() >= uiMax )
|
||
return false;
|
||
}
|
||
|
||
PartyStruct Party;
|
||
Party.pSession = pSession;
|
||
Party.bLeader = bLeader;
|
||
|
||
m_VecMember.push_back( Party );
|
||
m_mCharDBIDMember.insert( std::make_pair(pSession->GetCharacterDBID(),pSession) );
|
||
|
||
AddLastPartyDungeonInfo( pSession );
|
||
return true;
|
||
}
|
||
|
||
CDNGameRoom::PartyStruct * CDNGameRoom::GetPartyData(CDNUserSession * pSession)
|
||
{
|
||
for( DWORD i=0; i<m_VecMember.size(); i++ )
|
||
if( m_VecMember[i].pSession == pSession)
|
||
return &m_VecMember[i];
|
||
return NULL;
|
||
}
|
||
|
||
CDNGameRoom::PartyStruct * CDNGameRoom::GetPartyData( WCHAR *pwszCharacterName )
|
||
{
|
||
for( DWORD i=0; i<m_VecMember.size(); i++ )
|
||
if( __wcsicmp_l( m_VecMember[i].pSession->GetCharacterName(), pwszCharacterName ) == 0 )
|
||
return &m_VecMember[i];
|
||
return NULL;
|
||
}
|
||
|
||
CDNGameRoom::PartyStruct * CDNGameRoom::GetPartyDatabySessionID(UINT nSessionID, int &Seq)
|
||
{
|
||
for( DWORD i=0; i<m_VecMember.size(); i++ )
|
||
if (m_VecMember[i].pSession->GetSessionID() == nSessionID)
|
||
{
|
||
Seq = i;
|
||
return &m_VecMember[i];
|
||
}
|
||
return NULL;
|
||
}
|
||
|
||
CDNUserSession* CDNGameRoom::GetUserSessionByCharDBID( INT64 biCharDBID )
|
||
{
|
||
std::map<INT64,CDNUserSession*>::iterator itor = m_mCharDBIDMember.find( biCharDBID );
|
||
if( itor != m_mCharDBIDMember.end() )
|
||
return (*itor).second;
|
||
|
||
return NULL;
|
||
}
|
||
|
||
bool CDNGameRoom::SwapLeader(UINT nDelSessionID, UINT &nNewLeaderSessionID)
|
||
{
|
||
bool bCheck, bNewLeader;
|
||
bCheck = bNewLeader = false;
|
||
|
||
for( DWORD i=0; i<m_VecMember.size(); i++ )
|
||
{
|
||
if (m_VecMember[i].pSession->GetSessionID() == nDelSessionID)
|
||
{
|
||
if (m_VecMember[i].bLeader == true && m_VecMember.size() > 1)
|
||
{
|
||
m_VecMember[i].bLeader = false;
|
||
bNewLeader = true;
|
||
}
|
||
bCheck = true;
|
||
break;
|
||
}
|
||
}
|
||
|
||
#if defined( PRE_PARTY_DB )
|
||
CDNUserSession* pNewLeaderSession = NULL;
|
||
#endif // #if defined( PRE_PARTY_DB )
|
||
|
||
if (bNewLeader)
|
||
{
|
||
for( DWORD i=0; i<m_VecMember.size(); i++ )
|
||
{
|
||
if (m_VecMember[i].pSession->GetSessionID() != nDelSessionID && nNewLeaderSessionID == 0 && m_VecMember[i].pSession->bIsGMTrace() == false && m_VecMember[i].pSession->GetOutedMember() == false)
|
||
{
|
||
m_VecMember[i].bLeader = true;
|
||
nNewLeaderSessionID = m_VecMember[i].pSession->GetSessionID();
|
||
#if defined( PRE_PARTY_DB )
|
||
pNewLeaderSession = m_VecMember[i].pSession;
|
||
#endif // #if defined( PRE_PARTY_DB )
|
||
}
|
||
else
|
||
m_VecMember[i].bLeader = false;
|
||
}
|
||
|
||
for( DWORD i=0; i<m_VecMember.size(); i++ )
|
||
{
|
||
//리더가 바뀌었으면 모든 유저에게 변경을 알리자
|
||
m_VecMember[i].pSession->SendUpdatePartyUI(nDelSessionID, false);
|
||
m_VecMember[i].pSession->SendUpdatePartyUI(nNewLeaderSessionID, true);
|
||
}
|
||
}
|
||
|
||
if( pNewLeaderSession )
|
||
{
|
||
m_PartyStructData.biLeaderCharacterDBID = pNewLeaderSession->GetCharacterDBID();
|
||
#if defined( PRE_PARTY_DB )
|
||
GetDBConnection()->QueryModPartyLeader( pNewLeaderSession, GetPartyIndex() );
|
||
#endif // #if defined( PRE_PARTY_DB )
|
||
}
|
||
|
||
return bCheck;
|
||
}
|
||
|
||
bool CDNGameRoom::IsPartyLeader(UINT nSessionID)
|
||
{
|
||
for( DWORD i=0; i<m_VecMember.size(); i++ )
|
||
{
|
||
if (m_VecMember[i].pSession->GetSessionID() == nSessionID && m_VecMember[i].bLeader == true)
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
int CDNGameRoom::GetLeftMemberIndex()
|
||
{
|
||
for (int i = 0; i < PARTYMAX; i++)
|
||
{
|
||
if (m_nPartyMemberIndex[i] <= 0)
|
||
return i;
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
bool CDNGameRoom::SetPartyMemberIndex(int nIdx, UINT nSessionID, int nTeam /*= -1*/)
|
||
{
|
||
if (GetPartyIndex() > 0)
|
||
m_nPartyMemberIndex[nIdx] = nSessionID;
|
||
else if (bIsPvPRoom() && bIsOccupationMode())
|
||
{
|
||
if (nTeam == -1) return false;
|
||
if (nTeam == PvPCommon::Team::A)
|
||
m_nPartyMemberIndex[nIdx] = nSessionID;
|
||
else
|
||
{
|
||
if (GetPvPMaxUser() <= 0)
|
||
{
|
||
_DANGER_POINT();
|
||
return false;
|
||
}
|
||
m_nPartyMemberIndex[nIdx+(GetPvPMaxUser()/2)] = nSessionID;
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
bool CDNGameRoom::PartySwapMemberIndex(CSPartySwapMemberIndex * pPacket)
|
||
{
|
||
if( bIsFarmRoom() )
|
||
return true;
|
||
|
||
//verify count
|
||
#if defined( PRE_PARTY_DB )
|
||
if (pPacket->cCount > m_PartyStructData.nPartyMaxCount )
|
||
return false; //이러시면 아니데옵니다.
|
||
#else
|
||
if (pPacket->cCount > m_nMemberMax)
|
||
return false; //이러시면 아니데옵니다.
|
||
#endif
|
||
|
||
//verify index range
|
||
std::vector <BYTE> vDuplicate;
|
||
std::vector <BYTE>::iterator iDuplicater;
|
||
for (int i = 0; i < pPacket->cCount; i++)
|
||
{
|
||
#if defined( PRE_PARTY_DB )
|
||
if (pPacket->Index[i].cIndex > (m_PartyStructData.nPartyMaxCount-1))
|
||
return false;
|
||
#else
|
||
if (pPacket->Index[i].cIndex > (m_nMemberMax-1))
|
||
return false;
|
||
#endif
|
||
|
||
iDuplicater = std::find(vDuplicate.begin(), vDuplicate.end(), pPacket->Index[i].cIndex);
|
||
if (vDuplicate.end() != iDuplicater)
|
||
return false; //중복인덱스가 있으면 안데자나
|
||
|
||
vDuplicate.push_back(pPacket->Index[i].cIndex);
|
||
}
|
||
|
||
//백업용만들어두고
|
||
UINT nPartyMemberIndex[PARTYMAX];
|
||
memcpy(nPartyMemberIndex, m_nPartyMemberIndex, sizeof(m_nPartyMemberIndex));
|
||
memset(m_nPartyMemberIndex, 0, sizeof(m_nPartyMemberIndex));
|
||
|
||
for( DWORD i=0; i<m_VecMember.size(); i++ )
|
||
{
|
||
bool bCheck = false;
|
||
for (int j = 0; j < PARTYMAX; j++)
|
||
{
|
||
if (pPacket->Index[j].nSessionID == m_VecMember[i].pSession->GetSessionID())
|
||
{
|
||
m_VecMember[i].pSession->SetPartyMemberIndex(pPacket->Index[j].cIndex);
|
||
m_nPartyMemberIndex[m_VecMember[i].pSession->GetPartyMemberIndex()] = m_VecMember[i].pSession->GetSessionID();
|
||
bCheck = true;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (bCheck == false)
|
||
{
|
||
//원복한다.
|
||
memcpy(m_nPartyMemberIndex, nPartyMemberIndex, sizeof(m_nPartyMemberIndex));
|
||
for( DWORD h=0; h<m_VecMember.size(); h++ )
|
||
{
|
||
for (int k = 0; k < PARTYMAX; k++)
|
||
{
|
||
if (m_nPartyMemberIndex[k] == m_VecMember[h].pSession->GetSessionID())
|
||
{
|
||
m_VecMember[i].pSession->SetPartyMemberIndex(k);
|
||
break;
|
||
}
|
||
}
|
||
|
||
}
|
||
return false;
|
||
}
|
||
}
|
||
|
||
SendRefreshParty(0, NULL);
|
||
return true;
|
||
}
|
||
|
||
bool CDNGameRoom::IsRaidParty()
|
||
{
|
||
#if defined( PRE_PARTY_DB )
|
||
return m_PartyStructData.nPartyMaxCount >= RAIDPARTYCOUNTMIN ? true : false;
|
||
#else
|
||
return m_nMemberMax >= RAIDPARTYCOUNTMIN ? true : false;
|
||
#endif
|
||
}
|
||
|
||
void CDNGameRoom::SortMemberIndex(int nOutIndex)
|
||
{
|
||
//if (IsRaidParty() == false || nOutIndex < 0) return; //레이드파티가 아니면 해줄 필요 없다.
|
||
if (nOutIndex < 0) return; //레이드파티가 아니면 해줄 필요 없다.
|
||
#if defined( PRE_PARTY_DB )
|
||
if (nOutIndex < 0 || m_PartyStructData.nPartyMaxCount-1 < nOutIndex) return;
|
||
#else
|
||
if (nOutIndex < 0 || m_nMemberMax-1 < nOutIndex) return;
|
||
#endif
|
||
|
||
//진짜 나간인덱스인지 확인해본다
|
||
if (m_nPartyMemberIndex[nOutIndex] != 0)
|
||
m_nPartyMemberIndex[nOutIndex] = 0;
|
||
else
|
||
return;
|
||
|
||
//노말파티의 최대인원이 옵센카운트이다.
|
||
int nOffSetRemainIndex = (nOutIndex+1)%NORMPARTYCOUNTMAX;
|
||
if (nOffSetRemainIndex <= 0) return; //나머지카운트가 0이면 소팅할꺼읍다
|
||
|
||
int nOffSetIndex = (nOutIndex+1) > NORMPARTYCOUNTMAX ? (nOutIndex)/NORMPARTYCOUNTMAX : 0;
|
||
int nSortEnd = (nOffSetIndex*NORMPARTYCOUNTMAX) + NORMPARTYCOUNTMAX;
|
||
|
||
CDNUserSession * pSession = NULL;
|
||
for (int i = nOutIndex; i < (nSortEnd-1); i++)
|
||
{
|
||
if ((i+1) >= PARTYCOUNTMAX) break;
|
||
if (m_nPartyMemberIndex[i+1] <= 0) continue;
|
||
m_nPartyMemberIndex[i] = m_nPartyMemberIndex[i+1];
|
||
m_nPartyMemberIndex[i+1] = 0;
|
||
}
|
||
|
||
for (int h = 0; h < PARTYMAX; h++)
|
||
{
|
||
if (m_nPartyMemberIndex[h] <= 0) continue;
|
||
for( DWORD i=0; i<m_VecMember.size(); i++ )
|
||
{
|
||
if (m_VecMember[i].pSession->GetSessionID() == m_nPartyMemberIndex[h])
|
||
m_VecMember[i].pSession->SetPartyMemberIndex(h);
|
||
}
|
||
}
|
||
}
|
||
|
||
#if defined( PRE_FATIGUE_DROPITEM_PENALTY )
|
||
int CDNGameRoom::GetFatigueDropRate()
|
||
{
|
||
int iUserCount = 0;
|
||
int iDropRate = 0;
|
||
|
||
for( DWORD i=0; i<m_VecMember.size(); i++ )
|
||
{
|
||
CDNUserSession* pSession = m_VecMember[i].pSession;
|
||
|
||
if( pSession && pSession->GetState() == SESSION_STATE_GAME_PLAY )
|
||
{
|
||
++iUserCount;
|
||
|
||
if( pSession->bIsNoFatigueEnter() )
|
||
{
|
||
iDropRate += static_cast<int>(CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::FatigueDropItemPenalty_Rate )*100);
|
||
}
|
||
else
|
||
{
|
||
iDropRate += 100;
|
||
}
|
||
}
|
||
}
|
||
|
||
if( iUserCount <= 0 )
|
||
return 0;
|
||
|
||
return iDropRate/iUserCount;
|
||
}
|
||
|
||
#endif // #if defined( PRE_FATIGUE_DROPITEM_PENALTY )
|
||
|
||
int CDNGameRoom::GetPartyAvrLevel()
|
||
{
|
||
int nUserCnt, nMountLv;
|
||
nUserCnt = nMountLv = 0;
|
||
|
||
for( DWORD i=0; i<m_VecMember.size(); i++ )
|
||
{
|
||
nMountLv += m_VecMember[i].pSession->GetLevel();
|
||
nUserCnt++;
|
||
}
|
||
return nUserCnt == 0 ? 0 : nMountLv / nUserCnt;
|
||
}
|
||
|
||
void CDNGameRoom::GetLeaderSessionID(UINT &nSessionID)
|
||
{
|
||
for( DWORD i=0; i<m_VecMember.size(); i++ )
|
||
{
|
||
if (m_VecMember[i].bLeader)
|
||
{
|
||
nSessionID = m_VecMember[i].pSession->GetSessionID();
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
|
||
void CDNGameRoom::SetLeaderSession(UINT nSessionID)
|
||
{
|
||
for( DWORD i=0; i<m_VecMember.size(); i++ )
|
||
{
|
||
if (m_VecMember[i].pSession->GetSessionID() == nSessionID)
|
||
{
|
||
m_VecMember[i].bLeader = true;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
void CDNGameRoom::SendRefreshParty(UINT nSessionID, TProfile * pProfile)
|
||
{
|
||
if (GetPartyIndex() <= 0) return; //파티상태진입이 아니라면 0이다.
|
||
|
||
if (nSessionID > 0)
|
||
m_pPartyTask->RequestPartyMember();
|
||
|
||
SPartyMemberInfo Info[PARTYMAX];
|
||
memset(&Info, 0, sizeof(Info));
|
||
|
||
int nCount = 0;
|
||
UINT nLeaderSessionID = 0;
|
||
GetLeaderSessionID(nLeaderSessionID);
|
||
|
||
for( DWORD i=0; i<m_VecMember.size(); i++ )
|
||
{
|
||
if (m_VecMember[i].pSession->GetOutedMember()) continue;
|
||
|
||
m_VecMember[i].pSession->GetPartyMemberInfo(Info[nCount]);
|
||
nCount++;
|
||
}
|
||
|
||
if (nCount <= 0 && nLeaderSessionID <= 0)
|
||
return;
|
||
|
||
bool bAvailable = false;
|
||
#ifdef _USE_VOICECHAT
|
||
bAvailable = m_nVoiceChannelID[0] > 0 ? true : false; //일단은~ 0번만 있어요
|
||
#endif
|
||
#if defined( PRE_WORLDCOMBINE_PARTY )
|
||
int nWorldCombinePartyTableIndex = 0;
|
||
if(Party::bIsWorldCombineParty(m_PartyStructData.Type))
|
||
{
|
||
WorldCombineParty::WrldCombinePartyData* WorldCombinePartyData = g_pDataManager->GetCombinePartyData( m_PartyStructData.nPrimaryIndex );
|
||
if(WorldCombinePartyData)
|
||
nWorldCombinePartyTableIndex = WorldCombinePartyData->cIndex;
|
||
}
|
||
#endif
|
||
|
||
for( DWORD i=0; i<m_VecMember.size(); i++ )
|
||
{
|
||
#if defined( PRE_PARTY_DB )
|
||
#if defined( PRE_WORLDCOMBINE_PARTY )
|
||
if (m_VecMember[i].pSession->GetOutedMember())
|
||
continue;
|
||
m_VecMember[i].pSession->SendRefreshParty(nLeaderSessionID, nCount, bAvailable, Info, PARTYREFRESH_NONE, &m_PartyStructData, nWorldCombinePartyTableIndex );
|
||
#else
|
||
m_VecMember[i].pSession->SendRefreshParty(nLeaderSessionID, m_PartyStructData.wszPartyName, (BYTE)m_PartyStructData.nPartyMaxCount, m_PartyStructData.cMinLevel, nCount, m_PartyStructData.LootRule, m_PartyStructData.LootItemRank, bAvailable, m_PartyStructData.iTargetMapIndex, m_PartyStructData.TargetMapDifficulty, Info, PARTYREFRESH_NONE, m_PartyStructData.Type, m_PartyStructData.iBitFlag, m_PartyStructData.iPassword );
|
||
#endif
|
||
#else
|
||
m_VecMember[i].pSession->SendRefreshParty(nLeaderSessionID, m_wszPartyName, m_wszPartyPass, m_nMemberMax, m_nUserLvMin, m_nUserLvMax, nCount, m_ItemLootRule, m_ItemLootRank, bAvailable, m_nTargetMapIdx, m_PartyDifficulty, Info, PARTYREFRESH_NONE, m_cIsJobDice, m_nMemberMax >= RAIDPARTYCOUNTMIN ? _RAID_PARTY_8 : _NORMAL_PARTY);
|
||
#endif // #if defined( PRE_PARTY_DB )
|
||
|
||
if (pProfile)
|
||
m_VecMember[i].pSession->SendDisplayProfile(nSessionID, *pProfile);
|
||
}
|
||
}
|
||
|
||
bool CDNGameRoom::SetInviteCharacterName(const WCHAR * pwszInvitedCharacterName)
|
||
{
|
||
if (IsInviting())
|
||
return false;
|
||
|
||
_wcscpy(m_wszInvitedCharacterName, _countof(m_wszInvitedCharacterName), pwszInvitedCharacterName, (int)wcslen(pwszInvitedCharacterName));
|
||
m_nInivitedTime = timeGetTime();
|
||
|
||
for( DWORD i=0; i<m_VecMember.size(); i++ )
|
||
m_VecMember[i].pSession->SendPartyIniviteNotice(pwszInvitedCharacterName, ERROR_NONE);
|
||
|
||
return true;
|
||
}
|
||
|
||
bool CDNGameRoom::IsInviting()
|
||
{
|
||
if (m_nInivitedTime == 0 || m_nInivitedTime + (GAMEINVITEWAITTIME) < timeGetTime()) //초대한지 2분이 지났다면 안오는 것으로 간주
|
||
return false;
|
||
return true;
|
||
}
|
||
|
||
bool CDNGameRoom::IsInvitingUser(const WCHAR * pwszName)
|
||
{
|
||
if (!__wcsicmp_l(m_wszInvitedCharacterName, pwszName))
|
||
return true;
|
||
return false;
|
||
}
|
||
|
||
void CDNGameRoom::ResetInvite(int nRetCode, bool bNotice)
|
||
{
|
||
if (bNotice)
|
||
{
|
||
for( DWORD i=0; i<m_VecMember.size(); i++ )
|
||
m_VecMember[i].pSession->SendPartyIniviteNotice(m_wszInvitedCharacterName, nRetCode);
|
||
}
|
||
|
||
memset(m_wszInvitedCharacterName, 0, sizeof(m_wszInvitedCharacterName));
|
||
m_nInivitedTime = 0;
|
||
}
|
||
|
||
int CDNGameRoom::AdjustBreakintoUser(const WCHAR * pwszName, UINT nSessionID, int nRetCode, bool bNotice)
|
||
{
|
||
int nIndex = -1;
|
||
if (GetPartyIndex() > 0)
|
||
{
|
||
ResetInvite(nRetCode, bNotice); //인바이트 플래그 정리
|
||
//들어온 유저에게 인덱스 부여
|
||
nIndex = GetLeftMemberIndex();
|
||
|
||
//난입으로 들어올경우 게임서버에서 초대한 유저가 난입중 나갈경우가 있다 그때 처리용
|
||
UINT nLeaderSessionID = 0;
|
||
GetLeaderSessionID(nLeaderSessionID);
|
||
|
||
if (nLeaderSessionID <= 0)
|
||
SetLeaderSession(nSessionID);
|
||
}
|
||
|
||
return nIndex;
|
||
}
|
||
|
||
// DropItemList 에서 생성된 마지막 DropItem핸들을 넘겨준다.
|
||
DnDropItemHandle CDNGameRoom::RequestItemDropTable( const UINT uiTableID, EtVector3* pPos )
|
||
{
|
||
DNVector(CDnItem::DropItemStruct) vDropItem;
|
||
CDnDropItem::CalcDropItemList( this, uiTableID, vDropItem );
|
||
|
||
DnDropItemHandle hDropItem;
|
||
|
||
for( UINT i=0 ; i<vDropItem.size() ; ++i )
|
||
#if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)
|
||
hDropItem = m_pItemTask->RequestDropItem( vDropItem[i].dwUniqueID, *pPos, vDropItem[i].nItemID, vDropItem[i].nSeed, vDropItem[i].nCount, 0, -1, vDropItem[i].nEnchantID );
|
||
#else // #if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)
|
||
hDropItem = m_pItemTask->RequestDropItem( vDropItem[i].dwUniqueID, *pPos, vDropItem[i].nItemID, vDropItem[i].nSeed, vDropItem[i].nCount, 0 );
|
||
#endif // #if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)
|
||
|
||
return hDropItem;
|
||
}
|
||
|
||
void CDNGameRoom::AddDropItem( const DWORD dwUniqueID, DnDropItemHandle hDropItem )
|
||
{
|
||
m_mDropItem.insert( std::make_pair(dwUniqueID, hDropItem) );
|
||
}
|
||
|
||
void CDNGameRoom::EraseDropItem( const DWORD dwUniqueID )
|
||
{
|
||
m_mDropItem.erase( dwUniqueID );
|
||
}
|
||
|
||
DnDropItemHandle CDNGameRoom::FindDropItem( const DWORD dwUniqueID )
|
||
{
|
||
std::map<const DWORD,DnDropItemHandle>::iterator itor = m_mDropItem.find( dwUniqueID );
|
||
if( itor == m_mDropItem.end() )
|
||
return CDnDropItem::Identity();
|
||
|
||
return itor->second;
|
||
}
|
||
|
||
void CDNGameRoom::RequestChangeMapFromTrigger( int iMapIndex, int iGateNo )
|
||
{
|
||
if( m_vChangeMapQueue.empty() )
|
||
{
|
||
m_vChangeMapQueue.push_back( std::make_pair(iMapIndex,iGateNo) );
|
||
}
|
||
else
|
||
{
|
||
_DANGER_POINT();
|
||
}
|
||
}
|
||
|
||
void CDNGameRoom::SendRefreshRebirthCoin(UINT nSessionID, BYTE cRebirthCoin, BYTE cPCBangRebirthCoin, short nCashRebirthCoin, BYTE cVIPRebirthCoin)
|
||
{
|
||
for(DWORD i=0; i < m_VecMember.size(); i++)
|
||
m_VecMember[i].pSession->SendRefreshRebirthCoin(nSessionID, cRebirthCoin, cPCBangRebirthCoin, nCashRebirthCoin, cVIPRebirthCoin);
|
||
}
|
||
|
||
#ifdef _USE_PEERCONNECT
|
||
void CDNGameRoom::ConnectPeerRequest()
|
||
{
|
||
std::vector<PartyStruct>::iterator i1, i2;
|
||
for (i1 = m_VecMember.begin(); i1 != m_VecMember.end(); i1++)
|
||
{
|
||
if ((*i1).pSession->IsConnected())
|
||
for (i2 = m_VecMember.begin(); i2 != m_VecMember.end(); i2++)
|
||
{
|
||
if ((*i1).pSession != (*i2).pSession && (*i2).pSession->IsConnected() &&
|
||
m_PeerManager.IsConnectedPeer((*i1).pSession->GetSessionID(), (*i2).pSession->GetSessionID()) == false)
|
||
{//연결하라고 클라이언트에 알린다.
|
||
//일단은 붙어 있는 모든 클라이언트를 피어연결 시키지만 앞으로는 거리요소등등을 추가해서 유기적으로 연결 및 끊기를 하는게 좋겠다
|
||
SCPeerConnectRequest packet;
|
||
(*i2).pSession->GetUDPAddr(&packet.nDestAddrIP, &packet.nDestAddrPort);
|
||
packet.nSessionID[0] = (*i1).pSession->GetSessionID();
|
||
packet.nSessionID[1] = (*i2).pSession->GetSessionID();
|
||
|
||
(*i1).pSession->SendPacket(SC_SYSTEM, eSystem::SC_PEER_CONNECT_REQUEST, &packet, sizeof(packet), _RELIABLE);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
#endif
|
||
|
||
void CDNGameRoom::OnInitGameRoomUser()
|
||
{
|
||
if (m_VecMember.empty()) return;
|
||
|
||
for(DWORD i=0; i < m_VecMember.size(); i++)
|
||
{
|
||
#if defined( STRESS_TEST )
|
||
if( true )
|
||
#else
|
||
if (m_VecMember[i].pSession->IsConnected())
|
||
#endif
|
||
m_VecMember[i].pSession->InitialUser();
|
||
}
|
||
}
|
||
|
||
void CDNGameRoom::SendConnectedResult()
|
||
{
|
||
if (m_VecMember.empty()) return;
|
||
|
||
for(DWORD i=0; i < m_VecMember.size(); i++)
|
||
if (m_VecMember[i].pSession->GetState() == SESSION_STATE_LOADED)
|
||
m_VecMember[i].pSession->SendConnectedResult();
|
||
}
|
||
|
||
void CDNGameRoom::SendEquipData( CDNUserSession* pBreakIntoSession )
|
||
{
|
||
if( m_VecMember.empty() )
|
||
return;
|
||
|
||
std::vector<TPartyMemberDefaultParts> vDefaultParts;
|
||
std::vector<TPartyMemberWeaponOrder> vWeaponOreder;
|
||
std::vector<TPartyMemberEquip> vEquip;
|
||
std::vector<TPartyMemberCashEquip> vCashEquip;
|
||
std::vector<TPartyMemberGlyphEquip> vGlyphEquip;
|
||
#if defined(PRE_ADD_TALISMAN_SYSTEM)
|
||
std::vector<TPartyMemberTalismanEquip> vTalismanEquip;
|
||
#endif
|
||
#ifdef PRE_MOD_SYNCPACKET
|
||
std::vector<TPartyVehicle> vVehicle;
|
||
std::vector<TPartyVehicle> vPet;
|
||
#else //#ifdef PRE_MOD_SYNCPACKET
|
||
std::vector<TVehicle> vVehicle;
|
||
std::vector<TVehicle> vPet;
|
||
#endif //#ifdef PRE_MOD_SYNCPACKET
|
||
|
||
vDefaultParts.reserve( m_VecMember.size() );
|
||
vWeaponOreder.reserve( m_VecMember.size() );
|
||
vEquip.reserve( m_VecMember.size() );
|
||
vCashEquip.reserve( m_VecMember.size() );
|
||
vGlyphEquip.reserve( m_VecMember.size() );
|
||
#if defined(PRE_ADD_TALISMAN_SYSTEM)
|
||
vTalismanEquip.reserve( m_VecMember.size() );
|
||
#endif
|
||
vVehicle.reserve( m_VecMember.size() );
|
||
vPet.reserve( m_VecMember.size() );
|
||
|
||
for( DWORD i=0; i<m_VecMember.size(); i++ )
|
||
{
|
||
// DefaultParts
|
||
TPartyMemberDefaultParts DefaultParts;
|
||
#ifdef PRE_MOD_SYNCPACKET
|
||
DefaultParts.nSessionID = m_VecMember[i].pSession->GetSessionID();
|
||
#endif //#ifdef PRE_MOD_SYNCPACKET
|
||
DefaultParts.iDefaultPartsIndex[0] = m_VecMember[i].pSession->GetDefaultBody();
|
||
DefaultParts.iDefaultPartsIndex[1] = m_VecMember[i].pSession->GetDefaultLeg();
|
||
DefaultParts.iDefaultPartsIndex[2] = m_VecMember[i].pSession->GetDefaultHand();
|
||
DefaultParts.iDefaultPartsIndex[3] = m_VecMember[i].pSession->GetDefaultFoot();
|
||
vDefaultParts.push_back( DefaultParts );
|
||
|
||
// WeaponOrder
|
||
TPartyMemberWeaponOrder WeaponOrder;
|
||
#ifdef PRE_MOD_SYNCPACKET
|
||
WeaponOrder.nSessionID = m_VecMember[i].pSession->GetSessionID();
|
||
#endif //#ifdef PRE_MOD_SYNCPACKET
|
||
memcpy(WeaponOrder.cViewCashEquipBitmap, m_VecMember[i].pSession->GetViewCashEquipBitmap(), sizeof(WeaponOrder.cViewCashEquipBitmap));
|
||
vWeaponOreder.push_back( WeaponOrder );
|
||
|
||
// Equip
|
||
TPartyMemberEquip Equip;
|
||
memset( &Equip, 0, sizeof(Equip) );
|
||
|
||
#ifdef PRE_MOD_SYNCPACKET
|
||
Equip.nSessionID = m_VecMember[i].pSession->GetSessionID();
|
||
#endif //#ifdef PRE_MOD_SYNCPACKET
|
||
|
||
for( int j=0 ; j<EQUIPMAX; ++j )
|
||
{
|
||
if( m_VecMember[i].pSession->GetItem()->GetEquip(j) == NULL )
|
||
continue;
|
||
|
||
#ifdef PRE_MOD_SYNCPACKET
|
||
Equip.EquipArray[Equip.cCount].cSlotIndex = j;
|
||
Equip.EquipArray[Equip.cCount].Item = *(m_VecMember[i].pSession->GetItem()->GetEquip(j));
|
||
#else //#ifdef PRE_MOD_SYNCPACKET
|
||
Equip.EquipArray[Equip.cCount].cSlotIndex = j;
|
||
Equip.EquipArray[Equip.cCount].Item = *(m_VecMember[i].pSession->GetItem()->GetEquip(j));
|
||
#endif //#ifdef PRE_MOD_SYNCPACKET
|
||
|
||
++Equip.cCount;
|
||
}
|
||
vEquip.push_back( Equip );
|
||
|
||
// CashEquip
|
||
TPartyMemberCashEquip CashEquip;
|
||
memset( &CashEquip, 0, sizeof(CashEquip) );
|
||
|
||
#ifdef PRE_MOD_SYNCPACKET
|
||
CashEquip.nSessionID = m_VecMember[i].pSession->GetSessionID();
|
||
#endif //#ifdef PRE_MOD_SYNCPACKET
|
||
|
||
for( int j=0 ; j<CASHEQUIPMAX ; ++j )
|
||
{
|
||
if( m_VecMember[i].pSession->GetItem()->GetCashEquip(j) == NULL )
|
||
continue;
|
||
|
||
#ifdef PRE_MOD_SYNCPACKET
|
||
CashEquip.EquipArray[CashEquip.cCount].cSlotIndex = j;
|
||
CashEquip.EquipArray[CashEquip.cCount].Item = *(m_VecMember[i].pSession->GetItem()->GetCashEquip(j));
|
||
#else //#ifdef PRE_MOD_SYNCPACKET
|
||
CashEquip.EquipArray[CashEquip.cCount].cSlotIndex = j;
|
||
CashEquip.EquipArray[CashEquip.cCount].Item = *(m_VecMember[i].pSession->GetItem()->GetCashEquip(j));
|
||
#endif //#ifdef PRE_MOD_SYNCPACKET
|
||
|
||
CashEquip.cCount++;
|
||
}
|
||
vCashEquip.push_back( CashEquip );
|
||
|
||
// Glyph
|
||
TPartyMemberGlyphEquip GlyphEquip;
|
||
memset( &GlyphEquip, 0, sizeof(GlyphEquip) );
|
||
|
||
#ifdef PRE_MOD_SYNCPACKET
|
||
GlyphEquip.nSessionID = m_VecMember[i].pSession->GetSessionID();
|
||
#endif //#ifdef PRE_MOD_SYNCPACKET
|
||
|
||
for( int j=0 ; j<GLYPHMAX ; ++j )
|
||
{
|
||
if( m_VecMember[i].pSession->GetItem()->GetGlyph(j) == NULL )
|
||
continue;
|
||
#ifdef PRE_MOD_SYNCPACKET
|
||
GlyphEquip.EquipArray[GlyphEquip.cCount].cSlotIndex = j;
|
||
GlyphEquip.EquipArray[GlyphEquip.cCount].Item = *(m_VecMember[i].pSession->GetItem()->GetGlyph(j));
|
||
#else //#ifdef PRE_MOD_SYNCPACKET
|
||
GlyphEquip.EquipArray[GlyphEquip.cCount].cSlotIndex = j;
|
||
GlyphEquip.EquipArray[GlyphEquip.cCount].Item = *(m_VecMember[i].pSession->GetItem()->GetGlyph(j));
|
||
#endif //#ifdef PRE_MOD_SYNCPACKET
|
||
GlyphEquip.cCount++;
|
||
}
|
||
vGlyphEquip.push_back( GlyphEquip );
|
||
|
||
#if defined(PRE_ADD_TALISMAN_SYSTEM)
|
||
// Talisman
|
||
TPartyMemberTalismanEquip TalismanEquip;
|
||
memset( &TalismanEquip, 0, sizeof(TalismanEquip) );
|
||
#ifdef PRE_MOD_SYNCPACKET
|
||
TalismanEquip.nSessionID = m_VecMember[i].pSession->GetSessionID();
|
||
#endif //#ifdef PRE_MOD_SYNCPACKET
|
||
for( int j=0 ; j<TALISMAN_MAX ; ++j )
|
||
{
|
||
if( m_VecMember[i].pSession->GetItem()->GetTalisman(j) == NULL )
|
||
continue;
|
||
TalismanEquip.TalismanArray[TalismanEquip.cCount].cSlotIndex = j;
|
||
TalismanEquip.TalismanArray[TalismanEquip.cCount].Item = *(m_VecMember[i].pSession->GetItem()->GetTalisman(j));
|
||
TalismanEquip.cCount++;
|
||
}
|
||
vTalismanEquip.push_back( TalismanEquip );
|
||
#endif //#if defined(PRE_ADD_TALISMAN_SYSTEM)
|
||
|
||
// Vehicle
|
||
#ifdef PRE_MOD_SYNCPACKET
|
||
TPartyVehicle Vehicle;
|
||
memset( &Vehicle, 0, sizeof(Vehicle) );
|
||
Vehicle.nSessionID = m_VecMember[i].pSession->GetSessionID();
|
||
if( m_VecMember[i].pSession->GetItem()->GetVehicleEquip() )
|
||
Vehicle.tVehicle = *(m_VecMember[i].pSession->GetItem()->GetVehicleEquip());
|
||
#else //#ifdef PRE_MOD_SYNCPACKET
|
||
TVehicle Vehicle;
|
||
memset( &Vehicle, 0, sizeof(Vehicle) );
|
||
if( m_VecMember[i].pSession->GetItem()->GetVehicleEquip() )
|
||
Vehicle = *(m_VecMember[i].pSession->GetItem()->GetVehicleEquip());
|
||
#endif //#ifdef PRE_MOD_SYNCPACKET
|
||
vVehicle.push_back( Vehicle );
|
||
|
||
// Pet
|
||
#ifdef PRE_MOD_SYNCPACKET
|
||
TPartyVehicle Pet;
|
||
memset( &Pet, 0, sizeof(Pet) );
|
||
Pet.nSessionID = m_VecMember[i].pSession->GetSessionID();
|
||
if( m_VecMember[i].pSession->GetItem()->GetPetEquip() )
|
||
Pet.tVehicle = *(m_VecMember[i].pSession->GetItem()->GetPetEquip());
|
||
#else //#ifdef PRE_MOD_SYNCPACKET
|
||
TVehicle Pet;
|
||
memset( &Pet, 0, sizeof(Pet) );
|
||
if( m_VecMember[i].pSession->GetItem()->GetPetEquip() )
|
||
Pet = *(m_VecMember[i].pSession->GetItem()->GetPetEquip());
|
||
#endif //#ifdef PRE_MOD_SYNCPACKET
|
||
vPet.push_back( Pet );
|
||
}
|
||
|
||
if( pBreakIntoSession )
|
||
{
|
||
pBreakIntoSession->SendDefaultPartsData( vDefaultParts );
|
||
pBreakIntoSession->SendWeaponOrderData( vWeaponOreder );
|
||
pBreakIntoSession->SendEquipData( vEquip );
|
||
pBreakIntoSession->SendCashEquipData( vCashEquip );
|
||
pBreakIntoSession->SendGlyphEquipData( vGlyphEquip );
|
||
#if defined(PRE_ADD_TALISMAN_SYSTEM)
|
||
pBreakIntoSession->SendTalismanEquipData( vTalismanEquip );
|
||
#endif
|
||
pBreakIntoSession->SendVehicleEquipData( vVehicle );
|
||
pBreakIntoSession->SendPetEquipData(vPet);
|
||
}
|
||
else
|
||
{
|
||
for( DWORD i=0; i<m_VecMember.size(); i++ )
|
||
{
|
||
m_VecMember[i].pSession->SendDefaultPartsData( vDefaultParts );
|
||
m_VecMember[i].pSession->SendWeaponOrderData( vWeaponOreder );
|
||
m_VecMember[i].pSession->SendEquipData( vEquip );
|
||
m_VecMember[i].pSession->SendCashEquipData( vCashEquip );
|
||
m_VecMember[i].pSession->SendGlyphEquipData( vGlyphEquip );
|
||
#if defined(PRE_ADD_TALISMAN_SYSTEM)
|
||
m_VecMember[i].pSession->SendTalismanEquipData( vTalismanEquip );
|
||
#endif
|
||
m_VecMember[i].pSession->SendVehicleEquipData( vVehicle );
|
||
m_VecMember[i].pSession->SendPetEquipData( vPet );
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
void CDNGameRoom::SendSkillData( CDNUserSession* pBreakIntoSession )
|
||
{
|
||
if( m_VecMember.empty() )
|
||
return;
|
||
|
||
std::vector<TPartyMemberSkill> vSkill;
|
||
vSkill.reserve( m_VecMember.size() );
|
||
|
||
for( UINT i=0 ; i<m_VecMember.size() ; ++i )
|
||
{
|
||
TPartyMemberSkill MemberSkill;
|
||
memset( &MemberSkill, 0, sizeof(MemberSkill) );
|
||
|
||
#ifdef PRE_MOD_SYNCPACKET
|
||
MemberSkill.nSessionID = m_VecMember[i].pSession->GetSessionID();
|
||
#endif //#ifdef PRE_MOD_SYNCPACKET
|
||
for( int j=0; j<SKILLMAX; j++ )
|
||
{
|
||
if( m_VecMember[i].pSession->GetSkillData()->SkillList[j].nSkillID <= 0 )
|
||
continue;
|
||
|
||
// 지호씨 액션 파일 최적화 관련 작업, 파티원의 스킬을 모두 보내주도록 한다.
|
||
if( m_VecMember[i].pSession->GetSkillData()->SkillList[j].cSkillLevel < 1 )
|
||
continue;
|
||
|
||
//// 패시브 타입 및 강화 패시브 스킬을 골라서 보내주면 됨.
|
||
//if( CDnSkill::GetSkillType( m_VecMember[i].pSession->GetSkillData()->SkillList[j].nSkillID ) != CDnSkill::Passive &&
|
||
// CDnSkill::GetSkillType( m_VecMember[i].pSession->GetSkillData()->SkillList[j].nSkillID ) != CDnSkill::EnchantPassive )
|
||
// continue;
|
||
|
||
MemberSkill.SkillArray[MemberSkill.cCount] = m_VecMember[i].pSession->GetSkillData()->SkillList[j];
|
||
++MemberSkill.cCount;
|
||
}
|
||
vSkill.push_back( MemberSkill );
|
||
}
|
||
|
||
if( pBreakIntoSession )
|
||
{
|
||
pBreakIntoSession->SendSkillData( vSkill );
|
||
}
|
||
else
|
||
{
|
||
for( UINT i=0 ; i<m_VecMember.size() ; ++i )
|
||
m_VecMember[i].pSession->SendSkillData( vSkill );
|
||
}
|
||
}
|
||
|
||
|
||
void CDNGameRoom::SendEtcData( CDNUserSession *pBreakIntoSession )
|
||
{
|
||
if( m_VecMember.empty() )
|
||
return;
|
||
|
||
std::vector<TPartyEtcData> vEtcData;
|
||
vEtcData.reserve( m_VecMember.size() );
|
||
|
||
for( UINT i=0 ; i<m_VecMember.size() ; ++i )
|
||
{
|
||
TPartyEtcData EtcData;
|
||
memset( &EtcData, 0, sizeof(EtcData) );
|
||
|
||
#ifdef PRE_MOD_SYNCPACKET
|
||
EtcData.nSessionID = m_VecMember[i].pSession->GetSessionID();
|
||
#endif //#ifdef PRE_MOD_SYNCPACKET
|
||
EtcData.nSelectAppellation = m_VecMember[i].pSession->GetSelectAppellation();
|
||
EtcData.nCoverAppellation = m_VecMember[i].pSession->GetCoverAppellation();
|
||
EtcData.cGMTrace = m_VecMember[i].pSession->bIsGMTrace() ? 1 : 0;
|
||
#if defined(PRE_ADD_VIP)
|
||
EtcData.bVIP = m_VecMember[i].pSession->IsVIP();
|
||
#endif // #if defined(PRE_ADD_VIP)
|
||
EtcData.cAccountLevel = m_VecMember[i].pSession->GetAccountLevel();
|
||
vEtcData.push_back(EtcData);
|
||
}
|
||
|
||
if( pBreakIntoSession )
|
||
{
|
||
pBreakIntoSession->SendPartyEtcData( vEtcData );
|
||
#if defined( PRE_ADD_VIP_FARM )
|
||
if( pBreakIntoSession->GetEffectRepository() )
|
||
pBreakIntoSession->GetEffectRepository()->SendEffectItem();
|
||
#endif // #if defined( PRE_ADD_VIP_FARM )
|
||
}
|
||
else
|
||
{
|
||
for( UINT i=0 ; i<m_VecMember.size() ; ++i )
|
||
{
|
||
m_VecMember[i].pSession->SendPartyEtcData( vEtcData );
|
||
#if defined( PRE_ADD_VIP_FARM )
|
||
if( m_VecMember[i].pSession->GetEffectRepository() )
|
||
m_VecMember[i].pSession->GetEffectRepository()->SendEffectItem();
|
||
#endif // #if defined( PRE_ADD_VIP_FARM )
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
void CDNGameRoom::SendSecondAuthInfo( CDNUserSession* pBreakIntoSession )
|
||
{
|
||
if( pBreakIntoSession )
|
||
{
|
||
pBreakIntoSession->SendSecondAuthInfo( pBreakIntoSession->bIsSetSecondAuthPW(), pBreakIntoSession->bIsSetSecondAuthLock() );
|
||
}
|
||
else
|
||
{
|
||
for( UINT i=0 ; i<m_VecMember.size() ; ++i )
|
||
{
|
||
CDNUserSession* pSession = m_VecMember[i].pSession;
|
||
if( pSession )
|
||
{
|
||
pSession->SendSecondAuthInfo( pSession->bIsSetSecondAuthPW(), pSession->bIsSetSecondAuthLock() );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void CDNGameRoom::SendMaxLevelCharacterCount( CDNUserSession* pBreakIntoSession )
|
||
{
|
||
if( pBreakIntoSession )
|
||
{
|
||
pBreakIntoSession->SendMaxLevelCharacterCount( pBreakIntoSession->GetMaxLevelCharacterCount() );
|
||
}
|
||
else
|
||
{
|
||
for( UINT i=0 ; i<m_VecMember.size() ; ++i )
|
||
{
|
||
CDNUserSession* pSession = m_VecMember[i].pSession;
|
||
if( pSession )
|
||
{
|
||
pSession->SendMaxLevelCharacterCount( pSession->GetMaxLevelCharacterCount() );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void CDNGameRoom::SendCompleteGameReady( CDNUserSession* pBreakIntoSession )
|
||
{
|
||
if( pBreakIntoSession )
|
||
{
|
||
if( bIsPvPRoom() )
|
||
{
|
||
pBreakIntoSession->SendStartStage( m_bDirectConnect, m_iMapIdx, m_iGateIdx, m_iRandomSeed, m_StageDifficulty, 0);
|
||
}
|
||
else
|
||
{
|
||
if( m_pGameTask)
|
||
{
|
||
#if defined(PRE_ADD_WORLD_EVENT)
|
||
TEvent * pEvent = GetApplyEventType(WorldEvent::EVENT5);
|
||
#else
|
||
TEvent * pEvent = GetApplyEvent(_EVENT_1_DROPITEM);
|
||
#endif //#if defined(PRE_ADD_WORLD_EVENT)
|
||
pBreakIntoSession->SendStartStage( true, m_pGameTask->GetMapTableID(), m_pGameTask->GetStartPositionIndex(), m_iRandomSeed, m_StageDifficulty, pEvent == NULL ? 0 : pEvent->nAtt1);
|
||
}
|
||
else
|
||
_DANGER_POINT();
|
||
}
|
||
#if defined(PRE_ADD_VIP)
|
||
pBreakIntoSession->SendVIPInfo(pBreakIntoSession->m_nVIPTotalPoint, pBreakIntoSession->m_tVIPEndDate, pBreakIntoSession->m_bVIPAutoPay, pBreakIntoSession->m_bVIP);
|
||
#endif // #if defined(PRE_ADD_VIP)
|
||
}
|
||
else
|
||
{
|
||
#if defined(PRE_ADD_WORLD_EVENT)
|
||
TEvent * pEvent = GetApplyEventType(WorldEvent::EVENT5);
|
||
#else
|
||
TEvent * pEvent = GetApplyEvent(_EVENT_1_DROPITEM);
|
||
#endif //#if defined(PRE_ADD_WORLD_EVENT)
|
||
for( DWORD i=0; i<m_VecMember.size(); i++ )
|
||
{
|
||
m_VecMember[i].pSession->SendStartStage(m_bDirectConnect, m_iMapIdx, m_iGateIdx, m_iRandomSeed, m_StageDifficulty, pEvent == NULL ? 0 : pEvent->nAtt1);
|
||
|
||
#if defined(PRE_ADD_VIP)
|
||
GetUserData(i)->SendVIPInfo(GetUserData(i)->m_nVIPTotalPoint, GetUserData(i)->m_tVIPEndDate, GetUserData(i)->m_bVIPAutoPay, GetUserData(i)->m_bVIP);
|
||
#endif // #if defined(PRE_ADD_VIP)
|
||
}
|
||
}
|
||
}
|
||
|
||
void CDNGameRoom::SendGuildData( CDNUserSession* pBreakIntoSession )
|
||
{
|
||
if (m_VecMember.empty()) {
|
||
return;
|
||
}
|
||
|
||
std::vector<TPartyMemberGuild::TPartyMemberGuildView> vMemberGuildView;
|
||
vMemberGuildView.reserve( m_VecMember.size() );
|
||
|
||
for( UINT i=0 ; i<m_VecMember.size() ; ++i )
|
||
{
|
||
TPartyMemberGuild::TPartyMemberGuildView MemberGuildView;
|
||
MemberGuildView.Set( m_VecMember[i].pSession->GetSessionID(), m_VecMember[i].pSession->GetGuildSelfView() );
|
||
vMemberGuildView.push_back( MemberGuildView );
|
||
}
|
||
|
||
if (pBreakIntoSession)
|
||
{
|
||
pBreakIntoSession->SendPartyGuildData( vMemberGuildView );
|
||
}
|
||
else
|
||
{
|
||
for( UINT i=0 ; i<m_VecMember.size() ; ++i )
|
||
m_VecMember[i].pSession->SendPartyGuildData( vMemberGuildView );
|
||
}
|
||
}
|
||
|
||
void CDNGameRoom::SendMasterSystemSimpleInfo( CDNUserSession* pBreakIntoSession )
|
||
{
|
||
if( pBreakIntoSession )
|
||
{
|
||
pBreakIntoSession->SendMasterSystemSimpleInfo( const_cast<TMasterSystemSimpleInfo&>(pBreakIntoSession->GetMasterSystemData()->SimpleInfo) );
|
||
}
|
||
else
|
||
{
|
||
for( UINT i=0 ; i<m_VecMember.size() ; ++i )
|
||
{
|
||
m_VecMember[i].pSession->SendMasterSystemSimpleInfo( const_cast<TMasterSystemSimpleInfo&>(m_VecMember[i].pSession->GetMasterSystemData()->SimpleInfo) );
|
||
}
|
||
}
|
||
}
|
||
|
||
void CDNGameRoom::SendMasterSystemCountInfo( CDNUserSession* pBreakIntoSession )
|
||
{
|
||
MasterSystem::CRewardSystem::TCountInfo CountInfo;
|
||
|
||
if( pBreakIntoSession )
|
||
{
|
||
m_pMasterRewardSystem->GetCountInfo( pBreakIntoSession, CountInfo );
|
||
pBreakIntoSession->SendMasterSystemCountInfo( CountInfo.iMasterCount, CountInfo.iPupilCount, CountInfo.iClassmateCount );
|
||
}
|
||
else
|
||
{
|
||
for( UINT i=0 ; i<m_VecMember.size() ; ++i )
|
||
{
|
||
m_pMasterRewardSystem->GetCountInfo( m_VecMember[i].pSession, CountInfo );
|
||
m_VecMember[i].pSession->SendMasterSystemCountInfo( CountInfo.iMasterCount, CountInfo.iPupilCount, CountInfo.iClassmateCount );
|
||
}
|
||
}
|
||
}
|
||
#if defined( PRE_ADD_NPC_REPUTATION_SYSTEM )
|
||
void CDNGameRoom::SendReputationList( CDNUserSession* pBreakIntoSession )
|
||
{
|
||
if( pBreakIntoSession )
|
||
{
|
||
_ASSERT( pBreakIntoSession->GetReputationSystem() && pBreakIntoSession->GetReputationSystem()->GetEventHandler() );
|
||
pBreakIntoSession->GetReputationSystem()->GetEventHandler()->OnConnect( 0, true );
|
||
}
|
||
else
|
||
{
|
||
for( UINT i=0 ; i<m_VecMember.size() ; ++i )
|
||
{
|
||
_ASSERT( m_VecMember[i].pSession->GetReputationSystem() && m_VecMember[i].pSession->GetReputationSystem()->GetEventHandler() );
|
||
m_VecMember[i].pSession->GetReputationSystem()->GetEventHandler()->OnConnect( 0, true );
|
||
}
|
||
}
|
||
}
|
||
#endif // #if defined( PRE_ADD_NPC_REPUTATION_SYSTEM )
|
||
|
||
#if defined (PRE_ADD_BESTFRIEND)
|
||
void CDNGameRoom::SendBestFriendData( CDNUserSession* pBreakIntoSession )
|
||
{
|
||
if (m_VecMember.empty())
|
||
return;
|
||
|
||
std::vector<TPartyBestFriend> vMemberBestFriend;
|
||
vMemberBestFriend.reserve(m_VecMember.size());
|
||
|
||
for (UINT i=0; i<m_VecMember.size(); i++)
|
||
{
|
||
TPartyBestFriend MemberBestFriend = {0,};
|
||
MemberBestFriend.nSessionID = m_VecMember[i].pSession->GetSessionID();
|
||
|
||
TBestFriendInfo& Info = m_VecMember[i].pSession->GetBestFriend()->GetInfo();
|
||
MemberBestFriend.biBFItemSerial = Info.biItemSerial;
|
||
_wcscpy(MemberBestFriend.wszBFName, _countof(MemberBestFriend.wszBFName), Info.wszName, (int)wcslen(Info.wszName));
|
||
|
||
vMemberBestFriend.push_back( MemberBestFriend );
|
||
}
|
||
|
||
if (pBreakIntoSession)
|
||
{
|
||
pBreakIntoSession->SendPartyBestFriend( vMemberBestFriend );
|
||
}
|
||
else
|
||
{
|
||
for( UINT i=0 ; i<m_VecMember.size() ; ++i )
|
||
m_VecMember[i].pSession->SendPartyBestFriend( vMemberBestFriend );
|
||
}
|
||
}
|
||
#endif
|
||
|
||
#if defined( PRE_ADD_NAMEDITEM_SYSTEM )
|
||
void CDNGameRoom::SendPartyEffectSkillItemData( CDNUserSession* pBreakIntoSession )
|
||
{
|
||
if ( !pBreakIntoSession || m_VecMember.empty())
|
||
return;
|
||
|
||
for (UINT i=0; i<m_VecMember.size(); i++)
|
||
{
|
||
if( m_VecMember[i].pSession && m_VecMember[i].pSession->GetSessionID() != pBreakIntoSession->GetSessionID() )
|
||
{
|
||
std::vector<TEffectSkillData> vEffectSkill;
|
||
vEffectSkill.clear();
|
||
m_VecMember[i].pSession->GetItem()->GetEffectSkillItem( vEffectSkill);
|
||
pBreakIntoSession->SendEffectSkillItemData(m_VecMember[i].pSession->GetSessionID(), vEffectSkill, false);
|
||
}
|
||
}
|
||
}
|
||
#endif
|
||
|
||
#if defined( PRE_ADD_TOTAL_LEVEL_SKILL )
|
||
void CDNGameRoom::SendTotalLevelSkillInfo( CDNUserSession* pBreakIntoSession )
|
||
{
|
||
if ( !pBreakIntoSession || m_VecMember.empty())
|
||
return;
|
||
|
||
int* nTotalLevelSkillData = pBreakIntoSession->GetTotalLevelSkillData();
|
||
|
||
pBreakIntoSession->SendTotalLevel(pBreakIntoSession->GetSessionID(), pBreakIntoSession->GetTotalLevelSkillLevel());
|
||
for(int i=0;i<TotalLevelSkill::Common::MAXSLOTCOUNT;i++)
|
||
{
|
||
if(g_pDataManager->bIsTotalLevelSkillCashSlot(i))
|
||
pBreakIntoSession->SendTotalLevelSkillCashSlot(pBreakIntoSession->GetSessionID(), i, pBreakIntoSession->bIsTotalLevelSkillCashSlot(i), pBreakIntoSession->GetTotalLevelSkillCashSlot(i));
|
||
}
|
||
pBreakIntoSession->SendTotalLevelSkillList(pBreakIntoSession->GetSessionID(), nTotalLevelSkillData);
|
||
}
|
||
#endif
|
||
|
||
#if defined(_HSHIELD)
|
||
void CDNGameRoom::SendMakeReq()
|
||
{
|
||
if (m_VecMember.empty()) return;
|
||
|
||
for(DWORD i=0; i < m_VecMember.size(); i++){
|
||
if (m_VecMember[i].pSession->GetAccountLevel() != AccountLevel_Developer){ // 개발자가 아니면
|
||
m_VecMember[i].pSession->SendMakeRequest(); // crc요청
|
||
}
|
||
}
|
||
}
|
||
|
||
#elif defined(_GPK)
|
||
void CDNGameRoom::SendGPKCode()
|
||
{
|
||
if (m_VecMember.empty()) return;
|
||
if (m_bGPKCodeFlag) return;
|
||
m_bGPKCodeFlag = true;
|
||
ULONG nCurTick = timeGetTime();
|
||
|
||
for(DWORD i=0; i < m_VecMember.size(); i++)
|
||
{
|
||
m_VecMember[i].pSession->SendGPKCode();
|
||
m_VecMember[i].pSession->SendGPKAuthData();
|
||
|
||
m_VecMember[i].pSession->SendGPKData();
|
||
m_VecMember[i].pSession->SetCheckGPKTick(nCurTick);
|
||
m_VecMember[i].pSession->SetRecvGPKTick(nCurTick);
|
||
}
|
||
}
|
||
#endif // _HSHIELD
|
||
|
||
float CDNGameRoom::GetEventExpWhenMonsterDie(float fExp, bool bFriendBonus, char cClassID, BYTE cJobID)
|
||
{
|
||
if( fExp <= 0.f )
|
||
return 0.f;
|
||
|
||
time_t Time;
|
||
time(&Time);
|
||
|
||
float fEvent = 0.0f;
|
||
#if defined(PRE_ADD_WORLD_EVENT)
|
||
DNVector(TEvent)::iterator ii;
|
||
for (ii = m_EventList.begin(); ii != m_EventList.end(); ii++)
|
||
{
|
||
if (Time >= (*ii)._tBeginTime && Time <= (*ii)._tEndTime)
|
||
{
|
||
switch ((*ii).nEventType2)
|
||
{
|
||
case WorldEvent::EVENT1 : //1. 몬스터사망시 경험치(파티)
|
||
{
|
||
if( (*ii).nEventType1 == 0 || (*ii).nEventType1 == cClassID )
|
||
{
|
||
if (GetUserCount() >= (DWORD)(*ii).nAtt1)
|
||
fEvent += (float)((fExp * (float)((float)((*ii).nAtt2)/100)) + 0.5f);
|
||
}
|
||
break;
|
||
}
|
||
case WorldEvent::EVENT2 : //2. 몬스터사망시 경험치
|
||
{
|
||
if( (*ii).nEventType1 == 0 || (*ii).nEventType1 == cClassID )
|
||
{
|
||
fEvent += (float)((fExp * (float)((float)((*ii).nAtt1)/100)) + 0.5f);
|
||
}
|
||
break;
|
||
}
|
||
case WorldEvent::EVENT9 : //9. 파티유지
|
||
{
|
||
#if defined( PRE_PARTY_DB )
|
||
if (m_PartyStructData.iUpkeepCount > 0)
|
||
#else
|
||
if (m_nUpkeepCount > 0)
|
||
#endif
|
||
{
|
||
#if defined( PRE_PARTY_DB )
|
||
int nRate = (*ii).nAtt1 * m_PartyStructData.iUpkeepCount;
|
||
#else
|
||
int nRate = (*ii).nAtt1 * m_nUpkeepCount;
|
||
#endif
|
||
nRate = nRate > (*ii).nAtt2 ? (*ii).nAtt2 : nRate;
|
||
fEvent += (float)((fExp * (float)((float)(nRate)/100)) + 0.5f);
|
||
}
|
||
break;
|
||
}
|
||
case WorldEvent::EVENT10 : //10. 친구끼리 파티
|
||
{
|
||
if (bFriendBonus){
|
||
int nFriendExp = (*ii).nAtt1;
|
||
fEvent += (float)((fExp * (float)((float)(nFriendExp)/100)) + 0.5f);
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
#else //#if defined(PRE_ADD_WORLD_EVENT)
|
||
DNVector(TEvent)::iterator ii;
|
||
for (ii = m_EventList.begin(); ii != m_EventList.end(); ii++)
|
||
{
|
||
if (Time >= (*ii)._tBeginTime && Time <= (*ii)._tEndTime && (*ii).nEventType1 == _EVENT_1_EXP && (*ii).nEventType2 == _EVENT_2_MONSTERDIE)
|
||
{
|
||
switch ((*ii).nEventType3)
|
||
{
|
||
case _EVENT_3_NONE: fEvent += (float)((fExp * (float)((float)((*ii).nAtt1)/100)) + 0.5f); break;
|
||
case _EVENT_3_PARTY:
|
||
{
|
||
if (GetUserCount() >= (DWORD)(*ii).nAtt1)
|
||
fEvent += (float)((fExp * (float)((float)((*ii).nAtt2)/100)) + 0.5f);
|
||
break;
|
||
}
|
||
case _EVENT_3_UPKEEPPARTY:
|
||
{
|
||
#if defined( PRE_PARTY_DB )
|
||
if (m_PartyStructData.iUpkeepCount > 0)
|
||
#else
|
||
if (m_nUpkeepCount > 0)
|
||
#endif
|
||
{
|
||
#if defined( PRE_PARTY_DB )
|
||
int nRate = (*ii).nAtt1 * m_PartyStructData.iUpkeepCount;
|
||
#else
|
||
int nRate = (*ii).nAtt1 * m_nUpkeepCount;
|
||
#endif
|
||
nRate = nRate > (*ii).nAtt2 ? (*ii).nAtt2 : nRate;
|
||
fEvent += (float)((fExp * (float)((float)(nRate)/100)) + 0.5f);
|
||
}
|
||
break;
|
||
}
|
||
case _EVENT_3_FRIENDPARTY:
|
||
{
|
||
if (bFriendBonus){
|
||
int nFriendExp = (*ii).nAtt1;
|
||
fEvent += (float)((fExp * (float)((float)(nFriendExp)/100)) + 0.5f);
|
||
}
|
||
break;
|
||
}
|
||
case _EVENT_3_CLASSEXP:
|
||
{
|
||
int nRate = 0;
|
||
// nAtt1 클래스 ID, nAtt2 Job ID, nAtt3 경험치 %
|
||
if( cClassID == (*ii).nAtt1 )
|
||
{
|
||
if( (*ii).nAtt2 == 0 || cJobID == (*ii).nAtt2 )
|
||
nRate = (*ii).nAtt3;
|
||
}
|
||
if( nRate )
|
||
fEvent += (float)((fExp * (float)((float)(nRate)/100)) + 0.5f);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
#endif // #if defined(PRE_ADD_WORLD_EVENT)
|
||
return fEvent;
|
||
}
|
||
|
||
#if defined(PRE_ADD_WORLD_EVENT)
|
||
int CDNGameRoom::GetEventType(int nType, char cClassID)
|
||
{
|
||
time_t Time;
|
||
time(&Time);
|
||
|
||
DNVector(TEvent)::iterator ii;
|
||
for (ii = m_EventList.begin(); ii != m_EventList.end(); ii++)
|
||
{
|
||
if (Time >= (*ii)._tBeginTime && Time <= (*ii)._tEndTime)
|
||
{
|
||
if ((*ii).nEventType2 == nType)
|
||
{
|
||
if( (*ii).nEventType1 == 0 || cClassID == 0 || (*ii).nEventType1 == cClassID )
|
||
return (*ii).nAtt1;
|
||
}
|
||
}
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
TEvent * CDNGameRoom::GetApplyEventType(int nType)
|
||
{
|
||
time_t Time;
|
||
time(&Time);
|
||
|
||
DNVector(TEvent)::iterator ii;
|
||
for (ii = m_EventList.begin(); ii != m_EventList.end(); ii++)
|
||
{
|
||
if (Time >= (*ii)._tBeginTime && Time <= (*ii)._tEndTime && (*ii).nEventType2 == nType)
|
||
return &(*ii);
|
||
}
|
||
return NULL;
|
||
}
|
||
|
||
#else
|
||
TEvent * CDNGameRoom::GetApplyEvent(int nEventType, int nEventType2, int nEventType3)
|
||
{
|
||
time_t Time;
|
||
time(&Time);
|
||
|
||
DNVector(TEvent)::iterator ii;
|
||
for (ii = m_EventList.begin(); ii != m_EventList.end(); ii++)
|
||
if (Time >= (*ii)._tBeginTime && Time <= (*ii)._tEndTime && (*ii).nEventType1 == nEventType && (*ii).nEventType2 == nEventType2 && (*ii).nEventType3 == nEventType3)
|
||
return &(*ii);
|
||
return NULL;
|
||
}
|
||
#endif
|
||
|
||
bool CDNGameRoom::GetExtendDropRateIgnoreTime(int &nRate)
|
||
{
|
||
//드랍레이트관련은 조금 다른처리 GetEvent시 드랍관련 이벤트가 존재한다면 중간 데이터얻을시에는 시간검사를 하지 않는다.
|
||
DNVector(TEvent)::iterator ii;
|
||
for (ii = m_EventList.begin(); ii != m_EventList.end(); ii++)
|
||
{
|
||
#if defined(PRE_ADD_WORLD_EVENT)
|
||
if ((*ii).nEventType2 == WorldEvent::EVENT5)
|
||
#else
|
||
if ((*ii).nEventType1 == _EVENT_1_DROPITEM)
|
||
#endif
|
||
{
|
||
TEvent * pEvent = &(*ii);
|
||
nRate = pEvent->nAtt1;
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
void CDNGameRoom::GetEventExpWhenStageClear(CDNUserSession * pSession, int nCalcVal, BYTE &cCount, sEventStageClearBonus * pBonus)
|
||
{
|
||
time_t Time;
|
||
time(&Time);
|
||
#if defined(PRE_ADD_WORLD_EVENT)
|
||
/*
|
||
#if defined(_CH)
|
||
// ekey, ecard
|
||
int nEkey = CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::CLEAR_EXP_EKEYECARD );
|
||
if( nEkey > 0 )
|
||
{
|
||
if (pSession->CheckSndaAuthFlag(eChSndaAuthFlag_UseEKey) || pSession->CheckSndaAuthFlag(eChSndaAuthFlag_UseECard))
|
||
{
|
||
pBonus[cCount].nType = _EVENT_3_EKEYANDECARD;
|
||
pBonus[cCount].nClearEventBonusExperience = (int)(((float)nCalcVal * (float)((float)(nEkey)/100)) + 0.5f);
|
||
cCount++;
|
||
}
|
||
}
|
||
#endif //#if defined(_CH)
|
||
*/
|
||
DNVector(TEvent)::iterator ii;
|
||
for (ii = m_EventList.begin(); ii != m_EventList.end(); ii++)
|
||
{
|
||
if (Time >= (*ii)._tBeginTime && Time <= (*ii)._tEndTime )
|
||
{
|
||
switch ((*ii).nEventType2)
|
||
{
|
||
case WorldEvent::EVENT3 : //3. 스테이지클리어 경험치
|
||
{
|
||
if( (*ii).nEventType1 == 0 || (*ii).nEventType1 == pSession->GetClassID() )
|
||
{
|
||
pBonus[cCount].nType = WorldEvent::EVENT3;
|
||
pBonus[cCount].nClearEventBonusExperience = (int)(((float)nCalcVal * (float)((float)((*ii).nAtt1)/100)) + 0.5f);
|
||
cCount++;
|
||
}
|
||
break;
|
||
}
|
||
case WorldEvent::EVENT8 ://8. 2차인증
|
||
{
|
||
if( pSession->bIsSetSecondAuthPW() && ((*ii).nEventType1 == 0 || (*ii).nEventType1 == pSession->GetClassID()) )
|
||
{
|
||
pBonus[cCount].nType = WorldEvent::EVENT8;
|
||
pBonus[cCount].nClearEventBonusExperience = (int)(((float)nCalcVal * (float)((float)((*ii).nAtt1)/100)) + 0.5f);
|
||
cCount++;
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
#else // #if defined(PRE_ADD_WORLD_EVENT)
|
||
|
||
DNVector(TEvent)::iterator ii;
|
||
for (ii = m_EventList.begin(); ii != m_EventList.end(); ii++)
|
||
{
|
||
if (Time >= (*ii)._tBeginTime && Time <= (*ii)._tEndTime && (*ii).nEventType1 == _EVENT_1_EXP && (*ii).nEventType2 == _EVENT_2_CLEAR)
|
||
{
|
||
switch ((*ii).nEventType3)
|
||
{
|
||
case _EVENT_3_SECONDAUTH:
|
||
{
|
||
if (pSession->bIsSetSecondAuthPW())
|
||
{
|
||
pBonus[cCount].nType = _EVENT_3_SECONDAUTH;
|
||
pBonus[cCount].nClearEventBonusExperience = (int)(((float)nCalcVal * (float)((float)((*ii).nAtt1)/100)) + 0.5f);
|
||
cCount++;
|
||
}
|
||
break;
|
||
}
|
||
case _EVENT_3_EKEYANDECARD:
|
||
{
|
||
#if defined (_CH)
|
||
if (pSession->CheckSndaAuthFlag(eChSndaAuthFlag_UseEKey) || pSession->CheckSndaAuthFlag(eChSndaAuthFlag_UseECard))
|
||
{
|
||
pBonus[cCount].nType = _EVENT_3_EKEYANDECARD;
|
||
pBonus[cCount].nClearEventBonusExperience = (int)(((float)nCalcVal * (float)((float)((*ii).nAtt1)/100)) + 0.5f);
|
||
cCount++;
|
||
}
|
||
#endif
|
||
break;
|
||
}
|
||
case _EVENT_3_CLASSEXP:
|
||
{
|
||
|
||
int nRate = 0;
|
||
// nAtt1 클래스 ID, nAtt2 Job ID, nAtt3 경험치 %
|
||
if( pSession->GetClassID() == (*ii).nAtt1 )
|
||
{
|
||
if( (*ii).nAtt2 == 0 || pSession->GetUserJob() == (*ii).nAtt2 )
|
||
nRate = (*ii).nAtt3;
|
||
}
|
||
if( nRate )
|
||
{
|
||
pBonus[cCount].nType = _EVENT_3_CLASSEXP;
|
||
pBonus[cCount].nClearEventBonusExperience = (int)(((float)nCalcVal * (float)((float)(nRate)/100)) + 0.5f);
|
||
cCount++;
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (cCount >= EVENTCLEARBONUSMAX)
|
||
break;
|
||
}
|
||
}
|
||
#endif //#if defined(PRE_ADD_WORLD_EVENT)
|
||
}
|
||
|
||
|
||
void CDNGameRoom::GetAppliedEventValue(int &nDropRate, int &nUpkeepRate, int &nFriendBonusRate, bool * pUpkeepMax)
|
||
{
|
||
time_t Time;
|
||
time(&Time);
|
||
|
||
DNVector(TEvent)::iterator ii;
|
||
for (ii = m_EventList.begin(); ii != m_EventList.end(); ii++)
|
||
{
|
||
if (Time >= (*ii)._tBeginTime && Time <= (*ii)._tEndTime)
|
||
{
|
||
#if defined(PRE_ADD_WORLD_EVENT)
|
||
switch ((*ii).nEventType2)
|
||
{
|
||
case WorldEvent::EVENT5 : //5. 아이템 드랍률 증가:
|
||
{
|
||
nDropRate = (*ii).nAtt1;
|
||
break;
|
||
}
|
||
case WorldEvent::EVENT9 : //9. 파티유지_EVENT_1_EXP:
|
||
{
|
||
if (GetUserCount() > 1)
|
||
{
|
||
#if defined( PRE_PARTY_DB )
|
||
nUpkeepRate = (*ii).nAtt1 * m_PartyStructData.iUpkeepCount;
|
||
#else
|
||
nUpkeepRate = (*ii).nAtt1 * m_nUpkeepCount;
|
||
#endif
|
||
if (nUpkeepRate > (*ii).nAtt2)
|
||
{
|
||
if (pUpkeepMax)
|
||
*pUpkeepMax = true;
|
||
nUpkeepRate = (*ii).nAtt2;
|
||
}
|
||
}
|
||
else
|
||
nUpkeepRate = 0;
|
||
}
|
||
break;
|
||
case WorldEvent::EVENT10 : //10. 친구끼리 파티
|
||
{
|
||
nFriendBonusRate = (*ii).nAtt1;
|
||
}
|
||
break;
|
||
}
|
||
#else //#if defined(PRE_ADD_WORLD_EVENT)
|
||
switch ((*ii).nEventType1)
|
||
{
|
||
case _EVENT_1_DROPITEM:
|
||
{
|
||
nDropRate = (*ii).nAtt1;
|
||
break;
|
||
}
|
||
case _EVENT_1_EXP:
|
||
{
|
||
if ((*ii).nEventType2 == _EVENT_2_MONSTERDIE)
|
||
{
|
||
if ((*ii).nEventType3 == _EVENT_3_UPKEEPPARTY)
|
||
{
|
||
if (GetUserCount() > 1)
|
||
{
|
||
#if defined( PRE_PARTY_DB )
|
||
nUpkeepRate = (*ii).nAtt1 * m_PartyStructData.iUpkeepCount;
|
||
#else
|
||
nUpkeepRate = (*ii).nAtt1 * m_nUpkeepCount;
|
||
#endif
|
||
if (nUpkeepRate > (*ii).nAtt2)
|
||
{
|
||
if (pUpkeepMax)
|
||
*pUpkeepMax = true;
|
||
nUpkeepRate = (*ii).nAtt2;
|
||
}
|
||
}
|
||
else
|
||
nUpkeepRate = 0;
|
||
}
|
||
else if ((*ii).nEventType3 == _EVENT_3_FRIENDPARTY)
|
||
{
|
||
nFriendBonusRate = (*ii).nAtt1;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
#endif //#if defined(PRE_ADD_WORLD_EVENT)
|
||
}
|
||
}
|
||
}
|
||
|
||
void CDNGameRoom::CheckFriendBonus(UINT nDelSessionID)
|
||
{
|
||
//if (m_VecMember.size() <= 1) return;
|
||
#if defined(PRE_ADD_WORLD_EVENT)
|
||
if ( GetApplyEventType( WorldEvent::EVENT10 ) == NULL ) return;
|
||
#else
|
||
if (GetApplyEvent(_EVENT_1_EXP, _EVENT_2_MONSTERDIE, _EVENT_3_FRIENDPARTY) == NULL) return;
|
||
#endif
|
||
|
||
for(DWORD i=0; i < m_VecMember.size(); i++)
|
||
{
|
||
bool bCheck = false;
|
||
if (nDelSessionID != m_VecMember[i].pSession->GetSessionID()) //나가는 녀석이면 검사하지 않고 false로
|
||
{
|
||
CDNFriend * pFriend = m_VecMember[i].pSession->GetFriend();
|
||
for(DWORD j=0; j < m_VecMember.size(); j++)
|
||
{
|
||
if (m_VecMember[j].pSession->GetSessionID() == nDelSessionID) continue; //나가는 녀석이 검사 대상이라면 패쓰~
|
||
|
||
CDNFriend * pTempFriend = m_VecMember[j].pSession->GetFriend();
|
||
if (pTempFriend == NULL) continue;
|
||
|
||
if (pFriend->HasFriend(m_VecMember[j].pSession->GetCharacterDBID()) && pTempFriend->HasFriend(m_VecMember[i].pSession->GetCharacterDBID()))
|
||
{
|
||
bCheck = true;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
m_VecMember[i].pSession->SetFriendBonus(bCheck);
|
||
}
|
||
}
|
||
|
||
#ifdef PRE_ADD_BEGINNERGUILD
|
||
void CDNGameRoom::CheckBeginnerGuildBonus()
|
||
{
|
||
m_PartyStructData.bPartyBeginnerGuild = false;
|
||
|
||
CDNUserSession * pUser = NULL;
|
||
int nBegginerGuildCount = 0;
|
||
DNVector(PartyStruct)::iterator ii;
|
||
CDNGuildBase * pGuild = NULL;
|
||
for(ii = m_VecMember.begin(); ii != m_VecMember.end(); ii++)
|
||
{
|
||
pUser = (*ii).pSession;
|
||
if (pUser == NULL) continue;
|
||
if (pUser->bIsGMTrace()) continue;
|
||
|
||
pUser->m_bPartyBegginerGuild = false;
|
||
|
||
if (pUser->GetGuildUID().IsSet() == false)
|
||
continue;
|
||
|
||
pGuild = g_pGuildManager->At(pUser->GetGuildUID());
|
||
if (pGuild)
|
||
{
|
||
#if !defined( PRE_ADD_NODELETEGUILD )
|
||
CDetachAutoEx<CDNGuildBase> AutoDetach(pGuild);
|
||
if (TRUE == pGuild->IsEnable())
|
||
{
|
||
if (pGuild->GetInfo()->cGuildType == BeginnerGuild::Type::Beginner && pGuild->IsMemberExist(pUser->GetCharacterDBID()))
|
||
{
|
||
nBegginerGuildCount++;
|
||
pUser->m_bPartyBegginerGuild = true;
|
||
}
|
||
}
|
||
#else //#if !defined( PRE_ADD_NODELETEGUILD )
|
||
if (pGuild->GetInfo()->cGuildType == BeginnerGuild::Type::Beginner && pGuild->IsMemberExist(pUser->GetCharacterDBID()))
|
||
{
|
||
nBegginerGuildCount++;
|
||
pUser->m_bPartyBegginerGuild = true;
|
||
}
|
||
#endif //#if !defined( PRE_ADD_NODELETEGUILD )
|
||
}
|
||
}
|
||
|
||
if (nBegginerGuildCount >= 2)
|
||
m_PartyStructData.bPartyBeginnerGuild = true;
|
||
}
|
||
#endif //#ifdef PRE_ADD_BEGINNERGUILD
|
||
|
||
void CDNGameRoom::UpdateAppliedEventValue()
|
||
{
|
||
CheckFriendBonus();
|
||
#ifdef PRE_ADD_BEGINNERGUILD
|
||
int nDropRate = 0, nUpkeepRate = 0, nFriendRate = 0, nBeginnerGuildRate = 0;
|
||
#else //#ifdef PRE_ADD_BEGINNERGUILD
|
||
int nDropRate = 0, nUpkeepRate = 0, nFriendRate = 0;
|
||
#endif //#ifdef PRE_ADD_BEGINNERGUILD
|
||
bool bMax = false;
|
||
GetAppliedEventValue(nDropRate, nUpkeepRate, nFriendRate, &bMax);
|
||
#ifdef PRE_ADD_BEGINNERGUILD
|
||
CheckBeginnerGuildBonus();
|
||
nBeginnerGuildRate = m_PartyStructData.bPartyBeginnerGuild == true ? BeginnerGuild::Common::PartyBonusRate : 0;
|
||
#endif //#ifdef PRE_ADD_BEGINNERGUILD
|
||
|
||
for( DWORD i=0; i<GetUserCount(); i++ )
|
||
{
|
||
#ifdef PRE_ADD_BEGINNERGUILD
|
||
GetUserData(i)->SendPartyBonusValue(nUpkeepRate, nFriendRate, bMax, nBeginnerGuildRate);
|
||
#else //#ifdef PRE_ADD_BEGINNERGUILD
|
||
GetUserData(i)->SendPartyBonusValue(nUpkeepRate, nFriendRate, bMax);
|
||
#endif //#ifdef PRE_ADD_BEGINNERGUILD
|
||
}
|
||
}
|
||
|
||
void CDNGameRoom::ResetCompleteExperience()
|
||
{
|
||
m_nCompleteExperience = 0;
|
||
}
|
||
|
||
void CDNGameRoom::AddCompleteExperience( int nValue )
|
||
{
|
||
m_nCompleteExperience += nValue;
|
||
}
|
||
|
||
int CDNGameRoom::GetCompleteExperience()
|
||
{
|
||
return m_nCompleteExperience;
|
||
}
|
||
|
||
void CDNGameRoom::ResetDungeonPlayTime()
|
||
{
|
||
m_dwDungeonPlayerTime = 0;
|
||
}
|
||
|
||
void CDNGameRoom::AddDungeonPlayTime( DWORD dwValue )
|
||
{
|
||
m_dwDungeonPlayerTime += dwValue;
|
||
}
|
||
|
||
DWORD CDNGameRoom::GetDungeonPlayTime()
|
||
{
|
||
return m_dwDungeonPlayerTime;
|
||
}
|
||
|
||
#if defined( PRE_ADD_58761 )
|
||
void CDNGameRoom::StartDungeonGateTime(int nGateID)
|
||
{
|
||
// 관문 시작 로그
|
||
GetDBConnection()->QueryAddNestGateStartLog( GetDBThreadID(), GetWorldSetID(), 0, GetRoomLogIndex(), static_cast<BYTE>(GetUserCount()), nGateID );
|
||
m_nDungeonGateID = nGateID;
|
||
}
|
||
|
||
void CDNGameRoom::EndDungeonGateTime(int nGateID, bool bClearFlag/*=false*/)
|
||
{
|
||
//관문 종료 로그
|
||
#if defined( _WORK )
|
||
if(m_nDungeonGateID != nGateID )
|
||
g_Log.Log( LogType::_ERROR, L"api_trigger_EndDungeonGateTime Error ServerGateNumber:%d ApiGateNumber:%d", m_nDungeonGateID, nGateID );
|
||
#endif
|
||
|
||
if (GetDBConnection())
|
||
{
|
||
CDNUserSession * pUser;
|
||
for (int i = 0; i < (int)GetUserCount(); i++)
|
||
{
|
||
pUser = GetUserData(i);
|
||
if (pUser == NULL) continue;
|
||
GetDBConnection()->QueryAddNestGateClearLog( GetDBThreadID(), GetWorldSetID(), 0, GetRoomLogIndex(), bClearFlag, pUser->GetCharacterDBID(), pUser->GetUserJob(), pUser->GetLevel());
|
||
}
|
||
|
||
GetDBConnection()->QueryAddNestGateEndLog( GetDBThreadID(), GetWorldSetID(), 0, GetRoomLogIndex(), static_cast<BYTE>(GetUserCount()));
|
||
}
|
||
// 초기화
|
||
m_nDungeonGateID = 0;
|
||
}
|
||
|
||
void CDNGameRoom::NestDeathLog(CDNUserSession *pSession, int nMonsterID, int nSkillID, BYTE cCharacterJob, BYTE cCharacterLevel)
|
||
{
|
||
if (m_nDungeonGateID > 0)
|
||
GetDBConnection()->QueryNestDeathLog( pSession, GetRoomLogIndex(), nMonsterID, nSkillID, cCharacterJob, cCharacterLevel);
|
||
}
|
||
#endif
|
||
|
||
int CDNGameRoom::GetServerID() const
|
||
{
|
||
return m_pGameServer->GetServerID();
|
||
}
|
||
|
||
#ifdef _USE_VOICECHAT
|
||
void CDNGameRoom::GetUserTalking(TTalkingInfo * pInfo, int &nCount)
|
||
{
|
||
CDNUserSession * pSession = NULL;
|
||
DNVector(PartyStruct):: iterator ii;
|
||
for (ii = m_VecMember.begin(); ii != m_VecMember.end(); ii++)
|
||
{
|
||
pSession = (*ii).pSession;
|
||
if (pSession->IsTalking(&pInfo[nCount].cTalking))
|
||
{
|
||
pInfo[nCount].nSessionID = pSession->GetSessionID();
|
||
nCount++;
|
||
}
|
||
}
|
||
}
|
||
|
||
void CDNGameRoom::TalkingUpdate(ULONG nCurTick)
|
||
{
|
||
if (m_nVoiceChannelID[0] <= 0) return;
|
||
if (m_nTalkingTick + VOICEUPDATETIME > nCurTick) return;
|
||
|
||
TTalkingInfo Info[PARTYMAX];
|
||
memset(&Info, 0, sizeof(Info));
|
||
int nCount = 0;
|
||
|
||
GetUserTalking(Info, nCount);
|
||
|
||
if (nCount > 0)
|
||
{
|
||
CDNUserSession * pSession = NULL;
|
||
DNVector(PartyStruct):: iterator ii;
|
||
for (ii = m_VecMember.begin(); ii != m_VecMember.end(); ii++)
|
||
{
|
||
pSession = (*ii).pSession;
|
||
pSession->SendTalkingUpdate(nCount, Info);
|
||
}
|
||
}
|
||
m_nTalkingTick = nCurTick;
|
||
}
|
||
|
||
void CDNGameRoom::SendRefreshVoiceInfo(UINT nOutAccountDBID)
|
||
{
|
||
if (m_nVoiceChannelID[0] <= 0) return;
|
||
TVoiceMemberInfo Info[PARTYMAX] = { 0, };
|
||
int nCount = 0;
|
||
|
||
CDNUserSession * pUser;
|
||
for(DWORD i=0; i<GetUserCount(); i++)
|
||
{
|
||
pUser = GetUserData(i);
|
||
if(pUser)
|
||
{
|
||
Info[nCount].nSessionID = pUser->GetSessionID();
|
||
Info[nCount].cVoiceAvailable = pUser->GetVoiceAvailable() == true ? 1 : 0;
|
||
nCount++;
|
||
|
||
if (nOutAccountDBID > 0)
|
||
pUser->SetVoiceMute(nOutAccountDBID, false);
|
||
}
|
||
}
|
||
|
||
UINT nMuteSessionList[PARTYCOUNTMAX];
|
||
CDNUserSession * pTempUser;
|
||
for(DWORD i=0; i<GetUserCount(); i++)
|
||
{
|
||
pUser = GetUserData(i);
|
||
if (pUser)
|
||
{
|
||
pTempUser = NULL;
|
||
memset(nMuteSessionList, 0, sizeof(nMuteSessionList));
|
||
for (int j = 0; j < PARTYCOUNTMAX; j++)
|
||
{
|
||
if (pUser->m_nVoiceMutedList[j] <= 0) continue;
|
||
for(DWORD h=0; h<GetUserCount(); h++)
|
||
{
|
||
pTempUser = GetUserData(h);
|
||
if (pTempUser->GetAccountDBID() == pUser->m_nVoiceMutedList[j])
|
||
nMuteSessionList[j] = pTempUser->GetSessionID();
|
||
}
|
||
}
|
||
pUser->SendVoiceMemberInfoRefresh(nCount, nMuteSessionList, Info);
|
||
}
|
||
}
|
||
}
|
||
#endif
|
||
|
||
DWORD CDNGameRoom::GetLiveUserCount()
|
||
{
|
||
DWORD dwCount = 0;
|
||
|
||
DnActorHandle hActor;
|
||
for( DWORD i=0; i<GetUserCount(); i++ ) {
|
||
hActor = GetUserData(i)->GetActorHandle();
|
||
if( hActor && !hActor->IsDie() ) dwCount++;
|
||
}
|
||
return dwCount;
|
||
}
|
||
|
||
DWORD CDNGameRoom::GetUserCountWithoutPartyOutUser()
|
||
{
|
||
DWORD dwCount = 0;
|
||
for (int i = 0; i < (int)m_VecMember.size(); i++)
|
||
{
|
||
if (m_VecMember[i].pSession->GetOutedMember() == false)
|
||
dwCount++;
|
||
}
|
||
return dwCount;
|
||
}
|
||
|
||
DWORD CDNGameRoom::GetUserCountWithoutGM()
|
||
{
|
||
DWORD dwCount = 0;
|
||
for (int i = 0; i < (int)m_VecMember.size(); i++)
|
||
{
|
||
if (m_VecMember[i].pSession->bIsGMTrace() == false)
|
||
dwCount++;
|
||
}
|
||
return dwCount;
|
||
}
|
||
|
||
DWORD CDNGameRoom::GetGMCount()
|
||
{
|
||
DWORD dwCount = 0;
|
||
for( DWORD i=0; i<GetUserCount(); i++ )
|
||
{
|
||
if( GetUserData(i) && GetUserData(i)->bIsGMTrace() )
|
||
++dwCount;
|
||
}
|
||
|
||
return dwCount;
|
||
}
|
||
|
||
DWORD CDNGameRoom::GetUserCount( int iTeam )
|
||
{
|
||
DWORD dwCount = 0;
|
||
for( DWORD i=0; i<GetUserCount(); i++ )
|
||
{
|
||
if( GetUserData(i) && GetUserData(i)->GetTeam() == iTeam )
|
||
++dwCount;
|
||
}
|
||
|
||
return dwCount;
|
||
}
|
||
|
||
bool CDNGameRoom::GetOutMemberExist()
|
||
{
|
||
DWORD dwCount = 0;
|
||
for( DWORD i=0; i<GetUserCount(); i++ )
|
||
{
|
||
if(GetUserData(i) && GetUserData(i)->GetOutedMember())
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
DWORD CDNGameRoom::GetPartyUserCount(eGetUserCountType type)
|
||
{
|
||
DWORD dwCount = 0, i = 0;
|
||
|
||
DnActorHandle hActor;
|
||
for (; i<GetUserCount(); i++)
|
||
{
|
||
if (type == ePICKUPITEM)
|
||
{
|
||
CDNUserSession *pSession = GetUserData(i);
|
||
if (pSession)
|
||
{
|
||
hActor = pSession->GetActorHandle();
|
||
if (hActor && !hActor->IsDie()
|
||
#ifdef _CH
|
||
&& (pSession->GetFCMState() == FCMSTATE_NONE) // 3시간 이상 게임하면 아이템 줏기 못함 090624
|
||
#endif
|
||
)
|
||
dwCount++;
|
||
}
|
||
}
|
||
}
|
||
return dwCount;
|
||
}
|
||
|
||
bool CDNGameRoom::IsItemLootUserValid(DWORD userIdx)
|
||
{
|
||
CDNUserSession *pSession = GetUserData(userIdx);
|
||
if (pSession)
|
||
{
|
||
if( pSession->bIsGMTrace() )
|
||
return false;
|
||
|
||
#ifdef _CH
|
||
if (pSession->GetFCMState() != FCMSTATE_NONE)
|
||
return false;
|
||
#endif
|
||
DnActorHandle hActor = pSession->GetActorHandle();
|
||
if( !hActor || hActor->IsDie() || hActor->bIsObserver() )
|
||
return false;
|
||
}
|
||
else
|
||
{
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
UINT CDNGameRoom::GetCurrentItemLooterIdx()
|
||
{
|
||
if (m_nCurItemLooterInOrder < 0 || m_nCurItemLooterInOrder >= static_cast<int>(GetUserCount()) || GetUserCount() == 0)
|
||
{
|
||
m_nCurItemLooterInOrder = 0;
|
||
return m_nCurItemLooterInOrder;
|
||
}
|
||
|
||
m_nCurItemLooterInOrder %= GetUserCount();
|
||
|
||
for( int i=m_nCurItemLooterInOrder; i<(int)(GetUserCount()+m_nCurItemLooterInOrder); i++ ) {
|
||
int nIndex = i % GetUserCount();
|
||
if( IsItemLootUserValid( nIndex ) ) {
|
||
m_nCurItemLooterInOrder = (nIndex+1) % GetUserCount();
|
||
return nIndex;
|
||
}
|
||
}
|
||
|
||
_ASSERT(0);
|
||
g_Log.Log(LogType::_ERROR, L"[PARTY] ITEM LOOTING ERROR! NO VALID USER TO LOOT!! party_idx:%d\n", GetPartyIndex());
|
||
return 0;
|
||
}
|
||
|
||
void CDNGameRoom::CheckCurrentItemLooterIdx( PartyStruct *pEraseUser )
|
||
{
|
||
for( DWORD i=0; i<m_VecMember.size(); i++ ) {
|
||
if( pEraseUser == &m_VecMember[i] ) {
|
||
if( m_nCurItemLooterInOrder >= static_cast<int>(i) ) {
|
||
m_nCurItemLooterInOrder--;
|
||
if( m_nCurItemLooterInOrder < 0 ) m_nCurItemLooterInOrder = 0;
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
void CDNGameRoom::SendNextVillageInfo(const char * pIP, USHORT nPort, int nMapIndex, int nNextMapIndex, char cNextGateNo, short nRet, INT64 nItemSerial)
|
||
{
|
||
#if defined( PRE_PARTY_DB )
|
||
//여기서 파티 삭제
|
||
DelPartyDB();
|
||
#endif
|
||
if (nRet == ERROR_NONE)
|
||
{
|
||
for( DWORD i=0; i<m_VecMember.size(); i++ )
|
||
{
|
||
if (m_VecMember[i].pSession->bIsGMTrace()) continue;
|
||
if (cNextGateNo > 0) m_VecMember[i].pSession->VerifyValidMap(nNextMapIndex);
|
||
|
||
if (!m_VecMember[i].pSession->DeleteWarpVillageItemByUse(nItemSerial))
|
||
continue;
|
||
|
||
m_VecMember[i].pSession->SetNextVillageData(pIP, nPort, nMapIndex, nNextMapIndex, cNextGateNo);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
for( DWORD i=0; i<m_VecMember.size(); i++ )
|
||
m_VecMember[i].pSession->SendVillageInfo(pIP, nPort, nRet, 0, 0);
|
||
}
|
||
}
|
||
|
||
void CDNGameRoom::SendPvPUserState(UINT nAccountDBID, UINT uiUserState)
|
||
{
|
||
UINT nSessionID = 0;
|
||
for( DWORD i=0; i<m_VecMember.size(); i++ )
|
||
{
|
||
if (m_VecMember[i].pSession->GetAccountDBID() == nAccountDBID)
|
||
{
|
||
nSessionID = m_VecMember[i].pSession->GetSessionID();
|
||
m_VecMember[i].pSession->SetPvPUserState(uiUserState);
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (nSessionID > 0)
|
||
{
|
||
for( DWORD i=0; i<m_VecMember.size(); i++ )
|
||
m_VecMember[i].pSession->SendPvPUserState(nSessionID, uiUserState);
|
||
}
|
||
}
|
||
|
||
// 기존 유저에게 난입유저 정보 보냄
|
||
void CDNGameRoom::SendBreakIntoUser( CDNUserSession* pBreakIntoSession )
|
||
{
|
||
if( !pBreakIntoSession )
|
||
return;
|
||
|
||
SCROOM_SYNC_MEMBER_BREAKINTO TxPacket;
|
||
memset( &TxPacket, 0, sizeof(TxPacket) );
|
||
|
||
char* pBuffer = reinterpret_cast<char*>(TxPacket.EquipArray);
|
||
char* pOrgBuffer = pBuffer;
|
||
|
||
pBreakIntoSession->GetPartyMemberInfo( TxPacket.Member );
|
||
TxPacket.usTeam = pBreakIntoSession->GetTeam();
|
||
TxPacket.cGMTrace = pBreakIntoSession->bIsGMTrace() ? 1: 0;
|
||
TxPacket.iDefaultPartsIndex[0] = pBreakIntoSession->GetDefaultBody();
|
||
TxPacket.iDefaultPartsIndex[1] = pBreakIntoSession->GetDefaultLeg();
|
||
TxPacket.iDefaultPartsIndex[2] = pBreakIntoSession->GetDefaultHand();
|
||
TxPacket.iDefaultPartsIndex[3] = pBreakIntoSession->GetDefaultFoot();
|
||
|
||
memcpy(TxPacket.cViewCashEquipBitmap, pBreakIntoSession->GetViewCashEquipBitmap(), sizeof(TxPacket.cViewCashEquipBitmap));
|
||
|
||
// 호칭
|
||
TxPacket.iSelectAppellation = pBreakIntoSession->GetSelectAppellation();
|
||
TxPacket.nCoverAppellation = pBreakIntoSession->GetCoverAppellation();
|
||
TxPacket.cAccountLevel = pBreakIntoSession->GetAccountLevel();
|
||
if( pBreakIntoSession->GetItem()->GetVehicleEquip() )
|
||
TxPacket.VehicleInfo.SetCompact( *pBreakIntoSession->GetItem()->GetVehicleEquip() );
|
||
if( pBreakIntoSession->GetItem()->GetPetEquip() )
|
||
TxPacket.PetInfo.SetCompact( *pBreakIntoSession->GetItem()->GetPetEquip() );
|
||
|
||
// 장비
|
||
for( int i=0; i<EQUIPMAX ; ++i )
|
||
{
|
||
if( pBreakIntoSession->GetItem()->GetEquip(i) == NULL )
|
||
continue;
|
||
// SlotIndex
|
||
memcpy( pBuffer, &i, sizeof(char) );
|
||
pBuffer += sizeof(char);
|
||
// TItem
|
||
memcpy( pBuffer, pBreakIntoSession->GetItem()->GetEquip(i), sizeof(TItem) );
|
||
pBuffer += sizeof(TItem);
|
||
|
||
++TxPacket.nEquipCount;
|
||
}
|
||
|
||
// 캐쉬장비
|
||
for( int i=0 ; i<CASHEQUIPMAX ; ++i )
|
||
{
|
||
if( pBreakIntoSession->GetItem()->GetCashEquip(i) == NULL )
|
||
continue;
|
||
// SlotIndex
|
||
memcpy( pBuffer, &i, sizeof(char) );
|
||
pBuffer += sizeof(char);
|
||
// TItem
|
||
memcpy( pBuffer, pBreakIntoSession->GetItem()->GetCashEquip(i), sizeof(TItem) );
|
||
pBuffer += sizeof(TItem);
|
||
|
||
++TxPacket.nCashEquipCount;
|
||
}
|
||
|
||
// 문장
|
||
for( int i=0; i<GLYPHMAX ; ++i )
|
||
{
|
||
if( pBreakIntoSession->GetItem()->GetGlyph(i) == NULL )
|
||
continue;
|
||
// SlotIndex
|
||
memcpy( pBuffer, &i, sizeof(char) );
|
||
pBuffer += sizeof(char);
|
||
// TItem
|
||
memcpy( pBuffer, pBreakIntoSession->GetItem()->GetGlyph(i), sizeof(TItem) );
|
||
pBuffer += sizeof(TItem);
|
||
|
||
++TxPacket.nGlyphCount;
|
||
}
|
||
|
||
#if defined(PRE_ADD_TALISMAN_SYSTEM)
|
||
// 탈리스만
|
||
for( int i=0; i<TALISMAN_MAX ; ++i )
|
||
{
|
||
if( pBreakIntoSession->GetItem()->GetTalisman(i) == NULL )
|
||
continue;
|
||
// SlotIndex
|
||
memcpy( pBuffer, &i, sizeof(char) );
|
||
pBuffer += sizeof(char);
|
||
// TItem
|
||
memcpy( pBuffer, pBreakIntoSession->GetItem()->GetTalisman(i), sizeof(TItem) );
|
||
pBuffer += sizeof(TItem);
|
||
|
||
++TxPacket.nTalismanCount;
|
||
}
|
||
#endif
|
||
|
||
// 스킬
|
||
for( int i=0 ; i<SKILLMAX ; ++i )
|
||
{
|
||
if( pBreakIntoSession->GetSkillData()->SkillList[i].nSkillID <= 0 )
|
||
continue;
|
||
|
||
// 지호씨 액션 파일 최적화 관련 작업, 파티원의 스킬을 모두 보내주도록 한다.
|
||
|
||
if( pBreakIntoSession->GetSkillData()->SkillList[i].cSkillLevel < 1 )
|
||
continue;
|
||
|
||
|
||
//if( CDnSkill::GetSkillType( pBreakIntoSession->GetSkillData()->SkillList[i].nSkillID ) != CDnSkill::Passive &&
|
||
// CDnSkill::GetSkillType( pBreakIntoSession->GetSkillData()->SkillList[i].nSkillID ) != CDnSkill::EnchantPassive )
|
||
// continue;
|
||
|
||
memcpy( pBuffer, &(pBreakIntoSession->GetSkillData()->SkillList[i]), sizeof(TSkill) );
|
||
pBuffer += sizeof(TSkill);
|
||
++TxPacket.nSkillCount;
|
||
}
|
||
|
||
TxPacket.GuildSelfView = pBreakIntoSession->GetGuildSelfView();
|
||
|
||
int iSize = static_cast<int>(sizeof(TxPacket)-sizeof(TxPacket.EquipArray)-sizeof(TxPacket.SkillArray)+(pBuffer-pOrgBuffer));
|
||
for( UINT i=0; i<m_VecMember.size() ; ++i )
|
||
{
|
||
if( m_VecMember[i].pSession == pBreakIntoSession )
|
||
continue;
|
||
m_VecMember[i].pSession->AddSendData( SC_ROOM, eRoom::SC_SYNC_MEMBER_BREAKINTO, reinterpret_cast<char*>(&TxPacket), iSize );
|
||
}
|
||
|
||
#if defined (PRE_ADD_BESTFRIEND)
|
||
//절친 정보 전송
|
||
std::vector<TPartyBestFriend> vMemberBestFriend;
|
||
vMemberBestFriend.reserve(1);
|
||
|
||
TPartyBestFriend MemberBestFriend = {0,};
|
||
MemberBestFriend.nSessionID = pBreakIntoSession->GetSessionID();
|
||
|
||
TBestFriendInfo& Info = pBreakIntoSession->GetBestFriend()->GetInfo();
|
||
MemberBestFriend.biBFItemSerial = Info.biItemSerial;
|
||
_wcscpy(MemberBestFriend.wszBFName, _countof(MemberBestFriend.wszBFName), Info.wszName, (int)wcslen(Info.wszName));
|
||
|
||
vMemberBestFriend.push_back( MemberBestFriend );
|
||
|
||
for( UINT i=0; i<m_VecMember.size() ; ++i )
|
||
{
|
||
if( m_VecMember[i].pSession == pBreakIntoSession )
|
||
continue;
|
||
m_VecMember[i].pSession->SendPartyBestFriend( vMemberBestFriend );
|
||
}
|
||
#endif // #if defined (PRE_ADD_BESTFRIEND)
|
||
}
|
||
|
||
#if defined( PRE_ADD_NAMEDITEM_SYSTEM )
|
||
void CDNGameRoom::SendCompleteBreakIntoUser( CDNUserSession* pBreakIntoSession )
|
||
{
|
||
if(!pBreakIntoSession)
|
||
return;
|
||
|
||
// 월드맵과 던전인 경우의 처리가 틀림
|
||
CDnWorld *pWorld = GetWorld();
|
||
bool bDungeon = false;
|
||
if( pWorld && pWorld->GetMapType() == EWorldEnum::MapTypeDungeon )
|
||
{
|
||
bDungeon = true;
|
||
}
|
||
|
||
std::vector<TEffectSkillData> vEffectSkill;
|
||
vEffectSkill.clear();
|
||
pBreakIntoSession->GetItem()->GetEffectSkillItem( vEffectSkill );
|
||
CDNUserSession::ApplyEffectSkill(pBreakIntoSession->GetPlayerActor(), vEffectSkill , !bDungeon , pBreakIntoSession->GetGameRoom()->bIsPvPRoom() );
|
||
|
||
pBreakIntoSession->CheckEffectSkillItemData();
|
||
pBreakIntoSession->GetItem()->BroadcastEffectSkillItemData(false);
|
||
#if defined( PRE_WORLDCOMBINE_PARTY )
|
||
if(bIsWorldCombineParty())
|
||
{
|
||
ApplyWorldCombinePartyBuff(pBreakIntoSession);
|
||
}
|
||
#endif
|
||
|
||
#if defined( PRE_ADD_DIRECTNBUFF )
|
||
if( pWorld && pWorld->GetMapType() == EWorldEnum::MapTypeDungeon && GetGameTaskType() != GameTaskType::Farm )
|
||
{
|
||
if( bIsDirectPartyBuff() )
|
||
{
|
||
ApplyDirectPartyBuff( true );
|
||
if( pBreakIntoSession->bIsDirectPartyBuff() )
|
||
SendDirectPartyBuffMsg(pBreakIntoSession);
|
||
}
|
||
}
|
||
#endif
|
||
|
||
SendPartyEffectSkillItemData(pBreakIntoSession);
|
||
#if defined( PRE_ADD_TOTAL_LEVEL_SKILL )
|
||
SendTotalLevelSkillInfo(pBreakIntoSession);
|
||
#endif
|
||
#if defined( PRE_ADD_GUILDREWARDITEM )
|
||
pBreakIntoSession->SetGuildRewardItem();
|
||
pBreakIntoSession->ApplyGuildRewardSkill(bDungeon);
|
||
#endif
|
||
|
||
#if defined( PRE_FIX_BREAKINTO_BLOW_SYNC )
|
||
SendAddStateEffect( pBreakIntoSession );
|
||
#endif
|
||
|
||
}
|
||
#endif
|
||
|
||
void CDNGameRoom::SendHPSP( CDNUserSession* pBreakIntoSession )
|
||
{
|
||
if( !pBreakIntoSession )
|
||
return;
|
||
|
||
SCROOM_SYNC_MEMBERHPSP TxPacket;
|
||
memset( &TxPacket, 0, sizeof(TxPacket) );
|
||
|
||
UINT uiSendCount = 0;
|
||
|
||
for( UINT i=0 ; i<m_VecMember.size() ; ++i )
|
||
{
|
||
INT64 iHP = 0;
|
||
int iSP = 0;
|
||
|
||
if( m_VecMember[i].pSession && m_VecMember[i].pSession->GetActorHandle() )
|
||
{
|
||
if( m_VecMember[i].pSession == pBreakIntoSession )
|
||
{
|
||
// 난입 유저의 경우 백업 정보를 보내줌
|
||
PartyBackUpStruct BackupInfo;
|
||
if( GetBackupPartyInfo( pBreakIntoSession->GetCharacterDBID(), BackupInfo ) == true )
|
||
{
|
||
iHP = (INT64)(m_VecMember[i].pSession->GetActorHandle()->GetMaxHP() * BackupInfo.nHPPercent * 0.01);
|
||
iSP = m_VecMember[i].pSession->GetActorHandle()->GetSP();
|
||
}
|
||
else
|
||
{
|
||
iHP = m_VecMember[i].pSession->GetActorHandle()->GetHP();
|
||
iSP = m_VecMember[i].pSession->GetActorHandle()->GetSP();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
iHP = m_VecMember[i].pSession->GetActorHandle()->GetHP();
|
||
iSP = m_VecMember[i].pSession->GetActorHandle()->GetSP();
|
||
}
|
||
#if !defined( _FINAL_BUILD )
|
||
/*
|
||
WCHAR wszBuf[MAX_PATH];
|
||
wsprintf( wszBuf, L"[%s] HP:%d SP:%d\r\n", m_VecMember[i].pSession->GetActorHandle()->GetName(), iHP, iSP );
|
||
g_Log.Log( LogType::_NORMAL, pBreakIntoSession, wszBuf );
|
||
*/
|
||
#endif
|
||
}
|
||
|
||
#ifdef PRE_MOD_SYNCPACKET
|
||
TxPacket.tHPSP[TxPacket.cCount].nSessionID = m_VecMember[i].pSession->GetSessionID();
|
||
TxPacket.tHPSP[TxPacket.cCount].iHP = iHP;
|
||
TxPacket.tHPSP[TxPacket.cCount].iSP = iSP;
|
||
#else //#ifdef PRE_MOD_SYNCPACKET
|
||
TxPacket.iHPSPArr[TxPacket.cCount*2] = (int)iHP;
|
||
TxPacket.iHPSPArr[(TxPacket.cCount*2)+1] = iSP;
|
||
#endif //#ifdef PRE_MOD_SYNCPACKET
|
||
++TxPacket.cCount;
|
||
|
||
// Page완성
|
||
#ifdef PRE_MOD_SYNCPACKET
|
||
if( TxPacket.cCount%(_countof(TxPacket.tHPSP)) == 0 )
|
||
{
|
||
#else //#ifdef PRE_MOD_SYNCPACKET
|
||
if( TxPacket.cCount%(_countof(TxPacket.iHPSPArr)/2) == 0 )
|
||
{
|
||
TxPacket.unStartIndex = static_cast<USHORT>(uiSendCount);
|
||
#endif //#ifdef PRE_MOD_SYNCPACKET
|
||
pBreakIntoSession->AddSendData( SC_ROOM, eRoom::SC_SYNC_MEMBERHPSP, reinterpret_cast<char*>(&TxPacket), sizeof(TxPacket) );
|
||
|
||
uiSendCount += TxPacket.cCount;
|
||
TxPacket.cCount = 0;
|
||
}
|
||
}
|
||
|
||
if( TxPacket.cCount > 0 )
|
||
{
|
||
#ifdef PRE_MOD_SYNCPACKET
|
||
int iSize = sizeof(TxPacket)-sizeof(TxPacket.tHPSP)+TxPacket.cCount*sizeof(TSyncHPSP);
|
||
#else //#ifdef PRE_MOD_SYNCPACKET
|
||
TxPacket.unStartIndex = static_cast<USHORT>(uiSendCount);
|
||
int iSize = sizeof(TxPacket)-sizeof(TxPacket.iHPSPArr)+TxPacket.cCount*sizeof(TxPacket.iHPSPArr[0])*2;
|
||
#endif //#ifdef PRE_MOD_SYNCPACKET
|
||
|
||
pBreakIntoSession->AddSendData( SC_ROOM, eRoom::SC_SYNC_MEMBERHPSP, reinterpret_cast<char*>(&TxPacket), iSize );
|
||
}
|
||
}
|
||
|
||
void CDNGameRoom::SendBattleMode( CDNUserSession* pBreakIntoSession )
|
||
{
|
||
if( !pBreakIntoSession )
|
||
return;
|
||
|
||
SCROOM_SYNC_MEMBERBATTLEMODE TxPacket;
|
||
memset( &TxPacket, 0, sizeof(TxPacket) );
|
||
|
||
UINT uiSendCount = 0;
|
||
|
||
for( UINT i=0 ; i<m_VecMember.size() ; ++i )
|
||
{
|
||
BYTE cBattleMode = 0;
|
||
if( m_VecMember[i].pSession && m_VecMember[i].pSession->GetActorHandle() )
|
||
{
|
||
CDnPlayerActor* pActor = static_cast<CDnPlayerActor*>(m_VecMember[i].pSession->GetActorHandle().GetPointer() );
|
||
if( pActor )
|
||
cBattleMode = pActor->IsBattleMode() ? 1 : 0;
|
||
}
|
||
|
||
#ifdef PRE_MOD_SYNCPACKET
|
||
TxPacket.tBattleMode[TxPacket.cCount].nSessionID = m_VecMember[i].pSession->GetSessionID();
|
||
TxPacket.tBattleMode[TxPacket.cCount].cBattleMode = cBattleMode;
|
||
#else //#ifdef PRE_MOD_SYNCPACKET
|
||
TxPacket.cBattleModeArr[TxPacket.cCount] = cBattleMode;
|
||
#endif //#ifdef PRE_MOD_SYNCPACKET
|
||
++TxPacket.cCount;
|
||
|
||
// Page완성
|
||
#ifdef PRE_MOD_SYNCPACKET
|
||
if( TxPacket.cCount%_countof(TxPacket.tBattleMode) == 0 )
|
||
{
|
||
#else //#ifdef PRE_MOD_SYNCPACKET
|
||
if( TxPacket.cCount%_countof(TxPacket.cBattleModeArr) == 0 )
|
||
{
|
||
TxPacket.unStartIndex = static_cast<USHORT>(uiSendCount);
|
||
#endif //#ifdef PRE_MOD_SYNCPACKET
|
||
pBreakIntoSession->AddSendData( SC_ROOM, eRoom::SC_SYNC_MEMBERBATTLEMODE, reinterpret_cast<char*>(&TxPacket), sizeof(TxPacket) );
|
||
|
||
uiSendCount += TxPacket.cCount;
|
||
|
||
TxPacket.cCount = 0;
|
||
}
|
||
}
|
||
|
||
if( TxPacket.cCount > 0 )
|
||
{
|
||
#ifdef PRE_MOD_SYNCPACKET
|
||
int iSize = sizeof(TxPacket)-sizeof(TxPacket.tBattleMode)+TxPacket.cCount*sizeof(TBattleMode);
|
||
#else //#ifdef PRE_MOD_SYNCPACKET
|
||
TxPacket.unStartIndex = static_cast<USHORT>(uiSendCount);
|
||
int iSize = sizeof(TxPacket)-sizeof(TxPacket.cBattleModeArr)+TxPacket.cCount*sizeof(TxPacket.cBattleModeArr[0]);
|
||
#endif //#ifdef PRE_MOD_SYNCPACKET
|
||
|
||
pBreakIntoSession->AddSendData( SC_ROOM, eRoom::SC_SYNC_MEMBERBATTLEMODE, reinterpret_cast<char*>(&TxPacket), iSize );
|
||
}
|
||
}
|
||
|
||
|
||
// 난입한 유저에게 Blow 정보를 보내준다.
|
||
void CDNGameRoom::SendAddStateEffect( CDNUserSession* pBreakIntoGameSession )
|
||
{
|
||
if( !pBreakIntoGameSession )
|
||
return;
|
||
|
||
for( UINT i=0 ; i<m_VecMember.size() ; ++i )
|
||
{
|
||
if( m_VecMember[i].pSession == pBreakIntoGameSession )
|
||
continue;
|
||
|
||
DnActorHandle hActor = m_VecMember[i].pSession->GetActorHandle();
|
||
if( hActor )
|
||
hActor->CmdSyncBlow( pBreakIntoGameSession );
|
||
}
|
||
}
|
||
|
||
// 난입한 유저에게 유저들의 현재 위치정보를 보내준다.
|
||
void CDNGameRoom::SendPosition( CDNUserSession* pBreakIntoGameSession )
|
||
{
|
||
if( !pBreakIntoGameSession )
|
||
return;
|
||
|
||
for( UINT i=0 ; i<m_VecMember.size() ; ++i )
|
||
{
|
||
if( m_VecMember[i].pSession == pBreakIntoGameSession )
|
||
{
|
||
DnActorHandle hActor = m_VecMember[i].pSession->GetActorHandle();
|
||
if( hActor )
|
||
hActor->CmdWarp( *hActor->GetPosition(), EtVec3toVec2( *hActor->GetLookDir() ) );
|
||
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 난입한 유저에게 DropItem 정보를 보내준다.
|
||
void CDNGameRoom::SendDropItemList( CDNUserSession* pBreakIntoGameSession )
|
||
{
|
||
if( !pBreakIntoGameSession )
|
||
return;
|
||
|
||
DnActorHandle hActor = pBreakIntoGameSession->GetActorHandle();
|
||
if( !hActor )
|
||
return;
|
||
|
||
if( CDnDropItem::s_pVecProcessList[GetRoomID()].empty() )
|
||
return;
|
||
|
||
size_t stCount = CDnDropItem::s_pVecProcessList[GetRoomID()].size();
|
||
|
||
DNVector(DnDropItemHandle) vDropItem;
|
||
vDropItem.reserve( stCount );
|
||
|
||
for( UINT i=0 ; i<stCount ; ++i )
|
||
vDropItem.push_back( CDnDropItem::s_pVecProcessList[GetRoomID()][i]->GetMySmartPtr() );
|
||
|
||
//CDnDropItem::ScanItem( this, *hActor->GetPosition(), FLT_MAX, vDropItem );
|
||
|
||
//
|
||
SCROOM_SYNC_DROPITEMLIST TxPacket;
|
||
memset( &TxPacket, 0, sizeof(TxPacket) );
|
||
|
||
for( UINT i=0 ; i<vDropItem.size() ; ++i )
|
||
{
|
||
TDropItemSync* pDropItemSync = &TxPacket.sDropItemList[TxPacket.cCount];
|
||
|
||
pDropItemSync->nSessionID = vDropItem[i]->GetUniqueID();
|
||
pDropItemSync->fpos[0] = vDropItem[i]->GetPosition()->x;
|
||
pDropItemSync->fpos[1] = vDropItem[i]->GetPosition()->y;
|
||
pDropItemSync->fpos[2] = vDropItem[i]->GetPosition()->z;
|
||
pDropItemSync->nItemID = vDropItem[i]->GetItemID();
|
||
pDropItemSync->nRandomSeed = vDropItem[i]->GetRandomSeed();
|
||
pDropItemSync->nCount = vDropItem[i]->GetOverlapCount();
|
||
pDropItemSync->nRotate = vDropItem[i]->GetRotate();
|
||
pDropItemSync->uiLifeTime = static_cast<UINT>(vDropItem[i]->GetLifeTime()*1000);
|
||
pDropItemSync->fDistance = vDropItem[i]->GetDistance();
|
||
|
||
if( ++TxPacket.cCount >= SENDDROPITEMLISTMAX )
|
||
{
|
||
pBreakIntoGameSession->AddSendData( SC_ROOM, eRoom::SC_SYNC_DROPITEMLIST, reinterpret_cast<char*>(&TxPacket), sizeof(TxPacket) );
|
||
memset( &TxPacket, 0, sizeof(TxPacket) );
|
||
}
|
||
}
|
||
|
||
// 나머지것들 SEND
|
||
if( TxPacket.cCount > 0 )
|
||
{
|
||
UINT uiSize = sizeof(TxPacket)-sizeof(TxPacket.sDropItemList)+sizeof(TDropItemSync)*TxPacket.cCount;
|
||
pBreakIntoGameSession->AddSendData( SC_ROOM, eRoom::SC_SYNC_DROPITEMLIST, reinterpret_cast<char*>(&TxPacket), uiSize );
|
||
}
|
||
}
|
||
|
||
// Monster 동기화
|
||
void CDNGameRoom::SyncMonster( CDNUserSession* pBreakIntoGameSession )
|
||
{
|
||
DN_ASSERT( pBreakIntoGameSession != NULL, "CDNGameRoom::SyncMonster() pBreakIntoGameSession != NULL" );
|
||
DN_ASSERT( m_pGameTask != NULL, "CDNGameRoom::SyncMonster() m_pGameTask != NULL ");
|
||
|
||
m_pGameTask->SyncMonster( pBreakIntoGameSession );
|
||
}
|
||
|
||
void CDNGameRoom::SyncNpc( CDNUserSession* pBreakIntoGameSession )
|
||
{
|
||
DN_ASSERT( pBreakIntoGameSession != NULL, "CDNGameRoom::SyncNpc() pBreakIntoGameSession != NULL" );
|
||
DN_ASSERT( m_pGameTask != NULL, "CDNGameRoom::SyncNpc() m_pGameTask != NULL ");
|
||
|
||
m_pGameTask->SyncNpc( pBreakIntoGameSession );
|
||
}
|
||
|
||
// Prop 동기화
|
||
void CDNGameRoom::SyncProp( CDNUserSession* pBreakIntoGameSession )
|
||
{
|
||
CDnWorldSector* pSector = static_cast<CDnWorldSector*>(CDnWorld::GetInstance( this ).GetSector( 0.0f, 0.0f ));
|
||
for( UINT i=0 ; i<pSector->GetPropCount() ; ++i )
|
||
{
|
||
CEtWorldProp* pProp = pSector->GetPropFromIndex( i );
|
||
if( pProp )
|
||
{
|
||
if( static_cast<CDnWorldProp*>(pProp)->IsShow() )
|
||
pProp->OnSyncComplete( pBreakIntoGameSession );
|
||
else
|
||
static_cast<CDnWorldProp*>(pProp)->CmdShow( false, pBreakIntoGameSession );
|
||
}
|
||
}
|
||
}
|
||
|
||
void CDNGameRoom::CheckDiePlayer( CDNUserSession* pBreakIntoGameSession )
|
||
{
|
||
if( !pBreakIntoGameSession )
|
||
return;
|
||
|
||
PartyBackUpStruct BackupInfo;
|
||
// 파티 복구 난입인 경우 리더위치로 워프
|
||
if( GetBackupPartyInfo( pBreakIntoGameSession->GetCharacterDBID(), BackupInfo ) == true )
|
||
{
|
||
// 리더 위치로 워프
|
||
DnActorHandle hActor = pBreakIntoGameSession->GetActorHandle();
|
||
if( hActor )
|
||
{
|
||
hActor->SetHP( 0 );
|
||
}
|
||
}
|
||
}
|
||
|
||
// Player 동기화
|
||
void CDNGameRoom::SyncPlayer( CDNUserSession* pBreakIntoGameSession )
|
||
{
|
||
if( !pBreakIntoGameSession )
|
||
return;
|
||
|
||
// 파티인원 수 동기화
|
||
++m_iPartMemberCnt;
|
||
|
||
// 피로도 동기화
|
||
if( !bIsPvPRoom() )
|
||
{
|
||
for( UINT i=0 ; i<m_VecMember.size() ; ++i )
|
||
{
|
||
if( !m_VecMember[i].pSession )
|
||
continue;
|
||
|
||
m_VecMember[i].pSession->SetFatigue( m_VecMember[i].pSession->GetFatigue(), m_VecMember[i].pSession->GetWeeklyFatigue(), m_VecMember[i].pSession->GetPCBangFatigue(),
|
||
m_VecMember[i].pSession->GetEventFatigue(), m_VecMember[i].pSession->GetVIPFatigue() );
|
||
}
|
||
}
|
||
|
||
PartyBackUpStruct BackupInfo;
|
||
// 파티 복구 난입인 경우 리더위치로 워프
|
||
if( GetBackupPartyInfo( pBreakIntoGameSession->GetCharacterDBID(), BackupInfo ) == true )
|
||
{
|
||
// 리더 위치로 워프
|
||
DnActorHandle hActor = pBreakIntoGameSession->GetActorHandle();
|
||
|
||
UINT uiSessionID = 0;
|
||
GetLeaderSessionID( uiSessionID );
|
||
if( uiSessionID > 0 )
|
||
{
|
||
int Seq;
|
||
PartyStruct* pLeader = GetPartyDatabySessionID( uiSessionID, Seq );
|
||
if( pLeader && pLeader->pSession )
|
||
{
|
||
DnActorHandle hLeader = pLeader->pSession->GetActorHandle();
|
||
if( hActor && hLeader )
|
||
hActor->CmdWarp( *hLeader->GetPosition(), EtVec3toVec2(*hLeader->GetLookDir()) );
|
||
}
|
||
}
|
||
|
||
Ghost::Type::eCode Type = ( BackupInfo.nHPPercent > 0 ) ? Ghost::Type::PartyRestore : Ghost::Type::Normal;
|
||
pBreakIntoGameSession->SendGhostType( pBreakIntoGameSession->GetSessionID(), Type );
|
||
|
||
// 사망처리
|
||
if( hActor )
|
||
hActor->CmdRefreshHPSP( 0,0 );
|
||
|
||
// RebirthCoin 복원
|
||
PartyStruct* pStruct = GetPartyData( pBreakIntoGameSession );
|
||
if( pStruct )
|
||
{
|
||
pStruct->nUsableRebirthCoin = BackupInfo.nUsableRebirthCoin;
|
||
for( std::list<int>::iterator itor = BackupInfo.ReverseItemList.begin(); itor != BackupInfo.ReverseItemList.end(); itor++ )
|
||
pStruct->ReverseItemList.push_back( (*itor) );
|
||
pStruct->nUsableRebirthItemCoin = BackupInfo.nUsableRebirthItemCoin;
|
||
pBreakIntoGameSession->SendRebirthCoin( ERROR_NONE, BackupInfo.nUsableRebirthCoin, _REBIRTH_SELF, pBreakIntoGameSession->GetSessionID());
|
||
for( std::list<int>::iterator itor = BackupInfo.ReverseItemList.begin(); itor != BackupInfo.ReverseItemList.end(); itor++ )
|
||
pBreakIntoGameSession->SendSpecialRebirthItem( *itor, BackupInfo.nUsableRebirthItemCoin);
|
||
#if defined( PRE_ADD_STAGE_USECOUNT_ITEM )
|
||
for( std::map<int,int>::iterator itor = BackupInfo.UseLimitItem.begin(); itor != BackupInfo.UseLimitItem.end(); itor++ )
|
||
{
|
||
pStruct->UseLimitItem.insert(make_pair(itor->first, itor->second));
|
||
pBreakIntoGameSession->SendStageUseLimitItem( itor->first, itor->second );
|
||
}
|
||
#endif
|
||
}
|
||
}
|
||
|
||
if( GetGameTask() )
|
||
GetGameTask()->SyncTimeAttack( pBreakIntoGameSession );
|
||
}
|
||
|
||
// Gate 동기화
|
||
void CDNGameRoom::SyncGate( CDNUserSession* pBreakIntoGameSession )
|
||
{
|
||
if( !pBreakIntoGameSession )
|
||
return;
|
||
|
||
DN_ASSERT( m_pGameTask != NULL, "CDNGameRoom::SyncGate() m_pGameTask != NULL" );
|
||
m_pGameTask->RequestGateInfo( pBreakIntoGameSession );
|
||
}
|
||
|
||
void CDNGameRoom::AddRequestGetReversionItem(const TItem& itemInfo, DnDropItemHandle hDropItem)
|
||
{
|
||
if (m_pPartyTask)
|
||
m_pPartyTask->AddRequestGetReversionItem(itemInfo, hDropItem);
|
||
else
|
||
_DANGER_POINT();
|
||
}
|
||
|
||
bool CDNGameRoom::IsEnableAddRequestGetReversionItem(DnDropItemHandle hDropItem) const
|
||
{
|
||
if (m_pPartyTask)
|
||
return m_pPartyTask->IsEnableAddRequestGetReversionItem(hDropItem);
|
||
else
|
||
_DANGER_POINT();
|
||
|
||
return false;
|
||
}
|
||
|
||
void CDNGameRoom::BroadcastChatRoomView(CDNUserSession* pSender, TChatRoomView& ChatRoomView)
|
||
{
|
||
CDNUserSession* pUserSession;
|
||
for( UINT i=0 ; i<m_VecMember.size() ; ++i )
|
||
{
|
||
pUserSession = m_VecMember[i].pSession;
|
||
if (pSender == pUserSession)
|
||
continue;
|
||
|
||
pUserSession->SendChatRoomView( pSender->GetSessionID(), ChatRoomView );
|
||
}
|
||
}
|
||
|
||
void CDNGameRoom::BroadcastChatRoomEnterUser(CDNUserSession* pSender, CDNChatRoom* pChatRoom)
|
||
{
|
||
CDNUserSession* pUserSession;
|
||
for( UINT i=0 ; i<m_VecMember.size() ; ++i )
|
||
{
|
||
pUserSession = m_VecMember[i].pSession;
|
||
if (pSender == pUserSession)
|
||
continue;
|
||
|
||
pUserSession->SendChatRoomEnterUser( pChatRoom->GetChatRoomID(), pChatRoom->GetChatRoomType(), pSender->GetSessionID() );
|
||
}
|
||
}
|
||
|
||
void CDNGameRoom::BroadcastChatRoomLeaveUser(CDNUserSession* pSender, int nErrorCode)
|
||
{
|
||
CDNUserSession* pUserSession;
|
||
for( UINT i=0 ; i<m_VecMember.size() ; ++i )
|
||
{
|
||
pUserSession = m_VecMember[i].pSession;
|
||
if (pSender == pUserSession)
|
||
continue;
|
||
|
||
pUserSession->SendChatRoomLeaveUser( pSender->GetSessionID(), nErrorCode );
|
||
}
|
||
}
|
||
|
||
void CDNGameRoom::SendChatRoomInfo(CDNUserSession* pBreakIntoGameSession)
|
||
{
|
||
m_ChatRoomManager.SendChatRoomInfo(pBreakIntoGameSession);
|
||
}
|
||
|
||
#if defined( PRE_WORLDCOMBINE_PARTY )
|
||
|
||
bool CDNGameRoom::CheckDestroyWorldCombineParty()
|
||
{
|
||
if( bIsWorldCombineParty() )
|
||
{
|
||
if( GetGameTask() )
|
||
{
|
||
const TMapInfo* pMapInfo = g_pDataManager->GetMapInfo( GetGameTask()->GetMapTableID() );
|
||
if( pMapInfo )
|
||
return pMapInfo->MapType != EWorldEnum::MapTypeWorldMap;
|
||
}
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
void CDNGameRoom::ApplyWorldCombinePartyBuff( CDNUserSession* pBreakIntoSession )
|
||
{
|
||
if(!pBreakIntoSession)
|
||
return;
|
||
|
||
if( bIsWorldCombineParty() )
|
||
{
|
||
WorldCombineParty::WrldCombinePartyData* pCombinePartyData = g_pDataManager->GetCombinePartyData(GetWorldPartyPrimaryIndex());
|
||
if(pCombinePartyData)
|
||
{
|
||
// CSUseItem과 아이템데이터를 강제로 만들어서 넘겨줌
|
||
for( int i=0;i<WorldCombineParty::eType::MAXSKILLCOUNT;i++ )
|
||
{
|
||
if(pCombinePartyData->nSkillID[i] <= 0) continue;
|
||
|
||
CSUseItem pPacket;
|
||
memset(&pPacket, 0, sizeof(pPacket));
|
||
TItemData *pItemData = g_pDataManager->GetItemData(pCombinePartyData->nSkillID[i]);
|
||
|
||
bool bUseItem = true;
|
||
if (CDnWorld::GetInstance(this).GetMapType() == GlobalEnum::eMapTypeEnum::MAP_WORLDMAP)
|
||
bUseItem = false;
|
||
|
||
pBreakIntoSession->GetItem()->ApplyPartyEffectSkillItemData(&pPacket, pItemData, pBreakIntoSession->GetSessionID(), EffectSkillNameSpace::ShowEffectType::NONEEFFECT, false, bUseItem);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
#endif // #if defined( PRE_WORLDCOMBINE_PARTY )
|
||
|
||
|
||
bool CDNGameRoom::bIsIgnorePrefixSkill()
|
||
{
|
||
if( bIsLadderRoom() )
|
||
return false;
|
||
if( bIsGuildWarSystem() )
|
||
return false;
|
||
if( bIsLevelRegulation() )
|
||
return true;
|
||
|
||
return false;
|
||
}
|
||
|
||
CDNGameRoom::PartyBackUpStruct& CDNGameRoom::PartyBackUpStruct::operator=( CDNGameRoom::PartyStruct& Struct )
|
||
{
|
||
this->nUsableRebirthCoin = Struct.nUsableRebirthCoin;
|
||
for( std::list<int>::iterator itor = Struct.ReverseItemList.begin(); itor != Struct.ReverseItemList.end(); itor++ )
|
||
this->ReverseItemList.push_back( (*itor) );
|
||
|
||
this->nUsableRebirthItemCoin = Struct.nUsableRebirthItemCoin;
|
||
this->nHPPercent = 0;
|
||
this->nSPPercent = 0;
|
||
|
||
#if defined( PRE_ADD_STAGE_USECOUNT_ITEM )
|
||
|
||
for( std::map<int,int>::iterator itor = Struct.UseLimitItem.begin(); itor != Struct.UseLimitItem.end(); itor++ )
|
||
{
|
||
this->UseLimitItem.insert(make_pair(itor->first, itor->second));
|
||
}
|
||
#endif
|
||
|
||
if( Struct.pSession )
|
||
{
|
||
DnActorHandle hActor = Struct.pSession->GetActorHandle();
|
||
if( hActor )
|
||
{
|
||
this->nHPPercent = hActor->GetHPPercent();
|
||
this->nSPPercent = hActor->GetSPPercent();
|
||
|
||
if( this->nHPPercent == 0 )
|
||
{
|
||
if( hActor->IsDie() == false )
|
||
this->nHPPercent = 1;
|
||
}
|
||
}
|
||
}
|
||
return (*this);
|
||
}
|
||
|
||
void CDNGameRoom::AddLastPartyDungeonInfo( CDNUserSession* pSession )
|
||
{
|
||
if( pSession == NULL )
|
||
return;
|
||
|
||
bool bModDungeonInfo = false;
|
||
switch( m_cReqGameIDType )
|
||
{
|
||
case REQINFO_TYPE_PARTY:
|
||
{
|
||
bModDungeonInfo = true;
|
||
break;
|
||
}
|
||
}
|
||
|
||
INT64 biValue = 0;
|
||
if( bModDungeonInfo == true )
|
||
biValue = MAKELONG64( g_Config.nManagedID, GetRoomID() );
|
||
pSession->ModCommonVariableData( CommonVariable::Type::LastPartyDungeonInfo, biValue );
|
||
|
||
#if defined( _WORK )
|
||
std::cout << "[AddLastPartyDungeonInfo] AccountID:" << pSession->GetAccountDBID() << " ManagedID:" << g_Config.nManagedID << " RoomID:" << GetRoomID() << " Value:"<< biValue << std::endl;
|
||
#endif // #if defined( _WORK )
|
||
}
|
||
|
||
void CDNGameRoom::DelLastPartyDungeonInfo( CDNUserSession* pSession )
|
||
{
|
||
if( pSession == NULL )
|
||
return;
|
||
|
||
pSession->ModCommonVariableData( CommonVariable::Type::LastPartyDungeonInfo, 0 );
|
||
|
||
#if defined( _WORK )
|
||
std::cout << "[DelLastPartyDungeonInfo] AccountID:" << pSession->GetAccountDBID() << std::endl;
|
||
#endif // #if defined( _WORK )
|
||
}
|
||
|
||
void CDNGameRoom::AddBackupPartyInfo( CDNUserSession* pSession )
|
||
{
|
||
std::map<INT64,PartyBackUpStruct>::iterator itor = m_mPartyBackUp.find( pSession->GetCharacterDBID() );
|
||
if( itor != m_mPartyBackUp.end() )
|
||
{
|
||
if( itor->second.nHPPercent > 0 )
|
||
return;
|
||
}
|
||
|
||
INT64 biValue = 0;
|
||
if( pSession->GetCommonVariableDataValue( CommonVariable::Type::LastPartyDungeonInfo, biValue ) == false )
|
||
return;
|
||
|
||
if( biValue <= 0 )
|
||
return;
|
||
|
||
const TMapInfo* pMapInfo = g_pDataManager->GetMapInfo( pSession->GetMapIndex() );
|
||
if( pMapInfo == NULL || pMapInfo->bUserReturnSystem == false )
|
||
{
|
||
#if defined( _WORK )
|
||
std::cout << "[AddBackupPartyInfo] CharDBID:" << pSession->GetCharacterDBID() << " MapIndex:" << pSession->GetMapIndex() << " 백업가능맵이 아님" << std::endl;
|
||
#endif // #if defined( _WORK )
|
||
return;
|
||
}
|
||
|
||
PartyStruct* pStruct = GetPartyData( pSession );
|
||
m_mPartyBackUp[pSession->GetCharacterDBID()] = (*pStruct);
|
||
|
||
#if defined( _WORK )
|
||
std::cout << "[AddBackupPartyInfo] CharDBID:" << pSession->GetCharacterDBID() << std::endl;
|
||
#endif // #if defined( _WORK )
|
||
}
|
||
|
||
void CDNGameRoom::DelBackupPartyInfo()
|
||
{
|
||
m_mPartyBackUp.clear();
|
||
|
||
#if defined( _WORK )
|
||
std::cout << "[DelBackupPartyInfo] 모든 Backup 파티 정보 초기화" << std::endl;
|
||
#endif // #if defined( _WORK )
|
||
}
|
||
|
||
void CDNGameRoom::DelBackupPartyInfo( INT64 biCharacterDBID )
|
||
{
|
||
if( m_mPartyBackUp.find( biCharacterDBID ) == m_mPartyBackUp.end() )
|
||
{
|
||
#if defined( _WORK )
|
||
std::cout << "[DelBackupPartyInfo] CharDBID=" << biCharacterDBID << " 실패" << std::endl;
|
||
#endif // #if defined( _WORK )
|
||
return;
|
||
}
|
||
|
||
m_mPartyBackUp.erase( biCharacterDBID );
|
||
#if defined( _WORK )
|
||
std::cout << "[DelBackupPartyInfo] CharDBID=" << biCharacterDBID << " 성공" << std::endl;
|
||
#endif // #if defined( _WORK )
|
||
}
|
||
|
||
bool CDNGameRoom::bIsBackupPartyInfo( INT64 biCharacterDBID )
|
||
{
|
||
if( m_mPartyBackUp.find( biCharacterDBID ) == m_mPartyBackUp.end() )
|
||
{
|
||
#if defined( _WORK )
|
||
std::cout << "[bIsBackupPartyInfo] CharDBID=" << biCharacterDBID << " 백업유저아님" << std::endl;
|
||
#endif // #if defined( _WORK )
|
||
return false;
|
||
}
|
||
|
||
#if defined( _WORK )
|
||
std::cout << "[bIsBackupPartyInfo] CharDBID=" << biCharacterDBID << " 백업유저임" << std::endl;
|
||
#endif // #if defined( _WORK )
|
||
return true;
|
||
}
|
||
|
||
bool CDNGameRoom::GetBackupPartyInfo( INT64 biCharacterDBID, PartyBackUpStruct& BackupInfo )
|
||
{
|
||
std::map<INT64,PartyBackUpStruct>::iterator itor = m_mPartyBackUp.find( biCharacterDBID );
|
||
if( itor == m_mPartyBackUp.end() )
|
||
return false;
|
||
|
||
BackupInfo = (*itor).second;
|
||
return true;
|
||
}
|
||
|
||
#if defined( PRE_FIX_49129 )
|
||
bool CDNGameRoom::AddFirstPartyStruct( CDNUserSession* pSession )
|
||
{
|
||
if( bIsFarmRoom() == false )
|
||
{
|
||
UINT uiMax = bIsPvPRoom() ? PvPCommon::Common::MaxPlayer : PARTYCOUNTMAX;
|
||
|
||
if (pSession->bIsGMTrace())
|
||
uiMax = PARTYMAX;
|
||
|
||
if( m_MapFirstPartyMember.size() >= uiMax )
|
||
return false;
|
||
}
|
||
else
|
||
return false;
|
||
|
||
PartyFirstStruct PartyFirst;
|
||
PartyFirst.biCharacterDBID = pSession->GetCharacterDBID();
|
||
|
||
PartyFirst.nIndex = (int)m_MapFirstPartyMember.size();
|
||
m_MapFirstPartyMember.insert( std::make_pair(PartyFirst.biCharacterDBID,PartyFirst) );
|
||
|
||
return true;
|
||
}
|
||
CDNGameRoom::PartyFirstStruct* CDNGameRoom::GetFirstPartyData( DWORD dwIndex )
|
||
{
|
||
std::map<INT64, PartyFirstStruct>::iterator itor = m_MapFirstPartyMember.begin();
|
||
for(;itor != m_MapFirstPartyMember.end(); itor++)
|
||
{
|
||
if( itor->second.nIndex == dwIndex )
|
||
return &itor->second;
|
||
}
|
||
return NULL;
|
||
}
|
||
CDNGameRoom::PartyFirstStruct* CDNGameRoom::GetFirstPartyData( INT64 biCharacterID )
|
||
{
|
||
std::map<INT64, PartyFirstStruct>::iterator itor = m_MapFirstPartyMember.find( biCharacterID );
|
||
if( itor == m_MapFirstPartyMember.end() )
|
||
return NULL;
|
||
return &itor->second;
|
||
}
|
||
#endif
|
||
|
||
#if defined( PRE_PARTY_DB )
|
||
void CDNGameRoom::SetPartyID( TPARTYID PartyID )
|
||
{
|
||
m_PartyStructData.PartyID = PartyID;
|
||
}
|
||
|
||
void CDNGameRoom::AddPartyDB( CDNUserSession* pBreakIntoSession )
|
||
{
|
||
if( GetTaskMng() )
|
||
{
|
||
CDnPartyTask* pPartyTask = (CDnPartyTask*)(GetTaskMng()->GetTask("PartyTask"));
|
||
if( pPartyTask )
|
||
pPartyTask->AddPartyDB( pBreakIntoSession );
|
||
}
|
||
}
|
||
|
||
void CDNGameRoom::AddPartyMemberDB( CDNUserSession* pSession )
|
||
{
|
||
if( GetTaskMng() )
|
||
{
|
||
CDnPartyTask* pPartyTask = (CDnPartyTask*)(GetTaskMng()->GetTask("PartyTask"));
|
||
if( pPartyTask )
|
||
pPartyTask->AddPartyMemberDB( pSession );
|
||
}
|
||
}
|
||
|
||
void CDNGameRoom::DelPartyDB()
|
||
{
|
||
if( GetTaskMng() )
|
||
{
|
||
CDnPartyTask* pPartyTask = (CDnPartyTask*)(GetTaskMng()->GetTask("PartyTask"));
|
||
if( pPartyTask )
|
||
pPartyTask->DelPartyDB();
|
||
}
|
||
}
|
||
|
||
void CDNGameRoom::DelPartyMemberDB( CDNUserSession *pSession )
|
||
{
|
||
#if defined( PRE_WORLDCOMBINE_PARTY )
|
||
if( bIsWorldCombineParty() == true )
|
||
return;
|
||
#endif // #if defined( PRE_WORLDCOMBINE_PARTY )
|
||
|
||
if( GetTaskMng() )
|
||
{
|
||
CDnPartyTask* pPartyTask = (CDnPartyTask*)(GetTaskMng()->GetTask("PartyTask"));
|
||
if( pPartyTask )
|
||
pPartyTask->DelPartyMemberDB( pSession );
|
||
}
|
||
}
|
||
#endif
|
||
|
||
#if defined (PRE_WORLDCOMBINE_PARTY)
|
||
bool CDNGameRoom::IsCloseTargetMap(int nMapIndex)
|
||
{
|
||
if( bIsWorldCombineParty() )
|
||
{
|
||
if (nMapIndex != GetPartyTargetMapID())
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
bool CDNGameRoom::bIsWorldCombineParty()
|
||
{
|
||
if (GetPartyIndex() > 0)
|
||
{
|
||
return Party::bIsWorldCombineParty( m_PartyStructData.Type );
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
#endif // #if defined (PRE_WORLDCOMBINE_PARTY)
|
||
|
||
#if defined( PRE_ADD_DIRECTNBUFF )
|
||
|
||
void CDNGameRoom::ApplyDirectPartyBuff( bool bUseItem/*=false*/ )
|
||
{
|
||
CDNUserSession * pSession = NULL;
|
||
for( std::list<int>::iterator itor = m_DirectPartyBuffItemList.begin();itor != m_DirectPartyBuffItemList.end(); itor++ )
|
||
{
|
||
for(int i=0;i<(int)GetUserCount();i++)
|
||
{
|
||
if( GetUserData(i) != NULL )
|
||
{
|
||
pSession = GetUserData(i);
|
||
CSUseItem pPacket;
|
||
memset(&pPacket, 0, sizeof(pPacket));
|
||
TItemData *pItemData = g_pDataManager->GetItemData(*itor);
|
||
if( g_pDataManager->IsUseItemAllowMapTypeCheck( pItemData->nItemID, m_iMapIdx ) )
|
||
{
|
||
TEffectSkillData* EffectSkill = pSession->GetItem()->GetEffectSkillItem( EffectSkillNameSpace::SearchType::SkillID, pItemData->nSkillID );
|
||
if( !EffectSkill )
|
||
{
|
||
pSession->GetItem()->ApplyPartyEffectSkillItemData(&pPacket, pItemData, pSession->GetSessionID(), EffectSkillNameSpace::ShowEffectType::NONEEFFECT, false, bUseItem);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void CDNGameRoom::RemoveDirectPartyBuff( int nItemID, bool bAll /*= false*/ )
|
||
{
|
||
if(bAll)
|
||
{
|
||
CDNUserSession * pSession = NULL;
|
||
for( std::list<int>::iterator itor = m_DirectPartyBuffItemList.begin();itor != m_DirectPartyBuffItemList.end();itor++)
|
||
{
|
||
TItemData *pItemData = g_pDataManager->GetItemData(*itor);
|
||
if( pItemData )
|
||
{
|
||
for(int i=0;i<(int)GetUserCount();i++)
|
||
{
|
||
if( GetUserData(i) != NULL )
|
||
{
|
||
pSession = GetUserData(i);
|
||
if( pSession && pSession->GetPlayerActor() )
|
||
{
|
||
TEffectSkillData* EffectSkill = pSession->GetItem()->GetEffectSkillItem( EffectSkillNameSpace::SearchType::SkillID, pItemData->nSkillID );
|
||
if( EffectSkill )
|
||
{
|
||
CDNUserSession::RemoveEffectSkill(pSession->GetPlayerActor(), EffectSkill);
|
||
pSession->GetItem()->DelEffectSkillItem( pItemData->nSkillID );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
int nItemCount = 0;
|
||
for( std::list<int>::iterator itor = m_DirectPartyBuffItemList.begin();itor != m_DirectPartyBuffItemList.end();)
|
||
{
|
||
if( nItemID == *itor)
|
||
{
|
||
if(nItemCount == 0)
|
||
itor = m_DirectPartyBuffItemList.erase(itor);
|
||
else
|
||
itor++;
|
||
nItemCount++;
|
||
}
|
||
else
|
||
itor++;
|
||
}
|
||
|
||
if(nItemCount <= 1)
|
||
{
|
||
TItemData *pItemData = g_pDataManager->GetItemData(nItemID);
|
||
if( pItemData )
|
||
{
|
||
CDNUserSession * pSession = NULL;
|
||
for(int i=0;i<(int)GetUserCount();i++)
|
||
{
|
||
if( GetUserData(i) != NULL )
|
||
{
|
||
pSession = GetUserData(i);
|
||
if( pSession && pSession->GetPlayerActor() )
|
||
{
|
||
TEffectSkillData* EffectSkill = pSession->GetItem()->GetEffectSkillItem( EffectSkillNameSpace::SearchType::SkillID, pItemData->nSkillID );
|
||
if( EffectSkill )
|
||
{
|
||
CDNUserSession::RemoveEffectSkill(pSession->GetPlayerActor(), EffectSkill);
|
||
pSession->GetItem()->DelEffectSkillItem( pItemData->nSkillID );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
void CDNGameRoom::SendDirectPartyBuffMsg(CDNUserSession * pSession/*=NULL*/)
|
||
{
|
||
if(pSession)
|
||
pSession->SendDirectPartyBuffMsg();
|
||
else
|
||
{
|
||
for(int i=0;i<(int)GetUserCount();i++)
|
||
{
|
||
if( GetUserData(i) != NULL )
|
||
{
|
||
pSession = GetUserData(i);
|
||
if(pSession->bIsDirectPartyBuff())
|
||
{
|
||
pSession->SendDirectPartyBuffMsg();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
#endif
|
||
|
||
#if defined( PRE_ADD_NEWCOMEBACK )
|
||
|
||
void CDNGameRoom::DelPartyMemberAppellation( int nAppellationID )
|
||
{
|
||
if( GetTaskMng() )
|
||
{
|
||
CDnPartyTask* pPartyTask = (CDnPartyTask*)(GetTaskMng()->GetTask("PartyTask"));
|
||
if( pPartyTask )
|
||
pPartyTask->DelPartyMemberAppellation( nAppellationID );
|
||
}
|
||
}
|
||
|
||
bool CDNGameRoom::CheckPartyMemberAppellation( int nAppellationID/*=0*/ )
|
||
{
|
||
if( GetTaskMng() )
|
||
{
|
||
CDnPartyTask* pPartyTask = (CDnPartyTask*)(GetTaskMng()->GetTask("PartyTask"));
|
||
if( pPartyTask )
|
||
return pPartyTask->CheckPartyMemberAppellation( nAppellationID );
|
||
}
|
||
return false;
|
||
}
|
||
|
||
void CDNGameRoom::ApplyJoinMemberAppellation( CDNUserSession * pSession )
|
||
{
|
||
if( !pSession )
|
||
return;
|
||
if( GetTaskMng() )
|
||
{
|
||
CDnPartyTask* pPartyTask = (CDnPartyTask*)(GetTaskMng()->GetTask("PartyTask"));
|
||
if( pPartyTask )
|
||
pPartyTask->ApplyJoinMemberAppellation( pSession );
|
||
}
|
||
}
|
||
|
||
#endif
|
||
|
||
#if defined( PRE_FIX_BUFFITEM )
|
||
void CDNGameRoom::CheckEffectSkillItemData()
|
||
{
|
||
CDNUserSession * pSession = NULL;
|
||
|
||
for(int i=0;i<(int)GetUserCount();i++)
|
||
{
|
||
if( GetUserData(i) != NULL )
|
||
{
|
||
pSession = GetUserData(i);
|
||
if( pSession )
|
||
{
|
||
pSession->CheckEffectSkillItemData();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
#endif
|
||
|
||
#if defined( PRE_WORLDCOMBINE_PVP )
|
||
|
||
void CDNGameRoom::AddDBWorldPvPRoom( TWorldPvPMissionRoom *pMissionRoom, UINT nGMAccountDBID )
|
||
{
|
||
if( bIsWorldPvPRoom() )
|
||
{
|
||
if(bIsPvPRoom())
|
||
{
|
||
GetDBConnection()->QueryAddWorldPvPRoom( 0, GetWorldSetID(), nGMAccountDBID, g_Config.nManagedID, GetRoomID(), pMissionRoom );
|
||
}
|
||
}
|
||
}
|
||
|
||
void CDNGameRoom::AddDBWorldPvPRoomMember( CDNUserSession* pSession )
|
||
{
|
||
if( bIsWorldPvPRoom() )
|
||
{
|
||
if(bIsPvPRoom())
|
||
{
|
||
bool bObserverFlag = false;
|
||
if( pSession->GetTeam() == PvPCommon::Team::Observer )
|
||
{
|
||
bObserverFlag = true;
|
||
}
|
||
GetDBConnection()->QueryAddWorldPvPRoomMember( 0, GetWorldSetID(), pSession, GetPvPMaxUser(), GetWorldPvPRoomDBIndex(), bObserverFlag );
|
||
}
|
||
}
|
||
}
|
||
|
||
void CDNGameRoom::DelDBWorldPvPRoomMember( CDNUserSession* pSession )
|
||
{
|
||
if( bIsWorldPvPRoom() )
|
||
{
|
||
if(bIsPvPRoom())
|
||
{
|
||
GetDBConnection()->QueryDelWorldPvPRoomMember( 0, GetWorldSetID(), GetWorldPvPRoomDBIndex(), pSession );
|
||
}
|
||
}
|
||
}
|
||
|
||
void CDNGameRoom::SetWorldPvPRoomStart(bool bFlag)
|
||
{
|
||
if( bIsPvPRoom() )
|
||
{
|
||
m_bWorldPvPRoomStart = bFlag;
|
||
if( m_bWorldPvPRoomStart )
|
||
{
|
||
GetDBConnection()->QueryDelWorldPvPRoom( GetWorldSetID(), GetWorldPvPRoomDBIndex() );
|
||
if( GetPvPGameMode() && GetPvPGameMode()->GetPvPGameModeTable() )
|
||
{
|
||
switch( GetPvPGameMode()->GetPvPGameModeTable()->uiGameMode )
|
||
{
|
||
case PvPCommon::GameMode::PvP_AllKill:
|
||
{
|
||
GetPvPGameMode()->SetWorldPvPRoomStart();
|
||
}
|
||
break;
|
||
case PvPCommon::GameMode::PvP_Tournament:
|
||
{
|
||
// 대진표 완성
|
||
GetPvPGameMode()->SetWorldPvPRoomStart();
|
||
}
|
||
break;
|
||
default:
|
||
printf("CDNGameRoom::SetWorldPvPRoomStart DEFAULT PVP CASE INVALID\n");
|
||
break;
|
||
|
||
}
|
||
}
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
void CDNGameRoom::SetWorldPvPFARMRoomStart(bool bFlag)
|
||
{
|
||
|
||
printf("CDNGameRoom::SetWorldPvPRoomStart(bool bFlag) : %d \n",bFlag);
|
||
//rlkt 2016
|
||
//GetPvPGameMode()->SetWorldPvPRoomStart();
|
||
//return;
|
||
|
||
printf("CDNGameRoom::SetWorldPvPRoomStart room is pvp\n");
|
||
m_bWorldPvPRoomStart = bFlag;
|
||
if( m_bWorldPvPRoomStart )
|
||
{
|
||
GetDBConnection()->QueryDelWorldPvPRoom( GetWorldSetID(), GetWorldPvPRoomDBIndex() );
|
||
if( GetPvPGameMode() && GetPvPGameMode()->GetPvPGameModeTable() )
|
||
{
|
||
switch( GetPvPGameMode()->GetPvPGameModeTable()->uiGameMode )
|
||
{
|
||
case PvPCommon::GameMode::PvP_AllKill:
|
||
{
|
||
GetPvPGameMode()->SetWorldPvPRoomStart();
|
||
}
|
||
break;
|
||
case PvPCommon::GameMode::PvP_Tournament:
|
||
{
|
||
// 대진표 완성
|
||
GetPvPGameMode()->SetWorldPvPRoomStart();
|
||
}
|
||
break;
|
||
default:
|
||
printf("CDNGameRoom::SetWorldPvPRoomStart DEFAULT PVP CASE INVALID\n");
|
||
break;
|
||
|
||
}
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
bool CDNGameRoom::CheckWorldPvPRoomBreakInto( MAGABreakIntoRoom* pPacket )
|
||
{
|
||
DWORD nPlayerCount = 0;
|
||
DWORD nObserverCount = 0;
|
||
|
||
nObserverCount = GetBreakIntoUserTeamCount( PvPCommon::Team::Observer );
|
||
nPlayerCount = GetBreakIntoUserCount() - nObserverCount;
|
||
|
||
for( UINT i=0 ; i<GetUserCount() ; ++i )
|
||
{
|
||
CDNGameRoom::PartyStruct* pStruct = GetPartyData(i);
|
||
if( pStruct->pSession && pStruct->pSession->GetTeam() == PvPCommon::Team::Observer )
|
||
nObserverCount++;
|
||
else if( pStruct->pSession )
|
||
nPlayerCount++;
|
||
|
||
}
|
||
|
||
int nRet = ERROR_NONE;
|
||
if(bIsWorldPvPRoomStart())
|
||
nRet = ERROR_PVP_JOINROOM_NOTFOUNDROOM;
|
||
|
||
if( pPacket->uiTeam == PvPCommon::Team::Observer )
|
||
{
|
||
if( nObserverCount >= PvPCommon::Common::ExtendMaxObserverPlayer)
|
||
nRet = ERROR_PVP_JOINROOM_MAXPLAYER;
|
||
}
|
||
else if( nPlayerCount >= GetPvPMaxUser() )
|
||
{
|
||
nRet = ERROR_PVP_JOINROOM_MAXPLAYER;
|
||
}
|
||
|
||
if( nRet != ERROR_NONE )
|
||
{
|
||
g_pMasterConnectionManager->SendWorldPvPRoomJoinResult( pPacket->cWorldSetID, nRet, pPacket->uiAccountDBID );
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
DWORD CDNGameRoom::GetBreakIntoUserTeamCount( int nTeam )
|
||
{
|
||
int nCount = 0;
|
||
for( std::list<CDNUserSession*>::iterator itor=m_BreakIntoUserList.begin() ; itor!=m_BreakIntoUserList.end() ; ++itor )
|
||
{
|
||
CDNUserSession* pSession = (*itor);
|
||
|
||
// m_VecMember 에 아직 Push 안된애만
|
||
if( GetUserSession( pSession->GetSessionID() ) == NULL )
|
||
{
|
||
if( pSession->GetTeam() == nTeam )
|
||
nCount++;
|
||
}
|
||
}
|
||
return nCount;
|
||
}
|
||
|
||
#endif
|
||
|
||
#if defined(PRE_ADD_ACTIVEMISSION)
|
||
|
||
void CDNGameRoom::InitActiveMission()
|
||
{
|
||
CDnWorld *pWorld = GetWorld();
|
||
if(!pWorld || pWorld->GetMapType() != EWorldEnum::MapTypeDungeon) return;
|
||
if(!GetIsFirstInitializeDungeon()) return;
|
||
|
||
int nActiveMissionGainRate = 0;
|
||
bool bGuildBonus = false;
|
||
|
||
// 파티 풀멤버 전원이 같은 길드원이면 액티브미션 획득 확률 증가
|
||
if( pWorld->GetMaxPartyCount() > 1 && pWorld->GetMaxPartyCount() == GetUserCount() )
|
||
{
|
||
bGuildBonus = true;
|
||
for( UINT i=0 ; i<m_VecMember.size() ; ++i )
|
||
{
|
||
CDNUserSession* pSession = m_VecMember[i].pSession;
|
||
if( !pSession->GetGuildUID().IsSet() || pSession->GetGuildUID() != m_VecMember[0].pSession->GetGuildUID() )
|
||
{
|
||
bGuildBonus = false;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
switch(pWorld->GetMapSubType())
|
||
{
|
||
case EWorldEnum::MapSubTypeNone:
|
||
nActiveMissionGainRate = bGuildBonus ? ActiveMission::NoneTypeActiveMissionGainBonusRate : ActiveMission::NoneTypeActiveMissionGainRate;
|
||
break;
|
||
|
||
case EWorldEnum::MapSubTypeNest:
|
||
case EWorldEnum::MapSubTypeNestNormal:
|
||
nActiveMissionGainRate = bGuildBonus ? ActiveMission::NestTypeActiveMissionGainBonusRate : ActiveMission::NestTypeActiveMissionGainRate;
|
||
break;
|
||
}
|
||
|
||
if(nActiveMissionGainRate <= 0) return;
|
||
|
||
//확률 치트
|
||
int nActiveMissionCheatID = 0;
|
||
for( UINT i=0 ; i<m_VecMember.size() ; ++i )
|
||
{
|
||
if( m_VecMember[i].pSession->GetActiveMissionCheatID() > 0 )
|
||
{
|
||
nActiveMissionCheatID = m_VecMember[i].pSession->GetActiveMissionCheatID();
|
||
m_VecMember[i].pSession->SetActiveMissionCheatID(0); //치트 한번 수행되면 리셋
|
||
break;
|
||
}
|
||
}
|
||
|
||
TActiveMissionData *pActiveMissionData = NULL;
|
||
|
||
if(nActiveMissionCheatID > 0)
|
||
{
|
||
pActiveMissionData = g_pDataManager->GetActiveMissionData(nActiveMissionCheatID-1);
|
||
}
|
||
else
|
||
{
|
||
if ((rand() % 100) >= nActiveMissionGainRate ) return;
|
||
pActiveMissionData = g_pDataManager->GetRandomActiveMission(m_iMapIdx, rand());
|
||
}
|
||
|
||
if(!pActiveMissionData) return;
|
||
for( UINT i=0 ; i<m_VecMember.size() ; ++i )
|
||
m_VecMember[i].pSession->GetMissionSystem()->SetActiveMission(pActiveMissionData);
|
||
}
|
||
|
||
#endif
|
||
|
||
#if defined(PRE_ADD_RENEW_RANDOM_MAP)
|
||
void CDNGameRoom::OnSelectRandomMap( int nRootMapIndex, int nRandomMapIndex )
|
||
{
|
||
m_iRootMapIndex = nRootMapIndex;
|
||
m_iMapIdx = nRandomMapIndex;
|
||
|
||
g_Log.Log(LogType::_NORMAL, L"CDnGameRoom OnSelectRandomMap %d %d", nRootMapIndex, nRandomMapIndex );
|
||
}
|
||
#endif
|
||
|
||
|
||
DWORD CDNGameRoom::GetPartyUserClassCount(int nClassID)
|
||
{
|
||
DWORD nClassCount = 0;
|
||
for (UINT i = 0; i < m_VecMember.size(); i++)
|
||
{
|
||
if ( (m_VecMember[i].pSession->bIsGMTrace() == false) && (m_VecMember[i].pSession->GetClassID() == nClassID))
|
||
nClassCount++;
|
||
}
|
||
return nClassCount;
|
||
}
|
||
|
||
#if defined( PRE_ALTEIAWORLD_EXPLORE )
|
||
void CDNGameRoom::SetAlteiaWorld(bool bFlag)
|
||
{
|
||
m_bAlteiaWorld = bFlag;
|
||
if( bFlag )
|
||
{
|
||
m_dwAlteiaWorldStartTime = timeGetTime();
|
||
GetDBConnection()->QueryAddStageStartLog( GetDBThreadID(), GetWorldSetID(), 0, GetRoomLogIndex(), GetPartyLogIndex(), static_cast<BYTE>(GetUserCount()), GetGameTask()->GetMapTableID(), static_cast<DBDNWorldDef::DifficultyCode::eCode>(Dungeon::Difficulty::Easy+1) );
|
||
SetStageStartLogFlag( true );
|
||
SetStageEndLogFlag( false );
|
||
}
|
||
else
|
||
{
|
||
m_dwAlteiaWorldPlayTime = timeGetTime() - m_dwAlteiaWorldStartTime;
|
||
|
||
for (UINT i = 0; i < m_VecMember.size(); i++)
|
||
{
|
||
if( m_VecMember[i].pSession )
|
||
{
|
||
m_VecMember[i].pSession->AddAlteiaWorldResult(true);
|
||
}
|
||
}
|
||
|
||
GetDBConnection()->QueryAddStageEndLog( GetDBThreadID(), GetWorldSetID(), 0, GetRoomLogIndex(), DBDNWorldDef::WhereToGoCode::Village );
|
||
}
|
||
}
|
||
|
||
void CDNGameRoom::ResetAlteiaWorldmap()
|
||
{
|
||
if( GetGameTask() )
|
||
GetGameTask()->ResetAlteiaWorldmap();
|
||
}
|
||
|
||
DWORD CDNGameRoom::GetAlteiaPlayTime()
|
||
{
|
||
if( m_dwAlteiaWorldPlayTime > 0 )
|
||
return m_dwAlteiaWorldPlayTime;
|
||
|
||
return 0;
|
||
}
|
||
#endif
|
||
#if defined(PRE_ADD_CP_RANK)
|
||
void CDNGameRoom::SetAbyssStageClearBest(const TAGetStageClearBest* pA)
|
||
{
|
||
memcpy(&m_sLegendClearBest, &pA->sLegendClearBest, sizeof(m_sLegendClearBest));
|
||
memcpy(&m_sMonthlyClearBest, &pA->sMonthlyClearBest, sizeof(m_sMonthlyClearBest));
|
||
if( pA->sLegendClearBest.biCharacterDBID > 0 && m_sLegendClearBest.cRank > 0)
|
||
m_sLegendClearBest.cRank = m_sLegendClearBest.cRank - DBDNWorldDef::ClearGradeCode::eCode::SSS;
|
||
if( pA->sMonthlyClearBest.biCharacterDBID > 0 && m_sMonthlyClearBest.cRank > 0)
|
||
m_sMonthlyClearBest.cRank = m_sMonthlyClearBest.cRank - DBDNWorldDef::ClearGradeCode::eCode::SSS;
|
||
}
|
||
#endif //#if defined(PRE_ADD_CP_RANK)
|
||
|
||
|
||
#if defined( PRE_PVP_GAMBLEROOM )
|
||
void CDNGameRoom::CreateGambleRoom( BYTE cGambleType, int nGamblePrice )
|
||
{
|
||
if( cGambleType == PvPGambleRoom::Gold )
|
||
nGamblePrice *= 10000 ;
|
||
|
||
GetDBConnection()->QueryAddGambleRoom(m_cDBThreadID, GetWorldSetID(), GetRoomID(), cGambleType, nGamblePrice );
|
||
}
|
||
#endif |