Files
Sun1602/Server/AgentServer/AgentServer.cpp
T
2022-10-26 12:25:11 +08:00

1010 lines
29 KiB
C++

#include "stdafx.h"
#include "AgentServer.h"
#include <io.h>
#include <PacketStruct_ServerCommon.h>
#include <ServerOptionParser.h>
#ifdef _APPLY_NHN_FILTERFING
#include <IAF_Export.h> //lib 사용
#endif
//
#include <ServerSessions/ServerSessionManager.h>
#include <ServerSessions/MasterServerSession.h>
#include <ServerSessions/DBProxyServerSession.h>
#include <ServerSessions/AuthAgentServerSession.h>
#include <ServerSessions/WorldServerSession.h>
//
#include <PacketHandler/PacketHandler.h>
//
#include <UserSessions/UserManager.h>
#include <UserSessions/User.h>
#include <TimeCheck/HeartbeatManager.h>
//
#include <Zone/ZoneManager.h>
#include <Zone/WarControlManager.h>
#include <Zone/PortalManager.h>
//
#include <AgentParty/AgentPartyManager.h>
#include "BattleOpenTimeManager.h"
#include <Function/GuildRanking/GuildRanking.h>
//////////////////////////////////////////////////////////////////////////
// 임시 includes
#include "TimeCheck/ConnectionTimeoutFactory.h"
#include "TimeCheck/TimeKeeper.h"
#include "TimeCheck/ConnectionTimeout.h"
#include "Function/AgentServer.Timer.WorkLoad.h"
//
//////////////////////////////////////////////////////////////////////////
#include "Function/AgentScriptParserManager.h"
#include <ProhibitionWordParser.h>
#ifdef _NA_0_20110329_GAMEOPTION_SETTING
#include "Function/GameOptionManager.h"
#endif //_NA_0_20110329_GAMEOPTION_SETTING
// _NA_005026_20120527_CHAOS_ZONE_BATTLE_GROUND
#include <ChaosZoneSystem/AgentChaosZoneManager.h>
#include <ChaosZoneSystem/BattleGroundMatchingSystem.h>
#include <ChaosZoneSystem/BattleGroundManager.h>
#ifdef _NA_008679_20160202_REWORK_BATTLEGROUND
#include <TimeCheck/BattleGroundOpenTimeManager.h>
#endif // _NA_008679_20160202_REWORK_BATTLEGROUND
#include <ChaosZoneSystem/TeamBattleGroundManager.h> //_NA_006620_20130402_GM_BATTLE_GROUND_EVENT_GAME
#include <ChaosZoneSystem/FreePVPManager.h>
#ifdef _NA_008334_20150608_SONNENSCHEIN
#include <ChaosZoneSystem/SonnenScheinManager.h>
#endif //_NA_008334_20150608_SONNENSCHEIN
#ifdef _NA_008543_20151027_ONE_DAYS_GUILD_MISSION
#include <ChaosZoneSystem/OneDaysGuildMissionManager.h>
#endif //(_NA_008543_20151027_ONE_DAYS_GUILD_MISSION)
#if USING_GAMEGUARD
#include "GameGuard/GameGuard.h"
#endif //USING_GAMEGUARD
#include <PacketStruct_CW.h>
// <DEFINITIONs>
#define DISP_OK SUNLOG( eFULL_LOG, " [OK]" );
#define DISP_FAIL SUNLOG( eFULL_LOG, " Failed!" );
AgentServer* AgentServer::instance_ = NULL;
//━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
// <MOLA 5th Update Routine + HACK SHIELD>
// __NA000630_070817_MOLA_5th_UPDATE
sCLIENT_INIT_PRE_ENTRY_WRAP s_SECURE_INIT_PRE_ENTRY;
sCLIENT_INIT_PRE_ENTRY_WRAP* AgentServer::GetGResource()
{
return &s_SECURE_INIT_PRE_ENTRY;
}
#if USING_HACKSHIELD
AHNHS_SERVER_HANDLE AgentServer::GetHANDLEofHS()
{
return s_SECURE_INIT_PRE_ENTRY.GetHANDLEofHS();
}
#elif USING_XIGNCODE
#elif USING_FROST
#endif
//━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
//
// <CODEs><IMPLEMENTATION>
//
//
AgentServer::AgentServer()
{
m_pServerPoolRouter = NULL;
Init_ClearFields();
do
{ // Connect Sessions
m_pServerPoolRouter = new SERVER_SESSION_ROUTER;
SERVER_SESSION_ROUTER& rRouter = GetServerPoolRouter();
rRouter.Register<AuthAgentServerSession>(AUTH_AGENT_SERVER);
rRouter.Register<DBProxyServerSession>(GAME_DBPROXY);
rRouter.Register<WorldServerSession>(WORLD_SERVER);
rRouter.Register<MasterServerSession>(MASTER_SERVER);
rRouter.Register<BattleServerSession>(BATTLE_SERVER);
rRouter.Register<FieldServerSession>(FIELD_SERVER);
rRouter.Register<TempServerSessionEx>(TEMP_SERVER);
rRouter.Initialize( AUTH_AGENT_SERVER, 1, 1 );
rRouter.Initialize( GAME_DBPROXY, 1, 1 );
rRouter.Initialize( WORLD_SERVER, 1, 1 );
rRouter.Initialize( MASTER_SERVER, 1, 1 );
rRouter.Initialize( TEMP_SERVER, 10, 5 );
rRouter.Initialize( FIELD_SERVER, 2, 2 );
rRouter.Initialize( BATTLE_SERVER, 5, 5 );
} while(0);
}
AgentServer::~AgentServer()
{
Init_ClearFields();
}
AgentServer* AgentServer::CreateInstance()
{
instance_ = new AgentServer();
return instance_;
}
void AgentServer::DestroyInstance()
{
SAFE_DELETE(instance_);
}
VOID AgentServer::Init_ClearFields()
{
SetPhaseStatus( PHASE_UNKNOWN );
//m_bServiceMode;
//m_skServerKey;
SetDBProxyServerState( SERVER_NORMAL );
db_connector_index_ = 0;
memset( m_pServerSessions, 0, sizeof(m_pServerSessions) );
m_bShutDownProcess = FALSE;
//m_TimerUserCountReport;
//m_TimerServerInfoLog; // 서버정보의 로그를 남기는 타이머.
memset( m_pszWorldServerClientIP, 0, sizeof(m_pszWorldServerClientIP) );
m_wWorldServerClientPort = 0;
SAFE_DELETE( m_pServerPoolRouter );
}
BOOL AgentServer::Init()
{
//////////////////////////////////////////////////////////////////////////
// <환경설정 정보 읽기>
//
// (서비스/콘솔)모드 제어 확인할 것.
DWORD dwShutdownDelayTime = 0;
__READ_CONFIG_NUMBER( m_bServiceMode, "COMMON", "SERVICE_MODE", 0, AGENT_SERVER_INFO_FILE_NAME );
__READ_CONFIG_NUMBER( dwShutdownDelayTime, "ATTRIBUTES", "SHUTDOWN_DELAY_TIME", SHUTDOWN_NOACTION_DELAY_TIME, AGENT_SERVER_INFO_FILE_NAME );
SERVER_EXIT.TotalDelayTime() = dwShutdownDelayTime;
SERVER_EXIT.BlockUserOnRecvDelay() = 5*1000;
DISPMSG( "SHUTDOWN_DELAY_TIME:%u\n", dwShutdownDelayTime );
ASSERT( dwShutdownDelayTime > 0 );
if( !(dwShutdownDelayTime > 0) )
return FALSE;
if( !Init_PoolInfo() )
return FALSE;
;{
// (CHANGES) (f100424.2L) change the server key configuration that the non-master mode has \
// same channel based on the server key. the attribute value of the 'AGENTSERVER_ID' \
// will be represented by the server key read from the agent server configuration file that\
// to support the delvelopment mode multi-channel (1).
if (this->IsServerInfoFromFile())
{
int channel_id = 0;
__READ_CONFIG_NUMBER(channel_id, "SERVER_ADDINFO", "AGENTSERVER_ID", 0,
AGENT_SERVER_INFO_FILE_NAME);
SERVER_KEY change_key = GetKey();
change_key.m_ChannelID = static_cast<BYTE>(channel_id);
SetKey(change_key);
UpdateAppTitle();
}
};
//
CHAR pszWorldClientIP[16];
WORD dwWorldClientPort;
__READ_CONFIG_NUMBER( dwWorldClientPort, "SERVER_ADDINFO", "WORLDSERVER_CLIENT_PORT", 0, AGENT_SERVER_INFO_FILE_NAME );
__READ_CONFIG_STRING_IP( pszWorldClientIP, "SERVER_ADDINFO", "WORLDSERVER_CLIENT_IP", NULL, AGENT_SERVER_INFO_FILE_NAME );
SetWorldServerClientAddr( pszWorldClientIP, dwWorldClientPort );
__READ_CONFIG_NUMBER( m_bPVPMode, "SERVER_ADDINFO", "PVP_MODE", 1, AGENT_SERVER_INFO_FILE_NAME );
// SetChannelID( pServerEnv->wAgentServerID ); //< 채널 ID
//m_ServerKey.Set( (BYTE)m_ServerKey.GetWorldID(), (BYTE)pServerEnv->wAgentServerID, (BYTE)GetServerType(), (BYTE)m_ServerKey.GetServerID() );
Init_Logger();
// Agent 서버 시작 로그
SUNLOG( eCRITICAL_LOG, "*** 덜잿륩蛟역迦 ***" );
SUNLOG( eCRITICAL_LOG, "*** 덜잿륩蛟경굶뵀 = %d ***", SERVER_RELEASE_BUILD_NO );
#ifdef _NA_20100802_SPEED_HACK_DETECTION
TickSpeedChecker::LoadSettings(_T(".\\AgentServer.TickSpeedChecker.ini"));
if (TickSpeedChecker::IsGloballyEnabled())
{
CHAR log_file_path[256];
__READ_CONFIG_STRING(log_file_path, "LOGFILE", "SUN_LOGFILE_PATH", NULL, AGENT_SERVER_INFO_FILE_NAME);
TickSpeedChecker::CreateLogFile(log_file_path);
}
#endif
//////////////////////////////////////////////////////////////////////////
PacketHandler::RegisterHandler();
WorkLoadManager::CreateInstance();
UserManager::CreateInstance();
//
// (WAVERIX) (NOTE)
//ServerSessionManager::CreateInstance();
//
//-------------------------------------------------------------------------------------------------
// 유저 관련 정보 초기화
//-------------------------------------------------------------------------------------------------
g_ConnTimeoutFactory.InitPool( 5000 );
g_TimeKeeper.InitTimeKeeper( 5000 );
// (WAVERIX) (090520) (CHANGES) 스크립트 로딩 이후로 처리 시점 변경
//g_ZoneManager.CreateCharSelect();
// 파티매니저 초기화
AgentPartyManager::Instance()->Initialize( 1000 );
if( !Init_ScriptData( IsServerInfoFromFile() ) )
{
P_FAILED;
return FALSE;
}
P_SUCCESS;
m_TimerUserCountReport.SetTimer( 10000 );
if(Init_SecureLogic() == FALSE)
return FALSE;
// _NA_005026_20120527_CHAOS_ZONE_BATTLE_GROUND
BattleGroundManager::Instance()->Init();
#ifdef _NA_006620_20130402_GM_BATTLE_GROUND_EVENT_GAME
TeamBattleGroundManager::Instance()->Init();
#endif //_NA_006620_20130402_GM_BATTLE_GROUND_EVENT_GAME
#ifdef _NA_008334_20150608_SONNENSCHEIN
SonnenScheinManager::Instance()->Init();
#endif //_NA_008334_20150608_SONNENSCHEIN
#ifdef _NA_008543_20151027_ONE_DAYS_GUILD_MISSION
OneDaysGuildMissionManager::Instance()->Init();
#endif //(_NA_008543_20151027_ONE_DAYS_GUILD_MISSION)
// 서버 정보 로그 초기화~
// ServerInfoLogCycle
#if !defined(__WAVERIX_SOLAR_AUTH_SERVER_IMPLEMENTATION__)
StartServer();
#endif
do
{
PROCESS_AGENTSERVER_PERIODIC_WORKLOAD* pWorkNode = new PROCESS_AGENTSERVER_PERIODIC_WORKLOAD();
// (KEYWORD:CCU)
m_wkPeriodicWorkKey = WorkLoadManager::RegisterTask( pWorkNode );
} while(0);
m_BattleJoinTimer.SetTimer( 30000 );
m_RegisterTimer.SetTimer( 1000 );
return TRUE;
}
VOID AgentServer::Release()
{
SetPhaseStatus( PHASE_UNKNOWN );
PacketHandler::ReleaseHandler();
#if USING_HACKSHIELD
AHNHS_SERVER_HANDLE hHANDLEofHS = s_SECURE_INIT_PRE_ENTRY.GetHANDLEofHS();
_AhnHS_CloseServerHandle( hHANDLEofHS );
s_SECURE_INIT_PRE_ENTRY.SetHANDLEofHS( ANTICPX_INVALID_HANDLE_VALUE );
#elif USING_XIGNCODE
ns_secure::XignCode_Uninitialize();
#elif USING_FROST
#elif USING_GAMEGUARD
GameGuard::Instance()->release();
SUNLOG(eCRITICAL_LOG, "["__FUNCTION__"] Release GameGuard!");
#endif
if( m_pAgentScriptParserManager )
{
m_pAgentScriptParserManager->Release();
m_pAgentScriptParserManager->DestroyInstanceEx();
SAFE_DELETE( m_pAgentScriptParserManager );
}
//-------------------------------------------------------------------------------------------------
// 유저 관련 정보 해제
//-------------------------------------------------------------------------------------------------
g_TimeKeeper.ReleaseTimeKeeper();
g_ConnTimeoutFactory.ReleasePool();
//UserManager::Instance()->ReleaseAllUser();
SUNLOG( eCRITICAL_LOG, "*** AgentServer Close ***" );
}
VOID AgentServer::DoFinalize()
{
WorkLoadManager::DestroyInstance();
ServerSessionManager::DestroyInstance();
PortalManager::DestroyInstance(); // UserManager와 AgentPartyManager를 사용하기 때문에 둘보다 먼저 해제한다.
UserManager::DestroyInstance();
// 유저 OnDisconnect시 LeaveParty를 해야하므로 PartyManager 해제는 유저처리보다 나중에 한다.
AgentPartyManager::Instance()->Release(); AgentPartyManager::DestroyInstance();
#ifdef _NA_0_20110329_GAMEOPTION_SETTING
GameOptionManager::DestroyInstance();
#endif
ServerOptionParser::Instance()->Release(); ServerOptionParser::DestroyInstance();
// _NA_005026_20120527_CHAOS_ZONE_BATTLE_GROUND
AgentChaosZoneManager::DestroyInstance();
BattleGroundManager::Instance()->Release(); BattleGroundManager::DestroyInstance();
//_NA_006620_20130402_GM_BATTLE_GROUND_EVENT_GAME
TeamBattleGroundManager::Instance()->Release();
TeamBattleGroundManager::DestroyInstance();
//_NA_006088_20120910_CHAOS_ZONE_FREE_PVP
FreePVPManager::DestroyInstance();
SUNLOG( eCRITICAL_LOG, "*** AgentServer Close ***" );
// 게임로그
SAFE_DELETE(g_pLOG);
// SUNLOG
SAFE_DELETE(g_pSunLog);
SAFE_DELETE(g_pSecureLog);
SAFE_DELETE(g_pSunConnLog);
SAFE_DELETE(g_pSecureModuleLog);
}
BOOL AgentServer::Update( DWORD dwTick )
{
// Shutdown Process
// ...
if( SERVER_EXIT.IsShutDown() )
return FALSE;
// TODO: make to general timer
const util::ServerTimeInfoPerFrame& time_info = this->GetTimeInfoPerFrame();
WorkLoadManager::Update();
// timeout 관리 업데이트
g_TimeKeeper.Update();
g_ZoneManager.Process();
#ifdef _NA_004517_20120312_GAME_OPTION_TRANSACTION
GameOptionManager::Instance()->Update();
#endif // _NA_004517_20120312_GAME_OPTION_TRANSACTION
if( g_pSunLog ) g_pSunLog->Update();
if( g_pSecureLog ) g_pSecureLog->Update();
if( g_pSunConnLog ) g_pSunConnLog->Update();
if (g_pSecureModuleLog) {
g_pSecureModuleLog->Update();
}
g_BattleOpenTimeMng.Update(time_info);
#ifdef _NA004034_20120102_GUILD_POINT_SYSTEM
g_GuildRankingSystem.UpdateGuildRanking();
#endif //_NA004034_20120102_GUILD_POINT_SYSTEM
#ifdef _NA_008679_20160202_REWORK_BATTLEGROUND
BattleGroundManager::Instance()->Update(time_info);
#endif // _NA_008679_20160202_REWORK_BATTLEGROUND
#if USING_DUMMY_CLIENT
test_unit::UpdateDummyClient();
#endif
return TRUE;
}
VOID AgentServer::DisplayPoolInfo()
{
DISPMSG( "================= Pool Info =================\n" );
g_ZoneManager.DisplayerZonePoolInfo();
}
BOOL AgentServer::KeyEvent( CHAR ch )
{
MSG_CW_TEST_WEB msg;
switch(ch)
{
case 0x1B:
SERVER_EXIT.StartServerExitProcess();
return FALSE;
case ' ':
g_ZoneManager.Display();
AgentPartyManager::Instance()->Display();
//_NA_000000_20150507_TIME_DISPLAY
DisplayCurrentServerTime();
break;
#if USING_DUMMY_CLIENT
case 'D':
test_unit::StartDummyClient();
break;
#endif
case 'P': DisplayPoolInfo(); break;
case 'U': //xiaomi 警속쐙컇箇돕Field 관
if(SendToServerByIndex(FIELD_SERVER,&msg,sizeof(msg))){
DISPMSG( "Success\n" );
}else{
DISPMSG( "Faield\n" );
}
break;
case 'S':
#ifdef _DEBUG
PACKET_CONTROL::SetShowPacketStream( !PACKET_CONTROL::GetShowPacketStream() );
#endif
break;
case 'T':
#ifdef __WAVERIX_TEST_LOGIC_TASK_MACRO__
WaverixTestUnit();
#endif
break;
}
return TRUE;
}
BOOL AgentServer::SendToServerByIndex( eSERVER_TYPE stServerType, MSG_BASE* pMsg, WORD wSize )
{
BOOL bProcess = (BOOL)(MAX_SERVER > stServerType);
ServerSessionEx* pSession = NULL;
if( bProcess )
pSession = m_pServerSessions[stServerType];
if( bProcess )
{
if( pSession && pSession->IsConnected() )
return pSession->SendPacket( pMsg, wSize );
}
else
{
SUNLOG( eCRITICAL_LOG, _T("잘못된 서버타입으로 패킷 전송시도 %d"), stServerType );
}
return FALSE;
}
BOOL AgentServer::SendToAuthAgentServer( BYTE* pMsg, WORD wSize )
{
ServerSessionEx* pSession = m_pServerSessions[AUTH_AGENT_SERVER];
if( pSession && pSession->IsConnected() )
return pSession->Send( (BYTE*)pMsg, wSize );
return FALSE;
}
class SendToGameServerOp
{
private: MSG_BASE* m_pMsg;
WORD m_wSize;
public: SendToGameServerOp( MSG_BASE* pMsg, WORD wSize ) : m_pMsg(pMsg), m_wSize(wSize) {}
VOID operator() ( ServerSessionEx* pServerSession )
{
pServerSession->SendPacket( m_pMsg, m_wSize );
}
};
VOID AgentServer::SendToGameServer( MSG_BASE* pMsg, WORD wSize )
{
SendToGameServerOp op( pMsg, wSize );
ServerSessionManager::Instance()->Foreach( op );
}
BOOL AgentServer::IsConnectedTo( eSERVER_TYPE eServerType )
{
if( MAX_SERVER > eServerType )
{
ServerSessionEx* pSession = m_pServerSessions[eServerType];
if( pSession )
return pSession->IsConnected();
SUNLOG( eCRITICAL_LOG, _T("Undefined ConnectionType") );
return FALSE;
}
SUNLOG( eCRITICAL_LOG, _T("Undefined ServerType.") );
return FALSE;
}
BOOL AgentServer::ConnectTo( eSERVER_TYPE serverType )
{
ServerSession* pSession = NULL;
switch( serverType )
{
case MASTER_SERVER:
case GAME_DBPROXY:
case AUTH_AGENT_SERVER:
case WORLD_SERVER:
pSession = m_pServerSessions[serverType];
break;
}
if( !pSession ) return FALSE;
#ifndef __WAVERIX_SOLAR_AUTH_SERVER_IMPLEMENTATION__
if( pSession->IsConnecting() || pSession->IsConnected() )
{
ASSERT( !"중복 Connect 시도" );
return FALSE;
}
Connect( pSession );
return TRUE;
#else //
if( ! IsServerInfoFromFile() )
{
if( (MASTER_SERVER != serverType) && (GetPhaseStatus() != PHASE_SERVICE) )
return FALSE;
}
if( !( pSession->IsConnecting() || pSession->IsConnected() ) )
{
if( (MASTER_SERVER != serverType)
&& (! IsServerInfoFromFile() )
&& (GetPhaseStatus() != PHASE_SERVICE) )
return FALSE;
Connect( pSession );
return TRUE;
}
ASSERT( !"중복 Connect 시도" );
return FALSE;
#endif //
}
ServerSession* AgentServer::AllocServerSession( eSERVER_TYPE serverType )
{
ServerSession* pSession = (ServerSession*)m_pServerPoolRouter->Alloc( (DWORD)serverType );
if( pSession )
{
//GAME_DBPROXY:
//WORLD_SERVER:
//MASTER_SERVER:
//GUILD_SERVER:
//AUTH_AGENT_SERVER:
m_pServerSessions[serverType] = (ServerSessionEx*)pSession;
pSession->Init( this );
return pSession;
}
// ASSERT( !"존재하지 않는 서버타입입니다." );
return NULL;
}
VOID AgentServer::FreeServerSession( ServerSession* pServerSession )
{
((ServerSession*)pServerSession)->Release();
eSERVER_TYPE serverType = pServerSession->GetServerType();
m_pServerPoolRouter->Free( (DWORD)serverType, pServerSession );
}
VOID AgentServer::StartServerSideListen()
{
Listen( SERVER_IOHANDLER );
}
VOID AgentServer::StartClientSideListen()
{
Listen( CLIENT_IOHANDLER );
}
//------------------------------------------------------------------------------------------------
// 클라이언트 콜백
//------------------------------------------------------------------------------------------------
NetworkObject* AgentServer::CreateClientSideAcceptedObject()
{
return UserManager::Instance()->AllocUser( UT_TEMP_USER );
}
VOID AgentServer::DestroyClientSideAcceptedObject( NetworkObject* pNetworkObject )
{
UserManager::Instance()->FreeUser( (UserSession *)pNetworkObject );
}
VOID AgentServer::DestroyClientSideConnectedObject( NetworkObject* pNetworkObject )
{
ASSERT( !"들어 올 수 없음" );
}
//------------------------------------------------------------------------------------------------
// 서버 콜백
//------------------------------------------------------------------------------------------------
NetworkObject* AgentServer::CreateServerSideAcceptedObject()
{
ServerSession* pServerSession = GetInstance()->AllocServerSession( TEMP_SERVER );
return pServerSession;
}
VOID AgentServer::DestroyServerSideAcceptedObject( NetworkObject* pNetworkObject )
{
ServerSession * pServerSession = (ServerSession *)pNetworkObject;
GetInstance()->FreeServerSession( (ServerSession *)pNetworkObject );
}
VOID AgentServer::DestroyServerSideConnectedObject( NetworkObject* pNetworkObject )
{
// Nothing to do
//ServerSession *pServerSession = (ServerSession*)pNetworkObject;
//ServerSessionFactory::Instance()->FreeServerSession( (ServerSession *)pNetworkObject );
}
//------------------------------------------------------------------------------------------------
// 콘솔 메시지 콜백
//------------------------------------------------------------------------------------------------
VOID CallBackCommand( CHAR* szMessage )
{
switch(szMessage[0])
{
case 'c':
{
//DISPMSG( "[CallBackCommand ]Server Session :(%d) \n", AgentServer::GetInstance()->m_pIOCPServer->GetNumberOfConnections( AgentServer::SERVER_IOHANDLER ) );
}
break;
case 'i':
{
}
break;
}
}
// 모든 데이터 로딩이 완료되었을 경우 콜백으로 호출될 것이다.
VOID AgentServer::StartServer()
{
// <해야 할 일>
// 1. FieldServer에 접속되어 있는지?
// 2. 네트워크를 통해 필요한 모든 데이터를 받았는지? <-- 여기 들어왔다는 것은 파일로부터 읽지 않았다는 의미
// 3. <1,2>의 조건을 만족하면, CreateVillage를 호출한다.
// 그런데, FieldServer::init에 의하면 접속될 때마다 CreateVillage를 호출하는 데... 맞나?
// 한번만 호출하도록 해보자.
//
// <NOTICE>
// 이것이 호출되었다는 의미는 필요한 모든 데이터를 받았다는 의미다.
// 따라서 FieldServer의 접속 여부와 CreateVillage의 호출 여부가 될 것이다.
// 계속해서 감시할 필요가 있다. <필요인자: g_AgentServer, AgentServer::GetInstancee()->m_FieldServer>
// <THINKING>
// FieldServer가 끊어졌을 경우... 일단 재접될 것이며, 이때는...
AgentServer* const pAgentServer = AgentServer::GetInstance();
if( !WarControlManager::GetWorkKey() )
{
WarControlManager* pWorkNode = new WarControlManager();
const WORK_KEY wKey = WorkLoadManager::RegisterTask( pWorkNode );
WarControlManager::SetWorkKey( wKey );
}
// (WAVERIX) (090520) (CHANGES) 스크립트 로딩 이후로 처리 시점 변경
// (WAVERIX) (090712) (BUG-FIX) SolarAuth 연결 구조일 경우, 데이터 수신 완료 콜백으로 이것이
// 호출된다. 따라서 재 초기화가 발생한다. 해당 문제 수정.
static BOOLEAN s_bInited = 0;
if(s_bInited == 0)
{
g_ZoneManager.CreateCharSelect();
#ifdef __NA000000_081029_STATIC_ZONE_MATCHING_TABLE__
g_ZoneManager.CreateConstStaticZoneTable();
#endif
#ifdef _APPLY_NHN_FILTERFING
int result = IAF::LoadAbuseDB();
// error handling?
if(result != 0) {
SUNLOG(eCRITICAL_LOG, "Fail to load IAF LoadAbuseDB %d", result);
}
else {
SUNLOG(eCRITICAL_LOG, "Success to load IAF");
}
#endif
s_bInited = true;
}
#ifdef __WAVERIX_SOLAR_AUTH_SERVER_IMPLEMENTATION__
// 현 시점 PHASE_EXCHANGE일 것이다.
MSG_SERVERCOMMON_DATA_TRANSFER_SENDDATA_NTF msgNTF;
pAgentServer->SessionMasterServer()->Send( (BYTE*)&msgNTF, sizeof(msgNTF) );
//ServerSessionManager::Instance()->RegisterEvent_OnAcceptFieldServer( TRUE );
#endif //__WAVERIX_SOLAR_AUTH_SERVER_IMPLEMENTATION__
}
//////////////////////////////////////////////////////////////////////////
BOOL AgentServer::Init_PoolInfo()
{
sPOOL_SIZE_INFO rINFO;
switch( GetMode() )
{
case eSERVER_LIVE:
rINFO.dwUserPoolBase = 3500;
rINFO.dwUserPoolExtend = 100;
rINFO.dwTempUserPoolBase = 1000;
rINFO.dwTempUserPoolExtend = 100;
break;
case eSERVER_TESTLIVE:
rINFO.dwUserPoolBase = 1000;
rINFO.dwUserPoolExtend = 100;
rINFO.dwTempUserPoolBase = 100;
rINFO.dwTempUserPoolExtend = 100;
break;
default:
rINFO.dwUserPoolBase = 10;
rINFO.dwUserPoolExtend = 10;
rINFO.dwTempUserPoolBase = 10;
rINFO.dwTempUserPoolExtend = 10;
break;
}
BOOL bRet = ObjectPoolRouter::Instance()->InitializeByPoolInfo( &rINFO );
if( bRet ) DISPMSG( "INIT OBJPOOL SUCCESS\n" );
else
{
DISPMSG( "INIT OBJPOOL FAIL\n" );
return FALSE;
}
return TRUE;
}
BOOL AgentServer::Init_ScriptData( BOOL bReadFromFile )
{
// 스크립트 초기화 순서에 따라 영향을 받는 스크립트가 존재하므로 이 순서를 지켜주자.
m_pAgentScriptParserManager = new AgentScriptParserManager;
m_pAgentScriptParserManager->RegisterParser();
m_pAgentScriptParserManager->InitParserPool( NULL );
#ifdef __WAVERIX_SOLAR_AUTH_SERVER_IMPLEMENTATION__ //솔라오스할때는 Load를 나중에 한다.
return TRUE;
#else
return m_pAgentScriptParserManager->Load();
#endif
}
BOOL AgentServer::Init_Logger()
{
//-------------------------------------------------------------------------------------------------
// 로그 파일 정보 초기화
//-------------------------------------------------------------------------------------------------
BYTE bySunLogOption, bySunLogFileLevel;
CHAR pszLogFilePath[256];
__READ_CONFIG_NUMBER( bySunLogOption, "LOGFILE", "SUN_LOGFILE_OPTION", 0, AGENT_SERVER_INFO_FILE_NAME );
__READ_CONFIG_NUMBER( bySunLogFileLevel, "LOGFILE", "SUN_LOGFILE_LEVEL", 0, AGENT_SERVER_INFO_FILE_NAME );
__READ_CONFIG_STRING( pszLogFilePath, "LOGFILE", "SUN_LOGFILE_PATH", NULL, AGENT_SERVER_INFO_FILE_NAME );
//1. AgentLog
g_pSunLog = new CSunLog;
if( g_pSunLog->Init(bySunLogOption, bySunLogFileLevel, pszLogFilePath, "Agent") == false )
DISPMSG( "SUNLOG Initialize Failed...\n" );
//2. 보안로그
g_pSecureLog = new SecureLog();
if( g_pSecureLog->Init(bySunLogOption, bySunLogFileLevel, pszLogFilePath, "Secure", FALSE) )
{
g_pSecureLog->RegisterHandler( SecureLog::WriteMessage_Network );
// 초기화 되었을 때, 수행
//MessageSecure( eCRITICAL_LOG, _T("HELLO") );
//g_pSecureLog->Update();
//g_pSecureLog->Flush();
}
//3. ConnLog
g_pSunConnLog = new CSunLog;
if( g_pSunConnLog->Init(bySunLogOption, bySunLogFileLevel, pszLogFilePath, "AgentConn") == false )
DISPMSG( "SUNCONNLOG Initialize Failed...\n" );
#if USING_XIGNCODE
g_pSecureModuleLog = new CSunLog;
if (g_pSecureModuleLog->Init(bySunLogOption, bySunLogFileLevel, pszLogFilePath, "XignCode") == false)
{
DISPMSG("XignCodeLogger Initialize Failed...\n");
}
#endif
BYTE byLogOption;
__READ_CONFIG_NUMBER( byLogOption, "LOGFILE", "WOPS_LOGFILE_OPTION", 0, AGENT_SERVER_INFO_FILE_NAME );
__READ_CONFIG_STRING( pszLogFilePath, "LOGFILE", "WOPS_LOGFILE_PATH", NULL, AGENT_SERVER_INFO_FILE_NAME );
DISPMSG( "눼쉔踏狗휑羚...\n" );
g_pLOG = new AgentLog;
if( _access( pszLogFilePath, 0 ) == -1 )
{
if( !CreateDirectory(pszLogFilePath, NULL) )
printf( "눼쉔커쩌呵겨, 쨌쓺 = %s \n", pszLogFilePath );
}
TCHAR szBinPath[MAX_PATH], szTextPath[MAX_PATH];
strncpy(szBinPath, pszLogFilePath, MAX_PATH);
strcat(szBinPath, "\\\\AGENT");
strncpy(szTextPath, pszLogFilePath, MAX_PATH);
strcat(szTextPath, "\\\\AGENT_TEXT");
#ifdef __NA_0_ADD_VERSION_TO_LOG_FILE_NAME
TCHAR szFileName[MAX_PATH];
_sntprintf( szFileName, MAX_PATH, "%d_SUN_AGENT", NATION_BUILD_VERSION );
if( !g_pLOG->Init( byLogOption, szFileName, _T(szBinPath), _T(szTextPath) ) )
#else
if( !g_pLOG->Init( byLogOption, _T("SUN_AGENT"), _T(szBinPath), _T(szTextPath) ) )
#endif
DISPMSG( "GameLog File Failed...\n" );
// else
//DISP_OK;
return TRUE;
}
//BOOL AgentServer::CheckServerMode()
//{
// SERVER_ENV* pEnv = m_pFileParser->GetServerEnv();
// if( !pEnv ) return FALSE;
//
// //라이브나 테섭이면 무조건 0, 1이여야 한다.
// if( pEnv->byServerStatus == 3 || pEnv->byServerStatus == 4 ) //라이브(3)나 테섭(4)이면..
// {
// if( (pEnv->byFieldServerType == 0) && (pEnv->byBattleServerType == 1) )
// return TRUE;
//
// return FALSE;
// }
//
// return TRUE;
//}
//━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
//
BOOL AgentServer::Init_SecureLogic()
{
// MOLA LIBRARY Initialize
CryptManager::Init1st();
//--------------------------------------------------------------------------------------------
// <BEGIN> 패킷 암호화 관련 설정
//
// <070110, Waverix> 적용으로... 그 주기에 달려있다.
do
{
//eCRYPTOGRAPHY_KEY_CHANGE_TIMEOUT
DWORD dwServerMode = (DWORD)GetMode();
//printf( "CHECK ROUTINE Init_SecureLogic\n" );
RandomTimeUtil::Initialize( dwServerMode );
SecureManager* pWorkNode = new SecureManager();
pWorkNode->SetInformation( RandomTimeUtil::SECURE_MANAGER_UPDATE_INTERVAL(), RandomTimeUtil::USER_KEYCHANGE_TIMEOUT() );
WorkLoadManager::RegisterTask( pWorkNode );
} while(0);
//
// <END>
//--------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------
// Heartbeat처리 관련
do
{
//--------------------------------------------------------------------------------------------
// Heartbeat처리 관련
PROCESS_HEARTBEAT_VALUATION* pWorkNode = new PROCESS_HEARTBEAT_VALUATION;
sHEARTBEAT_VALUATION_INFO sINFO;
sINFO.m_dwCheckUserValuationPeriod = 30*RandomTimeUtil::SECOND; // 30초마다 전체 유저들을 대상으로 한 평가 수행
//sINFO.m_dwHeartbeatTick = 500; //HEARTBEAT_TICK;
//sINFO.m_dwValuationPeriod = 500*30; //HEARTBEAT_TICK*30;
sINFO.m_dwHeartbeatTick = HEARTBEAT_TICK;
sINFO.m_dwValuationPeriod = HEARTBEAT_TICK*30;
sINFO.m_bUseArmorKitHeartbeat = FALSE;
pWorkNode->SetInformation( &sINFO );
WorkLoadManager::RegisterTask( pWorkNode );
} while(0);
#if USING_HACKSHIELD && !defined(_DEBUG)
// init HackShield
do {
// filepath 읽어들이는 경로 변경 가능하게 설정할 것
// hsb파일 경로
CHAR tmp[512];
CHAR pszFilePath[512];
GetCurrentDirectory( sizeof(tmp), tmp );
_snprintf( pszFilePath, sizeof(pszFilePath), "%s%s", tmp, "\\AntiCpx.hsb" );
//CHAR* pszFilePath =
//"D:/PROJECT/SUN.MOLA/ForeignVersion/Server/_bin/GameClient_Debug.exe.hsb";
// "S:\\AntiCpx.hsb";
//"./AntiCpX.hsb";
printf( "path %s\n", pszFilePath );
AHNHS_SERVER_HANDLE hHANDLEofHS = _AhnHS_CreateServerObject( pszFilePath );
if( ANTICPX_INVALID_HANDLE_VALUE == hHANDLEofHS )
{
MessageOut( eCRITICAL_LOG, _T("Can't Create HackShield Instance") );
return FALSE;
}
s_SECURE_INIT_PRE_ENTRY.SetHANDLEofHS( hHANDLEofHS );
} while(0);
#elif USING_XIGNCODE /*&& !defined(_DEBUG)*/
if (ns_secure::XignCode_Initilize() == false) {
DISPMSG( "Can't Create SignCode Instance\n" );
return false;
}
#elif USING_FROST
#elif USING_GAMEGUARD
UINT32 gameguard_result = GameGuard::Instance()->init();
if (gameguard_result != ERROR_SUCCESS) {
DISPMSG( "GameGuard Initialize Failed!\n" );
return false;
}
else {
DISPMSG( "GameGuard Initialize Success!\n" );
}
#endif
#ifdef __WAVERIX_SECURITY_TEST__
static DWORD dwKeyInc = 100;
for( DWORD i=0 ; i<100 ; ++i )
{
User* pUser = (User*)UserManager::Instance()->AllocUser( UT_USER );
pUser->SetAuthID( dwKeyInc++ );
pUser->SetUserKey( dwKeyInc++ );
//g_pUser->GetHeartbeatChecker()->SetEnable( TRUE );
UserCrypts::AddCryptedUser( pUser );
UserManager::Instance()->AddUser( pUser );
}
#endif //__WAVERIX_SECURITY_TEST__
return TRUE;
}
//_NA_000000_20150507_TIME_DISPLAY
VOID AgentServer::DisplayCurrentServerTime()
{
SYSTEMTIME cur_time;
util::TimeSync::GetLocalTime(&cur_time);
__time64_t timevalue;
util::TimeSync::_time64(&timevalue);
SUNLOG(eCRITICAL_LOG, "CurServerTime_timevalue: %d", timevalue);
SUNLOG(eCRITICAL_LOG, "CurServerTime: [%d.%d.%d] [%d:%d:%d]", cur_time.wYear,
cur_time.wMonth, cur_time.wDay, cur_time.wHour, cur_time.wMinute, cur_time.wSecond);
}
//==================================================================================================
//==================================================================================================
//==================================================================================================