4904 lines
No EOL
309 KiB
C++
4904 lines
No EOL
309 KiB
C++
#include "stdafx.h"
|
||
#include "DnActor.h"
|
||
#include "GameSendPacket.h"
|
||
#include "DnWorldProp.h"
|
||
#include "Task.h"
|
||
#include "TaskManager.h"
|
||
#include "DNPartyTask.h"
|
||
#include "DNUserSession.h"
|
||
#include "DNRUDPGameServer.h"
|
||
#include "DNGameRoom.h"
|
||
#include "DNPvPGameRoom.h"
|
||
#include "DNIocpManager.h"
|
||
#include "DNMasterConnection.h"
|
||
#include "DNMasterConnectionManager.h"
|
||
#include "DNDBConnection.h"
|
||
#include "DNDBConnectionManager.h"
|
||
#include "DnPlayerActor.h"
|
||
#include "DnActor.h"
|
||
#include "Log.h"
|
||
#include "DNProtocol.h"
|
||
#include "DNGameServerScriptAPI.h"
|
||
#include "DNUserTcpConnection.h"
|
||
#include "DNLogConnection.h"
|
||
#include "DnGameTask.h"
|
||
#include "DNGameDataManager.h"
|
||
#include "PvPRespawnMode.h"
|
||
#include "DNFriend.h"
|
||
#include "DNIsolate.h"
|
||
#include "DNWorldUserState.h"
|
||
#include "DNMissionSystem.h"
|
||
#include "DNAppellation.h"
|
||
#include "DNMissionScheduler.h"
|
||
#include "DNAuthManager.h"
|
||
#include "DNRestraint.h"
|
||
#include "DNGuildSystem.h"
|
||
#include "VarArg.h"
|
||
#include "DnSkillTask.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 "MasterSystemCacheRepository.h"
|
||
#if defined( PRE_ADD_SECONDARY_SKILL )
|
||
#include "SecondarySkillRepository.h"
|
||
#endif // #if defined( PRE_ADD_SECONDARY_SKILL )
|
||
#include "DNChatRoom.h"
|
||
#include "DNChatRoomManager.h"
|
||
#include "LadderStats.h"
|
||
#include "DNTimeEventSystem.h"
|
||
#include "DnBlow.h"
|
||
#include "DNGuildRecruitCacheRepository.h"
|
||
#if defined (PRE_ADD_BESTFRIEND)
|
||
#include "DNBestFriend.h"
|
||
#endif
|
||
#if defined( PRE_PRIVATECHAT_CHANNEL )
|
||
#include "DNPrivateChatChannel.h"
|
||
#include "DnPrivateChatManager.h"
|
||
#endif
|
||
#if defined(PRE_FIX_69108)
|
||
#include "DNDLGameRoom.h"
|
||
#endif
|
||
#if defined(PRE_ADD_STAGE_CLEAR_ADD_REWARD)
|
||
#include "DnWorldOperationProp.h"
|
||
#include "DnItemTask.h"
|
||
#endif // #if defined(PRE_ADD_STAGE_CLEAR_ADD_REWARD)
|
||
#ifdef PRE_ADD_PACKETSIZE_CHECKER
|
||
#include "DNServiceConnection.h"
|
||
#endif //#ifdef PRE_ADD_PACKETSIZE_CHECKER
|
||
using namespace eItem;
|
||
|
||
extern TGameConfig g_Config;
|
||
|
||
CDNUserSession::CDNUserSession(unsigned int iUID, CDNRUDPGameServer * pServer, CDNGameRoom * pRoom)
|
||
{
|
||
m_pGameServer = pServer;
|
||
m_pGameRoom = pRoom;
|
||
m_pTcpConnection = NULL;
|
||
|
||
m_iState = SESSION_STATE_NONE;
|
||
m_iNetID = 0; //RUDPSocketFrame단에서 생성된 관리 ID이다 센드와 리시빙시에 필요.
|
||
m_nSessionID = iUID;
|
||
m_cPacketSeq = 1;
|
||
|
||
memset(m_szNextVillageIP, 0, sizeof(IPLENMAX));
|
||
m_nNextVillagePort = 0;
|
||
|
||
#if defined(_HSHIELD)
|
||
#if defined( PRE_ADD_HSHIELD_LOG )
|
||
g_Log.Log(LogType::_HACKSHIELD, m_pSession, L"[_AhnHS_CreateClientObject before - (%d) ] ServerHandle[%x] : 0x%x\r\n", GetSessionID(), g_Config.hHSServer, m_hHSClient);
|
||
#endif
|
||
m_hHSClient = _AhnHS_CreateClientObject(g_Config.hHSServer);
|
||
#if defined( PRE_ADD_HSHIELD_LOG )
|
||
g_Log.Log(LogType::_HACKSHIELD, m_pSession, L"[_AhnHS_CreateClientObject after - (%d) ] ServerHandle[%x] : 0x%x\r\n", GetSessionID(), g_Config.hHSServer, m_hHSClient);
|
||
#endif
|
||
if(m_hHSClient == ANTICPX_INVALID_HANDLE_VALUE){
|
||
DetachConnection(L"ANTICPX_INVALID_HANDLE_VALUE");
|
||
return;
|
||
}
|
||
|
||
m_dwCheckLiveTick = m_dwHShieldResponseTick = timeGetTime();
|
||
#endif // _HSHIELD
|
||
|
||
m_bStageAbortLog = true;
|
||
|
||
for( int i=0; i<3; i++ ) {
|
||
memset( m_pPacketQueueBuffer[i], 0, PACKET_QUEUE_SIZE );
|
||
m_nPacketQueueOffset[i] = 0;
|
||
m_nPacketQueueCount[i] = 0;
|
||
}
|
||
|
||
m_bIntededDisconnected = false;
|
||
m_bRudpDisconnected = false;
|
||
m_nRudpDisconnectedTick = 0;
|
||
|
||
m_iTeam = 0;
|
||
|
||
m_cKickKind = -1;
|
||
m_bAbsent = false;
|
||
m_bPvPGameModeFinish = false;
|
||
m_bGMTrace = false;
|
||
m_iDecreaseFatigue = 0;
|
||
m_bLoadingComplete = false;
|
||
m_iTotalMasterDecreaseFatigue = 0;
|
||
m_nPartyMemberIndex = -1;
|
||
m_nChatRoomID = 0;
|
||
m_bPvPFatigueOption = false;
|
||
m_biPickUpCoin = 0;
|
||
#if defined( PRE_USA_FATIGUE )
|
||
m_bNoFagiueEnter = false;
|
||
#endif // #if defined( PRE_USA_FATIGUE )
|
||
m_bOuted = false;
|
||
m_dwCheckUdpPing = timeGetTime();
|
||
m_pairUdpPing = std::make_pair(0,0);
|
||
m_dwKeepOperationID = 0;
|
||
|
||
m_bHide = false;
|
||
m_bTutorial = false;
|
||
m_uiPvPUserState = 0;
|
||
m_mGuildRewardItem.clear();
|
||
m_nPeriodeExpItemRate = 0;
|
||
#if defined( PRE_ADD_NAMEDITEM_SYSTEM )
|
||
m_nGoldBoxCheatID = 0;
|
||
#endif
|
||
#if defined(PRE_ADD_ACTIVEMISSION)
|
||
m_nActiveMissionCheatID = 0;
|
||
#endif
|
||
#if defined( PRE_ADD_DIRECTNBUFF )
|
||
m_bDirectPartyBuffItem = false;
|
||
m_DirectPartyBuffItemList.clear();
|
||
#endif
|
||
#ifdef PRE_MOD_INDUCE_TCPCONNECT
|
||
m_dwSendReqTCPConnect = 0;
|
||
m_bRecvReqTCPConnectMsg = false;
|
||
#endif //#ifdef PRE_MOD_INDUCE_TCPCONNECT
|
||
|
||
#if defined( PRE_ADD_GUILDREWARDITEM )
|
||
m_GuildRewardbuffItemList.clear();
|
||
#endif
|
||
#if defined( PRE_ALTEIAWORLD_EXPLORE )
|
||
m_nAlteiaWorldPosition = 1;
|
||
m_dwAlteiaWorldMoveNextMapTick = 0;
|
||
m_cDailyPlayCount = 0;
|
||
m_bCanDice = true;
|
||
#endif
|
||
|
||
#ifdef PRE_ADD_PACKETSIZE_CHECKER
|
||
m_nSendCheckTick = 0;
|
||
m_nSendCheckSize = 0;
|
||
m_nSendCheckCount = 0;
|
||
|
||
memset(m_SendDebugInfo, 0, sizeof(m_SendDebugInfo));
|
||
m_nSendDebugInfoCount = 0;
|
||
//memset(m_SendActorDebugInfo, 0, sizeof(m_SendActorDebugInfo));
|
||
//m_nSendActorDebugInfoCount = 0;
|
||
|
||
_ACTOR_SENDINFO Info;
|
||
memset(&Info, 0, sizeof(_ACTOR_SENDINFO));
|
||
for (int i = 0; i < eActor::SC_ACTOR_STATE_MAX; i++)
|
||
m_vActorSendInfo.push_back(Info);
|
||
m_bActorDebugSended = false;
|
||
#endif //#ifdef PRE_ADD_PACKETSIZE_CHECKER
|
||
}
|
||
|
||
CDNUserSession::~CDNUserSession()
|
||
{
|
||
for( DNVector(_STORE_PACKET)::iterator ii = m_pStoredPacketList.begin(); ii != m_pStoredPacketList.end(); ii++)
|
||
CLfhHeap::GetInstance()->_DeAlloc((*ii).pMsg);
|
||
}
|
||
|
||
const char * CDNUserSession::GetIp()
|
||
{
|
||
if(m_pTcpConnection)
|
||
return m_pTcpConnection->GetIp();
|
||
return NULL;
|
||
}
|
||
|
||
const WCHAR * CDNUserSession::GetIpW()
|
||
{
|
||
if(m_pTcpConnection)
|
||
return m_pTcpConnection->GetwszIp();
|
||
return NULL;
|
||
}
|
||
|
||
int CDNUserSession::GetServerID()
|
||
{
|
||
// 2009.01.20 김밥
|
||
// return 제대로 되지 않아 수정
|
||
if(m_pGameServer)
|
||
return m_pGameServer->GetServerID();
|
||
return -1;
|
||
}
|
||
|
||
int CDNUserSession::GetRoomID()
|
||
{
|
||
if(m_pGameRoom) return m_pGameRoom->GetRoomID();
|
||
return 0;
|
||
}
|
||
|
||
TPARTYID CDNUserSession::GetPartyID()
|
||
{
|
||
return m_pGameRoom->GetPartyIndex();
|
||
}
|
||
|
||
void CDNUserSession::SetSessionState(int nState)
|
||
{
|
||
if(m_iState == SESSION_STATE_DISCONNECTED) return; //이미 파이날유저가 불려진 경우에는 스테이트를 변경하지 않는다.
|
||
m_iState = nState;
|
||
|
||
if (m_iState == SESSION_STATE_LOADED)
|
||
m_bLoadUserData = true;
|
||
}
|
||
|
||
int CDNUserSession::GetPromotionValue(int nType)
|
||
{
|
||
std::vector <TUserPromotionData>::iterator ii;
|
||
for(ii = m_vPromotionData.begin(); ii != m_vPromotionData.end(); ii++)
|
||
{
|
||
if((*ii).nType == nType)
|
||
return(*ii).nValue;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
void CDNUserSession::SetKeepOperationID(DWORD dwUniqueID)
|
||
{
|
||
m_dwKeepOperationID = dwUniqueID;
|
||
}
|
||
|
||
bool CDNUserSession::IsConnected()
|
||
{
|
||
return(m_iState >= SESSION_STATE_CONNECTED) &&(m_iState != SESSION_STATE_DISCONNECTED) &&
|
||
(m_pTcpConnection != NULL && m_pTcpConnection->GetDelete() == false) ? true : false;
|
||
}
|
||
|
||
bool CDNUserSession::RUDPConnected(int iNetID)
|
||
{
|
||
_ASSERT(iNetID != 0);
|
||
if(m_iState >= SESSION_STATE_RUDP_CONNECTED || iNetID == 0)
|
||
{
|
||
g_Log.Log(LogType::_ERROR, this, L"Connect|ReConnected RUDP err NetID:%d\n", iNetID);
|
||
return false;
|
||
}
|
||
|
||
m_iNetID = iNetID;
|
||
SetSessionState(SESSION_STATE_RUDP_CONNECTED);
|
||
return true;
|
||
}
|
||
|
||
bool CDNUserSession::TCPConnected(CDNTcpConnection * pCon)
|
||
{
|
||
if(m_iState != SESSION_STATE_RUDP_CONNECTED)
|
||
{
|
||
g_Log.Log(LogType::_ERROR, this, L"Connect|RUDP Connected Not Yet ADBID[%d] CNAME[%s]", GetAccountDBID(), GetCharacterName());
|
||
return false;
|
||
}
|
||
|
||
if(g_pMasterConnectionManager->SendEnterGame(m_nWorldSetID, GetAccountDBID(), GetGameRoom()->GetRoomID(), m_pGameServer->GetServerID()) == false)
|
||
{
|
||
g_Log.Log(LogType::_ERROR, this, L"Connect|MasterCon Not Found ADBID[%d] CNAME[%s]", GetAccountDBID(), GetCharacterName());
|
||
return false;
|
||
}
|
||
|
||
m_pTcpConnection = pCon;
|
||
SetSessionState(SESSION_STATE_CONNECTED);
|
||
|
||
m_bCertified = false;
|
||
m_dwCertifyingTick = timeGetTime();
|
||
|
||
g_pAuthManager->QueryCheckAuth(GetCertifyingKey(), this);
|
||
|
||
InitVoice();
|
||
|
||
#ifdef PRE_MOD_INDUCE_TCPCONNECT
|
||
|
||
#endif //#ifdef PRE_MOD_INDUCE_TCPCONNECT
|
||
|
||
return true;
|
||
}
|
||
|
||
void CDNUserSession::RudpDisConnected()
|
||
{
|
||
//rudp만 끊긴겁니다. tcp연결과 room, session의 state를 확인해서 진짜 끊어져야 하는데
|
||
if(IsConnected() && m_iState != SESSION_STATE_SERVER_CHANGE) //일단 스테이트 변경은 하지 않습니다. rudp의 재연결 유도 합니다.
|
||
{
|
||
SendReConnectReq();
|
||
|
||
m_bRudpDisconnected = true;
|
||
m_nRudpDisconnectedTick = GetGameRoom()->GetGameTick(); //끊긴시간을 기억해 봅니다.
|
||
}
|
||
}
|
||
|
||
void CDNUserSession::_SendReconnectLogin()
|
||
{
|
||
if( m_pGameRoom->GetRoomState() != _GAME_STATE_SYNC2PLAY )
|
||
g_pMasterConnectionManager->SendLoginState(m_nWorldSetID, m_nAccountDBID);
|
||
else {
|
||
SendReconnectLogin(ERROR_GENERIC_INVALIDREQUEST, 0, 0);
|
||
}
|
||
}
|
||
|
||
void CDNUserSession::SetPromotionData(int nPromotionType, int nValue)
|
||
{
|
||
bool bAdded = false;
|
||
std::vector <TUserPromotionData>::iterator ii;
|
||
for(ii = m_vPromotionData.begin(); ii != m_vPromotionData.end(); ii++)
|
||
{
|
||
if((*ii).nType == nPromotionType)
|
||
{
|
||
(*ii).nValue = (*ii).nValue < nValue ? nValue :(*ii).nValue;
|
||
bAdded = true;
|
||
}
|
||
}
|
||
|
||
if(bAdded == false)
|
||
{
|
||
TUserPromotionData Promo;
|
||
memset(&Promo, 0, sizeof(TUserPromotionData));
|
||
|
||
Promo.nType = nPromotionType;
|
||
Promo.nValue = nValue;
|
||
// 피로도 감소 타입은 10000 배율을 사용하기 때문에 100배 해준다.
|
||
if( Promo.nType == PROMOTIONTYPE_DECREASEFATIGUE )
|
||
Promo.nValue *= 100;
|
||
|
||
m_vPromotionData.push_back(Promo);
|
||
}
|
||
}
|
||
|
||
void CDNUserSession::IntendedDisconnected()
|
||
{
|
||
m_bIntededDisconnected = true;
|
||
}
|
||
|
||
void CDNUserSession::DetachConnection(wchar_t *pwszIdent)
|
||
{
|
||
if(m_iState == SESSION_STATE_DISCONNECTED) return;
|
||
|
||
// 난입인경우 m_VecMember 에 pushback 하기 전인경우는 바로 RemoveMember() 호출해준다.
|
||
// 여기 주석처리하면 안되용~~~!!!
|
||
if(GetGameRoom())
|
||
{
|
||
if( GetGameRoom()->bIsBreakIntoUser( this ) )
|
||
{
|
||
if( GetGameRoom()->GetPartyData(this) == NULL )
|
||
{
|
||
GetGameRoom()->RemoveMember(this, pwszIdent);
|
||
if(GetTcpConnection())
|
||
GetTcpConnection()->DetachConnection(pwszIdent);
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
|
||
if(GetTcpConnection())
|
||
GetTcpConnection()->DetachConnection(pwszIdent);
|
||
else if(GetGameRoom())
|
||
GetGameRoom()->RemoveMember(this, pwszIdent);
|
||
else _DANGER_POINT();
|
||
|
||
#ifdef _USE_VOICECHAT
|
||
LeaveVoiceChannel();
|
||
if(GetGameRoom())
|
||
GetGameRoom()->SendRefreshVoiceInfo(GetAccountDBID());
|
||
else _DANGER_POINT();
|
||
#endif
|
||
}
|
||
|
||
#ifdef PRE_MOD_INDUCE_TCPCONNECT
|
||
void CDNUserSession::SendReqTCPConnect(DWORD dwCurTick)
|
||
{
|
||
if (GetState() != SESSION_STATE_RUDP_CONNECTED) return;
|
||
if (m_bRecvReqTCPConnectMsg == true) return;
|
||
if (m_dwSendReqTCPConnect == 0 || m_dwSendReqTCPConnect + 3000 < dwCurTick)
|
||
{
|
||
m_dwSendReqTCPConnect = dwCurTick;
|
||
SendPacket(SC_SYSTEM, eSystem::SC_TCP_CONNECT_REQ, NULL, 0, _RELIABLE);
|
||
g_Log.Log(LogType::_GAMECONNECTLOG, this, L"[%d] CS_CONNECT_REQUEST\n", g_Config.nManagedID);
|
||
}
|
||
}
|
||
|
||
void CDNUserSession::RecvReqTCPConnect()
|
||
{
|
||
g_Log.Log(LogType::_GAMECONNECTLOG, this, L"[%d] CS_TCP_CONNECT_REQ\n", g_Config.nManagedID);
|
||
}
|
||
#endif //#ifdef PRE_MOD_INDUCE_TCPCONNECT
|
||
|
||
void CDNUserSession::DoUpdate( DWORD dwCurTick )
|
||
{
|
||
#ifdef PRE_MOD_INDUCE_TCPCONNECT
|
||
if (GetGameRoom()->GetRoomState() == _GAME_STATE_READY2CONNECT || GetGameRoom()->GetRoomState() == _GAME_STATE_CONNECT2CHECKAUTH)
|
||
{
|
||
SendReqTCPConnect(dwCurTick);
|
||
return;
|
||
}
|
||
#endif //#ifdef PRE_MOD_INDUCE_TCPCONNECT
|
||
if( bIsCheckPing() == true )
|
||
{
|
||
if( dwCurTick-m_dwCheckUdpPing >= CHECK_UDP_PING_TICK )
|
||
{
|
||
m_dwCheckUdpPing = dwCurTick;
|
||
SendUdpPing( GetSessionID(), dwCurTick );
|
||
}
|
||
}
|
||
|
||
#if defined( PRE_ALTEIAWORLD_EXPLORE )
|
||
// if( m_dwAlteiaWorldMoveNextMapTick > 0 && dwCurTick - m_dwAlteiaWorldMoveNextMapTick >= AlteiaWorld::Common::MoveNextMapTick)
|
||
// {
|
||
// MoveAlteiaNextMap();
|
||
// }
|
||
#endif
|
||
|
||
CDNUserBase::DoUpdate(dwCurTick);
|
||
}
|
||
|
||
void CDNUserSession::DecreaseFatigue( bool bFinalUser/*=false*/ )
|
||
{
|
||
if( GetGameRoom() && GetGameRoom()->GetMasterRewardSystem() )
|
||
{
|
||
if( GetGameRoom()->GetMasterRewardSystem()->bIsFatigueReward( this ) )
|
||
{
|
||
m_iTotalMasterDecreaseFatigue += GetDecreaseFatigue(); // 피로도 누적
|
||
#if defined( _WORK )
|
||
WCHAR wszBuf[MAX_PATH];
|
||
wsprintf( wszBuf, L"[사제시스템] 피로도 보상 적용으로 깎이지 않음" );
|
||
SendDebugChat( wszBuf );
|
||
#endif // #if defined( _WORK )
|
||
return;
|
||
}
|
||
}
|
||
|
||
int iDecreaseFatigue = GetDecreaseFatigue();
|
||
if( iDecreaseFatigue > 0 )
|
||
{
|
||
// FinalUser 시에만 로딩중 끊긴 유저는 피로도 깎지 않는다.
|
||
if( bFinalUser && !bIsLoadingComplete() )
|
||
{
|
||
g_Log.Log(LogType::_LOADINGDISCONNECT, this, L"로딩중 끊겨서 피로도 깎지 않음 Fatigue(일반:%d 주간:%d PC방:%d Event:%d VIP:%d)\r\n", GetFatigue(), GetWeeklyFatigue(), GetPCBangFatigue(), GetEventFatigue(),GetEventFatigue());
|
||
return;
|
||
}
|
||
if( CDnWorld::GetInstance( GetGameRoom() ).GetMapType() == EWorldEnum::MapTypeDungeon )
|
||
{
|
||
int iPrevValue = iDecreaseFatigue;
|
||
|
||
// 레벨감소
|
||
int iLevelDecreaseValue = (iDecreaseFatigue*g_pDataManager->GetFatigue10000RatioFromPlayerCommonLevelTable( GetLevel() )/10000);
|
||
// 만렙감소
|
||
int iMaxLevelDecreaseValue = (iDecreaseFatigue*GetPromotionValue(PROMOTIONTYPE_DECREASEFATIGUE)/10000);
|
||
|
||
iDecreaseFatigue -= (iLevelDecreaseValue+iMaxLevelDecreaseValue);
|
||
if( iDecreaseFatigue < 0 )
|
||
iDecreaseFatigue = 0;
|
||
|
||
#if defined( _WORK )
|
||
WCHAR wszBuf[MAX_PATH];
|
||
wsprintf( wszBuf, L"최종피로도감소 피로도:%d 레벨감소:%d 만렙감소:%d 최종:%d\r\n", iPrevValue, iLevelDecreaseValue, iMaxLevelDecreaseValue, iDecreaseFatigue );
|
||
SendDebugChat( wszBuf );
|
||
#endif // #if defined( _WORK )
|
||
if( iDecreaseFatigue > 0 )
|
||
DecreaseFatigue( iDecreaseFatigue );
|
||
}
|
||
SetDecreaseFatigue(0);
|
||
}
|
||
}
|
||
|
||
void CDNUserSession::MasterMessageProcess(int iMainCmd, int iSubCmd, const void * pData, int iLen)
|
||
{//외부 메세지가 세션단에서 처리되어야 할 때 입니다.
|
||
switch(iMainCmd)
|
||
{
|
||
case MAGA_NEXTVILLAGEINFO:
|
||
{
|
||
MAGANextVillageInfo * pPacket = (MAGANextVillageInfo*)pData;
|
||
|
||
SetWindowState(WINDOW_NONE);
|
||
GetGameRoom()->SendNextVillageInfo(pPacket->szIP, pPacket->nPort, pPacket->nMapIdx, pPacket->nNextMapIdx, pPacket->nNextGateIdx, pPacket->nRet, pPacket->nItemSerial);
|
||
|
||
break;
|
||
}
|
||
|
||
case MAGA_REBIRTHVILLAGEINFO:
|
||
{
|
||
MAGARebirthVillageInfo *pInfo = (MAGARebirthVillageInfo*)pData;
|
||
|
||
if( pInfo->nRet == ERROR_NONE )
|
||
{
|
||
_strcpy( m_szNextVillageIP, _countof(m_szNextVillageIP), pInfo->szIP, (int)strlen(pInfo->szIP));
|
||
m_nNextVillagePort = pInfo->nPort;
|
||
|
||
m_bCharOutLog = false;
|
||
|
||
SetSessionState(SESSION_STATE_READY_TO_VILLAGE);
|
||
|
||
m_biCertifyingKey = g_pAuthManager->GetCertifyingKey();
|
||
DN_ASSERT(0 != m_biCertifyingKey, "Invalid!"); // 인증키가 0 이 생성되면 않됨 !!!(없음 의미)
|
||
|
||
g_pAuthManager->QueryStoreAuth(SERVERTYPE_GAME, this);
|
||
}
|
||
else
|
||
{
|
||
SendVillageInfo(m_szNextVillageIP, m_nNextVillagePort, pInfo->nRet, 0, 0);
|
||
_SendReconnectLogin();
|
||
}
|
||
|
||
if(m_pGameRoom)
|
||
{
|
||
GetGameRoom()->OnDelPartyMember(GetSessionID(), m_cKickKind);
|
||
#if defined(PRE_ADD_REVENGE)
|
||
if( m_pGameRoom->bIsPvPRoom() && !GetPvPGameModeFinish() )
|
||
static_cast<CDNPvPGameRoom*>(m_pGameRoom)->OnLeaveRoomBeforeFinish(GetSessionID());
|
||
#endif
|
||
}
|
||
|
||
break;
|
||
}
|
||
case MAGA_MOVEPVPGAMETOPVPLOBBY:
|
||
{
|
||
MAGAMovePvPGameToPvPLobby* pPacket = (MAGAMovePvPGameToPvPLobby*)pData;
|
||
|
||
if( pPacket->nRet == ERROR_NONE )
|
||
{
|
||
// 게임에서 나감 알림
|
||
if( m_pGameRoom )
|
||
#if defined(PRE_ADD_REVENGE)
|
||
{
|
||
m_pGameRoom->OnDelPartyMember(GetSessionID(), -1);
|
||
|
||
if( m_pGameRoom->bIsPvPRoom() && !GetPvPGameModeFinish() )
|
||
static_cast<CDNPvPGameRoom*>(m_pGameRoom)->OnLeaveRoomBeforeFinish(GetSessionID());
|
||
}
|
||
#else
|
||
m_pGameRoom->OnDelPartyMember(GetSessionID(), -1);
|
||
#endif
|
||
else
|
||
_DANGER_POINT();
|
||
|
||
_strcpy( m_szNextVillageIP, _countof(m_szNextVillageIP), pPacket->szIP, (int)strlen(pPacket->szIP) );
|
||
m_nNextVillagePort = pPacket->unPort;
|
||
|
||
m_bCharOutLog = false;
|
||
|
||
SetSessionState(SESSION_STATE_READY_TO_VILLAGE);
|
||
|
||
m_biCertifyingKey = g_pAuthManager->GetCertifyingKey();
|
||
DN_ASSERT(0 != m_biCertifyingKey, "Invalid!"); // 인증키가 0 이 생성되면 않됨 !!!(없음 의미)
|
||
|
||
g_pAuthManager->QueryStoreAuth(SERVERTYPE_GAME, this);
|
||
}
|
||
else {
|
||
SendVillageInfo( m_szNextVillageIP, m_nNextVillagePort, pPacket->nRet, 0, 0);
|
||
}
|
||
break;
|
||
}
|
||
|
||
case MAGA_LOGINSTATE:
|
||
{
|
||
MAGALoginState *pState = (MAGALoginState*)pData;
|
||
|
||
if(ERROR_NONE != pState->nRet) {
|
||
SendReconnectLogin(pState->nRet, 0, 0);
|
||
break;
|
||
}
|
||
|
||
SetSessionState(SESSION_STATE_READY_TO_LOGIN);
|
||
|
||
m_biCertifyingKey = g_pAuthManager->GetCertifyingKey();
|
||
DN_ASSERT(0 != m_biCertifyingKey, "Invalid!"); // 인증키가 0 이 생성되면 않됨 !!!(없음 의미)
|
||
|
||
g_pAuthManager->QueryStoreAuth(SERVERTYPE_GAME, this);
|
||
|
||
if(m_pGameRoom)
|
||
{
|
||
GetGameRoom()->OnDelPartyMember(GetSessionID(), m_cKickKind);
|
||
#if defined(PRE_ADD_REVENGE)
|
||
if( GetGameRoom()->bIsPvPRoom() && !GetPvPGameModeFinish() )
|
||
static_cast<CDNPvPGameRoom*>(GetGameRoom())->OnLeaveRoomBeforeFinish(GetSessionID());
|
||
#endif
|
||
}
|
||
|
||
break;
|
||
}
|
||
|
||
case MAGA_FRIENDADDNOTICE:
|
||
{
|
||
MAGAFriendAddNotice * pNotice = (MAGAFriendAddNotice*)pData;
|
||
SendFriendAddNotice(pNotice->wszAddName);
|
||
break;
|
||
}
|
||
|
||
case MAGA_PRIVATECHAT:
|
||
{
|
||
MAPrivateChat *pChat = (MAPrivateChat*)pData;
|
||
|
||
if(pChat->wChatLen > CHATLENMAX-1) break;
|
||
WCHAR wszChatMsg[CHATLENMAX] = { 0, };
|
||
_wcscpy(wszChatMsg, CHATLENMAX, pChat->wszChatMsg, pChat->wChatLen);
|
||
|
||
if( m_pIsolate && m_pIsolate->IsIsolateItem(pChat->wszFromCharacterName)) //내가 차단한 캐릭터에게서 온 메세지는 무시
|
||
break;
|
||
|
||
if( pChat->nRet == ERROR_NONE )
|
||
{
|
||
// GM이면 없는 사람처럼 해야함
|
||
if((GetAccountLevel() <= AccountLevel_QA) &&(GetAccountLevel() >= AccountLevel_New))
|
||
{
|
||
if(!GetGMCommand()->IsWhisperName(pChat->wszFromCharacterName))
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
SendChat(pChat->cType, pChat->wChatLen, pChat->wszFromCharacterName, wszChatMsg, NULL, pChat->nRet);
|
||
break;
|
||
}
|
||
|
||
case MAGA_CHAT:
|
||
{
|
||
MAChat *pChat = (MAChat*)pData;
|
||
|
||
if(pChat->wChatLen > CHATLENMAX-1 || pChat->wChatLen <= 0) break;
|
||
WCHAR wszChatMsg[CHATLENMAX] = { 0, };
|
||
_wcscpy(wszChatMsg, CHATLENMAX, pChat->wszChatMsg, pChat->wChatLen);
|
||
|
||
SendChat(static_cast<eChatType>(pChat->cType), pChat->wChatLen, pChat->wszFromCharacterName, wszChatMsg);
|
||
break;
|
||
}
|
||
|
||
case MAGA_DETACHUSER:
|
||
{
|
||
MADetachUser* pDetach = (MADetachUser*)pData;
|
||
if( pDetach->bIsDuplicate )
|
||
{
|
||
bool bIsDetach = true;
|
||
if( GetGameRoom() && GetGameRoom()->IsRoomCrash() )
|
||
// 크래쉬 방이면 Auth 리셋 해주라고 보냄..
|
||
bIsDetach = false;
|
||
|
||
g_pMasterConnectionManager->SendDuplicateLogin(GetWorldSetID(), pDetach->nAccountDBID, bIsDetach, pDetach->nSessionID);
|
||
if( GetGameRoom() )
|
||
g_Log.Log(LogType::_NORMAL, GetWorldSetID(), GetAccountDBID(), GetCharacterDBID(), GetSessionID(), L"[MAGA_DETACHUSER] Duplicate User InGame!! RoomState:%d, SessionState:%d, RoomCrash:%d\r\n", GetGameRoom()->GetRoomState(), m_iState, GetGameRoom()->IsRoomCrash());
|
||
else
|
||
g_Log.Log(LogType::_NORMAL, GetWorldSetID(), GetAccountDBID(), GetCharacterDBID(), GetSessionID(), L"[MAGA_DETACHUSER] Duplicate User InGame!! SessionState:%d\r\n", m_iState);
|
||
|
||
#if defined(PRE_MOD_DUPLICATION_LOGIN_MES)
|
||
// 중복 로그인으로 끊는 경우, 처음에는 클라이언트에게 접속 종료 요청.
|
||
// DetachFlag가 On인 경우에만 서버에서 접속을 종료시킴(클라가 조작되거나 패킷을 받지 않는 경우, 중복 로그인으로 연결 해제 요청이 다시 들어올수 있음)
|
||
if(bIsDetach && GetTcpConnection() && !GetTcpConnection()->GetDetachFlag())
|
||
SendCompleteDetachMsg( ERROR_DUPLICATEUSER_INGAME, L"ERROR_DUPLICATEUSER_INGAME", true);
|
||
else
|
||
DetachConnection(L"MAGA_DETACHUSER | DUPLICATEUSER");
|
||
|
||
break;
|
||
#endif // #if defined(PRE_MOD_DUPLICATION_LOGIN_MES)
|
||
}
|
||
DetachConnection(L"MAGA_DETACHUSER");
|
||
break;
|
||
}
|
||
|
||
#if defined(_CH)
|
||
case MAGA_FCMSTATE: // 피로도
|
||
{
|
||
MAFCMState *pState = (MAFCMState*)pData;
|
||
SetFCMOnlineMin(pState->nOnlineMin, pState->bSend);
|
||
break;
|
||
}
|
||
#endif // _CH
|
||
|
||
case MAGA_NOTIFYMAIL:
|
||
{
|
||
MANotifyMail *pMail = (MANotifyMail*)pData;
|
||
|
||
if(pMail->biToCharacterDBID == m_biCharacterDBID)
|
||
SendNotifyMail(pMail->wTotalMailCount, pMail->wNotReadMailCount, pMail->w7DaysLeftCount, pMail->bNewMail); // 우편왔다고 통보
|
||
break;
|
||
}
|
||
|
||
case MAGA_NOTIFYMARKET:
|
||
{
|
||
MANotifyMarket *pMarket = (MANotifyMarket*)pData;
|
||
|
||
if(pMarket->biSellerCharacterDBID == m_biCharacterDBID)
|
||
SendNotifyMarket(pMarket->nItemID, pMarket->wCalculationCount);
|
||
break;
|
||
}
|
||
|
||
case MAGA_NOTIFYGIFT:
|
||
{
|
||
MANotifyGift *pGift = (MANotifyGift*)pData;
|
||
|
||
if(pGift->biToCharacterDBID == GetCharacterDBID())
|
||
SendCashshopNotifyGift(pGift->bNew, pGift->nGiftCount); // 선물왔다고 통보
|
||
break;
|
||
}
|
||
|
||
case MAGA_RESTRAINT:
|
||
{
|
||
MARestraint * pPacket = (MARestraint*)pData;
|
||
GetDBConnection()->QueryGetRestraint( this );
|
||
break;
|
||
}
|
||
|
||
case MAGA_PCBANGRESULT:
|
||
{
|
||
MAPCBangResult *pResult = (MAPCBangResult*)pData;
|
||
PCBangResult(pResult);
|
||
break;
|
||
}
|
||
|
||
case MAGA_INVITEPARTYMEMBERRESULT:
|
||
{
|
||
MAGAInvitePartyMemberResult * pPacket = (MAGAInvitePartyMemberResult*)pData;
|
||
|
||
GetGameRoom()->ResetInvite(pPacket->nRetCode);
|
||
SendPartyInviteFail(pPacket->nRetCode);
|
||
break;
|
||
}
|
||
#if defined(PRE_MOD_REQ_JOIN_PARTY_ANSWER_MSG_APP)
|
||
case MAGA_GETPARTYID:
|
||
{
|
||
MAGAGetPartyID* pPacket = (MAGAGetPartyID*)(pData);
|
||
if(g_pMasterConnectionManager)
|
||
g_pMasterConnectionManager->SendGetPartyIDResult(GetGameRoom()->GetWorldSetID(), pPacket->nSenderAccountDBID, GetPartyID());
|
||
break;
|
||
}
|
||
case MAGA_REQPARTYASKJOIN:
|
||
{
|
||
MAGAReqPartyAskJoin* pPacket = (MAGAReqPartyAskJoin*)(pData);
|
||
if( GetPartyID() <= 0 )
|
||
{
|
||
if(g_pMasterConnectionManager)
|
||
g_pMasterConnectionManager->SendResPartyAskJoin( GetGameRoom()->GetWorldSetID(), ERROR_PARTY_ASKJOIN_PARTY_NOTFOUND, pPacket->nReqAccountDBID );
|
||
break;
|
||
}
|
||
// 월드존인지 검사
|
||
const TMapInfo* pMapInfo = g_pDataManager->GetMapInfo( GetMapIndex() );
|
||
if( pMapInfo == NULL || pMapInfo->MapType != GlobalEnum::MAP_WORLDMAP )
|
||
{
|
||
if(g_pMasterConnectionManager)
|
||
g_pMasterConnectionManager->SendResPartyAskJoin( GetGameRoom()->GetWorldSetID(), ERROR_PARTY_ASKJOIN_FAIL, pPacket->nReqAccountDBID );
|
||
break;
|
||
}
|
||
CDNUserSession* pLeader = GetGameRoom()->GetUserSessionByCharDBID((GetGameRoom()->GetPartyStructData().biLeaderCharacterDBID));
|
||
if( pLeader == NULL )
|
||
{
|
||
if(g_pMasterConnectionManager)
|
||
g_pMasterConnectionManager->SendResPartyAskJoin( GetGameRoom()->GetWorldSetID(), ERROR_PARTY_ASKJOIN_FAIL, pPacket->nReqAccountDBID );
|
||
break;
|
||
}
|
||
if( pLeader->GetIsolate()->IsIsolateItem(pPacket->wszReqChracterName) )
|
||
{
|
||
if(g_pMasterConnectionManager)
|
||
g_pMasterConnectionManager->SendResPartyAskJoin( GetGameRoom()->GetWorldSetID(), ERROR_PARTY_ASKJOIN_FAIL, pPacket->nReqAccountDBID );
|
||
break;
|
||
}
|
||
if( pLeader->IsAcceptAbleOption(pPacket->biReqCharacterDBID, pPacket->nReqAccountDBID, _ACCEPTABLE_CHECKTYPE_PARTYINVITE) == false)
|
||
{
|
||
if(g_pMasterConnectionManager)
|
||
g_pMasterConnectionManager->SendResPartyAskJoin( GetGameRoom()->GetWorldSetID(), ERROR_PARTY_ASKJOIN_FAIL, pPacket->nReqAccountDBID );
|
||
break;
|
||
}
|
||
if( !pLeader->IsNoneWindowState() )
|
||
{
|
||
if(g_pMasterConnectionManager)
|
||
g_pMasterConnectionManager->SendResPartyAskJoin( GetGameRoom()->GetWorldSetID(), ERROR_PARTY_ASKJOIN_DESTUSER_SITUATION_NOTALLOWED, pPacket->nReqAccountDBID );
|
||
break;
|
||
}
|
||
|
||
pLeader->SetWindowState(WINDOW_ISACCEPT);
|
||
pLeader->SendAskJoinToLeader(pPacket->wszReqChracterName, pPacket->cReqUserJob, pPacket->cReqUserLevel);
|
||
break;
|
||
}
|
||
#endif
|
||
|
||
case MAGA_USERTEMPDATA_RESULT:
|
||
{
|
||
MAGAUserTempDataResult * pPacket = (MAGAUserTempDataResult*)pData;
|
||
SetDungeonClearCount(pPacket->nDungeonClearCount);
|
||
#if defined(PRE_ADD_REMOTE_QUEST)
|
||
GetQuest()->RefreshRemoteQuest(pPacket->nAcceptWaitRemoteQuestCount, pPacket->AcceptWaitRemoteQuestList);
|
||
#endif
|
||
#if defined(PRE_ADD_GAMEQUIT_REWARD)
|
||
SetUserGameQuitRewardType(pPacket->eUserGameQuitRewardType);
|
||
#endif // #if defined(PRE_ADD_GAMEQUIT_REWARD)
|
||
break;
|
||
}
|
||
case MAGA_PVP_MEMBERINDEX:
|
||
{
|
||
MAGAPvPMemberIndex * pPacket = (MAGAPvPMemberIndex*)pData;
|
||
|
||
if(GetGameRoom()->bIsPvPRoom())
|
||
{
|
||
if(pPacket->nRetCode == ERROR_NONE)
|
||
{
|
||
CDNPvPGameRoom * pPvPRoom = static_cast<CDNPvPGameRoom*>(GetGameRoom());
|
||
if(pPvPRoom)
|
||
{
|
||
CSPartySwapMemberIndex packet;
|
||
memset(&packet, 0, sizeof(CSPartySwapMemberIndex));
|
||
|
||
packet.cCount = pPacket->cCount;
|
||
for (int h = 0; h < packet.cCount; h++)
|
||
{
|
||
packet.Index[h].cIndex = pPacket->Index[h].cIndex;
|
||
packet.Index[h].nSessionID = pPacket->Index[h].nSessionID;
|
||
}
|
||
|
||
if(pPvPRoom->PartySwapMemberIndex(&packet) == false)
|
||
_DANGER_POINT(); //우에에에에에에에엥
|
||
pPvPRoom->SendMemberIndex(pPacket->nTeam, pPacket->cCount, pPacket->Index, pPacket->nRetCode);
|
||
}
|
||
}
|
||
else
|
||
SendPvPMemberIndex(pPacket->nTeam, 0, NULL, pPacket->nRetCode);
|
||
}
|
||
else
|
||
_DANGER_POINT();
|
||
break;
|
||
}
|
||
|
||
case MAGA_PVP_MEMBERGRADE:
|
||
{
|
||
MAGAPvPMemberGrade * pPacket = (MAGAPvPMemberGrade*)pData;
|
||
|
||
if(GetGameRoom()->bIsPvPRoom())
|
||
{
|
||
CDNPvPGameRoom * pPvPRoom = static_cast<CDNPvPGameRoom*>(GetGameRoom());
|
||
if(pPvPRoom)
|
||
pPvPRoom->SendMemberGrade(pPacket->nTeam, pPacket->uiUserState, pPacket->nChangedSessionID, pPacket->nRetCode);
|
||
}
|
||
else _DANGER_POINT();
|
||
break;
|
||
}
|
||
#if defined(PRE_ADD_DWC)
|
||
case MAGA_DWC_TEAMCHAT:
|
||
{
|
||
MAChat *pChat = (MAChat*)pData;
|
||
|
||
if(pChat->wChatLen > CHATLENMAX-1 || pChat->wChatLen <= 0) break;
|
||
WCHAR wszChatMsg[CHATLENMAX] = { 0, };
|
||
_wcscpy(wszChatMsg, CHATLENMAX, pChat->wszChatMsg, pChat->wChatLen);
|
||
|
||
SendChat(static_cast<eChatType>(pChat->cType), pChat->wChatLen, pChat->wszFromCharacterName, wszChatMsg);
|
||
break;
|
||
}
|
||
#endif
|
||
}
|
||
}
|
||
|
||
void CDNUserSession::OnDBRecvAuth(int nSubCmd, char *pData)
|
||
{
|
||
CDNUserBase::OnDBRecvAuth(nSubCmd, pData);
|
||
}
|
||
|
||
void CDNUserSession::OnDBRecvCharInfo(int nSubCmd, char *pData)
|
||
{
|
||
CDNUserBase::OnDBRecvCharInfo(nSubCmd, pData);
|
||
|
||
switch(nSubCmd)
|
||
{
|
||
case QUERY_SELECTCHARACTER:
|
||
{
|
||
TASelectCharacter *pSelect = (TASelectCharacter*)pData;
|
||
if(pSelect->nRetCode != ERROR_NONE){
|
||
DetachConnection(L"QUERY_SELECTCHARACTER");
|
||
#ifdef _DEBUG
|
||
g_Log.Log(LogType::_ERROR, this, L"[ADBID:%u CDBID:%I64d SID:%u] QUERY_SELECTCHARACTER Ret:%d\r\n", pSelect->nAccountDBID, m_biCharacterDBID, m_nSessionID, pSelect->nRetCode);
|
||
#endif
|
||
return;
|
||
}
|
||
|
||
if(!m_pGameRoom){
|
||
DetachConnection(L"QUERY_SELECTCHARACTER m_pGameRoom = NULL");
|
||
#ifdef _DEBUG
|
||
g_Log.Log(LogType::_ERROR, this, L"[ADBID:%u CDBID:%I64d SID:%u] QUERY_SELECTCHARACTER Session not Found\r\n", pSelect->nAccountDBID, m_biCharacterDBID, m_nSessionID);
|
||
#endif
|
||
return;
|
||
}
|
||
|
||
#if defined( PRE_ADD_CHARACTERCHECKSUM )
|
||
if( m_bTutorial && pSelect->tLastLoginDate <= pSelect->tLastLogoutDate && pSelect->uiCheckSum )
|
||
{
|
||
UINT uiCheckSum = MakeCharacterCheckSum( pSelect->biCharacterDBID, pSelect->UserData.Status.cLevel, pSelect->UserData.Status.nExp, pSelect->UserData.Status.nCoin, pSelect->UserData.Status.nWarehouseCoin );
|
||
if( uiCheckSum != pSelect->uiCheckSum )
|
||
{
|
||
if( m_pDBCon )
|
||
{
|
||
#if defined(PRE_ADD_MULTILANGUAGE)
|
||
std::wstring wszRestraintReason = GetEtUIXML().GetUIString(CEtUIXML::idCategory1, 8418, m_eSelectedLanguage);
|
||
std::wstring wszRestraintReasonForDolis = GetEtUIXML().GetUIString(CEtUIXML::idCategory1, 8419, m_eSelectedLanguage);
|
||
#else //#if defined(PRE_ADD_MULTILANGUAGE)
|
||
std::wstring wszRestraintReason = GetEtUIXML().GetUIString(CEtUIXML::idCategory1, 8418);
|
||
std::wstring wszRestraintReasonForDolis = GetEtUIXML().GetUIString(CEtUIXML::idCategory1, 8419);
|
||
#endif //#if defined(PRE_ADD_MULTILANGUAGE)
|
||
|
||
// 안정화 되면 제재 걸도록 하자.
|
||
//m_pDBCon->QueryAddRestraint(this, DBDNWorldDef::RestraintTargetCode::Account, DBDNWorldDef::RestraintTypeCode::ConnectRestraint, wszRestraintReason.c_str(), wszRestraintReasonForDolis.c_str(), 9999);
|
||
}
|
||
//DetachConnection(L"QUERY_SELECTCHARACTER Invalid Character CheckSum");
|
||
g_Log.Log(LogType::_ERROR, this, L"Invalid Character CheckSum(cid:%I64d, level:%d, exp:%d, coin:%I64d, wcoin:%I64d, mychecksum:%x, dbchecksum:%x)\r\n", pSelect->biCharacterDBID, pSelect->UserData.Status.cLevel, pSelect->UserData.Status.nExp, pSelect->UserData.Status.nCoin, pSelect->UserData.Status.nWarehouseCoin, uiCheckSum, pSelect->uiCheckSum );
|
||
//return;
|
||
}
|
||
}
|
||
#endif // #if defined( PRE_ADD_CHARACTERCHECKSUM )
|
||
|
||
LoadUserData(pSelect);
|
||
|
||
#if defined( PRE_ADD_NPC_REPUTATION_SYSTEM )
|
||
_ASSERT( m_pReputationSystem && m_pReputationSystem->GetEventHandler() );
|
||
m_pReputationSystem->GetEventHandler()->OnConnect( pSelect->UserData.Status.tLastConnectDate, false );
|
||
#endif // #if defined( PRE_ADD_NPC_REPUTATION_SYSTEM )
|
||
|
||
GetDBConnection()->GetCountReceiveMail(this); // 메일, market 카운트 요청
|
||
GetDBConnection()->QueryGetCountHarvestDepotItem( this ); // 농장 창고 카운트 요청
|
||
|
||
#if defined(_KRAZ)
|
||
if (m_bTutorial)
|
||
m_pDBCon->QueryActozUpdateCharacterInfo(this, ActozCommon::UpdateType::Login);
|
||
#endif // #if defined(_KRAZ)
|
||
|
||
#ifdef _DEBUG
|
||
g_Log.Log(LogType::_NORMAL, this, L"[ADBID:%u CDBID:%I64d SID:%u] QUERY_SELECTCHARACTER\r\n", pSelect->nAccountDBID, m_biCharacterDBID, m_nSessionID);
|
||
#endif
|
||
}
|
||
break;
|
||
|
||
case QUERY_CHANGESERVERUSERDATA:
|
||
{
|
||
TAUpdateCharacter *pUpdate = (TAUpdateCharacter*)pData;
|
||
if(pUpdate->nRetCode != ERROR_NONE){
|
||
|
||
#ifdef _DEBUG
|
||
g_Log.Log(LogType::_ERROR, this, L"[ADBID:%u CDBID:%I64d SID:%u] QUERY_UPDATECHANGESERVER Ret:%d\r\n", pUpdate->nAccountDBID, m_biCharacterDBID, m_nSessionID, pUpdate->nRetCode);
|
||
#endif
|
||
return;
|
||
}
|
||
|
||
// 유저가 채널 이동하기전에 마스터에 임시데이터를 저장시켜준다.
|
||
if(g_pMasterConnectionManager)
|
||
g_pMasterConnectionManager->SendSaveUserTempData(GetWorldSetID(), this);
|
||
|
||
SendVillageInfo(m_szNextVillageIP, m_nNextVillagePort, ERROR_NONE, GetAccountDBID(), GetCertifyingKey());
|
||
SetSessionState(SESSION_STATE_SERVER_CHANGE);
|
||
if( GetGameRoom() )
|
||
GetGameRoom()->SetGoToVillageFlag( true );
|
||
}
|
||
break;
|
||
|
||
case QUERY_CHANGESTAGEUSERDATA:
|
||
{
|
||
TAChangeStageUserData *pUpdate = (TAChangeStageUserData*)pData;
|
||
|
||
if(pUpdate->nRetCode != ERROR_NONE){
|
||
|
||
#ifdef _DEBUG
|
||
g_Log.Log(LogType::_ERROR, this, L"[ADBID:%u CDBID:%I64d SID:%u] QUERY_CHANGESTAGEUSERDATA Ret:%d\r\n", pUpdate->nAccountDBID, m_biCharacterDBID, m_nSessionID, pUpdate->nRetCode);
|
||
#endif
|
||
return;
|
||
}
|
||
}
|
||
break;
|
||
|
||
case QUERY_GETCHARACTERPARTIALYBYDBID:
|
||
case QUERY_GETCHARACTERPARTIALYBYNAME:
|
||
{
|
||
TAGetCharacterPartialy * pPacket = (TAGetCharacterPartialy*)pData;
|
||
switch(pPacket->cReqType)
|
||
{
|
||
case _REQCHARACTERPARTIALY_FRIEND:
|
||
{
|
||
if(pPacket->nRetCode != ERROR_NONE) return;
|
||
if(pPacket->biCharacterDBID > 0)
|
||
{
|
||
TFriend * pFriend = m_pFriend->GetFriend(pPacket->biCharacterDBID);
|
||
if(pFriend == NULL) return;
|
||
sWorldUserState State;
|
||
memset(&State, 0, sizeof(sWorldUserState));
|
||
if(g_pWorldUserState->GetUserState(pFriend->wszCharacterName, pFriend->biFriendCharacterDBID, &State) == false)
|
||
State.nLocationState = _LOCATION_NONE;
|
||
if(pFriend != NULL)
|
||
SendFriendDetailInfo(pFriend->biFriendCharacterDBID, pFriend->nGroupDBID, pPacket->cClass, pPacket->cLevel, \
|
||
pPacket->cJob, &State, NULL, pFriend->wszFriendMemo);
|
||
else
|
||
_DANGER_POINT();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
|
||
case QUERY_OWNCHRACTERLEVEL:
|
||
{
|
||
//만랩이 몇마리인지 확인해 보아효~
|
||
int nMaxLevelCount = GetMaxLevelCharacterCount();
|
||
|
||
//레벨리스트를 얻었으니 필요한 정보를 세팅한다.
|
||
const TPromotionData * pPromo = NULL;
|
||
int nPromotionCount = g_pDataManager->GetPromotionCount();
|
||
|
||
for (int i = 0; i < nPromotionCount; i++)
|
||
{
|
||
pPromo = g_pDataManager->GetPromotionByIdx(i);
|
||
if (pPromo && pPromo->nConditionType == PROMOTION_CONDTIONTYPE_MAXLEVEL)
|
||
{
|
||
if (pPromo->nConditionValue <= nMaxLevelCount)
|
||
SetPromotionData(pPromo->nPromotionType, pPromo->nRewardValue);
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
|
||
void CDNUserSession::OnDBRecvEtc(int nSubCmd, char *pData)
|
||
{
|
||
CDNUserBase::OnDBRecvEtc(nSubCmd, pData);
|
||
}
|
||
|
||
void CDNUserSession::OnDBRecvQuest(int nSubCmd, char *pData)
|
||
{
|
||
CDNUserBase::OnDBRecvQuest(nSubCmd, pData);
|
||
}
|
||
|
||
void CDNUserSession::OnDBRecvMission(int nSubCmd, char *pData)
|
||
{
|
||
CDNUserBase::OnDBRecvMission(nSubCmd, pData);
|
||
}
|
||
|
||
void CDNUserSession::OnDBRecvSkill(int nSubCmd, char *pData)
|
||
{
|
||
CDNUserBase::OnDBRecvSkill(nSubCmd, pData);
|
||
}
|
||
|
||
void CDNUserSession::OnDBRecvFriend(int nSubCmd, char *pData)
|
||
{
|
||
CDNUserBase::OnDBRecvFriend(nSubCmd, pData);
|
||
}
|
||
|
||
void CDNUserSession::OnDBRecvIsolate(int nSubCmd, char *pData)
|
||
{
|
||
CDNUserBase::OnDBRecvIsolate(nSubCmd, pData);
|
||
}
|
||
|
||
void CDNUserSession::OnDBRecvPvP(int nSubCmd, char *pData)
|
||
{
|
||
CDNUserBase::OnDBRecvPvP(nSubCmd, pData);
|
||
|
||
switch(nSubCmd)
|
||
{
|
||
case QUERY_UPDATEPVPDATA:
|
||
{
|
||
TAUpdatePvPData* pPacket = reinterpret_cast<TAUpdatePvPData*>(pData);
|
||
|
||
if( pPacket->nRetCode != ERROR_NONE )
|
||
_DANGER_POINT();
|
||
|
||
switch( pPacket->Type )
|
||
{
|
||
case PvPCommon::QueryUpdatePvPDataType::FinishGameMode:
|
||
{
|
||
if( GetGameRoom() && GetGameRoom()->GetPvPGameMode() )
|
||
GetGameRoom()->GetPvPGameMode()->SendFinishGameMode( this );
|
||
else
|
||
_DANGER_POINT();
|
||
break;
|
||
}
|
||
case PvPCommon::QueryUpdatePvPDataType::GoPvPLobby:
|
||
{
|
||
SendPvPGameToPvPLobby();
|
||
break;
|
||
}
|
||
case PvPCommon::QueryUpdatePvPDataType::GoSelectChar:
|
||
{
|
||
_SendReconnectLogin();
|
||
break;
|
||
}
|
||
#if defined(PRE_MOD_PVP_LADDER_XP)
|
||
case PvPCommon::QueryUpdatePvPDataType::FinishLadder:
|
||
{
|
||
break;
|
||
}
|
||
#endif
|
||
}
|
||
break;
|
||
}
|
||
case QUERY_ADD_PVP_LADDERRESULT:
|
||
{
|
||
TAAddPvPLadderResult* pPacket = reinterpret_cast<TAAddPvPLadderResult*>(pData);
|
||
|
||
if( pPacket->nRetCode != ERROR_NONE )
|
||
_DANGER_POINT();
|
||
|
||
switch( pPacket->Type )
|
||
{
|
||
case PvPCommon::QueryUpdatePvPDataType::FinishGameMode:
|
||
{
|
||
if( GetGameRoom() && GetGameRoom()->GetPvPGameMode() )
|
||
GetGameRoom()->GetPvPGameMode()->SendFinishGameMode( this );
|
||
else
|
||
_DANGER_POINT();
|
||
break;
|
||
}
|
||
case PvPCommon::QueryUpdatePvPDataType::GoPvPLobby:
|
||
{
|
||
SendPvPGameToPvPLobby();
|
||
break;
|
||
}
|
||
case PvPCommon::QueryUpdatePvPDataType::GoSelectChar:
|
||
{
|
||
_SendReconnectLogin();
|
||
break;
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
case QUERY_GETLIST_PVP_LADDERSCORE:
|
||
{
|
||
TAGetListPvPLadderScore* pA = reinterpret_cast<TAGetListPvPLadderScore*>(pData);
|
||
if( pA->nRetCode == ERROR_NONE )
|
||
{
|
||
if( GetGameRoom()->bIsLadderRoom() )
|
||
{
|
||
#if defined(PRE_ADD_DWC)
|
||
if(static_cast<CDNPvPGameRoom*>(GetGameRoom())->bIsDWCMatch())
|
||
break;
|
||
#endif
|
||
LadderSystem::CStatsRepository* pRepository = static_cast<CDNPvPGameRoom*>(GetGameRoom())->GetLadderStatsRepositoryPtr();
|
||
if( pRepository )
|
||
{
|
||
pRepository->OnRecvLadderScore( GetCharacterDBID(), GetTeam(), pA );
|
||
}
|
||
else
|
||
_ASSERT(0);
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
#if defined( PRE_FIX_76282 )
|
||
case SYNC_GOPVPLOBBY:
|
||
{
|
||
TAHeader * pA = reinterpret_cast<TAHeader*>(pData);
|
||
if( pA->nRetCode == ERROR_NONE )
|
||
{
|
||
SendPvPGameToPvPLobby();
|
||
}
|
||
break;
|
||
}
|
||
#endif // #if defined( PRE_FIX_76282 )
|
||
}
|
||
}
|
||
|
||
void CDNUserSession::OnDBRecvDarkLair(int nSubCmd, char *pData)
|
||
{
|
||
CDNUserBase::OnDBRecvDarkLair(nSubCmd, pData);
|
||
}
|
||
|
||
|
||
void CDNUserSession::OnDBRecvGuild(int nSubCmd, char *pData)
|
||
{
|
||
CDNUserBase::OnDBRecvGuild(nSubCmd, pData);
|
||
|
||
switch(nSubCmd)
|
||
{
|
||
case QUERY_CREATEGUILD: // 길드 창설 결과
|
||
{
|
||
// GA 는 본 패킷을 처리하지 않음
|
||
}
|
||
DN_BREAK;
|
||
|
||
case QUERY_DISMISSGUILD: // 길드 해체 결과
|
||
{
|
||
// GA 는 본 패킷을 처리하지 않음
|
||
}
|
||
DN_BREAK;
|
||
|
||
case QUERY_ADDGUILDMEMBER: // 길드원 추가 결과
|
||
{
|
||
// GA 는 본 패킷을 처리하지 않음
|
||
}
|
||
DN_BREAK;
|
||
|
||
case QUERY_DELGUILDMEMBER: // 길드원 제거(탈퇴/추방) 결과
|
||
{
|
||
// GA 는 본 패킷을 처리하지 않음
|
||
}
|
||
DN_BREAK;
|
||
|
||
case QUERY_CHANGEGUILDINFO: // 길드 정보 변경 결과
|
||
{
|
||
const TAChangeGuildInfo *pPacket = reinterpret_cast<TAChangeGuildInfo*>(pData);
|
||
if(ERROR_NONE != pPacket->nRetCode) {
|
||
// 오류 발생
|
||
SendChangeGuildInfo(pPacket->nAccountDBID, pPacket->nCharacterDBID, pPacket->btGuildUpdate, pPacket->nRetCode, pPacket->nInt1, pPacket->nInt2, pPacket->biInt64, pPacket->Text, NULL);
|
||
break;
|
||
}
|
||
|
||
const TGuildUID GuildUID(pPacket->cWorldSetID, pPacket->nGuildDBID);
|
||
|
||
CDNGuildBase* pGuild = g_pGuildManager->At(GuildUID);
|
||
|
||
if(!pGuild)
|
||
{
|
||
SendChangeGuildInfo(pPacket->nAccountDBID, pPacket->nCharacterDBID, pPacket->btGuildUpdate, ERROR_GUILD_NOTEXIST_GUILDINFO, pPacket->nInt1, pPacket->nInt2, pPacket->biInt64, pPacket->Text, NULL);
|
||
break;
|
||
}
|
||
|
||
#if !defined( PRE_ADD_NODELETEGUILD )
|
||
CDetachAutoEx<CDNGuildBase> AutoDetach(pGuild);
|
||
if(FALSE == pGuild->IsEnable())
|
||
{
|
||
SendChangeGuildInfo(pPacket->nAccountDBID, pPacket->nCharacterDBID, pPacket->btGuildUpdate, ERROR_GUILD_NOTEXIST_GUILDINFO, pPacket->nInt1, pPacket->nInt2, pPacket->biInt64, pPacket->Text, NULL);
|
||
break;
|
||
}
|
||
#endif
|
||
|
||
pGuild->UpdateGuildInfo(this, pPacket);
|
||
}
|
||
break;
|
||
|
||
case QUERY_CHANGEGUILDMEMBERINFO: // 길드원 정보 변경 결과
|
||
{
|
||
const TAChangeGuildMemberInfo *pPacket = reinterpret_cast<TAChangeGuildMemberInfo*>(pData);
|
||
if(ERROR_NONE != pPacket->nRetCode) {
|
||
// 오류 발생
|
||
SendChangeGuildMemberInfo(pPacket->nReqAccountDBID, pPacket->nReqCharacterDBID, pPacket->nChgAccountDBID, pPacket->nChgCharacterDBID, pPacket->btGuildMemberUpdate, pPacket->nRetCode, pPacket->nInt1, pPacket->nInt2, pPacket->biInt64, pPacket->Text, NULL);
|
||
break;
|
||
}
|
||
DN_ASSERT(GetAccountDBID() == pPacket->nReqAccountDBID, "Invalid!");
|
||
|
||
const TGuildUID GuildUID(pPacket->cWorldSetID, pPacket->nGuildDBID);
|
||
|
||
CDNGuildBase* pGuild = g_pGuildManager->At(GuildUID);
|
||
|
||
if(!pGuild)
|
||
{
|
||
SendChangeGuildMemberInfo(pPacket->nReqAccountDBID, pPacket->nReqCharacterDBID, pPacket->nChgAccountDBID, pPacket->nChgCharacterDBID, pPacket->btGuildMemberUpdate, ERROR_GENERIC_UNKNOWNERROR, pPacket->nInt1, pPacket->nInt2, pPacket->biInt64, pPacket->Text, NULL);
|
||
break;
|
||
}
|
||
|
||
#if !defined( PRE_ADD_NODELETEGUILD )
|
||
CDetachAutoEx<CDNGuildBase> AutoDetach(pGuild);
|
||
if(FALSE == pGuild->IsEnable()) break;
|
||
#endif
|
||
|
||
pGuild->UpdateMemberInfo(this, pPacket);
|
||
}
|
||
break;
|
||
|
||
case QUERY_GETGUILDHISTORYLIST: // 길드 히스토리 목록 결과
|
||
{
|
||
// GA 는 본 패킷을 처리하지 않음
|
||
}
|
||
DN_BREAK;
|
||
case QUERY_CHANGEGUILDNAME: // 길드 이름 변경
|
||
{
|
||
const TAChangeGuildName *pPacket = reinterpret_cast<TAChangeGuildName*>(pData);
|
||
if(ERROR_NONE != pPacket->nRetCode)
|
||
{
|
||
SendGuildRenameResult(pPacket->nRetCode);
|
||
break;
|
||
}
|
||
// 아이템삭제, 길드 이름 변경 Send
|
||
int nItemID = 0;
|
||
const TItem *pItem = m_pItem->GetCashInventory(pPacket->biItemSerial);
|
||
if(pItem)
|
||
nItemID = pItem->nItemID;
|
||
|
||
if(m_pItem->DeleteItemByUse(ITEMPOSITION_CASHINVEN, -1, pPacket->biItemSerial))
|
||
{
|
||
GetEventSystem()->OnEvent( EventSystem::OnItemUse, 1, EventSystem::ItemID, nItemID );
|
||
const TGuildUID GuildUID(pPacket->cWorldSetID, pPacket->nGuildDBID);
|
||
g_pMasterConnectionManager->SendGuildChangeName(GetWorldSetID(), GuildUID, pPacket->wszGuildName);
|
||
SendGuildRenameResult(ERROR_NONE);
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
|
||
void CDNUserSession::OnDBRecvMail(int nSubCmd, char *pData)
|
||
{
|
||
CDNUserBase::OnDBRecvMail(nSubCmd, pData);
|
||
}
|
||
|
||
void CDNUserSession::OnDBRecvMarket(int nSubCmd, char *pData)
|
||
{
|
||
CDNUserBase::OnDBRecvMarket(nSubCmd, pData);
|
||
}
|
||
|
||
void CDNUserSession::OnDBRecvItem(int nSubCmd, char *pData)
|
||
{
|
||
CDNUserBase::OnDBRecvItem(nSubCmd, pData);
|
||
|
||
switch( nSubCmd )
|
||
{
|
||
case QUERY_GETPAGEMATERIALIZEDITEM:
|
||
{
|
||
int nRemain = m_pItem->GetCashInventoryTotalCount() - m_pItem->GetCashInventoryCount();
|
||
if( nRemain <= 0)
|
||
{
|
||
TItem *pCashItem = m_pItem->GetCashItemByType(ITEMTYPE_EXPAND);
|
||
if(pCashItem)
|
||
m_nExpandNestClearCount = g_pDataManager->GetItemTypeParam1(pCashItem->nItemID);
|
||
|
||
#if defined(PRE_ADD_TSCLEARCOUNTEX)
|
||
pCashItem = m_pItem->GetCashItemByType(ITEMTYPE_EXPAND_TS);
|
||
if(pCashItem)
|
||
m_nExpandTreasureStageClearCount = g_pDataManager->GetItemTypeParam1(pCashItem->nItemID);
|
||
#endif // #if defined(PRE_ADD_TSCLEARCOUNTEX)
|
||
|
||
// Vehicle Inventory
|
||
GetDBConnection()->QueryGetPageVehicle(this, 1, VEHICLEINVENTORYPAGEMAX);
|
||
}
|
||
break;
|
||
}
|
||
|
||
case QUERY_GETPAGEVEHICLE:
|
||
{
|
||
if(m_pItem->IsCompleteLimitlessItem())
|
||
SetSessionState(SESSION_STATE_LOADED);
|
||
break;
|
||
}
|
||
#if defined( PRE_ADD_NAMEDITEM_SYSTEM )
|
||
case QUERY_CHECK_NAMEDITEMCOUNT:
|
||
{
|
||
TACheckNamedItemCount* pA = reinterpret_cast<TACheckNamedItemCount*>(pData);
|
||
if( m_pGameRoom && m_pGameRoom->GetTaskMng() )
|
||
{
|
||
CDnGameTask* pTask = (CDnGameTask *)m_pGameRoom->GetTaskMng()->GetTask( "GameTask" );
|
||
if( pTask )
|
||
{
|
||
if( pTask->GetDungeonClearState() >= CDnGameTask::DungeonClearStateEnum::DCS_SelectRewardItemStay && pTask->GetDungeonClearState() <= CDnGameTask::DungeonClearStateEnum::DCS_RewardItemStay )
|
||
{
|
||
pTask->CheckSelectNamedItemResult( this, pA );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
#endif
|
||
}
|
||
}
|
||
|
||
void CDNUserSession::OnDBRecvCash(int nSubCmd, char *pData)
|
||
{
|
||
CDNUserBase::OnDBRecvCash(nSubCmd, pData);
|
||
}
|
||
|
||
void CDNUserSession::OnDBRecvMasterSystem(int nSubCmd, char *pData)
|
||
{
|
||
switch( nSubCmd )
|
||
{
|
||
case QUERY_GET_COUNTINFO:
|
||
{
|
||
TAGetMasterSystemCountInfo* pA = reinterpret_cast<TAGetMasterSystemCountInfo*>(pData);
|
||
|
||
if( GetGameRoom() )
|
||
{
|
||
if( GetGameRoom()->GetMasterRewardSystem() )
|
||
GetGameRoom()->GetMasterRewardSystem()->Update( this, pA );
|
||
}
|
||
return;
|
||
}
|
||
case QUERY_MOD_RESPECTPOINT:
|
||
{
|
||
TAModRespectPoint* pA = reinterpret_cast<TAModRespectPoint*>(pData);
|
||
SendMasterSystemRespectPoint( pA->iRespectPoint );
|
||
return;
|
||
}
|
||
case QUERY_MOD_FAVORPOINT:
|
||
{
|
||
TAModMasterFavorPoint* pA = reinterpret_cast<TAModMasterFavorPoint*>(pData);
|
||
SendMasterSystemFavorPoint( pA->biMasterCharacterDBID, pA->biPupilCharacterDBID, pA->iFavorPoint );
|
||
// 호감도 더해주기.
|
||
GetGameRoom()->GetMasterRewardSystem()->UpdateFavor(this, pA->biPupilCharacterDBID, pA->iFavorPoint );
|
||
|
||
// 제자에게 FavorPoint 알림
|
||
if( GetGameRoom() )
|
||
{
|
||
for( UINT i=0 ;i<GetGameRoom()->GetUserCount() ; ++i )
|
||
{
|
||
CDNUserSession* pSession = GetGameRoom()->GetUserData(i);
|
||
if( pSession && pSession->GetCharacterDBID() == pA->biPupilCharacterDBID )
|
||
{
|
||
pSession->SendMasterSystemFavorPoint( pA->biMasterCharacterDBID, pA->biPupilCharacterDBID, pA->iFavorPoint );
|
||
pSession->GetDBConnection()->QueryGetMasterSystemSimpleInfo( pSession->GetDBThreadID(), pSession, true, MasterSystem::EventType::DungeonClear );
|
||
pSession->QueryGetMasterSystemCountInfo( true );
|
||
}
|
||
}
|
||
}
|
||
return;
|
||
}
|
||
case QUERY_GET_MASTERCHARACTER_TYPE1:
|
||
{
|
||
TAGetMasterCharacterType1* pA = reinterpret_cast<TAGetMasterCharacterType1*>(pData);
|
||
MasterSystem::CCacheRepository::GetInstance().SetMasterCharacter( this, pA );
|
||
return;
|
||
}
|
||
case QUERY_GET_PUPILLIST:
|
||
{
|
||
TAGetListPupil* pA = reinterpret_cast<TAGetListPupil*>(pData);
|
||
MasterSystem::CCacheRepository::GetInstance().SetPupilList( this, pA );
|
||
return;
|
||
}
|
||
case QUERY_GET_MASTERANDCLASSMATE:
|
||
{
|
||
TAGetListMyMasterAndClassmate* pA = reinterpret_cast<TAGetListMyMasterAndClassmate*>(pData);
|
||
MasterSystem::CCacheRepository::GetInstance().SetMasterClassmateList( this, pA );
|
||
return;
|
||
}
|
||
}
|
||
|
||
// UserSession 단에서 처리하지 않았던 패킷은 UserBase 로 넘긴다.
|
||
CDNUserBase::OnDBRecvMasterSystem(nSubCmd, pData);
|
||
}
|
||
|
||
#if defined( PRE_PARTY_DB )
|
||
void CDNUserSession::OnDBRecvParty( int nSubCmd, char* pData )
|
||
{
|
||
// UserSession 단에서 처리하지 않았던 패킷은 UserBase 로 넘긴다.
|
||
CDNUserBase::OnDBRecvParty(nSubCmd, pData);
|
||
}
|
||
#endif // #if defined( PRE_PARTY_DB )
|
||
|
||
#if defined( PRE_ALTEIAWORLD_EXPLORE )
|
||
void CDNUserSession::OnDBRecvAlteiaWorld(int nSubCmd, char* pData)
|
||
{
|
||
CDNUserBase::OnDBRecvAlteiaWorld(nSubCmd, pData);
|
||
switch( nSubCmd )
|
||
{
|
||
case QUERY_ADD_ALTEIAWORLDSENDTICKETLIST:
|
||
{
|
||
const TAAddAlteiaWorldSendTicketList* pPacket = reinterpret_cast<TAAddAlteiaWorldSendTicketList*>(pData);
|
||
if( pPacket->nRetCode == ERROR_NONE )
|
||
{
|
||
SendAlteiaWorldSendTicket( pPacket->wszSendCharacterName );
|
||
|
||
if (g_pMasterConnectionManager)
|
||
g_pMasterConnectionManager->SendAddAlteiaWorldSendTicketResult( GetWorldSetID(), pPacket->nRetCode, pPacket->biSendCharacterDBID );
|
||
|
||
}
|
||
else
|
||
{
|
||
if (g_pMasterConnectionManager)
|
||
g_pMasterConnectionManager->SendAddAlteiaWorldSendTicketResult( GetWorldSetID(), pPacket->nRetCode, pPacket->biSendCharacterDBID );
|
||
|
||
}
|
||
}
|
||
break;
|
||
case QUERY_GET_ALTEIAWORLDINFO:
|
||
{
|
||
const TAGetAlteiaWorldInfo* pPacket = reinterpret_cast<const TAGetAlteiaWorldInfo*>(pData);
|
||
if( pPacket->nRetCode == ERROR_NONE )
|
||
{
|
||
m_cDailyPlayCount = (BYTE)pPacket->nDailyPlayCount;
|
||
}
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
#endif // #if defined(PRE_ALTEIAWORLD_EXPLORE)
|
||
|
||
#if defined (PRE_ADD_BESTFRIEND)
|
||
void CDNUserSession::OnDBRecvBestFriend(int nSubCmd, char* pData)
|
||
{
|
||
CDNUserBase::OnDBRecvBestFriend(nSubCmd, pData);
|
||
}
|
||
#endif // #if defined (PRE_ADD_BESTFRIEND)
|
||
|
||
int CDNUserSession::OnRecvCharMessage(int iSubCmd, char * pData, int iLen)
|
||
{
|
||
#if defined(PRE_ADD_STAGE_CLEAR_ADD_REWARD)
|
||
switch (iSubCmd)
|
||
{
|
||
case eChar::CS_STAGECLEAR_BONUSREWARD_SELECT:
|
||
{
|
||
int iResult = GetStageClearBonusReward(pData, iLen);
|
||
SendStageClearBonusRewardResult(iResult);
|
||
return iResult;
|
||
}
|
||
break;
|
||
//rlkt_test
|
||
case eChar::CS_DOSPECIALIZE: OnRecvSpecializeMessage(iSubCmd, pData, iLen); break;
|
||
}
|
||
#endif // #if defined(PRE_ADD_STAGE_CLEAR_ADD_REWARD)
|
||
return CDNUserBase::OnRecvCharMessage(iSubCmd, pData, iLen);
|
||
}
|
||
|
||
int CDNUserSession::OnRecvTradeMessage(int iSubCmd, char * pData, int iLen)
|
||
{
|
||
return CDNUserBase::OnRecvTradeMessage(iSubCmd, pData, iLen);
|
||
}
|
||
|
||
int CDNUserSession::OnRecvQuestMessage(int iSubCmd, char * pData, int iLen)
|
||
{
|
||
return CDNUserBase::OnRecvQuestMessage(iSubCmd, pData, iLen);
|
||
}
|
||
|
||
int CDNUserSession::OnRecvSystemMessage(int iSubCmd, char * pData, int iLen)
|
||
{
|
||
switch(iSubCmd)
|
||
{
|
||
case eSystem::CS_RECONNECTLOGIN: // 캐릭터 선택
|
||
{
|
||
if(m_iState != SESSION_STATE_GAME_PLAY)
|
||
return ERROR_NONE;
|
||
|
||
if( GetGameRoom() )
|
||
GetGameRoom()->DelLastPartyDungeonInfo( this );
|
||
|
||
BackUpEquipInfo();
|
||
|
||
if( m_pGameRoom->bIsPvPRoom() )
|
||
{
|
||
if( !GetPvPGameModeFinish() && m_pGameRoom->GetPvPGameMode() )
|
||
{
|
||
if( m_pGameRoom->GetPvPGameMode()->bIsPlayingUser( GetActorHandle() ) )
|
||
{
|
||
if( m_pGameRoom->bIsZombieMode() )
|
||
{
|
||
_SendReconnectLogin();
|
||
return ERROR_NONE;
|
||
}
|
||
#if defined( PRE_ADD_PVP_COMBOEXERCISE )
|
||
if( m_pGameRoom->bIsComboExerciseMode() )
|
||
{
|
||
_SendReconnectLogin();
|
||
return ERROR_NONE;
|
||
}
|
||
#endif // #if defined( PRE_ADD_PVP_COMBOEXERCISE )
|
||
#if defined(PRE_ADD_DWC)
|
||
if( m_pGameRoom->GetPvPGameMode()->GetPvPChannelType() == PvPCommon::RoomType::dwc || static_cast<CDNPvPGameRoom*>(m_pGameRoom)->bIsDWCMatch() )
|
||
{
|
||
_SendReconnectLogin();
|
||
return ERROR_NONE;
|
||
}
|
||
#endif
|
||
IScoreSystem* pScoreSystem = m_pGameRoom->GetPvPGameMode()->GetScoreSystem();
|
||
if( pScoreSystem )
|
||
{
|
||
if( pScoreSystem->QueryUpdatePvPData( PvPCommon::Team::Max, this, PvPCommon::QueryUpdatePvPDataType::GoSelectChar ) == false )
|
||
{
|
||
_DANGER_POINT();
|
||
_SendReconnectLogin();
|
||
}
|
||
#if defined( PRE_ADD_RACING_MODE)
|
||
if( m_pGameRoom->GetPvPGameMode()->bIsRacingMode() )
|
||
{
|
||
_SendReconnectLogin();
|
||
}
|
||
#endif
|
||
return ERROR_NONE;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// 스테이지 포기 페널티 먹여야 해요 내구도 감소
|
||
DnActorHandle hActor = GetActorHandle();
|
||
if( hActor )
|
||
{
|
||
CDnPlayerActor *pPlayer = static_cast<CDnPlayerActor *>(hActor.GetPointer());
|
||
pPlayer->OnStageGiveUp();
|
||
}
|
||
}
|
||
|
||
ChangeStageUserData();
|
||
|
||
_SendReconnectLogin();
|
||
return ERROR_NONE;
|
||
}
|
||
break;
|
||
|
||
case eSystem::CS_READY_2_RECIEVE:
|
||
{
|
||
CSReady2Recieve *pPacket = (CSReady2Recieve*)pData;
|
||
|
||
if(sizeof(CSReady2Recieve) != iLen)
|
||
return ERROR_INVALIDPACKET;
|
||
|
||
wcsncpy(m_wszVirtualIp, pPacket->wszVirtualIp, IPLENMAX);
|
||
WideCharToMultiByte(CP_ACP, 0, m_wszVirtualIp, -1, m_szVirtualIp, IPLENMAX, NULL, NULL);
|
||
|
||
SetSessionState(SESSION_STATE_READY_TO_SYNC);
|
||
SendUserInfo();
|
||
return ERROR_NONE;
|
||
}
|
||
|
||
case eSystem::CS_INTENDED_DISCONNECT:
|
||
{
|
||
//정상적인 종료 게임중이겠지 일단은 스테이트로 막습니다. 아싸리 접속이 안된놈이나 그런놈은 배제 게임하는 도중에 작살난 놈만
|
||
//if(m_GameState >= _GAME_STATE_SYNC2SYNC && m_GameState <= _GAME_STATE_PLAY)
|
||
// pSession->IntendedDisconnected();
|
||
return ERROR_NONE;
|
||
}
|
||
|
||
case eSystem::CS_ABANDONSTAGE: // 스테이지 포기
|
||
{
|
||
CDnGameTask *pTask = ( m_pGameRoom ) ? m_pGameRoom->GetGameTask() : NULL;
|
||
if (!pTask) return ERROR_GENERIC_INVALIDREQUEST;
|
||
if( pTask->IsWaitPlayCutScene() ) return ERROR_GENERIC_INVALIDREQUEST;
|
||
|
||
CSAbandonStage * pPacket = (CSAbandonStage*)pData;
|
||
|
||
if(iLen != sizeof(CSAbandonStage))
|
||
return ERROR_INVALIDPACKET;
|
||
|
||
int nResult = ERROR_NONE;
|
||
nResult = CmdAbandonStage( true, pPacket->bIsPartyOut, pPacket->bIntenedDisconnect );
|
||
if( nResult == ERROR_NONE ) {
|
||
ChangeStageUserData();
|
||
}
|
||
return nResult;
|
||
}
|
||
|
||
// PvP게임에서 PvP로비로 이동 요청
|
||
case eSystem::CS_MOVE_PVPGAMETOPVPLOBBY:
|
||
{
|
||
if(iLen != 0)
|
||
return ERROR_INVALIDPACKET;
|
||
|
||
if( m_iState != SESSION_STATE_GAME_PLAY )
|
||
return ERROR_NONE;
|
||
|
||
BackUpEquipInfo();
|
||
|
||
// 정상종료 되었으면...
|
||
if( !GetPvPGameModeFinish() )
|
||
{
|
||
if( m_pGameRoom && m_pGameRoom->GetPvPGameMode() )
|
||
{
|
||
if( m_pGameRoom->GetPvPGameMode()->bIsPlayingUser( GetActorHandle() ) )
|
||
{
|
||
#if defined( PRE_FIX_76282 )
|
||
bool bSyncGoPvP = false;
|
||
#endif // // #if defined( PRE_FIX_76282 )
|
||
if( m_pGameRoom->GetPvPGameMode()->bIsZombieMode() )
|
||
{
|
||
#if defined( PRE_FIX_76282 )
|
||
bSyncGoPvP = true;
|
||
#else // #if defined( PRE_FIX_76282 )
|
||
SendPvPGameToPvPLobby();
|
||
return ERROR_NONE;
|
||
#endif // // #if defined( PRE_FIX_76282 )
|
||
}
|
||
#if defined( PRE_ADD_RACING_MODE)
|
||
if( m_pGameRoom->GetPvPGameMode()->bIsRacingMode() )
|
||
{
|
||
#if defined( PRE_FIX_76282 )
|
||
bSyncGoPvP = true;
|
||
#else // #if defined( PRE_FIX_76282 )
|
||
m_pItem->RemoveInstantEquipVehicleData(true);
|
||
m_pItem->RemoveInstantVehicleItemData(true);
|
||
SendPvPGameToPvPLobby();
|
||
return ERROR_NONE;
|
||
#endif // #if defined( PRE_FIX_76282 )
|
||
}
|
||
#endif // #if defined( PRE_ADD_RACING_MODE)
|
||
#if defined( PRE_ADD_PVP_COMBOEXERCISE )
|
||
if( m_pGameRoom->GetPvPGameMode()->bIsComboExerciseMode() )
|
||
{
|
||
#if defined( PRE_FIX_76282 )
|
||
bSyncGoPvP = true;
|
||
#else // #if defined( PRE_FIX_76282 )
|
||
SendPvPGameToPvPLobby();
|
||
return ERROR_NONE;
|
||
#endif // #if defined( PRE_FIX_76282 )
|
||
}
|
||
#endif // #if defined( PRE_ADD_PVP_COMBOEXERCISE )
|
||
|
||
// #76282를 적용 하여 여기서 쿼리를 날리면 CPvPScoreSystem::QueryUpdatePvPData 에서 중복으로 날리는 부분을 막아줘야 함.
|
||
IScoreSystem* pScoreSystem = m_pGameRoom->GetPvPGameMode()->GetScoreSystem();
|
||
if( pScoreSystem )
|
||
{
|
||
if( pScoreSystem->QueryUpdatePvPData( PvPCommon::Team::Max, this, PvPCommon::QueryUpdatePvPDataType::GoPvPLobby ) == false )
|
||
{
|
||
_DANGER_POINT();
|
||
SendPvPGameToPvPLobby();
|
||
}
|
||
#if defined( PRE_FIX_76282 )
|
||
if( bSyncGoPvP && m_pDBCon )
|
||
{
|
||
m_pDBCon->SendSyncGoPvPLobby( this );
|
||
}
|
||
#endif // #if defined( PRE_FIX_76282 )
|
||
#if defined(PRE_ADD_DWC)
|
||
if( m_pGameRoom->GetPvPGameMode()->GetPvPChannelType() == PvPCommon::RoomType::dwc || static_cast<CDNPvPGameRoom*>(m_pGameRoom)->bIsDWCMatch() )
|
||
SendPvPGameToPvPLobby();
|
||
#endif
|
||
return ERROR_NONE;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
SendPvPGameToPvPLobby();
|
||
return ERROR_NONE;
|
||
}
|
||
|
||
case eSystem::CC_PEER_CONNECT_REQUEST:
|
||
//{
|
||
// CCPeerConnectRequest * pPacket = (CCPeerConnectRequest*)pData;
|
||
// if(pPacket->cState == 1) //PeerConnected Msg
|
||
// {
|
||
// if(m_PeerManager.IsConnectedPeer(pPacket->nSessionID[0], pPacket->nSessionID[1]) == false)
|
||
// m_PeerManager.ConnectPeer(pPacket->nSessionID[0], pPacket->nSessionID[1]);
|
||
// else
|
||
// _DANGER_POINT();
|
||
// }
|
||
// else if(pPacket->cState == 2) //PeerDisConnected Msg
|
||
// {
|
||
// if(m_PeerManager.IsConnectedPeer(pSession->GetSessionID(), pPacket->nSessionID[1]) == true)
|
||
// m_PeerManager.DisConnectPeer(pSession->GetSessionID(), pPacket->nSessionID[1]);
|
||
// else
|
||
// _DANGER_POINT();
|
||
// }
|
||
//}
|
||
return ERROR_NONE;
|
||
|
||
#ifdef PRE_MOD_INDUCE_TCPCONNECT
|
||
case eSystem::CS_CONNECTGAME:
|
||
{
|
||
m_bRecvReqTCPConnectMsg = true;
|
||
g_Log.Log( LogType::_GAMECONNECTLOG, L"MessageProcess CS_CONNECTGAME!!\n" );
|
||
return ERROR_NONE;
|
||
}
|
||
#endif //#ifdef PRE_MOD_INDUCE_TCPCONNECT
|
||
}
|
||
|
||
return CDNUserBase::OnRecvSystemMessage(iSubCmd, pData, iLen);
|
||
}
|
||
|
||
int CDNUserSession::OnRecvFriendMessage(int nSubCmd, char * pData, int nLen)
|
||
{
|
||
return CDNUserBase::OnRecvFriendMessage(nSubCmd, pData, nLen);
|
||
}
|
||
|
||
int CDNUserSession::OnRecvIsolateMessage(int nSubCmd, char * pData, int nLen)
|
||
{
|
||
return CDNUserBase::OnRecvIsolateMessage(nSubCmd, pData, nLen);
|
||
}
|
||
|
||
int CDNUserSession::OnRecvGameOptionMessage(int nSubCmd, char * pData, int nLen)
|
||
{
|
||
return CDNUserBase::OnRecvGameOptionMessage(nSubCmd, pData, nLen);
|
||
}
|
||
|
||
int CDNUserSession::OnRecvEtcMessage(int nSubCmd, char * pData, int nLen)
|
||
{
|
||
switch( nSubCmd )
|
||
{
|
||
case eEtc::CS_DARKLAIR_RANK_BOARD:
|
||
{
|
||
// 게임서버에서는 사용되지 않는다.
|
||
// 나중에 게임서버에서도 사용될 수도 있을거 같아서 UserBase 에서 Process 처리를 하고
|
||
// 게임서버에서 UserSession 단에서 현재는 막아둔다.
|
||
_ASSERT(0);
|
||
return ERROR_INVALIDPACKET; // 게임서버에 해당 요청 오면 끊어버림
|
||
}
|
||
}
|
||
|
||
return CDNUserBase::OnRecvEtcMessage(nSubCmd, pData, nLen);
|
||
}
|
||
|
||
int CDNUserSession::OnRecvRadioMessage(int nSubCmd, char * pData, int nLen)
|
||
{
|
||
switch(nSubCmd)
|
||
{
|
||
case eRadio::CS_USERADIO:
|
||
{
|
||
CSUseRadio * pPacket = (CSUseRadio*)pData;
|
||
|
||
if(sizeof(CSUseRadio) != nLen)
|
||
return ERROR_INVALIDPACKET;
|
||
|
||
if( !GetActorHandle() )
|
||
return ERROR_NONE;
|
||
|
||
CDNGameRoom * pRoom = GetGameRoom();
|
||
CDnPlayerActor * pActor = (CDnPlayerActor*)GetActorHandle().GetPointer();
|
||
|
||
if(pRoom && pActor)
|
||
{
|
||
int nTeam = pActor->GetTeam();
|
||
|
||
//#43512 파티원중 한명이 얼음감옥일때 라디오 메시지 전달 안되는 현상 수정
|
||
//얼음감옥이 설정 된 경우 팀 반전이 있음..
|
||
if (pActor->IsAppliedThisStateBlow(STATE_BLOW::BLOW_149))
|
||
nTeam = pActor->GetOriginalTeam();
|
||
|
||
for(DWORD i = 0; i < pRoom->GetUserCount(); i++)
|
||
{
|
||
CDNUserSession * pSession = pRoom->GetUserData(i);
|
||
if(pSession && pSession->GetActorHandle())
|
||
{
|
||
CDnPlayerActor * pDestActor = (CDnPlayerActor*)pSession->GetActorHandle().GetPointer();
|
||
|
||
//#43512 파티원중 한명이 얼음감옥일때 라디오 메시지 전달 안되는 현상 수정
|
||
//얼음감옥이 설정 된 경우 팀 반전이 있음..
|
||
int nDestActorTeam = pDestActor->GetTeam();
|
||
if (pDestActor->IsAppliedThisStateBlow(STATE_BLOW::BLOW_149))
|
||
nDestActorTeam = pDestActor->GetOriginalTeam();
|
||
|
||
if(nTeam == nDestActorTeam)
|
||
pSession->SendUseRadio(GetSessionID(), pPacket->nID);
|
||
}
|
||
}
|
||
return ERROR_NONE;
|
||
}
|
||
else
|
||
_DANGER_POINT();
|
||
|
||
return ERROR_NONE;
|
||
}
|
||
break;
|
||
}
|
||
return CDNUserBase::OnRecvRadioMessage(nSubCmd, pData, nLen);
|
||
}
|
||
|
||
#ifdef _USE_VOICECHAT
|
||
int CDNUserSession::OnRecvVoiceChatMessage(int nSubCmd, char * pData, int nLen)
|
||
{
|
||
switch(nSubCmd)
|
||
{
|
||
case eVoiceChat::CS_VOICEAVAILABLE:
|
||
{
|
||
CSVoiceChatAvailable * pPacket = (CSVoiceChatAvailable*)pData;
|
||
|
||
if(sizeof(CSVoiceChatAvailable) != nLen)
|
||
return ERROR_INVALIDPACKET;
|
||
|
||
m_bVoiceAvailable = pPacket->cAvailable > 0 ? true : false;
|
||
if(m_bVoiceAvailable)
|
||
{
|
||
if(m_nVoiceChannelID > 0) return ERROR_NONE;
|
||
if(GetGameRoom() && GetGameRoom()->m_nVoiceChannelID[0] > 0)
|
||
JoinVoiceChannel(GetGameRoom()->m_nVoiceChannelID[0], GetIp(), NULL, 0);
|
||
}
|
||
else
|
||
LeaveVoiceChannel();
|
||
|
||
//refresh해주자
|
||
if(GetGameRoom())
|
||
GetGameRoom()->SendRefreshVoiceInfo();
|
||
return ERROR_NONE;
|
||
}
|
||
break;
|
||
|
||
case eVoiceChat::CS_VOICEMUTE:
|
||
{
|
||
CSVoiceMute * pPacket = (CSVoiceMute*)pData;
|
||
|
||
if(sizeof(CSVoiceMute) != nLen)
|
||
return ERROR_INVALIDPACKET;
|
||
|
||
if(g_pVoiceChat && GetGameRoom()->m_nVoiceChannelID[0] > 0)
|
||
{
|
||
CDNUserSession * pSession = GetGameRoom()->GetUserSession(pPacket->nSessionID);
|
||
if(pSession)
|
||
{
|
||
g_pVoiceChat->MuteOneToOne(GetAccountDBID(), pSession->GetAccountDBID(), pPacket->cMute == 0 ? false : true);
|
||
//뮤트관련 정보가 있어야겠다아.
|
||
}
|
||
else
|
||
_DANGER_POINT();
|
||
}
|
||
else
|
||
_DANGER_POINT();
|
||
return ERROR_NONE;
|
||
}
|
||
break;
|
||
|
||
case eVoiceChat::CS_VOICECOMPLAINTREQ:
|
||
{
|
||
CSVoiceComplaintReq * pPacket = (CSVoiceComplaintReq*)pData;
|
||
|
||
if(sizeof(CSVoiceComplaintReq) != nLen)
|
||
return ERROR_INVALIDPACKET;
|
||
|
||
if(g_pVoiceChat && GetGameRoom()->m_nVoiceChannelID[0] > 0)
|
||
{
|
||
CDNUserSession * pSession = GetGameRoom()->GetUserSession(pPacket->nSessionID);
|
||
if(pSession)
|
||
{
|
||
g_pVoiceChat->ComplaintRequest(GetAccountDBID(), pSession->GetAccountDBID(), pSession->GetAccountDBID(), pPacket->szCategory, pPacket->szSubject, pPacket->szMsg);
|
||
}
|
||
else
|
||
_DANGER_POINT();
|
||
}
|
||
else
|
||
_DANGER_POINT();
|
||
return ERROR_NONE;
|
||
}
|
||
break;
|
||
}
|
||
return ERROR_UNKNOWN_HEADER;
|
||
}
|
||
#endif
|
||
|
||
#if defined( PRE_ADD_SECONDARY_SKILL )
|
||
|
||
int CDNUserSession::OnRecvSecondarySkillMessage( int nSubCmd, char* pData, int nLen )
|
||
{
|
||
switch( nSubCmd )
|
||
{
|
||
case eSecondarySkill::CS_DELETE:
|
||
{
|
||
// 월드존 검사
|
||
if( CDnWorld::GetInstance( GetGameRoom() ).GetMapType() != EWorldEnum::MapTypeWorldMap )
|
||
{
|
||
SecondarySkill::CSDelete* pPacket = reinterpret_cast<SecondarySkill::CSDelete*>(pData);
|
||
SendDelSecondarySkill( ERROR_SECONDARYSKILL_DELETE_FAILED_DONTALLOWMAP, pPacket->iSkillID );
|
||
return ERROR_GENERIC_INVALIDREQUEST;
|
||
}
|
||
|
||
break;
|
||
}
|
||
}
|
||
|
||
return CDNUserBase::OnRecvSecondarySkillMessage( nSubCmd, pData, nLen );
|
||
}
|
||
|
||
#endif // #if defined( PRE_ADD_SECONDARY_SKILL )
|
||
|
||
int CDNUserSession::OnRecvChatRoomMessage(int nSubCmd, char *pData, int nLen)
|
||
{
|
||
// 농장에서만 채팅룸을 이용할수 있다.
|
||
if(!m_pGameRoom->bIsFarmRoom())
|
||
return ERROR_INVALIDPACKET;
|
||
|
||
switch( nSubCmd )
|
||
{
|
||
case eChatRoom::CS_CREATECHATROOM:
|
||
{
|
||
CSCreateChatRoom * pCreateChatRoom = (CSCreateChatRoom *)pData;
|
||
if(sizeof(CSCreateChatRoom) != nLen) return ERROR_INVALIDPACKET;
|
||
|
||
TChatRoomView ChatRoomView;
|
||
|
||
// 0. 다른 채팅방에 참여중인가?
|
||
if( m_nChatRoomID > 0 )
|
||
{
|
||
SendChatRoomCreateChatRoom( ERROR_CHATROOM_ANOTHERROOM, ChatRoomView );
|
||
return ERROR_NONE;
|
||
}
|
||
|
||
int nChatRoomID = 0;
|
||
// 1. 방 생성
|
||
nChatRoomID = m_pGameRoom->m_ChatRoomManager.CreateChatRoom( GetSessionID(), pCreateChatRoom->wszName, pCreateChatRoom->nRoomType,
|
||
pCreateChatRoom->nRoomAllow, pCreateChatRoom->wszPassword, pCreateChatRoom->PRLine1, pCreateChatRoom->PRLine2, pCreateChatRoom->PRLine3, m_pGameRoom );
|
||
|
||
if( nChatRoomID == 0 )
|
||
{
|
||
// 방생성 실패 - ERROR_CHATROOM_FAILEDMAKEROOM
|
||
SendChatRoomCreateChatRoom( ERROR_CHATROOM_FAILEDMAKEROOM, ChatRoomView );
|
||
return ERROR_NONE;
|
||
}
|
||
|
||
// 방찾기
|
||
CDNChatRoom * pChatRoom = m_pGameRoom->m_ChatRoomManager.GetChatRoom( nChatRoomID );
|
||
if( pChatRoom == NULL )
|
||
{
|
||
// 방생성 실패 - ERROR_CHATROOM_FAILEDMAKEROOM
|
||
SendChatRoomCreateChatRoom( ERROR_CHATROOM_FAILEDMAKEROOM, ChatRoomView );
|
||
return ERROR_NONE;
|
||
}
|
||
|
||
|
||
// 방 디스플레이 정보
|
||
ChatRoomView.Set( pChatRoom->GetChatRoomID(), pChatRoom->GetChatRoomName(), pChatRoom->GetChatRoomType(), pChatRoom->UsePassword(),
|
||
pChatRoom->GetChatRoomPRLine1(), pChatRoom->GetChatRoomPRLine2(), pChatRoom->GetChatRoomPRLine3() );
|
||
|
||
// 2. 리더 입장
|
||
int nRet = ERROR_NONE;
|
||
nRet = pChatRoom->EnterRoom( m_nSessionID, pCreateChatRoom->wszPassword, true );
|
||
|
||
if( nRet != ERROR_NONE )
|
||
{
|
||
// 리더가 입장을 못하였므로 방을 파괴한다.
|
||
if( pChatRoom->GetUserCount() <= 0 )
|
||
{
|
||
m_pGameRoom->m_ChatRoomManager.DestroyChatRoom( pChatRoom->GetChatRoomID() );
|
||
}
|
||
}
|
||
|
||
// 결과전송 - 방을 생성한 캐릭터에게 보내진다.
|
||
SendChatRoomCreateChatRoom( nRet, ChatRoomView );
|
||
|
||
// 주변 캐릭터에게 전송
|
||
m_pGameRoom->BroadcastChatRoomView(this, ChatRoomView);
|
||
|
||
return ERROR_NONE;
|
||
}
|
||
break;
|
||
case eChatRoom::CS_ENTERCHATROOM:
|
||
{
|
||
CSChatRoomEnterRoom * pEnterRoom = (CSChatRoomEnterRoom *)pData;
|
||
if(sizeof(CSChatRoomEnterRoom) != nLen) return ERROR_INVALIDPACKET;
|
||
|
||
int nRet = ERROR_NONE;
|
||
int UserSessionIDs[CHATROOMMAX];
|
||
int nUserCount = 0;
|
||
int LeaderSID = 0;
|
||
memset( UserSessionIDs, 0, sizeof(UserSessionIDs) );
|
||
|
||
// 방찾기
|
||
CDNChatRoom * pChatRoom = m_pGameRoom->m_ChatRoomManager.GetChatRoom( pEnterRoom->nChatRoomID );
|
||
if( pChatRoom == NULL )
|
||
{
|
||
SendChatRoomEnterRoom( ERROR_CHATROOM_INVALIDCHATROOM, LeaderSID, UserSessionIDs, nUserCount );
|
||
return ERROR_NONE;
|
||
}
|
||
|
||
// 일반 유저 입장
|
||
nRet = pChatRoom->EnterRoom( m_nSessionID, pEnterRoom->wszPassword, false );
|
||
if( nRet == ERROR_NONE )
|
||
{
|
||
// 방장의 세션 ID
|
||
if( pChatRoom->GetLeaderID() > 0 )
|
||
{
|
||
CDNUserSession * pLeaderSession = m_pGameRoom->GetUserSession(pChatRoom->GetLeaderID());
|
||
if( pLeaderSession ) LeaderSID = pLeaderSession->GetSessionID();
|
||
}
|
||
|
||
// 참여자들의 세션 ID
|
||
for( int i=0; i<CHATROOMMAX; i++ )
|
||
{
|
||
if( pChatRoom->GetMemberAIDFromIndex(i) <= 0 ) continue;
|
||
CDNUserSession * pUserSession = m_pGameRoom->GetUserSession( pChatRoom->GetMemberAIDFromIndex(i) );
|
||
if( pUserSession == NULL ) continue;
|
||
|
||
UserSessionIDs[ nUserCount ] = pUserSession->GetSessionID();
|
||
nUserCount++;
|
||
}
|
||
}
|
||
|
||
// 결과전송
|
||
SendChatRoomEnterRoom( nRet, LeaderSID, UserSessionIDs, nUserCount );
|
||
|
||
if( nRet == ERROR_NONE )
|
||
{
|
||
// 주변 캐릭터에게 전송
|
||
m_pGameRoom->BroadcastChatRoomEnterUser(this, pChatRoom);
|
||
// 프로필 전송
|
||
if( pChatRoom->GetChatRoomType() == CHATROOMTYPE_PR && GetProfile()->bOpenPublic )
|
||
pChatRoom->SendProfileToAll( GetSessionID(), *GetProfile() );
|
||
}
|
||
|
||
return ERROR_NONE;
|
||
}
|
||
break;
|
||
case eChatRoom::CS_CHANGEROOMOPTION:
|
||
{
|
||
CSChatRoomChangeRoomOption * pChangeOption = (CSChatRoomChangeRoomOption*)pData;
|
||
if(sizeof(CSChatRoomChangeRoomOption) != nLen) return ERROR_INVALIDPACKET;
|
||
|
||
// 방찾기
|
||
CDNChatRoom * pChatRoom = m_pGameRoom->m_ChatRoomManager.GetChatRoom( m_nChatRoomID );
|
||
if( pChatRoom == NULL )
|
||
{
|
||
SendChatRoomChangeRoomOption( ERROR_CHATROOM_INVALIDCHATROOM, pChangeOption->ChatRoomView );
|
||
return ERROR_NONE;
|
||
}
|
||
|
||
// 방장이 아니면 방옵션을 바꿀 수 없다.
|
||
if( pChatRoom->IsLeader( m_nSessionID ) == false )
|
||
{
|
||
SendChatRoomChangeRoomOption( ERROR_CHATROOM_ONLYLEADER, pChangeOption->ChatRoomView );
|
||
return ERROR_NONE;
|
||
}
|
||
|
||
pChatRoom->ChangeRoomOption( pChangeOption->ChatRoomView.m_wszChatRoomName, pChangeOption->ChatRoomView.m_nChatRoomType,
|
||
pChangeOption->nRoomAllow, pChangeOption->wszPassword,
|
||
pChangeOption->ChatRoomView.m_wszChatRoomPRLine1,
|
||
pChangeOption->ChatRoomView.m_wszChatRoomPRLine2,
|
||
pChangeOption->ChatRoomView.m_wszChatRoomPRLine3 );
|
||
|
||
TChatRoomView RoomView;
|
||
RoomView.Set( pChatRoom->GetChatRoomID(), pChatRoom->GetChatRoomName(), pChatRoom->GetChatRoomType(), pChatRoom->UsePassword(),
|
||
pChatRoom->GetChatRoomPRLine1(), pChatRoom->GetChatRoomPRLine2(), pChatRoom->GetChatRoomPRLine3() );
|
||
|
||
SendChatRoomChangeRoomOption( ERROR_NONE, RoomView );
|
||
|
||
// 주변 캐릭터에게 전송
|
||
m_pGameRoom->BroadcastChatRoomView(this, RoomView);
|
||
|
||
return ERROR_NONE;
|
||
}
|
||
break;
|
||
case eChatRoom::CS_KICKUSER:
|
||
{
|
||
CSChatRoomKickUser * pKickUser = (CSChatRoomKickUser *)pData;
|
||
if(sizeof(CSChatRoomKickUser) != nLen) return ERROR_INVALIDPACKET;
|
||
|
||
int nRet = ERROR_NONE;
|
||
|
||
// 방찾기
|
||
CDNChatRoom * pChatRoom = m_pGameRoom->m_ChatRoomManager.GetChatRoom( m_nChatRoomID );
|
||
if( pChatRoom == NULL )
|
||
{
|
||
SendChatRoomKickUser( ERROR_CHATROOM_INVALIDCHATROOM, pKickUser->nKickUserSessionID );
|
||
return ERROR_NONE;
|
||
}
|
||
|
||
// 방장이 아니면 강퇴명령을 사용할 수 없다.
|
||
if( pChatRoom->IsLeader( m_nSessionID ) == false )
|
||
{
|
||
SendChatRoomKickUser( ERROR_CHATROOM_ONLYLEADER, pKickUser->nKickUserSessionID );
|
||
return ERROR_NONE;
|
||
}
|
||
|
||
// 자기 자신은 강퇴 시킬수 없다.
|
||
if( GetSessionID() == pKickUser->nKickUserSessionID )
|
||
{
|
||
return ERROR_NONE;
|
||
}
|
||
|
||
CDNUserSession *pUserSession = m_pGameRoom->GetUserSession(pKickUser->nKickUserSessionID);
|
||
if( pUserSession == NULL )
|
||
{
|
||
return ERROR_NONE;
|
||
}
|
||
|
||
// 유저 삭제
|
||
nRet = pChatRoom->LeaveUser( pUserSession->GetSessionID(), pKickUser->nKickReason );
|
||
if( nRet == ERROR_NONE )
|
||
{
|
||
// 강퇴된 캐릭터에게 메시지 전달
|
||
pUserSession->SendChatRoomLeaveUser( pUserSession->GetSessionID(), pKickUser->nKickReason );
|
||
|
||
// 주변 캐릭터에게 전송
|
||
m_pGameRoom->BroadcastChatRoomLeaveUser(pUserSession, pKickUser->nKickReason);
|
||
}
|
||
|
||
return ERROR_NONE;
|
||
}
|
||
break;
|
||
case eChatRoom::CS_LEAVEROOM:
|
||
{
|
||
if(0 != nLen) return ERROR_INVALIDPACKET;
|
||
|
||
int nRet = ERROR_NONE;
|
||
|
||
CDNChatRoom * pChatRoom = m_pGameRoom->m_ChatRoomManager.GetChatRoom( m_nChatRoomID );
|
||
if( pChatRoom == NULL )
|
||
{
|
||
return ERROR_NONE;
|
||
}
|
||
|
||
if( pChatRoom->IsLeader(GetSessionID()) )
|
||
{
|
||
// 리더가 방에서 나가는 경우 방이 삭제된다.
|
||
while( pChatRoom->GetUserCount() > 0 )
|
||
{
|
||
UINT UserAID = pChatRoom->GetMemberAIDFromIndex( 0 );
|
||
if( UserAID <= 0 ) break; // 무한루프 방지를 위해 루프를 탈출하도록 한다.
|
||
|
||
CDNUserSession * pUserSession = m_pGameRoom->GetUserSession( UserAID );
|
||
if( pUserSession == NULL ) break; // 무한루프 방지를 위해 루프를 탈출하도록 한다.
|
||
|
||
nRet = pChatRoom->LeaveUser( pUserSession->GetSessionID(), CHATROOMLEAVE_DESTROYROOM );
|
||
if( nRet == ERROR_NONE )
|
||
{
|
||
// 방에서 나가게 되는 캐릭터와 주변 캐릭터에게 메시지를 전송한다.
|
||
if( pChatRoom->IsLeader( GetSessionID() ) )
|
||
{
|
||
TChatRoomView RoomView;
|
||
RoomView.Set( 0, L"", CHATROOMTYPE_NONE, false, L"", L"", L"" );
|
||
pUserSession->SendChatRoomLeaveUser( pUserSession->GetSessionID(), CHATROOMLEAVE_DESTROYROOM );
|
||
m_pGameRoom->BroadcastChatRoomView( pUserSession, RoomView );
|
||
}
|
||
else
|
||
{
|
||
pUserSession->SendChatRoomLeaveUser( pUserSession->GetSessionID(), CHATROOMLEAVE_DESTROYROOM );
|
||
m_pGameRoom->BroadcastChatRoomLeaveUser( pUserSession, CHATROOMLEAVE_DESTROYROOM );
|
||
}
|
||
}
|
||
}
|
||
// 방폭~!
|
||
m_pGameRoom->m_ChatRoomManager.DestroyChatRoom( pChatRoom->GetChatRoomID() );
|
||
}
|
||
else
|
||
{
|
||
// 유저가 방에서 나감
|
||
nRet = pChatRoom->LeaveUser( GetSessionID(), CHATROOMLEAVE_LEAVE );
|
||
if( nRet == ERROR_NONE )
|
||
{
|
||
// 방을 나간 캐릭터에게 메시지 전달
|
||
SendChatRoomLeaveUser( GetSessionID(), CHATROOMLEAVE_LEAVE );
|
||
|
||
// 주변 캐릭터에게 전송
|
||
m_pGameRoom->BroadcastChatRoomLeaveUser( this, CHATROOMLEAVE_LEAVE );
|
||
}
|
||
}
|
||
|
||
return ERROR_NONE;
|
||
}
|
||
break;
|
||
}
|
||
|
||
return ERROR_UNKNOWN_HEADER;
|
||
}
|
||
|
||
int CDNUserSession::OnRecvPvPMessage(int nSubCmd, char * pData, int nLen)
|
||
{
|
||
switch(nSubCmd)
|
||
{
|
||
case ePvP::CS_SWAPMEMBERINDEX:
|
||
{
|
||
CSPvPTeamSwapMemberIndex * pPacket = (CSPvPTeamSwapMemberIndex*)pData;
|
||
if(g_pMasterConnectionManager)
|
||
g_pMasterConnectionManager->SendPvPSwapMemberIndex(GetWorldSetID(), GetAccountDBID(), pPacket->cCount, pPacket->Index);
|
||
else
|
||
SendPvPMemberIndex(0, 0, NULL, ERROR_PVP_SWAPTEAM_MEMBERINDEX_FAIL);
|
||
return ERROR_NONE;
|
||
}
|
||
|
||
case ePvP::CS_GUILDWAR_CHANGEMEMBER_GRADE:
|
||
{
|
||
CSPvPGuildWarChangeMemberGrade * pPacket = (CSPvPGuildWarChangeMemberGrade*)pData;
|
||
|
||
if(sizeof(CSPvPGuildWarChangeMemberGrade) != nLen)
|
||
return ERROR_INVALIDPACKET;
|
||
|
||
if(g_pMasterConnectionManager)
|
||
g_pMasterConnectionManager->SendPvPChangeMemberGrade(GetWorldSetID(), GetAccountDBID(), pPacket->nType, pPacket->nSessionID, pPacket->bAsign);
|
||
else
|
||
SendPvPGuildWarMemberGrade(0, 0, ERROR_PVP_CHANGEMEMBERGRADE_FAIL);
|
||
return ERROR_NONE;
|
||
}
|
||
|
||
case ePvP::CS_CONCENTRATE_ORDER:
|
||
{
|
||
CSOrderConcentrate * pPacket = (CSOrderConcentrate*)pData;
|
||
|
||
if(sizeof(CSOrderConcentrate) != nLen)
|
||
return ERROR_INVALIDPACKET;
|
||
|
||
if(!(GetPvPUserState()&PvPCommon::UserState::GuildWarCaptain) && !(GetPvPUserState()&PvPCommon::UserState::GuildWarSedcondCaptain))
|
||
return ERROR_NONE;
|
||
|
||
for( UINT i=0 ; i<GetGameRoom()->GetUserCount() ; ++i )
|
||
{
|
||
CDNUserSession* pSession = GetGameRoom()->GetUserData(i);
|
||
if(pSession)
|
||
pSession->SendGuildWarConcentrateOrder(GetSessionID(), pPacket->vPosition);
|
||
}
|
||
return ERROR_NONE;
|
||
}
|
||
#if defined( PRE_WORLDCOMBINE_PVP )
|
||
case ePvP::CS_PVP_WORLDPVPROOM_STARTMSG:
|
||
{
|
||
WorldPvPMissionRoom::CSWorldPvPRoomStartMsg * pPacket = (WorldPvPMissionRoom::CSWorldPvPRoomStartMsg*)pData;
|
||
|
||
if(sizeof(WorldPvPMissionRoom::CSWorldPvPRoomStartMsg) != nLen)
|
||
return ERROR_INVALIDPACKET;
|
||
|
||
if( GetGameRoom()->bIsWorldPvPRoom() && !GetGameRoom()->bIsWorldPvPRoomStart() )
|
||
{
|
||
CPvPGameMode * pMode = GetGameRoom()->GetPvPGameMode();
|
||
if( pMode )
|
||
{
|
||
if( pMode->CheckWorldPvPRoomMinMemberCount() )
|
||
{
|
||
if( GetGameRoom()->GetWorldPvPRoomReqType() == WorldPvPMissionRoom::Common::GMRoom )
|
||
{
|
||
// 팀 셋팅체크
|
||
}
|
||
GetGameRoom()->SetWorldPvPRoomStart(true);
|
||
}
|
||
else
|
||
{
|
||
SendWorldPvPRoomStartResult(ERROR_GENERIC_INVALIDREQUEST);
|
||
GetGameRoom()->GetPvPGameMode()->SetSendStartMsg(false);
|
||
}
|
||
}
|
||
}
|
||
return ERROR_NONE;
|
||
}
|
||
break;
|
||
#endif
|
||
}
|
||
return ERROR_UNKNOWN_HEADER;
|
||
}
|
||
|
||
#if defined( PRE_PRIVATECHAT_CHANNEL )
|
||
int CDNUserSession::OnRecvPrivateChatChannelMessage(int nSubCmd, char * pData, int nLen)
|
||
{
|
||
return CDNUserBase::OnRecvPrivateChatChannelMessage( nSubCmd, pData, nLen );
|
||
}
|
||
#endif
|
||
|
||
#if defined( PRE_ALTEIAWORLD_EXPLORE )
|
||
int CDNUserSession::OnRecvWorldAlteiaMessage(int nSubCmd, char *pData, int nLen)
|
||
{
|
||
switch( nSubCmd )
|
||
{
|
||
case eAlteiaWorld::CS_ALTEIAWORLD_DICE:
|
||
{
|
||
int nRet = AlteiaWorldDice();
|
||
if( nRet != ERROR_NONE )
|
||
{
|
||
SendAlteiaWorldDiceResult( nRet, 0 );
|
||
}
|
||
}
|
||
break;
|
||
case eAlteiaWorld::CS_ALTEIAWORLD_NEXTMAP:
|
||
{
|
||
MoveAlteiaNextMap();
|
||
}
|
||
break;
|
||
}
|
||
return CDNUserBase::OnRecvWorldAlteiaMessage( nSubCmd, pData, nLen );
|
||
}
|
||
#endif
|
||
|
||
|
||
void CDNUserSession::SendPacket(int iMainCmd, int iSubCmd, const void * pMsg, int iLen, int iPrior)
|
||
{
|
||
#ifdef PRE_ADD_PACKETSIZE_CHECKER
|
||
if (m_nSendCheckTick == 0)
|
||
m_nSendCheckTick = timeGetTime();
|
||
unsigned long CurTick = timeGetTime();
|
||
|
||
m_nSendCheckSize += iLen;
|
||
m_nSendCheckCount++;
|
||
|
||
int cnt = m_nSendDebugInfoCount++&127;
|
||
m_SendDebugInfo[cnt]._DebugMainCmd = iMainCmd;
|
||
m_SendDebugInfo[cnt]._DebugSubCmd = iSubCmd;
|
||
m_SendDebugInfo[cnt]._DebugTick = CurTick;
|
||
m_SendDebugInfo[cnt]._DebugSize = iLen;
|
||
|
||
if (m_bActorDebugSended == false && m_nSendCheckTick + 10000 < CurTick && GetGameRoom())
|
||
{
|
||
if (m_nSendCheckSize > (1024 * 500) || m_nSendCheckCount > 10000)
|
||
{
|
||
g_Log.Log(LogType::_ERROR, L"[%d] Report|Frame SendSize SID[%d] Class[%d] Job[%d] MapIndex[%d] AvrCur[%d] Sum[%d] Cnt[%d]\n", g_Config.nManagedID, GetSessionID(), GetClassID(), GetUserJob(), GetGameRoom()->GetGameTask()->GetMapTableID(), m_nSendCheckSize / m_nSendCheckCount, m_nSendCheckSize, m_nSendCheckCount);
|
||
if (g_pServiceConnection)
|
||
{
|
||
WCHAR wszBuf[GAMEDELAYSIZE] = {0,};
|
||
wsprintf( wszBuf, L"[%d] Report|Frame SendSize SID[%d] Class[%d] Job[%d] MapIndex[%d] AvrCur[%d] Sum[%d] Cnt[%d]", g_Config.nManagedID, GetSessionID(), GetClassID(), GetUserJob(), GetGameRoom()->GetGameTask()->GetMapTableID(), m_nSendCheckSize / m_nSendCheckCount, m_nSendCheckSize, m_nSendCheckCount);
|
||
g_pServiceConnection->SendGameDelayedReport(wszBuf);
|
||
}
|
||
|
||
USES_CONVERSION;
|
||
std::wstring wstrLogText;
|
||
bool bSended = false;
|
||
int nAddedCount = 0;
|
||
for (int nLogCout = 0; nLogCout < (int)m_vActorSendInfo.size(); nLogCout++)
|
||
{
|
||
if (bSended == false)
|
||
{
|
||
wstrLogText.clear();
|
||
wstrLogText = L"[";
|
||
wstrLogText += I2W(g_Config.nManagedID);
|
||
wstrLogText += L"] Report|Frame SendActorInfo ";
|
||
bSended = true;
|
||
}
|
||
|
||
if (m_vActorSendInfo[nLogCout].nSendCount <= 0)
|
||
continue;
|
||
|
||
wstrLogText += L"[SC:";
|
||
wstrLogText += I2W(nLogCout);
|
||
wstrLogText += L" SCC:";
|
||
wstrLogText += I2W(m_vActorSendInfo[nLogCout].nSendCount);
|
||
wstrLogText += L"]";
|
||
nAddedCount++;
|
||
|
||
if (nAddedCount >= 4)
|
||
{
|
||
if (g_pServiceConnection && GAMEDELAYSIZE > (int)wstrLogText.size())
|
||
g_pServiceConnection->SendGameDelayedReport(const_cast<WCHAR*>(wstrLogText.c_str()));
|
||
|
||
wstrLogText += L"\n";
|
||
g_Log.Log(LogType::_ERROR, L"%s\n", wstrLogText.c_str());
|
||
|
||
bSended = false;
|
||
nAddedCount = 0;
|
||
}
|
||
}
|
||
m_bActorDebugSended = true;
|
||
|
||
for (int nLogCount = 0; nLogCount < 128; nLogCount++)
|
||
{
|
||
g_Log.Log(LogType::_ERROR, L"[%d] Report|Frame SendDebugInfo MCmd[%d] SCmd[%d] Tick[%d] Size[%d]\n", g_Config.nManagedID, m_SendDebugInfo[nLogCount]._DebugMainCmd, m_SendDebugInfo[nLogCount]._DebugSubCmd, \
|
||
m_SendDebugInfo[nLogCount]._DebugTick, m_SendDebugInfo[nLogCount]._DebugSize);//, m_SendActorDebugInfo[nLogCount]._dwUniqueID, m_SendActorDebugInfo[nLogCount]._ActorSubCmd, m_SendActorDebugInfo[nLogCount]._PacketBroadFlag);
|
||
if (g_pServiceConnection)
|
||
{
|
||
WCHAR wszBuf[GAMEDELAYSIZE] = {0,};
|
||
wsprintf( wszBuf, L"[%d] Report|Frame SendDebugInfo MCmd[%d] SCmd[%d] Tick[%d] Size[%d]", g_Config.nManagedID, m_SendDebugInfo[nLogCount]._DebugMainCmd, m_SendDebugInfo[nLogCount]._DebugSubCmd, \
|
||
m_SendDebugInfo[nLogCount]._DebugTick, m_SendDebugInfo[nLogCount]._DebugSize);//, m_SendActorDebugInfo[nLogCount]._dwUniqueID, m_SendActorDebugInfo[nLogCount]._ActorSubCmd, m_SendActorDebugInfo[nLogCount]._PacketBroadFlag);
|
||
g_pServiceConnection->SendGameDelayedReport(wszBuf);
|
||
}
|
||
}
|
||
}
|
||
|
||
m_nSendCheckTick = CurTick;
|
||
m_nSendCheckSize = 0;
|
||
m_nSendCheckCount = 0;
|
||
}
|
||
#endif //#ifdef PRE_ADD_PACKETSIZE_CHECKER
|
||
|
||
//몇가지 빼고는 tcp로 쏴져요~
|
||
if(m_pGameRoom->GetRoomState() == _GAME_STATE_SYNC2SYNC)
|
||
StorePacket(iMainCmd, iSubCmd, (char*)pMsg, iLen);
|
||
else
|
||
{
|
||
// 요기가 그 몇가지............일단머 좀 구찮게 되어 있지만 디스패치단은 통일이 되어 있음. 나머지는 막쏴도 됩니다.
|
||
// Note: 물약 먹는 거 싱크 안맞는 게 의심되서 게임에서 사용하는 아이템 패킷은 액터 메시지와 마찬가지로 UDP로 뺍니다..
|
||
// udp/tcp 순서 맞추어 놓았습니다. 고로 컨넥되어 있으면 막쏴도 데요.
|
||
bool bSendUdp = false;
|
||
switch( iMainCmd ) {
|
||
case SC_ACTOR:
|
||
case SC_ACTORBUNDLE:
|
||
case SC_PROP:
|
||
bSendUdp = true;
|
||
break;
|
||
|
||
case SC_SYSTEM:
|
||
switch( iSubCmd ) {
|
||
case eSystem::SC_TCP_CONNECT_REQ:
|
||
bSendUdp = true;
|
||
break;
|
||
}
|
||
break;
|
||
case SC_ROOM:
|
||
{
|
||
switch( iSubCmd )
|
||
{
|
||
case eRoom::SC_SYNC_MEMBERINFO:
|
||
case eRoom::SC_SYNC_MEMBERTEAM:
|
||
case eRoom::SC_SYNC_MEMBERDEFAULTPARTS:
|
||
case eRoom::SC_SYNC_MEMBEREQUIP:
|
||
case eRoom::SC_SYNC_MEMBERSKILL:
|
||
case eRoom::SC_SYNC_MEMBER_BREAKINTO:
|
||
case eRoom::SC_SYNC_MEMBERHPSP:
|
||
case eRoom::SC_SYNC_MEMBERBATTLEMODE:
|
||
case eRoom::SC_SYNC_DROPITEMLIST:
|
||
case eRoom::SC_SYNC_DATUMTICK:
|
||
case eRoom::SC_DLDUNGEONCLEAR_RANKINFO:
|
||
case eRoom::SC_START_DRAGONNEST:
|
||
case eRoom::SC_DUNGEONCLEAR_MSG:
|
||
case eRoom::SC_DLDUNGEONCLEAR_MSG:
|
||
{
|
||
// PvP Sync 패킷을 TCP 로 쏴줌.
|
||
bSendUdp = false;
|
||
break;
|
||
}
|
||
default:
|
||
{
|
||
bSendUdp = true;
|
||
break;
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
case SC_QUEST:
|
||
switch( iSubCmd ) {
|
||
case eQuest::SC_PLAYCUTSCENE:
|
||
case eQuest::SC_COMPLETE_CUTSCENE:
|
||
bSendUdp = true;
|
||
break;
|
||
}
|
||
break;
|
||
|
||
}
|
||
|
||
bool bSendOK = true;
|
||
BYTE cPrevPacketSeq = m_cPacketSeq;
|
||
|
||
if( bSendUdp && iLen >= 512 )
|
||
{
|
||
#ifdef _FINAL_BUILD
|
||
#else //#ifdef _FINAL_BUILD
|
||
g_Log.Log(LogType::_ERROR, this, L"SendError Check Packet Size MCMD[%d] SCMD[%d] PL[%d]\n", iMainCmd, iSubCmd, iLen);
|
||
#endif //#ifdef _FINAL_BUILD
|
||
bSendUdp = false;
|
||
}
|
||
|
||
if (bSendUdp && iMainCmd != SC_ACTORBUNDLE && iPrior == _RELIABLE)
|
||
FlushPacketQueue();
|
||
|
||
//reliable udp와 tcp인경우에만 올립니다
|
||
BYTE cSeq = 0;
|
||
if((bSendUdp && iPrior == _RELIABLE) || bSendUdp == false)
|
||
cSeq = m_cPacketSeq += 2;
|
||
|
||
//rlkt_udp
|
||
//bSendUdp = false;
|
||
|
||
if( bSendUdp )
|
||
{
|
||
#ifdef _PACKET_COMP
|
||
//if(m_pTcpConnection && m_pTcpConnection->GetIsUseComp()) m_pTcpConnection->SetPacketComp(false);
|
||
#endif
|
||
|
||
if(m_pGameServer->Send(m_iNetID, iMainCmd, iSubCmd, pMsg, iLen, iPrior, cSeq) < 0)
|
||
{
|
||
bSendOK = false;
|
||
#ifdef _DEBUG
|
||
if (iMainCmd == SC_SYSTEM && iSubCmd == SC_TCP_CONNECT_REQ)
|
||
g_Log.Log(LogType::_ERROR, this, L"UDP SendError NETID[%d] MCMD[%d] SCMD[%d] PL[%d] PRIOR[%d]\n", m_iNetID, iMainCmd, iSubCmd, iLen, iPrior);
|
||
#endif
|
||
//g_Log.Log(LogType::_ERROR, this, L"UDP SendError NETID[%d] MCMD[%d] SCMD[%d] PL[%d] PRIOR[%d]\n", m_iNetID, iMainCmd, iSubCmd, iLen, iPrior);
|
||
}
|
||
}
|
||
else if(m_pTcpConnection != NULL)// && m_pTcpConnection->GetDelete() == false && m_pTcpConnection->GetActive())
|
||
{
|
||
if(m_pTcpConnection->AddSendData(iMainCmd, iSubCmd, (char*)pMsg, iLen, NULL, cSeq) < 0)
|
||
{
|
||
bSendOK = false;
|
||
//g_Log.Log(LogType::_ERROR, this, L"TCP SendError ADBID[%d] CNAME[%s] MCMD[%d] SCMD[%d] PL[%d]\n", GetAccountDBID(), GetCharacterName(), iMainCmd, iSubCmd, iLen);
|
||
}
|
||
}
|
||
#if !defined( STRESS_TEST )
|
||
else
|
||
{
|
||
bSendOK = false;
|
||
//g_Log.Log(LogType::_ERROR, this, L"SendError ADBID[%d] CNAME[%s] MCMD[%d] SCMD[%d] PL[%d]\n", GetAccountDBID(), GetCharacterName(), iMainCmd, iSubCmd, iLen);
|
||
}
|
||
#endif
|
||
|
||
if((bSendUdp && iPrior == _RELIABLE) || bSendUdp == false)
|
||
{
|
||
if( !bSendOK )
|
||
{
|
||
m_cPacketSeq = cPrevPacketSeq;
|
||
}
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
int CDNUserSession::AddSendData(int iMainCmd, int iSubCmd, char *pData, int iLen)
|
||
{
|
||
SendPacket(iMainCmd, iSubCmd, pData, iLen, _RELIABLE);
|
||
return 0;
|
||
}
|
||
|
||
#if defined(PRE_ADD_MULTILANGUAGE)
|
||
void CDNUserSession::PreInitializeUser(WCHAR * wszAccountName, UINT nAccountDBID, UINT nSessionID, INT64 biCharacterDBID, int iTeam, int nWorldID, int nVillageID, bool bTutorial, bool bAdult, char cPCBangGrade, char cSelectedLanguage, TMemberVoiceInfo * pInfo)
|
||
#else //#if defined(PRE_ADD_MULTILANGUAGE)
|
||
void CDNUserSession::PreInitializeUser(WCHAR * wszAccountName, UINT nAccountDBID, UINT nSessionID, INT64 biCharacterDBID, int iTeam, int nWorldID, int nVillageID, bool bTutorial, bool bAdult, char cPCBangGrade, TMemberVoiceInfo * pInfo)
|
||
#endif //#if defined(PRE_ADD_MULTILANGUAGE)
|
||
{
|
||
SetAccountName(wszAccountName);
|
||
m_nAccountDBID = nAccountDBID;
|
||
m_nSessionID = nSessionID;
|
||
m_biCharacterDBID = biCharacterDBID;
|
||
m_iTeam = iTeam;
|
||
m_nWorldSetID = nWorldID;
|
||
m_cVillageID = nVillageID;
|
||
m_bAdult = bAdult;
|
||
SetPCBangGrade(cPCBangGrade);
|
||
|
||
if(m_bPCBang)
|
||
{
|
||
#if !defined(_KR)
|
||
SendPCBang(m_cPCBangGrade, NULL);
|
||
#endif
|
||
}
|
||
m_bTutorial = bTutorial;
|
||
|
||
#ifdef _USE_VOICECHAT
|
||
if(pInfo)
|
||
{
|
||
m_bVoiceAvailable = pInfo->cVoiceAvailable == 0 ? false : true;
|
||
memcpy(m_nVoiceMutedList, pInfo->nMutedList, sizeof(UINT[PARTYCOUNTMAX]));
|
||
m_nVoiceChannelID = 0;
|
||
m_cIsTalking = 0;
|
||
m_nVoiceJoinType = _VOICEJOINTYPE_NONE;
|
||
}
|
||
#endif
|
||
#if defined(PRE_ADD_MULTILANGUAGE)
|
||
m_eSelectedLanguage = static_cast<MultiLanguage::SupportLanguage::eSupportLanguage>(cSelectedLanguage);
|
||
#endif //#if defined(PRE_ADD_MULTILANGUAGE)
|
||
SetSessionState(SESSION_STATE_READY);
|
||
}
|
||
|
||
void CDNUserSession::QueryGetMasterSystemCountInfo( bool bClientSend, CDNDBConnection* pDBCon/*=NULL*/, BYTE cThreadID/*=0*/ )
|
||
{
|
||
if( GetGameRoom() == NULL )
|
||
return;
|
||
|
||
// 일부 Task 에서는 해당 정보가 필요없다.
|
||
switch( GetGameRoom()->GetGameTaskType() )
|
||
{
|
||
case GameTaskType::Farm:
|
||
case GameTaskType::PvP:
|
||
{
|
||
return;
|
||
}
|
||
}
|
||
|
||
std::vector<INT64> vPartyListExceptMe;
|
||
for( UINT i=0 ; i<GetGameRoom()->GetUserCount() ; ++i )
|
||
{
|
||
CDNUserSession* pSession = GetGameRoom()->GetUserData(i);
|
||
if( pSession && pSession != this && pSession->bIsGMTrace() == false )
|
||
vPartyListExceptMe.push_back( pSession->GetCharacterDBID() );
|
||
}
|
||
|
||
if( pDBCon )
|
||
pDBCon->QueryGetMasterSystemCountInfo( cThreadID, this, bClientSend, vPartyListExceptMe );
|
||
else
|
||
GetDBConnection()->QueryGetMasterSystemCountInfo( GetDBThreadID(), this, bClientSend, vPartyListExceptMe );
|
||
}
|
||
|
||
void CDNUserSession::InitialUser()
|
||
{
|
||
//Query Character Data
|
||
BYTE cThreadID = 0;
|
||
CDNDBConnection *pTempDBCon = g_pDBConnectionManager->GetDBConnection(cThreadID);
|
||
pTempDBCon->QueryGetMasterSystemSimpleInfo( cThreadID, this, false, MasterSystem::EventType::Init );
|
||
QueryGetMasterSystemCountInfo( false, pTempDBCon, cThreadID );
|
||
|
||
#if defined( PRE_ADD_NPC_REPUTATION_SYSTEM )
|
||
pTempDBCon->QueryGetListNpcReputation( cThreadID, this );
|
||
#endif // #if defined( PRE_ADD_NPC_REPUTATION_SYSTEM )
|
||
|
||
#if defined( PRE_ADD_SECONDARY_SKILL )
|
||
pTempDBCon->QueryGetListSecondarySkill( cThreadID, this );
|
||
#endif // #if defined( PRE_ADD_SECONDARY_SKILL )
|
||
|
||
if( GetGameRoom()->bIsFarmRoom() )
|
||
{
|
||
pTempDBCon->QueryGetFieldCountByCharacter( cThreadID, GetWorldSetID(), m_nAccountDBID, m_biCharacterDBID, false );
|
||
pTempDBCon->QueryGetListFieldForCharacter( cThreadID, GetWorldSetID(), GetAccountDBID(), GetCharacterDBID(), GetRoomID() );
|
||
}
|
||
pTempDBCon->QueryGetListPvPLadderScore( cThreadID, this );
|
||
pTempDBCon->QueryGetPVPGhoulScores( cThreadID, this );
|
||
|
||
pTempDBCon->QueryGetListEtcPoint( cThreadID, this );
|
||
|
||
pTempDBCon->QueryGetAbuseMonitor( cThreadID, this );
|
||
|
||
#if defined(PRE_ADD_ABUSE_ACCOUNT_RESTRAINT)
|
||
|
||
#if defined(PRE_ADD_MULTILANGUAGE)
|
||
pTempDBCon->QueryGetWholeAbuseMonitor( cThreadID, this, m_eSelectedLanguage );
|
||
#else //#if defined(PRE_ADD_MULTILANGUAGE)
|
||
pTempDBCon->QueryGetWholeAbuseMonitor( cThreadID, this );
|
||
#endif //#if defined(PRE_ADD_MULTILANGUAGE)
|
||
|
||
#endif //#if defined(PRE_ADD_ABUSE_ACCOUNT_RESTRAINT)
|
||
pTempDBCon->QueryGetListVariableReset( cThreadID, this );
|
||
#if defined( PRE_ADD_TOTAL_LEVEL_SKILL )
|
||
pTempDBCon->QueryGetTotalSkillLevel(cThreadID, this);
|
||
#endif
|
||
|
||
#if defined( PRE_PARTY_DB )
|
||
pTempDBCon->QuerySelectCharacter( cThreadID, this );
|
||
#else
|
||
pTempDBCon->QuerySelectCharacter( cThreadID, this, 0 );
|
||
#endif
|
||
|
||
#if defined (PRE_ADD_BESTFRIEND)
|
||
pTempDBCon->QueryGetBestFriend(cThreadID, this, false);
|
||
#endif
|
||
|
||
//Query Friend Data
|
||
pTempDBCon->QueryFriendList(cThreadID, this );
|
||
|
||
//Query Isolate Data
|
||
pTempDBCon->QueryGetIsolateList(cThreadID, this);
|
||
|
||
//Query GameOption
|
||
pTempDBCon->QueryGetGameOption(cThreadID, this);
|
||
|
||
//Cash Inventory
|
||
pTempDBCon->QueryGetPageMaterializedItem(cThreadID, this, 1, CASHINVENTORYPAGEMAX);
|
||
|
||
pTempDBCon->QueryGetProfile(cThreadID, this);
|
||
#if defined( PRE_ADD_LIMITED_SHOP )
|
||
pTempDBCon->QueryGetLimitedShopItem(cThreadID, this);
|
||
#endif
|
||
|
||
#if defined( PRE_ADD_STAMPSYSTEM )
|
||
pTempDBCon->QueryGetListCompleteChallenges(cThreadID, this);
|
||
#endif // #if defined( PRE_ADD_STAMPSYSTEM )
|
||
#if defined( PRE_ALTEIAWORLD_EXPLORE )
|
||
pTempDBCon->QueryGetAlteiaWorldInfo(cThreadID, this);
|
||
#endif
|
||
|
||
#ifdef _DEBUG
|
||
g_Log.Log(LogType::_NORMAL, this, L"[ADBID:%u CDBID:%I64d SID:%u] [InitialUser]\r\n", m_nAccountDBID, m_biCharacterDBID, m_nSessionID);
|
||
#endif
|
||
|
||
SetSessionState(SESSION_STATE_LOAD);
|
||
}
|
||
|
||
void CDNUserSession::BackUpEquipInfo()
|
||
{
|
||
if( m_BackupEquipInfo.first > 0 )
|
||
{
|
||
int iInvenIndex = GetItem()->FindInventorySlotBySerial( m_BackupEquipInfo.first );
|
||
int iDestIndex = GetItem()->GetInventory(iInvenIndex) ? GetItem()->GetEquipSlotIndex( GetItem()->GetInventory(iInvenIndex)->nItemID ) : -1;
|
||
if( iInvenIndex >= 0 && iDestIndex >= 0 )
|
||
{
|
||
CSMoveItem TxPacket;
|
||
memset( &TxPacket, 0, sizeof(TxPacket) );
|
||
|
||
TxPacket.cMoveType = MoveType_InvenToEquip;
|
||
TxPacket.cSrcIndex = static_cast<BYTE>(iInvenIndex);
|
||
TxPacket.biSrcItemSerial = m_BackupEquipInfo.first;
|
||
TxPacket.cDestIndex = static_cast<BYTE>(iDestIndex);
|
||
TxPacket.wCount = 1;
|
||
|
||
GetItem()->SetMoveItemCheckGameMode( false );
|
||
GetGameRoom()->OnDispatchMessage( this, CS_ITEM, eItem::CS_MOVEITEM, reinterpret_cast<char*>(&TxPacket), sizeof(TxPacket), 0 );
|
||
GetItem()->SetMoveItemCheckGameMode( true );
|
||
}
|
||
|
||
m_BackupEquipInfo = std::make_pair(0,0);
|
||
}
|
||
}
|
||
|
||
void CDNUserSession::CheckAndSendStageClearLog(bool bClear)
|
||
{
|
||
if( bClear )
|
||
{
|
||
if( !m_pGameRoom )
|
||
return;
|
||
|
||
// 스테이지 클리어 로그 (RequestDungeonClear를 호출하진 않았지만 성공한 경우)
|
||
if( m_pGameRoom->GetStageStartLogFlag() == true )
|
||
{
|
||
CDnPlayerActor *pPlayer = GetPlayerActor();
|
||
if( !pPlayer )
|
||
return;
|
||
|
||
BYTE cThreadID;
|
||
CDNDBConnection* pDBCon = g_pDBConnectionManager->GetDBConnection( cThreadID );
|
||
if( pDBCon )
|
||
{
|
||
|
||
#if defined( PRE_ADD_36870 )
|
||
pDBCon->QueryAddStageClearLog( cThreadID, m_pGameRoom->GetWorldSetID(), GetAccountDBID(), m_pGameRoom->GetRoomLogIndex(), GetCharacterDBID(), GetUserJob(), GetLevel(),
|
||
true, static_cast<DBDNWorldDef::ClearGradeCode::eCode>(0), pPlayer->GetMaxComboCount(), pPlayer->GetKillBossCount(), 0, 0, 0, 0,
|
||
m_pGameRoom->GetDungeonPlayTime()/1000, m_pGameRoom->GetDungeonClearRound());
|
||
#else
|
||
pDBCon->QueryAddStageClearLog( cThreadID, m_pGameRoom->GetWorldSetID(), GetAccountDBID(), m_pGameRoom->GetRoomLogIndex(), GetCharacterDBID(), GetUserJob(), GetLevel(),
|
||
true, static_cast<DBDNWorldDef::ClearGradeCode::eCode>(0), pPlayer->GetMaxComboCount(), pPlayer->GetKillBossCount(), 0, 0, 0, 0, 0 );
|
||
#endif // #if defined( PRE_ADD_36870 )
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// 스테이지 클리어 로그( 실패한경우 ) && StartLog 가 있는 경우
|
||
if( GetLastStageClearRank() == -1 && m_pGameRoom->GetStageStartLogFlag() == true )
|
||
{
|
||
BYTE cThreadID;
|
||
CDNDBConnection* pDBCon = g_pDBConnectionManager->GetDBConnection( cThreadID );
|
||
if( pDBCon )
|
||
{
|
||
#if defined( PRE_ADD_36870 )
|
||
pDBCon->QueryAddStageClearLog( cThreadID, m_pGameRoom->GetWorldSetID(), GetAccountDBID(), m_pGameRoom->GetRoomLogIndex(), GetCharacterDBID(), GetUserJob(), GetLevel(),
|
||
false, static_cast<DBDNWorldDef::ClearGradeCode::eCode>(0), 0, 0, 0, 0, 0, 0, 0, m_pGameRoom->GetDungeonClearRound());
|
||
#else
|
||
pDBCon->QueryAddStageClearLog( cThreadID, m_pGameRoom->GetWorldSetID(), GetAccountDBID(), m_pGameRoom->GetRoomLogIndex(), GetCharacterDBID(), GetUserJob(), GetLevel(),
|
||
false, static_cast<DBDNWorldDef::ClearGradeCode::eCode>(0), 0, 0, 0, 0, 0, 0, 0 );
|
||
#endif // #if defined( PRE_ADD_36870 )
|
||
}
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
void CDNUserSession::FinalUser()
|
||
{
|
||
if(m_iState == SESSION_STATE_DISCONNECTED) return;
|
||
|
||
FinalizeEvent();
|
||
|
||
#if defined( STRESS_TEST )
|
||
#else
|
||
g_Log.Log( LogType::_GAMECONNECTLOG, this, L"[%d] FinalUser() SessionState=%d RoomState=%d ip=%s\n", g_Config.nManagedID, m_iState, GetGameRoom() ? GetGameRoom()->GetRoomState() : -1, GetIpW() ? GetIpW() : L"None" );
|
||
#endif // #if defined( STRESS_TEST )
|
||
|
||
BackUpEquipInfo();
|
||
|
||
// InstantItem 날린다.
|
||
if( m_iState != SESSION_STATE_SERVER_CHANGE )
|
||
GetItem()->RemoveInstantItemData( false );
|
||
|
||
if(m_iState != SESSION_STATE_SERVER_CHANGE && m_iState != SESSION_STATE_RECONNECTLOGIN)
|
||
{
|
||
if(GetGameRoom())
|
||
{
|
||
GetGameRoom()->OnDelPartyMember(GetSessionID(), m_cKickKind);
|
||
#if defined(PRE_ADD_REVENGE)
|
||
if( m_pGameRoom->bIsPvPRoom() && !GetPvPGameModeFinish() )
|
||
static_cast<CDNPvPGameRoom*>(m_pGameRoom)->OnLeaveRoomBeforeFinish(GetSessionID());
|
||
#endif
|
||
}
|
||
else
|
||
_DANGER_POINT();
|
||
}
|
||
#if defined( PRE_PARTY_DB )
|
||
else if( GetGameRoom() && GetGameRoom()->GetGameType() != REQINFO_TYPE_SINGLE )
|
||
{
|
||
if( GetGameRoom()->GetTaskMng() )
|
||
{
|
||
CDnPartyTask* pPartyTask = (CDnPartyTask*)(GetGameRoom()->GetTaskMng()->GetTask("PartyTask"));
|
||
if( pPartyTask )
|
||
pPartyTask->DelPartyMemberDB( this );
|
||
}
|
||
}
|
||
#endif
|
||
|
||
#if defined( PRE_WORLDCOMBINE_PVP )
|
||
if( GetGameRoom() && GetGameRoom()->bIsWorldPvPRoom() )
|
||
{
|
||
if( GetGameRoom()->GetWorldPvPRoomReqType() == WorldPvPMissionRoom::Common::GMRoom && GetAccountDBID() == GetGameRoom()->GetWorldPvPRoomCreateGMAccountDBID() )
|
||
{
|
||
CDNGameRoom::PartyStruct * pStruct = NULL;
|
||
CDNUserSession * pSession = NULL;
|
||
|
||
for (DWORD i = 0; i < GetGameRoom()->GetUserCount(); i++)
|
||
{
|
||
pStruct = GetGameRoom()->GetPartyData(i);
|
||
pSession = pStruct->pSession;
|
||
if ( pStruct && pSession && pSession != this )
|
||
{
|
||
pSession->SendPvPGameToPvPLobby();
|
||
}
|
||
}
|
||
}
|
||
|
||
GetGameRoom()->DelDBWorldPvPRoomMember( this );
|
||
if( GetGameRoom()->GetPvPGameMode() )
|
||
{
|
||
if( GetGameRoom()->GetPvPGameMode()->bIsSendStartMsg() && !GetGameRoom()->GetPvPGameMode()->bIsWaitStartCount() )
|
||
{
|
||
if( GetSessionID() == GetGameRoom()->GetPvPGameMode()->GetSendStartMsgSessionID() )
|
||
{
|
||
GetGameRoom()->GetPvPGameMode()->SetSendStartMsg(false);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
#endif
|
||
#if defined( PRE_ADD_DIRECTNBUFF )
|
||
if( !m_DirectPartyBuffItemList.empty() )
|
||
{
|
||
for(std::list<int>::iterator itor=m_DirectPartyBuffItemList.begin();itor!=m_DirectPartyBuffItemList.end();itor++)
|
||
{
|
||
GetGameRoom()->RemoveDirectPartyBuff(*itor);
|
||
}
|
||
}
|
||
#endif
|
||
|
||
SendPartyBonusValue(0, 0);
|
||
|
||
CheckAndSendStageClearLog();
|
||
|
||
if(m_bStageAbortLog && m_pGameRoom->GetTaskMng() )
|
||
{
|
||
CDnGameTask* pTask = (CDnGameTask *)m_pGameRoom->GetTaskMng()->GetTask( "GameTask" );
|
||
#if defined( _WORK )
|
||
if(true)
|
||
#else
|
||
if(pTask && pTask->IsEnteredDungeon())
|
||
#endif // #if defined( _WORK )
|
||
ChangeStageUserData();
|
||
}
|
||
|
||
// 거래 중이면 거래 중단
|
||
if(m_nExchangeTargetSessionID > 0){
|
||
CDNUserSession *pSession = FindUserSession(m_nExchangeTargetSessionID);
|
||
if(pSession){
|
||
pSession->SendExchangeCancel();
|
||
pSession->ClearExchangeInfo();
|
||
}
|
||
SendExchangeCancel();
|
||
ClearExchangeInfo();
|
||
}
|
||
if(m_nExchangeSenderSID > 0){
|
||
CDNUserSession *pSession = FindUserSession(m_nExchangeSenderSID);
|
||
if(pSession){
|
||
pSession->SendExchangeReject(m_nSessionID);
|
||
pSession->ClearExchangeInfo();
|
||
}
|
||
}
|
||
if(m_nExchangeReceiverSID > 0){
|
||
CDNUserSession *pSession = FindUserSession(m_nExchangeReceiverSID);
|
||
if(pSession){
|
||
pSession->SendExchangeRequest(m_nSessionID, ERROR_EXCHANGE_SENDERCANCEL); // 수락, 거절 버튼창 없애기
|
||
pSession->ClearExchangeInfo();
|
||
}
|
||
}
|
||
|
||
// 강종 유저 어뷰징 방지 피로도 감소 체크
|
||
DecreaseFatigue(true);
|
||
|
||
if( m_hActor ) {
|
||
if( m_iState != SESSION_STATE_SERVER_CHANGE && m_iState != SESSION_STATE_RECONNECTLOGIN ) {
|
||
// 내구도 감소
|
||
if( m_hActor->IsPlayerActor() )
|
||
{
|
||
CDnPlayerActor *pPlayer = static_cast<CDnPlayerActor *>(m_hActor.GetPointer());
|
||
if(pPlayer)
|
||
pPlayer->OnStageGiveUp();
|
||
else
|
||
_DANGER_POINT();
|
||
}
|
||
else
|
||
{
|
||
_DANGER_POINT();
|
||
}
|
||
}
|
||
if( m_iState == SESSION_STATE_GAME_PLAY || m_iState == SESSION_STATE_RECONNECTLOGIN ) {
|
||
SaveUserData();
|
||
LastUpdateUserData();
|
||
}
|
||
}
|
||
else{
|
||
if (m_iState > SESSION_STATE_LOADED && m_pTimeEventSystem)
|
||
m_pTimeEventSystem->SaveUserData( true );
|
||
}
|
||
|
||
if(m_bNeedUpdateOption)
|
||
GetDBConnection()->QuerySetGameOption(this, &m_GameOption);
|
||
|
||
// Rotha : 탈것해제
|
||
if( m_hActor )
|
||
{
|
||
if( m_hActor->IsPlayerActor() )
|
||
{
|
||
CDnPlayerActor *pPlayer = static_cast<CDnPlayerActor *>(m_hActor.GetPointer());
|
||
if(pPlayer && pPlayer->IsVehicleMode() && pPlayer->GetMyVehicleActor())
|
||
pPlayer->UnRideVehicle();
|
||
}
|
||
}
|
||
|
||
// 채팅방에서 채팅중이라면, 방에서 나감
|
||
if( m_nChatRoomID > 0 )
|
||
{
|
||
CDNChatRoom * pChatRoom = m_pGameRoom->m_ChatRoomManager.GetChatRoom( m_nChatRoomID );
|
||
if( pChatRoom != NULL )
|
||
{
|
||
if( pChatRoom->IsLeader( GetSessionID() ) )
|
||
{
|
||
// 리더가 끊기는 경우 방이 삭제된다.
|
||
while( pChatRoom->GetUserCount() > 0 )
|
||
{
|
||
UINT UserAID = pChatRoom->GetMemberAIDFromIndex( 0 );
|
||
if( UserAID <= 0 ) break; // 무한루프 방지를 위해 루프를 탈출하도록 한다.
|
||
|
||
CDNUserSession * pUserSession = NULL;
|
||
if( UserAID == GetSessionID() )
|
||
pUserSession = this;
|
||
else
|
||
pUserSession = m_pGameRoom->GetUserSession( UserAID );
|
||
if( pUserSession == NULL ) break; // 무한루프 방지를 위해 루프를 탈출하도록 한다.
|
||
|
||
int nRet = pChatRoom->LeaveUser( pUserSession->GetSessionID(), CHATROOMLEAVE_DESTROYROOM );
|
||
if( nRet == ERROR_NONE )
|
||
{
|
||
// 방에서 나가게 되는 캐릭터와 주변 캐릭터에게 메시지를 전송한다.
|
||
if( UserAID != GetSessionID() ) // 본인은 이미 게임을 끊었으므로 메시지를 전달하지 않는다.
|
||
pUserSession->SendChatRoomLeaveUser( pUserSession->GetSessionID(), CHATROOMLEAVE_DESTROYROOM );
|
||
|
||
m_pGameRoom->BroadcastChatRoomLeaveUser( pUserSession, CHATROOMLEAVE_DESTROYROOM );
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// 본인은 이미 게임을 끊었으므로 메시지를 전달하지 않는다.
|
||
// 주변에 메시지 전달(방인원 포함)
|
||
m_pGameRoom->BroadcastChatRoomLeaveUser( this, CHATROOMLEAVE_LEAVE );
|
||
|
||
pChatRoom->LeaveUser( GetSessionID(), CHATROOMLEAVE_LEAVE );
|
||
}
|
||
|
||
// 인원이 없으면 방을 삭제한다.
|
||
if( pChatRoom->GetUserCount() <= 0 )
|
||
{
|
||
m_pGameRoom->m_ChatRoomManager.DestroyChatRoom( pChatRoom->GetChatRoomID() );
|
||
}
|
||
}
|
||
}
|
||
|
||
GetGameRoom()->AddBackupPartyInfo( this );
|
||
|
||
// 원래 여기서 지워주면 ?
|
||
SAFE_RELEASE_SPTR( m_hActor );
|
||
|
||
if((m_iState != SESSION_STATE_SERVER_CHANGE) &&(m_iState != SESSION_STATE_RECONNECTLOGIN))
|
||
{
|
||
GetDBConnection()->QueryLogout(this, m_szMID);
|
||
|
||
if(m_bCertified) { // 주의 !!! - 반드시 QUERY_CHECKAUTH 를 통과하여 인증을 받은 사용자에 한해서만 인증정보 리셋이 수행되어야 함 !!!
|
||
// 리스트에 넣지말고 즉시 처리하자
|
||
g_pAuthManager->QueryResetAuth(m_nWorldSetID, m_nAccountDBID, GetSessionID());
|
||
}
|
||
|
||
if( m_bCertified ) // 인증이 통과한 애만 마스터한테 지우라고 하자..
|
||
// 여기서 SendDelUser() 를 호출 해줘야합니다.
|
||
{
|
||
g_pMasterConnectionManager->SendDelUser(GetWorldSetID(), GetAccountDBID(), m_bIntededDisconnected, m_nSessionID);
|
||
}
|
||
}
|
||
|
||
if(m_iState == SESSION_STATE_RECONNECTLOGIN)
|
||
g_pMasterConnectionManager->SendCheckReconnectLogin(GetWorldSetID(), GetAccountDBID());
|
||
|
||
if( m_iState != SESSION_STATE_SERVER_CHANGE )
|
||
{
|
||
if( GetDBConnection() ){
|
||
GetDBConnection()->QueryLogoutCharacter( this );
|
||
#if defined(_KRAZ)
|
||
m_pDBCon->QueryActozUpdateCharacterInfo(this, ActozCommon::UpdateType::Logout);
|
||
#endif // #if defined(_KRAZ)
|
||
}
|
||
if( g_pMasterConnectionManager )
|
||
g_pMasterConnectionManager->SendMasterSystemSyncConnect( GetWorldSetID(), false, GetCharacterName(), GetMasterSystemData() );
|
||
|
||
const TGuildUID GuildUID = GetGuildUID();
|
||
if(GuildUID.IsSet())
|
||
{
|
||
if(g_pMasterConnectionManager)
|
||
{
|
||
g_pMasterConnectionManager->SendChangeGuildMemberInfo(GetWorldSetID(), GuildUID, GetAccountDBID(), GetCharacterDBID(), GetAccountDBID(), GetCharacterDBID(), GUILDMEMBUPDATE_TYPE_LOGINOUT, _LOCATION_NONE, 0, 0, NULL, true);
|
||
}
|
||
}
|
||
#if defined( PRE_PRIVATECHAT_CHANNEL )
|
||
if(GetPrivateChannelID())
|
||
{
|
||
CDNPrivateChaChannel* pPrivateChatChannel = g_pPrivateChatChannelManager->GetPrivateChannelInfo( GetWorldSetID(), GetPrivateChannelID() );
|
||
if(pPrivateChatChannel)
|
||
{
|
||
m_pDBCon->QueryOutPrivateChatChannelMember( m_pSession, PrivateChatChannel::Common::ExitMember );
|
||
pPrivateChatChannel->DelPrivateChannelMember( PrivateChatChannel::Common::OutMember, GetCharacterDBID() );
|
||
if( GetCharacterDBID() == pPrivateChatChannel->GetMasterCharacterDBID() )
|
||
{
|
||
m_pDBCon->QueryModPrivateChatChannelInfo( m_pSession, pPrivateChatChannel->GetChannelName(), PrivateChatChannel::Common::ChangeMaster, pPrivateChatChannel->GetChannelPassword(), pPrivateChatChannel->GetNextMasterCharacterDBID());
|
||
pPrivateChatChannel->ModPrivateChannelInfo( PrivateChatChannel::Common::ChangeMaster, pPrivateChatChannel->GetChannelPassword(), pPrivateChatChannel->GetNextMasterCharacterDBID() );
|
||
|
||
if(g_pMasterConnectionManager)
|
||
{
|
||
g_pMasterConnectionManager->SendModPrivateChatChannelInfo(m_pSession->GetWorldSetID(), pPrivateChatChannel->GetChannelID(), PrivateChatChannel::Common::ChangeMaster, pPrivateChatChannel->GetChannelPassword(), pPrivateChatChannel->GetMasterCharacterDBID() );
|
||
}
|
||
}
|
||
|
||
if(g_pMasterConnectionManager)
|
||
{
|
||
g_pMasterConnectionManager->SendDelPrivateChatChannelMember( m_pSession->GetWorldSetID(), PrivateChatChannel::Common::OutMember, pPrivateChatChannel->GetChannelID(), GetCharacterDBID(), GetCharacterName() );
|
||
}
|
||
SetPrivateChannelID(0);
|
||
}
|
||
}
|
||
#endif
|
||
}
|
||
|
||
m_bCertified = false;
|
||
|
||
if(m_pTcpConnection)
|
||
{//접속이 완전히 이루어지기 전에 세션의 삭제가 일어날 경우 나올 수 있음
|
||
#if defined( PRE_FIX_SOCKETCONTEXT_DANGLINGPTR )
|
||
DWORD dwTime = timeGetTime();
|
||
bool bDelete = false;
|
||
#if defined( _WORK )
|
||
while( true )
|
||
#else
|
||
while( timeGetTime()-dwTime <= 1000 )
|
||
#endif // #if defined( _WORK )
|
||
{
|
||
CSocketContext* pSocketContext = m_pTcpConnection->GetSocketContext();
|
||
CDNTcpConnection* pTcpCon = m_pTcpConnection;
|
||
|
||
if( InterlockedCompareExchange( &pSocketContext->m_lActiveCount, CSocketContext::DeleteFlag, 0 ) == 0 )
|
||
{
|
||
bDelete = true;
|
||
pTcpCon->SetSocketContext(NULL, NULL);
|
||
m_pTcpConnection = NULL;
|
||
SAFE_DELETE(pTcpCon);
|
||
g_pIocpManager->ClearSocketContext(pSocketContext);
|
||
#if defined( PRE_FIX_SOCKETCONTEXT_DANGLINGPTR ) && defined( _WORK)
|
||
std::cout << "삭제삭제오예~~~~~" << std::endl;
|
||
#endif // #if defined( PRE_FIX_SOCKETCONTEXT_DANGLINGPTR ) && defined( _WORK)
|
||
break;
|
||
}
|
||
else
|
||
{
|
||
#if defined( _WORK)
|
||
std::cout << "댕글댕글댕글링~~~" << std::endl;
|
||
#else
|
||
g_Log.Log(LogType::_ERROR, L"[%d] GameServer Occur DanglingPointer!!!\r\n", g_Config.nManagedID );
|
||
#endif // #if defined( _WORK)
|
||
}
|
||
}
|
||
|
||
if( bDelete == false )
|
||
{
|
||
g_Log.Log(LogType::_ERROR, L"[%d] GameServer DanglingPointer Delete Fail!!!\r\n", g_Config.nManagedID );
|
||
}
|
||
#else
|
||
g_pIocpManager->ClearSocketContext(GetTcpConnection()->GetSocketContext());
|
||
GetTcpConnection()->SetSocketContext(NULL, NULL);
|
||
delete GetTcpConnection();
|
||
m_pTcpConnection = NULL;
|
||
#endif // #if defined( PRE_FIX_SOCKETCONTEXT_DANGLINGPTR )
|
||
}
|
||
|
||
SetSessionState(SESSION_STATE_DISCONNECTED);
|
||
|
||
m_pGameRoom->m_iPartMemberCnt--;
|
||
if(GetGameRoom()->GetPartyIndex() > 0)
|
||
{
|
||
GetGameRoom()->SortMemberIndex(GetPartyMemberIndex());
|
||
SetPartyMemberIndex(-1);
|
||
GetGameRoom()->SendRefreshParty(0, NULL);
|
||
}
|
||
|
||
g_Log.Log(LogType::_NORMAL, this, L"[ADBID:%u CDBID:%I64d SID:%u] CDNUserConnection::FinalUser\r\n", m_nAccountDBID, m_biCharacterDBID, m_nSessionID);
|
||
}
|
||
|
||
void CDNUserSession::InitVoice()
|
||
{
|
||
#ifdef _USE_VOICECHAT
|
||
if(GetGameRoom()->m_nVoiceChannelID[0] > 0)
|
||
JoinVoiceChannel(GetGameRoom()->m_nVoiceChannelID[0], GetIp(), NULL, 0, false, true);
|
||
#endif
|
||
}
|
||
|
||
void CDNUserSession::SendSeqLevel(BYTE cSeqLevel)
|
||
{
|
||
SendRoomSeqLevel(this, cSeqLevel);
|
||
}
|
||
|
||
void CDNUserSession::SendBackToVillage( bool bIsPartyOut, char cKickKind/*=-1*/, const int iMapIndex/*=-1*/ )
|
||
{
|
||
m_cKickKind = cKickKind;
|
||
if(m_cKickKind == 1)
|
||
{
|
||
for (int i = 0; i < PARTYKICKMAX; i++)
|
||
if(GetGameRoom()->GetPartyKickedAccountID(i) == 0)
|
||
GetGameRoom()->SetPartyKickedAccountID(i,GetAccountDBID());
|
||
}
|
||
|
||
int iLastVillageMapIndex = ( iMapIndex != -1 ) ? iMapIndex : m_UserData.Status.nLastVillageMapIndex;
|
||
if(GetLastSubVillageMapIndex() > 0)
|
||
iLastVillageMapIndex = GetLastSubVillageMapIndex();
|
||
|
||
if(bIsGMTrace())
|
||
{
|
||
//따라들어온 지엠이라면 무조건 그냥 나감
|
||
g_pMasterConnectionManager->SendRebirthVillageInfo(m_nWorldSetID, m_nAccountDBID, iLastVillageMapIndex );
|
||
return;
|
||
}
|
||
#if defined(PRE_WORLDCOMBINE_PARTY )
|
||
else if(GetGameRoom()->GetGameType() == REQINFO_TYPE_PARTY && GetGameRoom()->GetUserCountWithoutGM() == 1 && bIsPartyOut == false && !GetGameRoom()->bIsWorldCombineParty())
|
||
#else
|
||
else if(GetGameRoom()->GetGameType() == REQINFO_TYPE_PARTY && GetGameRoom()->GetUserCountWithoutGM() == 1 && bIsPartyOut == false)
|
||
#endif
|
||
{
|
||
//혼자이고 포기가 아니라면 파티 유지.
|
||
g_pMasterConnectionManager->SendRequestNextVillageInfo(m_nWorldSetID, iLastVillageMapIndex, -1, true, GetGameRoom());
|
||
#if defined(PRE_FIX_69108)
|
||
//랭킹 업데이트 처리
|
||
CDNGameRoom* pGameRoom = GetGameRoom();
|
||
if( pGameRoom )
|
||
{
|
||
CDnGameTask *pTask = (CDnGameTask*)pGameRoom->GetTaskMng()->GetTask("GameTask");
|
||
if( pTask && pTask->GetGameTaskType() == GameTaskType::DarkLair && CDnWorld::GetInstance(GetGameRoom()).GetMapType() == EWorldEnum::MapTypeDungeon)
|
||
{
|
||
GetGameRoom()->AddDungeonPlayTime( timeGetTime() - pTask->GetStageCreateTime() );
|
||
for( DWORD i=0; i<pTask->GetUserCount(); i++ ) {
|
||
CDNGameRoom::PartyStruct *pStruct = pTask->GetPartyData(i);
|
||
if( pStruct == NULL ) continue;
|
||
((CDNDLGameRoom*)GetGameRoom())->SetUpdateRankData( pStruct->pSession );
|
||
}
|
||
((CDNDLGameRoom*)GetGameRoom())->RequestRankQueryData();
|
||
}
|
||
}
|
||
#endif
|
||
return;
|
||
}
|
||
|
||
#if defined( PRE_ADD_58761 )
|
||
if(GetGameRoom()->GetDungeonGateID() > 0)
|
||
{
|
||
if (GetGameRoom()->GetDBConnection())
|
||
GetGameRoom()->GetDBConnection()->QueryAddNestGateClearLog( GetGameRoom()->GetDBThreadID(), GetGameRoom()->GetWorldSetID(), 0, GetGameRoom()->GetRoomLogIndex(), false, GetCharacterDBID(), GetUserJob(), GetLevel());
|
||
}
|
||
#endif //#if defined( PRE_ADD_58761 )
|
||
|
||
if( GetGameRoom() )
|
||
GetGameRoom()->DelLastPartyDungeonInfo( this );
|
||
|
||
if (g_pMasterConnectionManager->SendRebirthVillageInfo(m_nWorldSetID, m_nAccountDBID, iLastVillageMapIndex ))
|
||
SetOutedMember();
|
||
}
|
||
|
||
void CDNUserSession::SendPvPGameToPvPLobby()
|
||
{
|
||
if( g_pMasterConnectionManager )
|
||
{
|
||
bool bIsLadderRoom = false;
|
||
if( GetGameRoom() )
|
||
bIsLadderRoom = GetGameRoom()->bIsLadderRoom();
|
||
g_pMasterConnectionManager->SendPvPGameToPvPLobby( m_nWorldSetID, m_nAccountDBID, m_pGameRoom->GetPvPIndex(), GetLastVillageMapIndex(), bIsLadderRoom );
|
||
}
|
||
else
|
||
_DANGER_POINT();
|
||
}
|
||
|
||
void CDNUserSession::SendConnectedResult()
|
||
{
|
||
SendConnectedGameServer(this, m_nSessionID);
|
||
}
|
||
|
||
void CDNUserSession::SendUserInfo()
|
||
{
|
||
CheckInitializeSchedule();
|
||
|
||
#if defined (PRE_ADD_BESTFRIEND)
|
||
m_pBestFriend->CheckAndSendData();
|
||
#endif
|
||
//이동시 마다 칭호를 보내줘야함
|
||
SendAppellationList(m_UserData.Appellation.Appellation);
|
||
GetAppellation()->SendPeriodAppellationTime();
|
||
#if defined(PRE_ADD_REMOTE_QUEST)
|
||
ModifyCompleteQuest(); //선택되지 않은 일일퀘 마킹에 필요
|
||
#endif
|
||
SendGlyphExpireData(m_pItem->GetGlyphExpireDate());
|
||
#if defined(PRE_ADD_TALISMAN_SYSTEM)
|
||
SendTalismanExpireData(m_pItem->IsTalismanCashSlotEntend(), m_pItem->GetTalismanExpireDate());
|
||
#endif
|
||
|
||
//#if defined( PRE_ADD_GUILDREWARDITEM )
|
||
//#else // #if defined( PRE_ADD_GUILDREWARDITEM )
|
||
const TGuildUID GuildUID = GetGuildUID();
|
||
|
||
if(GuildUID.IsSet())
|
||
{
|
||
CDNGuildBase* pGuild = g_pGuildManager->At(GuildUID);
|
||
if (pGuild)
|
||
{
|
||
#if !defined( PRE_ADD_NODELETEGUILD )
|
||
CDetachAutoEx<CDNGuildBase> AutoDetach(pGuild);
|
||
if (pGuild->IsEnable())
|
||
{
|
||
#endif
|
||
TGuildRewardItem *RewardItemInfo;
|
||
RewardItemInfo = pGuild->GetGuildRewardItem();
|
||
SetGuildRewardItem(RewardItemInfo);
|
||
SendGuildRewardItem(RewardItemInfo);
|
||
#if !defined( PRE_ADD_NODELETEGUILD )
|
||
}
|
||
#endif
|
||
}
|
||
}
|
||
//#endif // #if defined( PRE_ADD_GUILDREWARDITEM )
|
||
|
||
//#if defined( PRE_ADD_TOTAL_LEVEL_SKILL )
|
||
// for(int i=0;i<TotalLevelSkill::Common::MAXSLOTCOUNT;i++)
|
||
// {
|
||
// if(g_pDataManager->bIsTotalLevelSkillCashSlot(i))
|
||
// m_pSession->SendTotalLevelSkillCashSlot(m_pSession->GetSessionID(), i, m_pSession->bIsTotalLevelSkillCashSlot(i), m_pSession->GetTotalLevelSkillCashSlot(i));
|
||
// }
|
||
//#endif
|
||
|
||
if(m_bTutorial){ // 튜토리얼로
|
||
#ifdef _PACKET_COMP
|
||
//if(m_pTcpConnection) m_pTcpConnection->SetPacketComp(true);
|
||
#endif
|
||
|
||
#ifdef _USE_VOICECHAT
|
||
SendVoiceChatInfo(g_Config.szPublicDolbyIp, g_Config.nControlPort, g_Config.nAudioPort, m_nAccountDBID);
|
||
#endif
|
||
SendEnter(this);
|
||
SendEquipList( m_pItem );
|
||
|
||
SendInvenList( m_pItem );
|
||
SendWarehouseList(m_UserData.Status.nWarehouseCoin, m_pItem);
|
||
#if defined(PRE_ADD_SERVER_WAREHOUSE)
|
||
SendServerWareHouseList(m_pItem);
|
||
SendServerWareHouseCashList(m_pItem);
|
||
#endif
|
||
SendSkill(m_UserData.Skill[DualSkill::Type::Primary].SkillList, DualSkill::Type::Primary);
|
||
SendSkill(m_UserData.Skill[DualSkill::Type::Secondary].SkillList, DualSkill::Type::Secondary);
|
||
SendSkillPageCount( GetItem()->GetSkillPageCount() );
|
||
SendQuickSlotList(m_UserData.Status.QuickSlot);
|
||
SendMissionList(m_UserData.Mission.nMissionScore, m_UserData.Mission.MissionGain, m_UserData.Mission.MissionAchieve, m_UserData.Mission.wLastMissionAchieve);
|
||
|
||
SendPvPData( m_UserData.PvP );
|
||
SendGlyphTimeInfo(m_UserData.Status.nGlyphDelayTime, m_UserData.Status.nGlyphRemainTime);
|
||
SendDailyMissionList( 0, m_UserData.Mission.DailyMission );
|
||
SendDailyMissionList( 1, m_UserData.Mission.WeeklyMission );
|
||
SendDailyMissionList( 2, m_UserData.Mission.GuildWarMission );
|
||
SendDailyMissionList( 4, m_UserData.Mission.GuildCommonMission );
|
||
SendDailyMissionList( 5, m_UserData.Mission.WeekendEventMission );
|
||
SendDailyMissionList( 6, m_UserData.Mission.WeekendRepeatMission );
|
||
#if defined(PRE_ADD_MONTHLY_MISSION)
|
||
SendDailyMissionList( 7, m_UserData.Mission.MonthlyMission );
|
||
#endif // #if defined(PRE_ADD_MONTHLY_MISSION)
|
||
SendKeySetting( &m_KeySetting );
|
||
SendPadSetting( &m_PadSetting );
|
||
SendNestClear(m_UserData.Status.NestClear);
|
||
#if defined( PRE_ADD_SECONDARY_SKILL )
|
||
if( m_pSecondarySkillRepository )
|
||
m_pSecondarySkillRepository->SendList();
|
||
#endif // #if defined( PRE_ADD_SECONDARY_SKILL )
|
||
|
||
if(m_pRestraint) m_pRestraint->SendRestraintList();
|
||
|
||
if( GetDBConnection() )
|
||
GetDBConnection()->QueryLoginCharacter( this );
|
||
SendGuildWarFestivalPoint();
|
||
SendPvPGhoulScores(&m_PvPTotalGhoulScores);
|
||
|
||
#if defined(_KR)
|
||
g_pMasterConnectionManager->SendPCBangResult(GetWorldSetID(), m_nAccountDBID);
|
||
#endif // _KR
|
||
}
|
||
#if defined(PRE_ADD_EQUIPLOCK)
|
||
SendLockItems(m_pItem);
|
||
#endif // #if defined(PRE_ADD_EQUIPLOCK)
|
||
}
|
||
|
||
bool CDNUserSession::LoadUserData(TASelectCharacter *pSelect)
|
||
{
|
||
bool bResult = CDNUserBase::LoadUserData(pSelect);
|
||
if( !bResult ) return false;
|
||
|
||
if(g_pMasterConnectionManager)
|
||
g_pMasterConnectionManager->SendLoadUserTempData(GetWorldSetID(), GetAccountDBID());
|
||
|
||
return true;
|
||
}
|
||
|
||
bool CDNUserSession::SaveUserData()
|
||
{
|
||
CDNUserBase::SaveUserData();
|
||
if( GetPlayerActor() )
|
||
GetPlayerActor()->SaveUserData(m_UserData);
|
||
return true;
|
||
}
|
||
|
||
void CDNUserSession::ChangeServerUserData()
|
||
{
|
||
if(m_UserData.Status.cClass <= 0) return; // 0으로 저장될 때가 있어서 일단 이렇게 -_-;
|
||
if(IsCertified() == false)
|
||
{
|
||
g_Log.Log(LogType::_ERROR, this, L"[ADBID:%u CDBID:%I64d SID:%u] CDNUserConnection::ChangeServerUserData IsCertified() == false!!\r\n", m_nAccountDBID, m_biCharacterDBID, m_nSessionID);
|
||
return;
|
||
}
|
||
|
||
m_pTimeEventSystem->SaveUserData( false );
|
||
SaveUserData();
|
||
|
||
CDNDBConnection *pDBCon = GetDBConnection();
|
||
if(!pDBCon){
|
||
g_Log.Log(LogType::_ERROR, this, L"[ADBID:%u CDBID:%I64d SID:%u] CDNUserConnection::ChangeServerUserData DBConnection NULL!!\r\n", m_nAccountDBID, m_biCharacterDBID, m_nSessionID);
|
||
return;
|
||
}
|
||
|
||
pDBCon->QueryUpdateUserData(QUERY_CHANGESERVERUSERDATA, this, &m_UserData, true );
|
||
pDBCon->QuerySaveItemLocationIndex(this);
|
||
#if defined(PRE_ADD_DOORS_PROJECT)
|
||
pDBCon->QuerySaveCharacterAbility(this);
|
||
#endif
|
||
#if defined(_KRAZ)
|
||
pDBCon->QueryActozUpdateCharacterInfo(this, ActozCommon::UpdateType::Sync);
|
||
#endif // #if defined(_KRAZ)
|
||
}
|
||
|
||
void CDNUserSession::LastUpdateUserData()
|
||
{
|
||
if(m_UserData.Status.cClass <= 0) return; // 0으로 저장될 때가 있어서 일단 이렇게 -_-;
|
||
if(!m_bLoadUserData) return;
|
||
|
||
m_pTimeEventSystem->SaveUserData( true );
|
||
|
||
CDNDBConnection *pDBCon = GetDBConnection();
|
||
if(!pDBCon){
|
||
g_Log.Log(LogType::_ERROR, this, L"[ADBID:%u CDBID:%I64d SID:%u] CDNUserConnection::LastUpdateCharacter DBConnection NULL!!\r\n", m_nAccountDBID, m_biCharacterDBID, m_nSessionID);
|
||
return;
|
||
}
|
||
|
||
pDBCon->QueryUpdateUserData(QUERY_LASTUPDATEUSERDATA, this, &m_UserData, false );
|
||
pDBCon->QuerySaveItemLocationIndex(this);
|
||
#if defined(PRE_ADD_DOORS_PROJECT)
|
||
pDBCon->QuerySaveCharacterAbility(this);
|
||
#endif
|
||
}
|
||
|
||
void CDNUserSession::ChangeStageUserData(int nAddPetExp/* = 0*/)
|
||
{
|
||
if(IsCertified() == false)
|
||
return;
|
||
|
||
if(m_UserData.Status.cClass <= 0) return; // 0으로 저장될 때가 있어서 일단 이렇게 -_-;
|
||
|
||
SaveUserData(); // 일단 먼저 세이브
|
||
|
||
std::vector<INT64> VecSerialList;
|
||
std::vector<USHORT> VecDurList;
|
||
VecSerialList.clear();
|
||
VecDurList.clear();
|
||
|
||
m_pItem->GetEquipItemDurability(VecSerialList, VecDurList);
|
||
m_pItem->GetInventoryItemDurability(VecSerialList, VecDurList);
|
||
|
||
int nDeathCount = 0;
|
||
BYTE cDifficult = 0;
|
||
CDnPlayerActor *pPlayer = GetPlayerActor();
|
||
if( pPlayer )
|
||
{
|
||
nDeathCount = pPlayer->GetStageDeathCount();
|
||
pPlayer->ClearStageDeathCount(); // 저장하고 초기화
|
||
}
|
||
CDNGameRoom *pGameRoom = GetGameRoom();
|
||
if( pGameRoom )
|
||
cDifficult = pGameRoom->m_StageDifficulty+1;
|
||
|
||
// PCBangRebirthCoin을 GetPCBangRebirthCoin()으로 안쓰는 이유 -> 피씨방이든 아니든 고정값을 보내주기위해 (함수호출하면 피씨방이 아닐때 0으로 바뀜)
|
||
m_pDBCon->QueryChangeStageUserData(this, m_UserData.Status.cPCBangRebirthCoin, VecSerialList, VecDurList, nDeathCount, cDifficult, GetPickUpCoin(), m_pItem->GetPetBodySerial(), nAddPetExp);
|
||
|
||
#if defined(_KRAZ)
|
||
m_pDBCon->QueryActozUpdateCharacterInfo(this, ActozCommon::UpdateType::Sync);
|
||
#endif // #if defined(_KRAZ)
|
||
|
||
// Reset
|
||
m_biPickUpCoin = 0;
|
||
}
|
||
|
||
void CDNUserSession::SetNextVillageData(const char * pIP, USHORT nPort, int nMapIndex, int nNextMapIndex, char cNextGateNo)
|
||
{
|
||
GetGameRoom()->DelLastPartyDungeonInfo( this );
|
||
|
||
if(pIP != NULL && nPort > 0)
|
||
{
|
||
_strcpy( m_szNextVillageIP, _countof(m_szNextVillageIP), pIP, (int)strlen(pIP) );
|
||
m_nNextVillagePort = nPort;
|
||
|
||
m_biCertifyingKey = g_pAuthManager->GetCertifyingKey();
|
||
DN_ASSERT(0 != m_biCertifyingKey, "Invalid!"); // 인증키가 0 이 생성되면 않됨 !!!(없음 의미)
|
||
|
||
SetSessionState(SESSION_STATE_READY_TO_VILLAGE);
|
||
|
||
g_pAuthManager->QueryStoreAuth(SERVERTYPE_GAME, this);
|
||
}
|
||
|
||
if(cNextGateNo > 0){ // 제대로 게이트 앞에 섰을때만 저장한다.(Random일경우는 gateidx가 -1이므로 저장하지않는다)
|
||
if(g_pDataManager->GetMapType( nNextMapIndex ) == GlobalEnum::eMapTypeEnum::MAP_VILLAGE){
|
||
SetMapIndex(nMapIndex);
|
||
|
||
if(nNextMapIndex > 0){
|
||
bool bUpdate = true;
|
||
switch( g_pDataManager->GetMapSubType( nNextMapIndex ) )
|
||
{
|
||
case GlobalEnum::eMapSubTypeEnum::MAPSUB_PVPVILLAGE:
|
||
case GlobalEnum::eMapSubTypeEnum::MAPSUB_PVPLOBBY:
|
||
{
|
||
bUpdate = false;
|
||
break;
|
||
}
|
||
}
|
||
if( bUpdate )
|
||
SetLastMapIndex(nNextMapIndex);
|
||
}
|
||
}
|
||
else
|
||
SetMapIndex(nNextMapIndex);
|
||
|
||
m_UserData.Status.cLastVillageGateNo = cNextGateNo;
|
||
}
|
||
|
||
ChangeStageUserData();
|
||
|
||
m_bCharOutLog = false;
|
||
}
|
||
|
||
void CDNUserSession::SetMapIndex(int nMapIndex)
|
||
{
|
||
if(m_bTutorial) return; // 튜토리얼은 저장하면 안됨
|
||
|
||
CDNUserBase::SetMapIndex(nMapIndex);
|
||
|
||
GetDBConnection()->QueryMapInfo(this); // db 저장 100128
|
||
}
|
||
|
||
void CDNUserSession::SetFatigue(int nFatigue, int nWeeklyFatigue, int nPCBangFatigue, int nEventFatigue, int nVIPFatigue, bool bDBSave/* = true*/)
|
||
{
|
||
CDNUserBase::SetFatigue(nFatigue, nWeeklyFatigue, nPCBangFatigue, nEventFatigue, nVIPFatigue, bDBSave);
|
||
|
||
for(DWORD i = 0; i < m_pGameRoom->GetUserCount(); i++){
|
||
CDNGameRoom::PartyStruct *pStruct = m_pGameRoom->GetPartyData(i);
|
||
if(pStruct == NULL) continue;
|
||
pStruct->pSession->SendFatigue(GetSessionID(), nFatigue, nWeeklyFatigue, nPCBangFatigue, nEventFatigue, nVIPFatigue);
|
||
}
|
||
}
|
||
|
||
void CDNUserSession::DecreaseFatigue(int nGap)
|
||
{
|
||
#if defined(PRE_ADD_WORLD_EVENT) // 이건 없어 집니다.
|
||
#else
|
||
// PvP 피로도 모소는 이벤트랑 상관없이 까자.
|
||
if( !GetGameRoom()->bIsPvPRoom() )
|
||
{
|
||
TEvent * pEvent = GetGameRoom()->GetApplyEvent(_EVENT_1_FATIGUE);
|
||
if(pEvent) return; // 이벤트면 안깎고 나감
|
||
}
|
||
#endif //#if defined(PRE_ADD_WORLD_EVENT)
|
||
|
||
// GM난입 피로도 감소 없음~!
|
||
if( bIsGMTrace() )
|
||
return;
|
||
// 옵져버 피로도 감소 없음~!
|
||
if( m_hActor && m_hActor->bIsObserver() )
|
||
return;
|
||
|
||
CDNUserBase::DecreaseFatigue(nGap);
|
||
|
||
int nMax = g_pDataManager->GetFatigue(GetUserJob(), m_UserData.Status.cLevel);
|
||
for(DWORD i = 0; i < m_pGameRoom->GetUserCount(); i++){
|
||
CDNGameRoom::PartyStruct *pStruct = m_pGameRoom->GetPartyData(i);
|
||
if(pStruct == NULL) continue;
|
||
pStruct->pSession->SendFatigue(GetSessionID(), GetFatigue(), GetWeeklyFatigue(), GetPCBangFatigue(), GetEventFatigue(), GetVIPFatigue());
|
||
}
|
||
}
|
||
|
||
void CDNUserSession::IncreaseFatigue(int nGap)
|
||
{
|
||
if(nGap <= 0) return;
|
||
|
||
CDNUserBase::IncreaseFatigue(nGap);
|
||
|
||
for(DWORD i = 0; i < m_pGameRoom->GetUserCount(); i++){
|
||
CDNGameRoom::PartyStruct *pStruct = m_pGameRoom->GetPartyData(i);
|
||
if(pStruct == NULL) continue;
|
||
pStruct->pSession->SendFatigue(GetSessionID(), GetFatigue(), GetWeeklyFatigue(), GetPCBangFatigue(), GetEventFatigue(), GetVIPFatigue());
|
||
}
|
||
}
|
||
|
||
void CDNUserSession::SetDefaultMaxFatigue(bool bSend)
|
||
{
|
||
CDNUserBase::SetDefaultMaxFatigue(bSend);
|
||
|
||
if( bSend ) {
|
||
for(DWORD i = 0; i < m_pGameRoom->GetUserCount(); i++){
|
||
CDNGameRoom::PartyStruct *pStruct = m_pGameRoom->GetPartyData(i);
|
||
if(pStruct == NULL) continue;
|
||
if(pStruct->pSession != this)
|
||
pStruct->pSession->SendFatigue(GetSessionID(), GetFatigue(), GetWeeklyFatigue(), GetPCBangFatigue(), GetEventFatigue(), GetVIPFatigue());
|
||
}
|
||
}
|
||
}
|
||
|
||
void CDNUserSession::SetDefaultMaxWeeklyFatigue(bool bSend)
|
||
{
|
||
CDNUserBase::SetDefaultMaxWeeklyFatigue(bSend);
|
||
|
||
if( bSend ) {
|
||
for(DWORD i = 0; i < m_pGameRoom->GetUserCount(); i++){
|
||
CDNGameRoom::PartyStruct *pStruct = m_pGameRoom->GetPartyData(i);
|
||
if(pStruct == NULL) continue;
|
||
if(pStruct->pSession != this)
|
||
pStruct->pSession->SendFatigue(GetSessionID(), GetFatigue(), GetWeeklyFatigue(), GetPCBangFatigue(), GetEventFatigue(), GetVIPFatigue());
|
||
}
|
||
}
|
||
}
|
||
|
||
void CDNUserSession::SetDefaultMaxRebirthCoin(bool bSend)
|
||
{
|
||
CDNUserBase::SetDefaultMaxRebirthCoin(bSend);
|
||
|
||
if(bSend)
|
||
{
|
||
if( GetPlayerActor() && GetPlayerActor()->GetPartyData() )
|
||
SendRebirthCoin(ERROR_NONE, GetPlayerActor()->GetPartyData()->nUsableRebirthCoin, _REBIRTH_SELF, GetSessionID());
|
||
}
|
||
}
|
||
|
||
CDnPlayerActor* CDNUserSession::GetPlayerActor()
|
||
{
|
||
if( !m_hActor )
|
||
return NULL;
|
||
|
||
CDnPlayerActor *pPlayer = static_cast<CDnPlayerActor *>(m_hActor.GetPointer());
|
||
return pPlayer;
|
||
}
|
||
|
||
void CDNUserSession::AddPacketQueue( const DWORD dwUniqueID, const BYTE cSubCmd, const BYTE *pBuffer, const int nSize, const int nPrior )
|
||
{
|
||
if(( sizeof(DWORD) + sizeof(BYTE) + sizeof(WORD) + nSize ) >= PACKET_QUEUE_SIZE ) {
|
||
_ASSERT(0);
|
||
return;
|
||
}
|
||
if( m_nPacketQueueOffset[nPrior] +( sizeof(DWORD) + sizeof(BYTE) + sizeof(WORD) + nSize ) >= PACKET_QUEUE_SIZE ) {
|
||
FlushPacketQueue( nPrior );
|
||
}
|
||
CheckFlushQueue( nPrior, dwUniqueID, cSubCmd );
|
||
|
||
memcpy( m_pPacketQueueBuffer[nPrior] + m_nPacketQueueOffset[nPrior], &dwUniqueID, sizeof(DWORD) ); m_nPacketQueueOffset[nPrior] += sizeof(DWORD);
|
||
memcpy( m_pPacketQueueBuffer[nPrior] + m_nPacketQueueOffset[nPrior], &cSubCmd, sizeof(BYTE) ); m_nPacketQueueOffset[nPrior] += sizeof(BYTE);
|
||
memcpy( m_pPacketQueueBuffer[nPrior] + m_nPacketQueueOffset[nPrior], &nSize, sizeof(WORD) ); m_nPacketQueueOffset[nPrior] += sizeof(WORD);
|
||
memcpy( m_pPacketQueueBuffer[nPrior] + m_nPacketQueueOffset[nPrior], pBuffer, nSize ); m_nPacketQueueOffset[nPrior] += nSize;
|
||
|
||
#ifdef PRE_ADD_PACKETSIZE_CHECKER
|
||
if (cSubCmd < (BYTE)m_vActorSendInfo.size())
|
||
{
|
||
m_vActorSendInfo[cSubCmd].nSendCount++;
|
||
m_vActorSendInfo[cSubCmd].nSendSize += nSize;
|
||
}
|
||
/*int cnt = m_nSendActorDebugInfoCount++&31;
|
||
m_SendActorDebugInfo[cnt]._dwUniqueID = dwUniqueID;
|
||
m_SendActorDebugInfo[cnt]._ActorSubCmd = cSubCmd;
|
||
m_SendActorDebugInfo[cnt]._PacketBroadFlag = bBroad ? 1 : 0;*/
|
||
#endif //#ifdef PRE_ADD_PACKETSIZE_CHECKER
|
||
|
||
m_nPacketQueueCount[nPrior]++;
|
||
m_dwVecPacketQueueUniqueList[nPrior].push_back( dwUniqueID );
|
||
}
|
||
|
||
void CDNUserSession::CheckFlushQueue( int nPrior, DWORD dwUniqueID, BYTE cSubCmd )
|
||
{
|
||
bool bCheckFlush = true;
|
||
switch( cSubCmd ) {
|
||
case eActor::SC_CP:
|
||
bCheckFlush = false;
|
||
break;
|
||
default: break;
|
||
}
|
||
for( int i=0; i<3; i++ ) {
|
||
if( i == nPrior ) continue;
|
||
if( std::find( m_dwVecPacketQueueUniqueList[i].begin(), m_dwVecPacketQueueUniqueList[i].end(), dwUniqueID ) != m_dwVecPacketQueueUniqueList[i].end() ) {
|
||
FlushPacketQueue( i );
|
||
}
|
||
}
|
||
}
|
||
|
||
void CDNUserSession::FlushPacketQueue( int nPrior )
|
||
{
|
||
if( nPrior == -1 ) {
|
||
for( int i=0; i<3; i++ ) FlushPacketQueue(i);
|
||
return;
|
||
}
|
||
|
||
if( m_nPacketQueueCount[nPrior] == 0 ) return;
|
||
SendGameActorBundleMsg( this, m_nPacketQueueCount[nPrior], m_pPacketQueueBuffer[nPrior], m_nPacketQueueOffset[nPrior], nPrior );
|
||
|
||
m_nPacketQueueOffset[nPrior] = 0;
|
||
m_nPacketQueueCount[nPrior] = 0;
|
||
m_dwVecPacketQueueUniqueList[nPrior].clear();
|
||
}
|
||
|
||
void CDNUserSession::FlushStoredPacket()
|
||
{
|
||
ScopeLock<CSyncLock> Lock( m_StoreSync );
|
||
|
||
DNVector(_STORE_PACKET)::iterator ii;
|
||
for(ii = m_pStoredPacketList.begin(); ii != m_pStoredPacketList.end(); ii++)
|
||
{
|
||
SendPacket((*ii).iMainCmd, (*ii).iSubCmd, (*ii).pMsg, (*ii).iSize, _RELIABLE);
|
||
CLfhHeap::GetInstance()->_DeAlloc((*ii).pMsg);
|
||
}
|
||
m_pStoredPacketList.clear();
|
||
}
|
||
|
||
void CDNUserSession::StorePacket(int iMainCmd, int iSubCmd, const char * pData, int nLen)
|
||
{
|
||
ScopeLock<CSyncLock> Lock( m_StoreSync );
|
||
|
||
_STORE_PACKET Store;
|
||
Store.iMainCmd = iMainCmd;
|
||
Store.iSubCmd = iSubCmd;
|
||
Store.iSize = nLen;
|
||
Store.pMsg = static_cast<char*>(CLfhHeap::GetInstance()->_Alloc(nLen));
|
||
memcpy(Store.pMsg, pData, nLen);
|
||
|
||
m_pStoredPacketList.push_back(Store);
|
||
}
|
||
|
||
CDNUserSession* CDNUserSession::FindUserSession(UINT nSessionID)
|
||
{
|
||
return m_pGameRoom->GetUserSession(nSessionID);
|
||
}
|
||
|
||
#if !defined(PRE_DELETE_DUNGEONCLEAR)
|
||
bool CDNUserSession::IsNeedDungeonLevelSave( int nMapTableID )
|
||
{
|
||
DNTableFileFormat *pMapSox = GetDNTable( CDnTableDB::TMAP );
|
||
DNTableFileFormat *pEnterDungeonSox = GetDNTable( CDnTableDB::TDUNGEONENTER );
|
||
|
||
if( !pMapSox->IsExistItem( nMapTableID ) ) return false;
|
||
int nDungeonEnterTableID = pMapSox->GetFieldFromLablePtr( nMapTableID, "_EnterConditionTableID" )->GetInteger();
|
||
if( nDungeonEnterTableID < 1 || !pEnterDungeonSox->IsExistItem( nDungeonEnterTableID ) ) return false;
|
||
|
||
int nLevel = pEnterDungeonSox->GetFieldFromLablePtr( nDungeonEnterTableID, "_LvlMin" )->GetInteger();
|
||
if( nLevel < 1 || GetLevel() - nLevel >= 30 ) return false;
|
||
|
||
return true;
|
||
}
|
||
|
||
bool CDNUserSession::CheckDungeonEnterLevel( int nMapTableID )
|
||
{
|
||
if( !IsNeedDungeonLevelSave( nMapTableID ) ) return false;
|
||
return CDNUserBase::CheckDungeonEnterLevel(nMapTableID);
|
||
}
|
||
|
||
void CDNUserSession::CalcDungeonEnterLevel(int nMapTableID, char &cOpenHard, char &cOpenVeryHard)
|
||
{
|
||
CDNUserBase::CalcDungeonEnterLevel( nMapTableID, cOpenHard, cOpenVeryHard );
|
||
if( GetMaxLevelCharacterCount() > 0 ) {
|
||
cOpenHard = cOpenVeryHard = true;
|
||
}
|
||
}
|
||
|
||
bool CDNUserSession::UpdateDungenEnterLevel( int nCurrentStageConstructionLevel, int nRank )
|
||
{
|
||
CDnGameTask *pTask = (CDnGameTask *)m_pGameRoom->GetTaskMng()->GetTask( "GameTask" );
|
||
if( !pTask ) return false;
|
||
|
||
int nEnterMapTableID = pTask->GetEnterMapTableID();
|
||
if( nEnterMapTableID < 1 ) return false;
|
||
int nDungeonEnterTableID = pTask->GetDungeonEnterTableID();
|
||
if( nDungeonEnterTableID < 1 ) return false;
|
||
if( !IsNeedDungeonLevelSave( nEnterMapTableID ) ) return false;
|
||
|
||
DNTableFileFormat *pSox = GetDNTable( CDnTableDB::TDUNGEONENTER );
|
||
static char *szRankStr[] = { "_Hard", "_VeryHard" };
|
||
char szLabel[32];
|
||
|
||
sprintf_s( szLabel, "%sOpenRank", szRankStr[nCurrentStageConstructionLevel-1] );
|
||
int nNeedRank = pSox->GetFieldFromLablePtr( nDungeonEnterTableID, szLabel )->GetInteger();
|
||
if( nRank > nNeedRank ) return false;
|
||
|
||
int nSlotIndex = GetDungeonLevelIndex( nEnterMapTableID, NULL );
|
||
if( nSlotIndex == -1 ) return false;
|
||
|
||
if( nCurrentStageConstructionLevel - 1 != GetDungeonClearType(nSlotIndex) ) return false;
|
||
|
||
SetDungeonClearType(nSlotIndex, nCurrentStageConstructionLevel); // db저장 포함
|
||
|
||
SendGameOpenDungeonLevel( this, nEnterMapTableID, nCurrentStageConstructionLevel + 1 );
|
||
|
||
return true;
|
||
}
|
||
|
||
void CDNUserSession::RefreshDungeonEnterLevel()
|
||
{
|
||
for( int i=0; i<DUNGEONCLEARMAX; i++ ) {
|
||
int nMapIndex = GetDungeonClearMapIndex(i);
|
||
if( nMapIndex < 1 ) continue;
|
||
|
||
if( !IsNeedDungeonLevelSave( nMapIndex ) ) {
|
||
SetDungeonClear(i, 0, 0); // db저장?
|
||
}
|
||
}
|
||
}
|
||
#endif // #if !defined(PRE_DELETE_DUNGEONCLEAR)
|
||
|
||
void CDNUserSession::CopyDefaultParts( int* pDest )
|
||
{
|
||
*pDest = GetDefaultBody();
|
||
*(pDest+1) = GetDefaultLeg();
|
||
*(pDest+2) = GetDefaultHand();
|
||
*(pDest+3) = GetDefaultFoot();
|
||
}
|
||
|
||
void CDNUserSession::SendPvPModeStartTick( const UINT uiStartTick )
|
||
{
|
||
if( m_iState != SESSION_STATE_GAME_PLAY )
|
||
{
|
||
_DANGER_POINT();
|
||
return;
|
||
}
|
||
|
||
if( m_hActor )
|
||
m_hActor->ResetActor();
|
||
|
||
SCPVP_MODE_STARTTICK TxPacket;
|
||
memset( &TxPacket, 0, sizeof(TxPacket) );
|
||
|
||
TxPacket.uiStartTick = uiStartTick;
|
||
TxPacket.uiCurTick = timeGetTime();
|
||
|
||
AddSendData( SC_PVP, ePvP::SC_MODE_STARTTICK, reinterpret_cast<char*>(&TxPacket), sizeof(TxPacket) );
|
||
}
|
||
|
||
void CDNUserSession::SendPvPModeFinish( const CPvPGameMode* pPvPMode )
|
||
{
|
||
SCPVP_FINISH_PVPMODE TxPacket;
|
||
memset( &TxPacket, 0, sizeof(TxPacket) );
|
||
|
||
TxPacket.uiWinTeam = pPvPMode->GetWinTeam();
|
||
TxPacket.Reason = pPvPMode->GetFinishReason();
|
||
#if defined(PRE_ADD_PVP_TOURNAMENT)
|
||
TxPacket.uiWinSessionID = pPvPMode->GetLastWinSessionID();
|
||
#endif
|
||
pPvPMode->GetGameModeScore( TxPacket.uiATeamScore, TxPacket.uiBTeamScore );
|
||
|
||
AddSendData( SC_PVP, ePvP::SC_FINISH_PVPMODE, reinterpret_cast<char*>(&TxPacket), sizeof(TxPacket) );
|
||
}
|
||
|
||
void CDNUserSession::SendPvPRoundStart()
|
||
{
|
||
AddSendData( SC_PVP, ePvP::SC_START_PVPROUND, NULL, 0 );
|
||
}
|
||
|
||
#if defined(PRE_ADD_PVP_TOURNAMENT)
|
||
void CDNUserSession::SendPvPRoundFinish( const UINT uiWinTeam, PvPCommon::FinishReason::eCode Reason, const CPvPGameMode* pPvPMode, const UINT uiWInSessionID, const char cTournamentStep )
|
||
#else
|
||
void CDNUserSession::SendPvPRoundFinish( const UINT uiWinTeam, PvPCommon::FinishReason::eCode Reason, const CPvPGameMode* pPvPMode )
|
||
#endif
|
||
{
|
||
SCPVP_FINISH_PVPROUND TxPacket;
|
||
memset( &TxPacket, 0, sizeof(TxPacket) );
|
||
|
||
TxPacket.uiWinTeam = uiWinTeam;
|
||
TxPacket.Reason = Reason;
|
||
#if defined(PRE_ADD_PVP_TOURNAMENT)
|
||
TxPacket.uiWinSessionID = uiWInSessionID;
|
||
TxPacket.cTournamentStep = cTournamentStep;
|
||
#endif //#if defined(PRE_ADD_PVP_TOURNAMENT)
|
||
pPvPMode->GetGameModeScore( TxPacket.uiATeamScore, TxPacket.uiBTeamScore );
|
||
|
||
AddSendData( SC_PVP, ePvP::SC_FINISH_PVPROUND, reinterpret_cast<char*>(&TxPacket), sizeof(TxPacket) );
|
||
}
|
||
|
||
void CDNUserSession::SendSuccessBreakInto( const UINT uiSessionID )
|
||
{
|
||
SCPVP_SUCCESSBREAKINTO TxPacket;
|
||
memset( &TxPacket, 0, sizeof(TxPacket) );
|
||
|
||
TxPacket.uiSessionID = uiSessionID;
|
||
|
||
AddSendData( SC_PVP, ePvP::SC_BREAKINTO_SUCCESS, reinterpret_cast<char*>(&TxPacket), sizeof(TxPacket) );
|
||
}
|
||
void CDNUserSession::SendPvPAddPoint( UINT uiSessionID, const UINT uiScoreType, const UINT uiAddPoint )
|
||
{
|
||
SCPVP_ADDPOINT TxPacket;
|
||
memset( &TxPacket, 0, sizeof(TxPacket) );
|
||
|
||
TxPacket.uiSessionID = uiSessionID;
|
||
TxPacket.uiScoreType = uiScoreType;
|
||
TxPacket.uiAddPoint = uiAddPoint;
|
||
|
||
AddSendData( SC_PVP, ePvP::SC_ADDPOINT, reinterpret_cast<char*>(&TxPacket), sizeof(TxPacket) );
|
||
}
|
||
|
||
void CDNUserSession::SendPvPSelectCaptain( UINT uiSessionID, WCHAR* wszName )
|
||
{
|
||
SCPVP_SELECTCAPTAIN TxPacket;
|
||
memset( &TxPacket, 0, sizeof(TxPacket) );
|
||
|
||
TxPacket.uiSessionID = uiSessionID;
|
||
|
||
AddSendData( SC_PVP, ePvP::SC_SELECTCAPTAIN, reinterpret_cast<char*>(&TxPacket), sizeof(TxPacket) );
|
||
|
||
#if !defined( _FINAL_BUILD )
|
||
WCHAR wszChat[MAX_PATH];
|
||
wsprintf( wszChat, L"%s 님이 대장입니다.", wszName );
|
||
SendChat( CHATTYPE_TEAMCHAT, static_cast<int>(wcslen(wszChat)), L"", wszChat );
|
||
#endif // #if defined( _FINAL_BUILD )
|
||
}
|
||
|
||
void CDNUserSession::SendPvPSelectZombie( std::map<DWORD,DnActorHandle>& mZombie )
|
||
{
|
||
SCPVP_SELECTZOMBIE TxPacket;
|
||
memset( &TxPacket, 0, sizeof(TxPacket) );
|
||
|
||
if( _countof(TxPacket.Zombies) < mZombie.size() )
|
||
return;
|
||
|
||
for( std::map<DWORD,DnActorHandle>::iterator itor=mZombie.begin() ; itor!=mZombie.end() ; ++itor )
|
||
{
|
||
TxPacket.Zombies[TxPacket.cCount].uiSessionID = (*itor).second->GetSessionID();
|
||
TxPacket.Zombies[TxPacket.cCount].nMonsterMutationTableID = (*itor).second->GetMonsterMutationTableID();
|
||
TxPacket.Zombies[TxPacket.cCount].bZombie = true;
|
||
TxPacket.Zombies[TxPacket.cCount].iScale = static_cast<int>((*itor).second->GetScale()->x*100);
|
||
++TxPacket.cCount;
|
||
|
||
#if !defined( _FINAL_BUILD )
|
||
WCHAR wszChat[MAX_PATH];
|
||
wsprintf( wszChat, L"%s 님이 좀비입니다.", (*itor).second->GetName() );
|
||
SendChat( CHATTYPE_TEAMCHAT, static_cast<int>(wcslen(wszChat)), L"", wszChat );
|
||
#endif // #if defined( _FINAL_BUILD )
|
||
}
|
||
|
||
int iSize = sizeof(TxPacket)-sizeof(TxPacket.Zombies)+(TxPacket.cCount*sizeof(TZombieInfo));
|
||
AddSendData( SC_PVP, ePvP::SC_SELECTZOMBIE, reinterpret_cast<char*>(&TxPacket), iSize );
|
||
}
|
||
|
||
void CDNUserSession::SendPvPSelectZombie( DnActorHandle hActor, int nTableID, bool bZombie, bool bRemoveStateBlow, int iScale )
|
||
{
|
||
SCPVP_SELECTZOMBIE TxPacket;
|
||
memset( &TxPacket, 0, sizeof(TxPacket) );
|
||
|
||
TxPacket.Zombies[TxPacket.cCount].uiSessionID = hActor->GetSessionID();
|
||
TxPacket.Zombies[TxPacket.cCount].nMonsterMutationTableID = nTableID;
|
||
TxPacket.Zombies[TxPacket.cCount].bZombie = bZombie;
|
||
TxPacket.Zombies[TxPacket.cCount].bRemoveStateBlow = bRemoveStateBlow;
|
||
TxPacket.Zombies[TxPacket.cCount].iScale = iScale;
|
||
++TxPacket.cCount;
|
||
|
||
#if !defined( _FINAL_BUILD )
|
||
if( bZombie )
|
||
{
|
||
WCHAR wszChat[MAX_PATH];
|
||
wsprintf( wszChat, L"%s 님이 좀비입니다.", hActor->GetName() );
|
||
SendChat( CHATTYPE_TEAMCHAT, static_cast<int>(wcslen(wszChat)), L"", wszChat );
|
||
}
|
||
#endif // #if defined( _FINAL_BUILD )
|
||
|
||
int iSize = sizeof(TxPacket)-sizeof(TxPacket.Zombies)+(TxPacket.cCount*sizeof(TZombieInfo));
|
||
AddSendData( SC_PVP, ePvP::SC_SELECTZOMBIE, reinterpret_cast<char*>(&TxPacket), iSize );
|
||
}
|
||
|
||
#if defined(PRE_MOD_PVP_LADDER_XP)
|
||
void CDNUserSession::UpdatePvPLevel()
|
||
{
|
||
TPvPGroup* pPvPData = GetPvPData();
|
||
if( !pPvPData ) return;
|
||
|
||
// PvP_Level
|
||
for( UINT i=pPvPData->cLevel ; i<PvPCommon::Common::MaxRank ; ++i )
|
||
{
|
||
const TPvPRankTable* pPvPRankTable = g_pDataManager->GetPvPRankTable( i );
|
||
if( !pPvPRankTable )
|
||
{
|
||
_DANGER_POINT();
|
||
break;
|
||
}
|
||
|
||
#ifdef PRE_MOD_PVPRANK
|
||
if (pPvPRankTable->cType != PvPCommon::RankTable::ExpValue)
|
||
continue;
|
||
|
||
if( pPvPData->uiXP >= pPvPRankTable->uiXP )
|
||
#if defined(PRE_ADD_PVPLEVEL_MISSION)
|
||
SetPvPLevel(static_cast<BYTE>(i+1));
|
||
#else
|
||
pPvPData->cLevel = static_cast<BYTE>(i+1);
|
||
#endif
|
||
else
|
||
break;
|
||
#else //#ifdef PRE_MOD_PVPRANK
|
||
if( pPvPData->uiXP >= pPvPRankTable->uiXP )
|
||
#if defined(PRE_ADD_PVPLEVEL_MISSION)
|
||
SetPvPLevel(static_cast<BYTE>(i+1));
|
||
#else
|
||
pPvPData->cLevel = static_cast<BYTE>(i+1);
|
||
#endif
|
||
else
|
||
break;
|
||
#endif //#ifdef PRE_MOD_PVPRANK
|
||
}
|
||
}
|
||
#endif
|
||
|
||
void CDNUserSession::SetHide(bool bHide)
|
||
{
|
||
m_bHide = bHide;
|
||
|
||
for(DWORD i = 0; i < m_pGameRoom->GetUserCount(); i++){
|
||
CDNGameRoom::PartyStruct *pStruct = m_pGameRoom->GetPartyData(i);
|
||
if(pStruct == NULL) continue;
|
||
pStruct->pSession->SendHide(m_nSessionID, bHide);
|
||
}
|
||
}
|
||
|
||
// Guild
|
||
void CDNUserSession::RefreshGuildSelfView()
|
||
{
|
||
for(DWORD i = 0; i < m_pGameRoom->GetUserCount(); i++) {
|
||
CDNGameRoom::PartyStruct *pStruct = m_pGameRoom->GetPartyData(i);
|
||
if(NULL == pStruct) {
|
||
continue;
|
||
}
|
||
pStruct->pSession->SendGuildSelfView(GetSessionID(), m_GuildSelfView);
|
||
}
|
||
}
|
||
|
||
int CDNUserSession::CmdAbandonStage( const bool bDecreaseDurability, bool bPartyOut, bool bIntenedDisconnect, const int iMapIndex/*=-1*/ )
|
||
{
|
||
if(m_iState != SESSION_STATE_GAME_PLAY || GetGameRoom()->GetRoomState() != _GAME_STATE_PLAY)
|
||
return ERROR_GENERIC_INVALIDREQUEST;
|
||
|
||
if( m_pGameRoom && m_pGameRoom->bIsPvPRoom() )
|
||
{
|
||
_DANGER_POINT();
|
||
return ERROR_GENERIC_INVALIDREQUEST;
|
||
}
|
||
|
||
CDNGameRoom::PartyStruct * pStruct = GetGameRoom()->GetPartyData(this);
|
||
if(pStruct)
|
||
{
|
||
if(pStruct->nEnteredGateIndex != -1)
|
||
{
|
||
_DANGER_POINT();
|
||
return ERROR_GENERIC_INVALIDREQUEST;
|
||
}
|
||
}
|
||
|
||
DnActorHandle hActor = GetActorHandle();
|
||
if( hActor )
|
||
{
|
||
CDnPlayerActor *pPlayer = static_cast<CDnPlayerActor *>(hActor.GetPointer());
|
||
if(pPlayer)
|
||
{
|
||
if( bDecreaseDurability )
|
||
{
|
||
//던전에서는 해주고
|
||
if(m_pGameRoom->GetWorld()->GetMapType() == EWorldEnum::MapTypeEnum::MapTypeDungeon)
|
||
{
|
||
// 스테이지 포기 페널티 먹여야 해요 내구도 감소
|
||
pPlayer->OnStageGiveUp();
|
||
pPlayer->CmdRemoveStateEffect(STATE_BLOW::BLOW_099);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if( bIntenedDisconnect == false )
|
||
SendBackToVillage( bPartyOut, -1, iMapIndex );
|
||
m_bStageAbortLog = false;
|
||
|
||
return ERROR_NONE;
|
||
}
|
||
|
||
void CDNUserSession::SetUserJob(BYTE cJob)
|
||
{
|
||
|
||
CDNUserBase::SetUserJob( cJob );
|
||
|
||
DnActorHandle hActor = GetActorHandle();
|
||
if( hActor )
|
||
{
|
||
CDnPlayerActor *pPlayer = static_cast<CDnPlayerActor *>(hActor.GetPointer());
|
||
pPlayer->CmdChangeJob( cJob );
|
||
}
|
||
|
||
for(DWORD i = 0; i < m_pGameRoom->GetUserCount(); i++){
|
||
CDNGameRoom::PartyStruct *pStruct = m_pGameRoom->GetPartyData(i);
|
||
if(pStruct == NULL) continue;
|
||
if( pStruct->pSession == this ) continue;
|
||
|
||
pStruct->pSession->SendChangeJob( m_nSessionID, cJob );
|
||
}
|
||
}
|
||
|
||
void CDNUserSession::BroadcastingEffect(char cType, char cState)
|
||
{
|
||
for(DWORD i = 0; i < m_pGameRoom->GetUserCount(); i++){
|
||
CDNGameRoom::PartyStruct *pStruct = m_pGameRoom->GetPartyData(i);
|
||
if(pStruct == NULL) continue;
|
||
if( pStruct->pSession->GetState() != SESSION_STATE_GAME_PLAY )
|
||
continue;
|
||
pStruct->pSession->SendBroadcastingEffect(GetSessionID(), cType, cState);
|
||
}
|
||
}
|
||
|
||
void CDNUserSession::VerifyValidMap(int nNextMapIndex)
|
||
{
|
||
#if defined(_FINAL_BUILD)
|
||
// 일반계정만 체크
|
||
if((GetAccountLevel() <= AccountLevel_QA) &&(GetAccountLevel() >= AccountLevel_New))
|
||
return;
|
||
#endif // #if defined(_FINAL_BUILD)
|
||
|
||
if(!g_pDataManager->CheckChangeMap(GetMapIndex(), nNextMapIndex))
|
||
{
|
||
WCHAR wszBuf[100];
|
||
wsprintf( wszBuf, L"GAME Prev[%d]->Next[%d]", GetMapIndex(), nNextMapIndex);
|
||
GetDBConnection()->QueryAddAbuseLog(this, ABUSE_MOVE_SERVERS, wszBuf);
|
||
}
|
||
}
|
||
|
||
|
||
void CDNUserSession::RecvUdpPing( DWORD dwTick )
|
||
{
|
||
DWORD dwCur = timeGetTime();
|
||
if( dwCur < dwTick )
|
||
{
|
||
_DANGER_POINT();
|
||
return;
|
||
}
|
||
|
||
DWORD dwGap = (dwCur-dwTick);
|
||
#if defined( _WORK )
|
||
//std::cout << "UDPPing=" << dwGap << std::endl;
|
||
#endif // #if defined( _WORK )
|
||
m_pairUdpPing.first += dwGap;
|
||
++m_pairUdpPing.second;
|
||
}
|
||
|
||
void CDNUserSession::WritePingLog()
|
||
{
|
||
int iTcpPing = -1;
|
||
int iUdpPing = -1;
|
||
if( m_pairTcpPing.second > 0 )
|
||
iTcpPing = m_pairTcpPing.first/m_pairTcpPing.second;
|
||
if( m_pairUdpPing.second > 0 )
|
||
iUdpPing = m_pairUdpPing.first/m_pairUdpPing.second;
|
||
|
||
if( iTcpPing == -1 && iUdpPing == -1 )
|
||
return;
|
||
|
||
g_Log.Log( LogType::_PING, this, L"[%d] IP=%S TcpPing=%dms(%d/%d) UdpPing=%dms(%d/%d)\r\n", g_Config.nManagedID, GetIp(), iTcpPing, m_pairTcpPing.first, m_pairTcpPing.second, iUdpPing, m_pairUdpPing.first, m_pairUdpPing.second );
|
||
}
|
||
|
||
void CDNUserSession::ApplySourceEffect(CDnPlayerActor* pPlayerActor, const TSourceData& source, bool bOnInitialize/* = false*/)
|
||
{
|
||
if (!pPlayerActor)
|
||
return;
|
||
|
||
if (source.nItemID <= 0 || source.nRemainTime <= 0)
|
||
return;
|
||
|
||
const TItemData* pItemData = g_pDataManager->GetItemData(source.nItemID);
|
||
if (!pItemData)
|
||
return;
|
||
|
||
const TSkillData* pSkill = g_pDataManager->GetSkillData(pItemData->nSkillID);
|
||
if (!pSkill || pSkill->vLevelDataList.empty())
|
||
return;
|
||
|
||
CDnSkill::SkillInfo skillInfo;
|
||
std::vector<CDnSkill::StateEffectStruct> stateEffects;
|
||
CDnSkill::CreateSkillInfo(pSkill->nSkillID, pSkill->vLevelDataList[0].cSkillLevel, skillInfo, stateEffects);
|
||
|
||
skillInfo.hSkillUser = pPlayerActor->GetActorHandle();
|
||
|
||
// 어떤 근원 아이템의 상태효과가 기존에 있다면 있던 상태효과를 제거하고 넣어준다.
|
||
int iSE = pPlayerActor->GetNumAppliedStateBlow();
|
||
for( int i = 0; i < iSE; ++i )
|
||
{
|
||
DnBlowHandle hBlow = pPlayerActor->GetAppliedStateBlow( i );
|
||
if( hBlow->IsFromSourceItem() )
|
||
pPlayerActor->AddStateBlowIDToRemove( hBlow->GetBlowID() );
|
||
}
|
||
|
||
// 지우라고 요청한 것을 서버에서도 바로 지금 지운다.
|
||
pPlayerActor->RemoveResetStateBlow();
|
||
|
||
for each (CDnSkill::StateEffectStruct stateEffect in stateEffects)
|
||
{
|
||
int iBlowID = pPlayerActor->CmdAddStateEffect(&skillInfo, static_cast<STATE_BLOW::emBLOW_INDEX>(stateEffect.nID), (source.nRemainTime*1000), stateEffect.szValue.c_str(), false, true);
|
||
pPlayerActor->SendRemoveStateEffectGraphic(static_cast<STATE_BLOW::emBLOW_INDEX>(stateEffect.nID));
|
||
if( -1 != iBlowID )
|
||
{
|
||
DnBlowHandle hBlow = pPlayerActor->GetStateBlowFromID( iBlowID );
|
||
hBlow->FromSourceItem();
|
||
|
||
// #45646 근원 아이템을 사용하고 게임서버에 처음 입장했을 때만 HP/MP 를 풀로 채워준다.
|
||
if( bOnInitialize )
|
||
hBlow->SetHPMPFullWhenBegin();
|
||
}
|
||
|
||
// 탈것엔 이동속도 변경 상태효과를 제외하고는 의미 없음. 추후에 기획쪽에서 요청하면 추가.
|
||
//if (pPlayerActor->GetMyVehicleActor())
|
||
//{
|
||
// int iBlowID = pPlayerActor->GetMyVehicleActor()->CmdAddStateEffect(&skillInfo, static_cast<STATE_BLOW::emBLOW_INDEX>(stateEffect.nID), source.nRemainTime, stateEffect.szValue.c_str(), false, true);
|
||
//}
|
||
}
|
||
}
|
||
|
||
#if defined( PRE_ADD_NAMEDITEM_SYSTEM )
|
||
void CDNUserSession::ApplyEffectSkill( CDnPlayerActor* pPlayerActor, std::vector<TEffectSkillData>& vEffectSkill, bool bOnInitialize , bool bIsPvpGameRoom )
|
||
{
|
||
if( !pPlayerActor || ( pPlayerActor && !pPlayerActor->GetActorHandle() ) )
|
||
return;
|
||
|
||
if( vEffectSkill.empty() )
|
||
return;
|
||
|
||
std::vector<TEffectSkillData>::iterator itor = vEffectSkill.begin();
|
||
|
||
for(;itor != vEffectSkill.end(); itor++)
|
||
{
|
||
ApplyEffectSkill( pPlayerActor, &(*itor), bOnInitialize , bIsPvpGameRoom );
|
||
}
|
||
}
|
||
|
||
void CDNUserSession::ApplyEffectSkill( CDnPlayerActor* pPlayerActor, TEffectSkillData* EffectSkill, bool bOnInitialize , bool bIsPvpGameRoom )
|
||
{
|
||
if( !pPlayerActor || ( pPlayerActor && !pPlayerActor->GetActorHandle() ) )
|
||
return;
|
||
if( !EffectSkill )
|
||
return;
|
||
if (EffectSkill->nSkillID <= 0 || ( EffectSkill->tExpireDate <= 0 && EffectSkill->bEternity == false ))
|
||
return;
|
||
|
||
const TSkillData* pSkill = g_pDataManager->GetSkillData(EffectSkill->nSkillID);
|
||
if (!pSkill || pSkill->vLevelDataList.empty())
|
||
return;
|
||
|
||
int nItemType = g_pDataManager->GetItemMainType(EffectSkill->nItemID);
|
||
if( ( (nItemType == ITEMTYPE_GLOBAL_PARTY_BUFF) || (nItemType == ITEMTYPE_BESTFRIEND) ) && bIsPvpGameRoom )
|
||
return;
|
||
|
||
CDnSkill::SkillInfo skillInfo;
|
||
std::vector<CDnSkill::StateEffectStruct> stateEffects;
|
||
#if defined( PRE_FIX_BUFFITEM )
|
||
CDnSkill::CreateSkillInfo(EffectSkill->nSkillID, EffectSkill->nSkillLevel, skillInfo, stateEffects);
|
||
#else
|
||
CDnSkill::CreateSkillInfo(pSkill->nSkillID, pSkill->vLevelDataList[0].cSkillLevel, skillInfo, stateEffects);
|
||
#endif
|
||
|
||
skillInfo.hSkillUser = pPlayerActor->GetActorHandle();
|
||
|
||
for each (CDnSkill::StateEffectStruct stateEffect in stateEffects)
|
||
{
|
||
int nRemainTime = EffectSkill->nRemainTime * 1000;
|
||
if( EffectSkill->bEternity == true )
|
||
nRemainTime = -1;
|
||
|
||
int iBlowID = pPlayerActor->CmdAddStateEffect(&skillInfo, static_cast<STATE_BLOW::emBLOW_INDEX>(stateEffect.nID), nRemainTime , stateEffect.szValue.c_str(), true, true);
|
||
pPlayerActor->SendRemoveStateEffectGraphic(static_cast<STATE_BLOW::emBLOW_INDEX>(stateEffect.nID));
|
||
if( -1 != iBlowID )
|
||
{
|
||
DnBlowHandle hBlow = pPlayerActor->GetStateBlowFromID( iBlowID );
|
||
if( hBlow )
|
||
{
|
||
// #45646 근원 아이템을 사용하고 게임서버에 처음 입장했을 때만 HP/MP 를 풀로 채워준다.
|
||
hBlow->FromSourceItem();
|
||
|
||
if( bOnInitialize )
|
||
hBlow->SetHPMPFullWhenBegin();
|
||
|
||
EffectSkill->bApplySkill = true;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void CDNUserSession::RemoveEffectSkill( CDnPlayerActor* pPlayerActor, TEffectSkillData* EffectSkill )
|
||
{
|
||
if( !pPlayerActor || ( pPlayerActor && !pPlayerActor->GetActorHandle() ) )
|
||
return;
|
||
if( !EffectSkill )
|
||
return;
|
||
if( EffectSkill->nSkillID <= 0 )
|
||
return;
|
||
|
||
const TSkillData* pSkill = g_pDataManager->GetSkillData(EffectSkill->nSkillID);
|
||
if (!pSkill || pSkill->vLevelDataList.empty())
|
||
return;
|
||
|
||
int iSE = pPlayerActor->GetNumAppliedStateBlow();
|
||
for( int i = 0; i < iSE; ++i )
|
||
{
|
||
DnBlowHandle hBlow = pPlayerActor->GetAppliedStateBlow( i );
|
||
if( hBlow )
|
||
{
|
||
if( hBlow->GetParentSkillInfo() && hBlow->GetParentSkillInfo()->iSkillID == pSkill->nSkillID )
|
||
pPlayerActor->AddStateBlowIDToRemove( hBlow->GetBlowID() );
|
||
}
|
||
}
|
||
// 지우라고 요청한 것을 서버에서도 바로 지금 지운다.
|
||
EffectSkill->bApplySkill = false;
|
||
pPlayerActor->RemoveResetStateBlow();
|
||
}
|
||
|
||
#if defined( PRE_FIX_BUFFITEM )
|
||
void CDNUserSession::RemoveApplySkill( CDnPlayerActor* pPlayerActor, int nSkillID )
|
||
{
|
||
if( !pPlayerActor || ( pPlayerActor && !pPlayerActor->GetActorHandle() ) )
|
||
return;
|
||
if( nSkillID <= 0 )
|
||
return;
|
||
|
||
const TSkillData* pSkill = g_pDataManager->GetSkillData(nSkillID);
|
||
if (!pSkill || pSkill->vLevelDataList.empty())
|
||
return;
|
||
|
||
int iSE = pPlayerActor->GetNumAppliedStateBlow();
|
||
for( int i = 0; i < iSE; ++i )
|
||
{
|
||
DnBlowHandle hBlow = pPlayerActor->GetAppliedStateBlow( i );
|
||
if( hBlow )
|
||
{
|
||
if( hBlow->GetParentSkillInfo() && hBlow->GetParentSkillInfo()->iSkillID == pSkill->nSkillID )
|
||
pPlayerActor->AddStateBlowIDToRemove( hBlow->GetBlowID() );
|
||
}
|
||
}
|
||
// 지우라고 요청한 것을 서버에서도 바로 지금 지운다.
|
||
pPlayerActor->RemoveResetStateBlow();
|
||
}
|
||
#endif
|
||
#endif
|
||
|
||
int CDNUserSession::TryWarpVillage(int nMapIndex, INT64 nItemSerial)
|
||
{
|
||
if (m_pGameRoom->GetRoomState() != _GAME_STATE_PLAY)
|
||
return ERROR_GENERIC_INVALIDREQUEST;
|
||
|
||
if (!IsWindowState(WINDOW_BLIND))
|
||
return ERROR_ITEM_FAIL;
|
||
|
||
CDnGameTask *pTask = (CDnGameTask*)m_pGameRoom->GetTaskMng()->GetTask("GameTask");
|
||
SetNextVillageData(NULL, 0, pTask->GetMapTableID(), nMapIndex, 1);
|
||
g_pMasterConnectionManager->SendRequestNextVillageInfo(GetWorldSetID(), GetAccountDBID(), nMapIndex, 1, true, nItemSerial);
|
||
|
||
return ERROR_NONE;
|
||
}
|
||
|
||
void CDNUserSession::SetGuildRewardItem( TGuildRewardItem* GuildRewardItem )
|
||
{
|
||
#if defined( PRE_ADD_GUILDREWARDITEM )
|
||
if(GetPlayerActor())
|
||
{
|
||
for(int i = GUILDREWARDEFFECT_TYPE_ADDSKILLTYPE1; i <= GUILDREWARDEFFECT_TYPE_ADDSKILLTYPE4; i++)
|
||
{
|
||
std::map<int, TGuildRewardItem>::iterator itor = m_mGuildRewardItem.find(i);
|
||
if( itor != m_mGuildRewardItem.end() )
|
||
{
|
||
// 스킬들은 nEffectValue가 레벨이고 nEffectValue2가 스킬인덱스
|
||
DnSkillHandle hSkill = GetPlayerActor()->FindSkill( itor->second.nEffectValue2 );
|
||
if( hSkill )
|
||
GetPlayerActor()->RemoveSkill(hSkill->GetClassID());
|
||
}
|
||
}
|
||
}
|
||
m_mGuildRewardItem.clear();
|
||
#endif
|
||
for(int i=GUILDREWARDEFFECT_TYPE_EXTRAEXP; i<GUILDREWARDEFFECT_TYPE_CNT; i++)
|
||
{
|
||
if( GuildRewardItem[i].nItemID > 0 )
|
||
{
|
||
m_mGuildRewardItem.insert(pair<int,TGuildRewardItem>(i, GuildRewardItem[i]));
|
||
}
|
||
}
|
||
}
|
||
|
||
int CDNUserSession::GetGuildRewardItemValue( int nType )
|
||
{
|
||
std::map<int, TGuildRewardItem>::iterator itor = m_mGuildRewardItem.find(nType);
|
||
if( itor != m_mGuildRewardItem.end() )
|
||
{
|
||
if( itor->second.nItemID > 0 && itor->second.nEffectValue > 0 )
|
||
return itor->second.nEffectValue;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
#if defined( PRE_ADD_GUILDREWARDITEM )
|
||
void CDNUserSession::SetGuildRewardItem()
|
||
{
|
||
const TGuildUID GuildUID = GetGuildUID();
|
||
|
||
if(GuildUID.IsSet())
|
||
{
|
||
CDNGuildBase* pGuild = g_pGuildManager->At(GuildUID);
|
||
if (pGuild)
|
||
{
|
||
#if !defined( PRE_ADD_NODELETEGUILD )
|
||
CDetachAutoEx<CDNGuildBase> AutoDetach(pGuild);
|
||
if (pGuild->IsEnable())
|
||
{
|
||
#endif
|
||
TGuildRewardItem *RewardItemInfo;
|
||
RewardItemInfo = pGuild->GetGuildRewardItem();
|
||
SetGuildRewardItem(RewardItemInfo);
|
||
SendGuildRewardItem(RewardItemInfo);
|
||
#if !defined( PRE_ADD_NODELETEGUILD )
|
||
}
|
||
#endif
|
||
}
|
||
}
|
||
}
|
||
|
||
void CDNUserSession::ApplyGuildRewardSkill( bool bUseItem/*=false*/ )
|
||
{
|
||
if(!GetPlayerActor())
|
||
return;
|
||
|
||
for(int i = GUILDREWARDEFFECT_TYPE_ADDSKILLTYPE1; i <= GUILDREWARDEFFECT_TYPE_ADDSKILLTYPE4; i++)
|
||
{
|
||
std::map<int, TGuildRewardItem>::iterator itor = m_mGuildRewardItem.find(i);
|
||
if( itor != m_mGuildRewardItem.end() )
|
||
{
|
||
AddGuildRewardItemBuff( itor->second.nEffectValue2);
|
||
}
|
||
}
|
||
ApplyGuildRewardItemBuff(bUseItem);
|
||
}
|
||
|
||
void CDNUserSession::AddGuildRewardItemBuff( int nItemID )
|
||
{
|
||
m_GuildRewardbuffItemList.push_back(nItemID);
|
||
}
|
||
|
||
void CDNUserSession::ApplyGuildRewardItemBuff( bool bUseItem/*=false*/ )
|
||
{
|
||
for( std::list<int>::iterator itor = m_GuildRewardbuffItemList.begin();itor != m_GuildRewardbuffItemList.end(); itor++ )
|
||
{
|
||
CSUseItem pPacket;
|
||
memset(&pPacket, 0, sizeof(pPacket));
|
||
TItemData *pItemData = g_pDataManager->GetItemData(*itor);
|
||
if( g_pDataManager->IsUseItemAllowMapTypeCheck( pItemData->nItemID, GetGameRoom()->m_iMapIdx ) )
|
||
{
|
||
TEffectSkillData* EffectSkill = GetItem()->GetEffectSkillItem( EffectSkillNameSpace::SearchType::SkillID, pItemData->nSkillID );
|
||
if( !EffectSkill )
|
||
{
|
||
GetItem()->ApplyPartyEffectSkillItemData(&pPacket, pItemData, GetSessionID(), EffectSkillNameSpace::ShowEffectType::NONEEFFECT, false, bUseItem);
|
||
}
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
#endif
|
||
void CDNUserSession::SetPeriodExpItemRate()
|
||
{
|
||
// 경험치 획득 아이템 검사..
|
||
std::vector<const TItem*> vItem;
|
||
m_pItem->GetCashInventoryItemListByType( ITEMTYPE_PERIODEXPITEM, vItem );
|
||
m_nPeriodeExpItemRate = 0;
|
||
|
||
if( vItem.empty() )
|
||
return;
|
||
|
||
for( UINT i=0 ; i<vItem.size() ; ++i )
|
||
{
|
||
if( m_nPeriodeExpItemRate < g_pDataManager->GetItemTypeParam1(vItem[i]->nItemID) )
|
||
{
|
||
if( g_pDataManager->GetItemTypeParam2(vItem[i]->nItemID) > 0 && GetLevel() >= g_pDataManager->GetItemTypeParam2(vItem[i]->nItemID) )
|
||
continue;
|
||
|
||
m_nPeriodeExpItemRate = g_pDataManager->GetItemTypeParam1(vItem[i]->nItemID);
|
||
}
|
||
}
|
||
}
|
||
|
||
#if defined( PRE_ADD_NAMEDITEM_SYSTEM )
|
||
void CDNUserSession::ApplyPartyEffectSkillItemData( CSUseItem *pPacket, TItemData *pItemData, UINT nUseSessionID, EffectSkillNameSpace::ShowEffectType::eType eType, bool bSendDB, bool bUseItem )
|
||
{
|
||
if( GetGameRoom() )
|
||
{
|
||
CDnPartyTask* pPartyTask = (CDnPartyTask*)(GetGameRoom()->GetTaskMng()->GetTask("PartyTask"));
|
||
if( pPartyTask && pItemData)
|
||
{
|
||
if(pItemData->nTypeParam[0] == EffectSkillNameSpace::BuffType::Partybuff )
|
||
{
|
||
pPartyTask->ApplyPartyEffectSkillItemData(pPacket, pItemData, nUseSessionID, eType, bSendDB, bUseItem);
|
||
}
|
||
else
|
||
{
|
||
GetItem()->ApplyPartyEffectSkillItemData( pPacket, pItemData, GetSessionID(), eType, true, true );
|
||
}
|
||
|
||
}
|
||
}
|
||
}
|
||
#endif
|
||
|
||
#if defined(_ID)
|
||
void CDNUserSession::SetIDNPcCafeInfo(const char* strMacAddress, const char* strKey)
|
||
{
|
||
_strcpy(m_szMacAddress, _countof(m_szMacAddress), strMacAddress, (int)strlen(strMacAddress));
|
||
_strcpy(m_szKey, _countof(m_szKey), strKey, (int)strlen(strKey));
|
||
}
|
||
#endif
|
||
|
||
#if defined( PRE_ADD_BESTFRIEND )
|
||
void CDNUserSession::BestFriendChangeLevel(BYTE cLevel, bool bSend /*= false*/)
|
||
{
|
||
if(bSend)
|
||
{
|
||
if( GetBestFriend()->IsRegistered() )
|
||
{
|
||
sWorldUserState State;
|
||
if (g_pWorldUserState->GetUserState(GetBestFriend()->GetInfo().wszName, GetBestFriend()->GetInfo().biCharacterDBID, &State))
|
||
{
|
||
if (g_pMasterConnectionManager)
|
||
g_pMasterConnectionManager->SendLevelUpBestFriend(GetWorldSetID(), cLevel, m_pBestFriend->GetInfo().wszName);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
GetBestFriend()->ChangeLevel(cLevel);
|
||
}
|
||
#endif
|
||
|
||
#if defined( PRE_ADD_DIRECTNBUFF )
|
||
void CDNUserSession::SendDirectPartyBuffMsg()
|
||
{
|
||
for(std::list<int>::iterator itor = m_DirectPartyBuffItemList.begin();itor!=m_DirectPartyBuffItemList.end();itor++)
|
||
{
|
||
for (DWORD i = 0; i < m_pSession->GetGameRoom()->GetUserCount(); ++i)
|
||
{
|
||
if( !g_pDataManager->IsUseItemAllowMapTypeCheck( *itor, GetGameRoom()->m_iMapIdx ) )
|
||
continue;
|
||
const CDNGameRoom::PartyStruct* pPartyStruct = m_pSession->GetGameRoom()->GetPartyData(i);
|
||
if(pPartyStruct && pPartyStruct->pSession)
|
||
{
|
||
pPartyStruct->pSession->SendWorldSystemMsg(WORLDCHATTYPE_DIRECTPARTYBUFF, *itor, GetCharacterName(), 0 );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
#endif
|
||
|
||
#if defined( PRE_ADD_NEWCOMEBACK )
|
||
void CDNUserSession::SetComebackAppellation( int nAppelationID )
|
||
{
|
||
if( m_nComebackAppellation != nAppelationID )
|
||
{
|
||
int nPrevComebackAppellation = m_nComebackAppellation;
|
||
m_nComebackAppellation = nAppelationID;
|
||
|
||
GetDBConnection()->QueryModMemberComebackInfo( this, GetPartyID() );
|
||
|
||
if( nPrevComebackAppellation > 0 )
|
||
{
|
||
// 기존 버프 삭제
|
||
if( GetGameRoom() && GetGameRoom()->bIsComebackParty() )
|
||
{
|
||
GetGameRoom()->DelPartyMemberAppellation(nPrevComebackAppellation);
|
||
}
|
||
}
|
||
|
||
if( m_nComebackAppellation > 0 )
|
||
{
|
||
// 버프 적용 및 파티 상태 변경
|
||
TAppellationData *pAData = g_pDataManager->GetAppellationData( nAppelationID );
|
||
if( pAData )
|
||
{
|
||
if( pAData->nSkillItemID > 0 )
|
||
{
|
||
CSUseItem pPacket;
|
||
memset(&pPacket, 0, sizeof(pPacket));
|
||
pPacket.biInvenSerial = GetItem()->MakeItemSerial();
|
||
TItemData* pBuffItemData = g_pDataManager->GetItemData( pAData->nSkillItemID );
|
||
if( pBuffItemData && GetGameRoom() )
|
||
{
|
||
GetGameRoom()->SetComebackParty(true);
|
||
bool bUseItem = true;
|
||
EWorldEnum::MapTypeEnum MapType = CDnWorld::GetInstance(GetGameRoom()).GetMapType();
|
||
if( MapType == EWorldEnum::MapTypeWorldMap )
|
||
bUseItem = false;
|
||
ApplyPartyEffectSkillItemData(&pPacket, pBuffItemData, m_pSession->GetSessionID(), EffectSkillNameSpace::ShowEffectType::NONEEFFECT, false, bUseItem);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
#endif
|
||
|
||
#if defined( PRE_FIX_BUFFITEM )
|
||
void CDNUserSession::CheckEffectSkillItemData()
|
||
{
|
||
std::vector<TEffectSkillData> vEffectSkill;
|
||
vEffectSkill.clear();
|
||
GetItem()->GetEffectSkillItem( vEffectSkill );
|
||
if(vEffectSkill.empty())
|
||
return;
|
||
|
||
for( int i=0;i<vEffectSkill.size();i++ )
|
||
{
|
||
if( !g_pDataManager->IsUseItemAllowMapTypeCheck( vEffectSkill[i].nItemID, GetGameRoom()->m_iMapIdx ) )
|
||
{
|
||
CDNUserSession::RemoveEffectSkill(GetPlayerActor(), &vEffectSkill[i]);
|
||
GetItem()->BroadcastDelEffectSkillItemData( vEffectSkill[i].nItemID );
|
||
}
|
||
else
|
||
{
|
||
CSUseItem pPacket;
|
||
memset(&pPacket, 0, sizeof(pPacket));
|
||
pPacket.biInvenSerial = GetItem()->MakeItemSerial();
|
||
TItemData* pBuffItemData = g_pDataManager->GetItemData(vEffectSkill[i].nItemID);
|
||
if( pBuffItemData )
|
||
{
|
||
TEffectSkillData* EffectSkill = GetItem()->GetEffectSkillItem( EffectSkillNameSpace::SearchType::SkillID, pBuffItemData->nSkillID );
|
||
if( EffectSkill && EffectSkill->bApplySkill == false )
|
||
{
|
||
GetItem()->BroadcastEffectSkillItemData( false, pBuffItemData->nSkillID, EffectSkillNameSpace::ShowEffectType::NONEEFFECT );
|
||
CDNUserSession::ApplyEffectSkill(GetPlayerActor(), EffectSkill, true, GetGameRoom()->bIsPvPRoom() );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
#endif
|
||
|
||
#if defined(PRE_ADD_STAGE_CLEAR_ADD_REWARD)
|
||
int CDNUserSession::GetStageClearBonusReward(char *pData, int nLen)
|
||
{
|
||
if(nLen != sizeof(CSStageClearBonusRewardSelect))
|
||
return ERROR_INVALIDPACKET;
|
||
|
||
CSStageClearBonusRewardSelect* pPacket = (CSStageClearBonusRewardSelect*)pData;
|
||
if(pPacket->nItemID <= 0 || pPacket->nPropID <= 0)
|
||
return ERROR_GENERIC_INVALIDREQUEST;
|
||
|
||
//보상아이템 찾기
|
||
int nMapID = m_pGameRoom->GetGameTask()->GetMapTableID();
|
||
int nDropItemGroup = g_pDataManager->GetBonusDropGroupID(nMapID, pPacket->nItemID);
|
||
if(nDropItemGroup == 0)
|
||
{
|
||
//맵, 필요아이템으로 보상그룹을 찾을수 없으면 패킷 조작이거나 리소스가 잘못된 경우임
|
||
g_Log.Log(LogType::_ERROR, this, L"[StageClearBonusReward] BonusReward Find Fail(MapID[%d] NeedItemID[%d])\n", nMapID, pPacket->nItemID);
|
||
return ERROR_GENERIC_INVALIDREQUEST;
|
||
}
|
||
//인벤에 아이템이 있는지 확인
|
||
bool IsCashItem = g_pDataManager->IsCashItem(pPacket->nItemID);
|
||
|
||
if(IsCashItem)
|
||
if(m_pItem->GetCashItemCountByItemID(pPacket->nItemID) <= 0)
|
||
return ERROR_GENERIC_INVALIDREQUEST;
|
||
else
|
||
if(m_pItem->GetInventoryItemCount(pPacket->nItemID) <= 0)
|
||
return ERROR_GENERIC_INVALIDREQUEST;
|
||
|
||
//프랍 체크
|
||
std::vector<CEtWorldProp *> VecProp;
|
||
m_pGameRoom->GetWorld()->FindPropFromCreateUniqueID( pPacket->nPropID, &VecProp );
|
||
if( VecProp.empty() )
|
||
return ERROR_GENERIC_INVALIDREQUEST;
|
||
|
||
//프랍 타입 체크. Chest타입이 아니면 원하는 애가 아님...
|
||
if(static_cast<CDnWorldProp *>( VecProp[0] )->GetPropType() != PTE_Operation)
|
||
return ERROR_GENERIC_INVALIDREQUEST;
|
||
|
||
CDnWorldOperationProp *pProp = static_cast<CDnWorldOperationProp *>( VecProp[0] );
|
||
if( !pProp )
|
||
return ERROR_GENERIC_INVALIDREQUEST;
|
||
|
||
if(!pProp->IsShow())
|
||
return ERROR_GENERIC_INVALIDREQUEST;
|
||
|
||
CDnItemTask *pItemTask = (CDnItemTask *)GetGameRoom()->GetTaskMng()->GetTask( "ItemTask" );
|
||
if(!pItemTask)
|
||
return ERROR_GENERIC_INVALIDREQUEST;
|
||
|
||
//이미 보상을 받았는지, 프랍을 클릭했는지 확인
|
||
if(pProp->IsClickPropAndCheckUser(m_hActor))
|
||
{
|
||
//만약 보상을 받았거나, 프랍을 클릭도 안한 유저가 여기까지 온거면 핵이거나 패킷 조작일수 있음...
|
||
g_Log.Log(LogType::_ERROR, this, L"[StageClearBonusReward] Retry BonusReward(MapID:[%d] PropID[%d] NeedItemID[%d]\n", nMapID, pPacket->nPropID, pPacket->nItemID);
|
||
return ERROR_GENERIC_INVALIDREQUEST;
|
||
}
|
||
//보상 체크
|
||
DNVector(CDnItem::DropItemStruct) VecDropItemList;
|
||
CDnDropItem::CalcDropItemList(GetGameRoom(), m_pGameRoom->GetGameTask()->GetStageDifficulty(), nDropItemGroup, VecDropItemList);
|
||
if(VecDropItemList.empty())
|
||
{
|
||
//드랍 그룹ID가 있는데, 실제로 드랍해 줄 아이템이 없으면 리소스 문제.. 로그남기자
|
||
g_Log.Log(LogType::_ERROR, this, L"[StageClearBonusReward] DropItemGroup Is Empty(MapID:[%d] NeedItemID[%d] DropGroupID[%d])\n", nMapID, pPacket->nItemID, nDropItemGroup);
|
||
return ERROR_GENERIC_INVALIDREQUEST;
|
||
}
|
||
|
||
//키 아이템 삭제
|
||
if(IsCashItem)
|
||
{
|
||
if(!m_pItem->DeleteCashInventoryByItemID(pPacket->nItemID, 1, DBDNWorldDef::UseItem::Use))
|
||
{
|
||
g_Log.Log(LogType::_ERROR, this, L"[StageClearBonusReward] Delete Item Failed(Cash)(MapID:[%d] NeedItemID[%d] DropGroupID[%d]) \n", nMapID, pPacket->nItemID, nDropItemGroup);
|
||
return ERROR_GENERIC_INVALIDREQUEST;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if(!m_pItem->DeleteInventoryByItemID(pPacket->nItemID, 1, DBDNWorldDef::UseItem::Use))
|
||
{
|
||
g_Log.Log(LogType::_ERROR, this, L"[StageClearBonusReward] Delete Item Failed(Normal)(MapID:[%d] NeedItemID[%d] DropGroupID[%d]) \n", nMapID, pPacket->nItemID, nDropItemGroup);
|
||
return ERROR_GENERIC_INVALIDREQUEST;
|
||
}
|
||
}
|
||
|
||
for( DWORD j=0; j<VecDropItemList.size(); j++ ) {
|
||
#if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)
|
||
pItemTask->RequestDropItem( VecDropItemList[j].dwUniqueID, *(GetActorHandle()->GetPosition()), VecDropItemList[j].nItemID, VecDropItemList[j].nSeed, VecDropItemList[j].nCount, (short)( _rand(GetGameRoom())%360 ), m_nSessionID, VecDropItemList[j].nEnchantID);
|
||
#else // #if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)
|
||
pItemTask->RequestDropItem( VecDropItemList[j].dwUniqueID, *(GetActorHandle()->GetPosition()), VecDropItemList[j].nItemID, VecDropItemList[j].nSeed, VecDropItemList[j].nCount, (short)( _rand(GetGameRoom())%360 ), m_nSessionID);
|
||
#endif // #if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)
|
||
}
|
||
GetEventSystem()->OnEvent( EventSystem::OnItemUse, 1, EventSystem::ItemID, pPacket->nItemID);
|
||
//프랍 Disabled
|
||
pProp->CmdEnableOperator(m_hActor, false);
|
||
return ERROR_NONE;
|
||
}
|
||
void CDNUserSession::SendStageClearBonusRewardResult(int nResult)
|
||
{
|
||
SCStageClearBonusRewardSelect TxPacket;
|
||
memset(&TxPacket, 0, sizeof(SCStageClearBonusRewardSelect));
|
||
TxPacket.nResult = nResult;
|
||
|
||
AddSendData(SC_CHAR, eChar::SC_STAGECLEAR_BONUSREWARD_SELECT, reinterpret_cast<char*>(&TxPacket), sizeof(TxPacket));
|
||
}
|
||
#endif // #if defined(PRE_ADD_STAGE_CLEAR_ADD_REWARD)
|
||
|
||
#if defined( PRE_ALTEIAWORLD_EXPLORE )
|
||
|
||
int CDNUserSession::AlteiaWorldDice()
|
||
{
|
||
if( GetGameRoom() )
|
||
{
|
||
if( GetGameRoom()->bIsAlteiaWorld() )
|
||
{
|
||
if( !m_bCanDice )
|
||
{
|
||
SendAlteiaWorldDiceResult( ERROR_GENERIC_INVALIDREQUEST );
|
||
return ERROR_GENERIC_INVALIDREQUEST;
|
||
}
|
||
int nDiceNumber = (_rand(GetGameRoom()) % MAXALTEIADICENUMBER)+1;
|
||
m_nAlteiaWorldPosition += nDiceNumber;
|
||
if( m_nAlteiaWorldPosition >= g_pDataManager->GetAlteiaWorldMapMaxCount() )
|
||
{
|
||
nDiceNumber = g_pDataManager->GetAlteiaWorldMapMaxCount() - (m_nAlteiaWorldPosition - nDiceNumber);
|
||
m_nAlteiaWorldPosition = g_pDataManager->GetAlteiaWorldMapMaxCount();
|
||
}
|
||
|
||
TAlteiaWorldMapInfo* pAlteiaWorldMapInfo = g_pDataManager->GetAlteiaWorldMapInfo(m_nAlteiaWorldPosition);
|
||
|
||
if(pAlteiaWorldMapInfo)
|
||
{
|
||
m_dwAlteiaWorldMoveNextMapTick = timeGetTime();
|
||
SendAlteiaWorldDiceResult( ERROR_NONE, nDiceNumber);
|
||
m_bCanDice = false;
|
||
return ERROR_NONE;
|
||
}
|
||
else
|
||
{
|
||
g_Log.Log(LogType::_NORMAL, m_pSession, L"AlateiaWorldMapInfo Index:d Error!!\r\n",m_nAlteiaWorldPosition);
|
||
SendAlteiaWorldDiceResult( ERROR_GENERIC_INVALIDREQUEST );
|
||
return ERROR_GENERIC_INVALIDREQUEST;
|
||
}
|
||
|
||
}
|
||
}
|
||
return ERROR_GENERIC_INVALIDREQUEST;
|
||
}
|
||
|
||
void CDNUserSession::MoveAlteiaNextMap()
|
||
{
|
||
if( m_bCanDice )
|
||
{
|
||
SendAlteiaWorldDiceResult( ERROR_GENERIC_INVALIDREQUEST );
|
||
return;
|
||
}
|
||
|
||
TAlteiaWorldMapInfo* pAlteiaWorldMapInfo = g_pDataManager->GetAlteiaWorldMapInfo(m_nAlteiaWorldPosition);
|
||
|
||
if(pAlteiaWorldMapInfo)
|
||
{
|
||
GetGameRoom()->SetAlteiaWorldMap(true);
|
||
GetGameRoom()->ReserveInitStateAndSync( pAlteiaWorldMapInfo->nMapID, 1, CRandom::Seed(GetGameRoom()), pAlteiaWorldMapInfo->Difficulty, true );
|
||
m_dwAlteiaWorldMoveNextMapTick = 0;
|
||
m_bCanDice = true;
|
||
}
|
||
}
|
||
|
||
void CDNUserSession::AddAlteiaWorldResult( bool bClearFlag )
|
||
{
|
||
if( bClearFlag )
|
||
{
|
||
int nGoldKeyCount = 0;
|
||
int nGoldKeyItemID = 0;
|
||
m_cDailyPlayCount++;
|
||
std::vector<TItem *> pVecResultList;
|
||
int nGoldkeyItemID = (int)CGlobalWeightIntTable::GetInstance().GetValue(CGlobalWeightIntTable::AlteiaWorldGoldKeyItemID);
|
||
m_pItem->GetInventoryItemListFromItemID(nGoldkeyItemID , pVecResultList );
|
||
for( std::vector<TItem *>::iterator itor = pVecResultList.begin(); itor != pVecResultList.end();itor++)
|
||
{
|
||
nGoldKeyCount += (*itor)->wCount;
|
||
}
|
||
DWORD dwPlayTick = GetGameRoom()->GetAlteiaPlayTime();
|
||
if( dwPlayTick > 0 )
|
||
dwPlayTick = dwPlayTick/1000;
|
||
GetDBConnection()->QueryAddAlteiaWorldPlayResult( this, nGoldKeyCount, dwPlayTick, GetGuildUID().nDBID );
|
||
if( m_cDailyPlayCount >= (BYTE)CGlobalWeightTable::GetInstance().GetValue( CGlobalWeightTable::AlteiaWorldDailyPlayCount ) )
|
||
{
|
||
// 버프 지급
|
||
int nBuffItemID = (int)CGlobalWeightIntTable::GetInstance().GetValue(CGlobalWeightIntTable::AlteiaWorldBuffItemID);
|
||
TItemData *pItemData = g_pDataManager->GetItemData(nBuffItemID);
|
||
if( pItemData )
|
||
{
|
||
CSUseItem pPacket;
|
||
memset(&pPacket, 0, sizeof(pPacket));
|
||
GetItem()->ApplyPartyEffectSkillItemData(&pPacket, pItemData, GetSessionID(), EffectSkillNameSpace::ShowEffectType::NONEEFFECT, true, false);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
#endif
|
||
|
||
void CDNUserSession::OnRecvSpecializeMessage(int iSubCmd, char * pData, int iLen)
|
||
{
|
||
if (sizeof(CSSpecialize) != iLen)
|
||
return;
|
||
CSSpecialize* pPacket = (CSSpecialize*)pData;
|
||
|
||
//rlkt_jobchange
|
||
if (pPacket->nSelectedClass < 0 || pPacket->nSelectedClass > 100)
|
||
return;
|
||
|
||
DNTableFileFormat* pJobTable = GetDNTable(CDnTableDB::TJOB);
|
||
|
||
// 현재 직업의 단계값과 루트 직업을 얻어옴.
|
||
int iNowJob = m_pSession->GetUserJob();
|
||
int iNowJobDeep = 0;
|
||
int iNowRootJob = 0;
|
||
for (int i = 0; i < pJobTable->GetItemCount(); ++i)
|
||
{
|
||
int iItemID = pJobTable->GetItemID(i);
|
||
if (iItemID == iNowJob)
|
||
{
|
||
iNowJobDeep = pJobTable->GetFieldFromLablePtr(iItemID, "_JobNumber")->GetInteger();
|
||
iNowRootJob = pJobTable->GetFieldFromLablePtr(iItemID, "_BaseClass")->GetInteger();
|
||
break;
|
||
}
|
||
}
|
||
|
||
int iJobIDToChange = pPacket->nSelectedClass;
|
||
|
||
// 바꾸기 원하는 직업과 단계가 같거나 큰지 확인.
|
||
bool bSuccess = false;
|
||
map<int, int> mapRootJob;
|
||
for (int i = 0; i < pJobTable->GetItemCount(); ++i)
|
||
{
|
||
int iItemID = pJobTable->GetItemID(i);
|
||
if (iItemID == iJobIDToChange)
|
||
{
|
||
int iJobRootToChange = pJobTable->GetFieldFromLablePtr(iItemID, "_BaseClass")->GetInteger();
|
||
if (iNowRootJob == iJobRootToChange)
|
||
{
|
||
int iJobDeepToChange = pJobTable->GetFieldFromLablePtr(iItemID, "_JobNumber")->GetInteger();
|
||
if (iNowJobDeep < iJobDeepToChange)
|
||
{
|
||
// 부모 직업도 맞아야 함.
|
||
int iParentJobID = pJobTable->GetFieldFromLablePtr(iItemID, "_ParentJob")->GetInteger();
|
||
if (iParentJobID == iNowJob)
|
||
{
|
||
m_pSession->SetUserJob(iJobIDToChange);
|
||
// 한국에서는 현재 전직시 초기화를 수행하지 않음.(#19141)
|
||
// 따라서 치트키로 전직을 했을 시 스킬 초기화를 따로 하도록 호출해준다.
|
||
#ifdef _VILLAGESERVER
|
||
for (int nSkillPage = DualSkill::Type::Primary; nSkillPage < DualSkill::Type::MAX; nSkillPage++)
|
||
m_pSession->GetSkill()->ResetSkill(nSkillPage);
|
||
#endif // #ifdef _VILLAGESERVER
|
||
bSuccess = true;
|
||
}
|
||
else
|
||
{
|
||
// 바꾸고자 하는 직업의 부모 직업이 현재 직업이 아님.
|
||
wstring wszString = FormatW(L"현재 직업에선 전직 할 수 없는 직업입니다.!!\r\n");
|
||
m_pSession->SendChat(CHATTYPE_NORMAL, (int)wszString.size() * sizeof(WCHAR), L"", (WCHAR*)wszString.c_str());
|
||
|
||
return;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// 바꾸고자하는 직업이 아래 단계임. 못바꿈.
|
||
wstring wszString = FormatW(L"같거나 낮은 단계의 직업으로 바꿀 수 없습니다!!\r\n");
|
||
m_pSession->SendChat(CHATTYPE_NORMAL, (int)wszString.size() * sizeof(WCHAR), L"", (WCHAR*)wszString.c_str());
|
||
|
||
return;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// 바꾸고자하는 직업이 다른 클래스임. 못바꿈.
|
||
wstring wszString = FormatW(L"다른 클래스의 직업으로 바꿀 수 없습니다!!\r\n");
|
||
m_pSession->SendChat(CHATTYPE_NORMAL, (int)wszString.size() * sizeof(WCHAR), L"", (WCHAR*)wszString.c_str());
|
||
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (false == bSuccess)
|
||
{
|
||
wstring wszString = FormatW(L"잘못된 Job ID 입니다..\r\n");
|
||
m_pSession->SendChat(CHATTYPE_NORMAL, (int)wszString.size() * sizeof(WCHAR), L"", (WCHAR*)wszString.c_str());
|
||
|
||
return;
|
||
}
|
||
} |