366 lines
10 KiB
C++
366 lines
10 KiB
C++
#include "stdafx.h"
|
|
#include "SunUpdateServer.h"
|
|
|
|
#include <IOCPServer.h>
|
|
#include <NetworkObject.h>
|
|
#include <PublicDefine.h>
|
|
#include "ServerScriptParser.h"
|
|
#include "ServerStruct.h"
|
|
#include <conio.h>
|
|
#include "PacketHandler.h"
|
|
#include "UserSessionFactory.h"
|
|
#include "UserManager.h"
|
|
#include "ServerSessionFactory.h"
|
|
#include "ServerSessionManager.h"
|
|
#include "UserInfoParser.h"
|
|
#include "ServerInfoParser.h"
|
|
#include "AgentInfoParser.h"
|
|
#include "AccessInfoParser.h"
|
|
#include "WorldManager.h"
|
|
#include "FtpInfoParser.h"
|
|
|
|
#ifdef _NA_006543_20130318_HEARTBEAT
|
|
#include "ServerSessionManager.h"
|
|
#endif
|
|
|
|
|
|
/************************************************************************/
|
|
/* 콜백함수 */
|
|
/************************************************************************/
|
|
NetworkObject* CreateClientSideAcceptedObject();
|
|
VOID DestroyClientSideAcceptedObject( NetworkObject * pNetworkObject );
|
|
VOID DestroyClientSideConnectedObject( NetworkObject * pNetworkObject );
|
|
|
|
NetworkObject* CreateServerSideAcceptedObject();
|
|
VOID DestroyServerSideAcceptedObject( NetworkObject * pNetworkObject );
|
|
VOID DestroyServerSideConnectedObject( NetworkObject * pNetworkObject );
|
|
|
|
|
|
SunUpdateServer::SunUpdateServer()
|
|
{
|
|
m_pIOCPServer = NULL;
|
|
m_bIsShutDown = FALSE;
|
|
m_dwFPS = 0;
|
|
}
|
|
|
|
SunUpdateServer::~SunUpdateServer()
|
|
{
|
|
|
|
}
|
|
|
|
VOID SunUpdateServer::Release()
|
|
{
|
|
//-------------------------------------------------------------------------------------------------
|
|
// IOCP 해제
|
|
//-------------------------------------------------------------------------------------------------
|
|
|
|
if( m_pIOCPServer )
|
|
{
|
|
m_pIOCPServer->Shutdown();
|
|
SAFE_DELETE( m_pIOCPServer );
|
|
}
|
|
|
|
ServerSessionFactory::Instance()->DestroyInstance();
|
|
ServerSessionManager::Instance()->Release(); ServerSessionManager::Instance()->DestroyInstance();
|
|
UserSessionFactory::Instance()->Release(); UserSessionFactory::Instance()->DestroyInstance();
|
|
UserManager::Instance()->Release(); UserManager::Instance()->DestroyInstance();
|
|
|
|
UserInfoParser::DestroyInstance();
|
|
ServerInfoParser::DestroyInstance();
|
|
AgentInfoParser::DestroyInstance();
|
|
PacketHandler::Instance()->DestroyInstance();
|
|
|
|
WorldManager::Instance()->Release(); WorldManager::DestroyInstance();
|
|
}
|
|
|
|
BOOL SunUpdateServer::Init()
|
|
{
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// XML 데이터 파싱
|
|
if( !UserInfoParser::Instance()->Load( "UserInfo.xml" ) )
|
|
{
|
|
MessageBox( NULL, "UserInfo.xml 로드 실패", NULL, MB_OK );
|
|
return FALSE;
|
|
}
|
|
|
|
if( !ServerInfoParser::Instance()->Load( "ServerInfo.xml") )
|
|
{
|
|
MessageBox( NULL, "ServerInfo.xml 로드 실패", NULL, MB_OK );
|
|
return FALSE;
|
|
}
|
|
|
|
if( !AgentInfoParser::Instance()->Load( "AgentInfo.xml") )
|
|
{
|
|
MessageBox( NULL, "AgentInfo.xml 로드 실패", NULL, MB_OK );
|
|
return FALSE;
|
|
}
|
|
|
|
if( !AccessInfoParser::Instance()->Load( "AccessInfo.xml") )
|
|
{
|
|
MessageBox( NULL, "AccessInfo.xml 로드 실패", NULL, MB_OK );
|
|
return FALSE;
|
|
}
|
|
|
|
if( !FtpInfoParser::Instance()->Load( "FTPInfo.xml") )
|
|
{
|
|
MessageBox( NULL, "FTPInfo.xml 로드 실패", NULL, MB_OK );
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
// World, Channel, UnitServer 구성
|
|
WorldManager::Instance()->MakeWorld();
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// 서버 스크립트 읽고 구조체에 적용.
|
|
if( !ServerScriptParser::Instance()->Load("./UpdateServer.ini") )
|
|
{
|
|
MSGOUT( "UpdateServer.ini 로드 실패" );
|
|
return FALSE;
|
|
}
|
|
|
|
SERVER_ENV* pServerEnv = ServerScriptParser::Instance()->GetServerEnv();
|
|
if( !pServerEnv )
|
|
{
|
|
MSGOUT( "pServerEnv 가져오기 실패" );
|
|
return FALSE;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Factory Creator
|
|
ServerSessionFactory::Instance()->Init( pServerEnv->ServerIoHandler.dwMaxAcceptSession );
|
|
UserSessionFactory::Instance()->Init( pServerEnv->ClientIoHandler.dwMaxAcceptSession );
|
|
UserManager::Instance()->Init( pServerEnv->ClientIoHandler.dwMaxAcceptSession );
|
|
|
|
IOHANDLER_DESC desc[2];
|
|
desc[0].dwIoHandlerKey = CLIENT_IOHANDLER;
|
|
desc[0].dwMaxAcceptSession = pServerEnv->ClientIoHandler.dwMaxAcceptSession;
|
|
desc[0].dwMaxConnectSession = pServerEnv->ClientIoHandler.dwMaxConnectSession;
|
|
desc[0].dwSendBufferSize = pServerEnv->ClientIoHandler.dwSendBufferSize;
|
|
desc[0].dwRecvBufferSize = pServerEnv->ClientIoHandler.dwRecvBufferSize;
|
|
desc[0].dwTimeOut = pServerEnv->ClientIoHandler.dwTimeOut;
|
|
desc[0].dwNumberOfAcceptThreads = pServerEnv->ClientIoHandler.dwNumberOfAcceptThreads;
|
|
desc[0].dwNumberOfIoThreads = pServerEnv->ClientIoHandler.dwNumberOfIoThreads;
|
|
desc[0].dwNumberOfConnectThreads = pServerEnv->ClientIoHandler.dwNumberOfConnectThreads;
|
|
desc[0].dwMaxPacketSize = pServerEnv->ClientIoHandler.dwMaxPacketSize;
|
|
desc[0].fnCreateAcceptedObject = CreateClientSideAcceptedObject;
|
|
desc[0].fnDestroyAcceptedObject = DestroyClientSideAcceptedObject;
|
|
desc[0].fnDestroyConnectedObject = DestroyClientSideConnectedObject;
|
|
|
|
m_strOutSideIP = pServerEnv->ClientIoHandler.szIP;
|
|
m_wOutSidePort = pServerEnv->ClientIoHandler.wPort;
|
|
|
|
desc[1].dwIoHandlerKey = SERVER_IOHANDLER;
|
|
desc[1].dwMaxAcceptSession = pServerEnv->ServerIoHandler.dwMaxAcceptSession;
|
|
desc[1].dwMaxConnectSession = pServerEnv->ServerIoHandler.dwMaxConnectSession;
|
|
desc[1].dwSendBufferSize = pServerEnv->ServerIoHandler.dwSendBufferSize;
|
|
desc[1].dwRecvBufferSize = pServerEnv->ServerIoHandler.dwRecvBufferSize;
|
|
desc[1].dwTimeOut = pServerEnv->ServerIoHandler.dwTimeOut;
|
|
desc[1].dwNumberOfAcceptThreads = pServerEnv->ServerIoHandler.dwNumberOfAcceptThreads;
|
|
desc[1].dwNumberOfIoThreads = pServerEnv->ServerIoHandler.dwNumberOfIoThreads;
|
|
desc[1].dwNumberOfConnectThreads = pServerEnv->ServerIoHandler.dwNumberOfConnectThreads;
|
|
desc[1].dwMaxPacketSize = pServerEnv->ServerIoHandler.dwMaxPacketSize;
|
|
desc[1].fnCreateAcceptedObject = CreateServerSideAcceptedObject;
|
|
desc[1].fnDestroyAcceptedObject = DestroyServerSideAcceptedObject;
|
|
desc[1].fnDestroyConnectedObject = DestroyServerSideConnectedObject;
|
|
|
|
m_strInSideIP = pServerEnv->ServerIoHandler.szIP;
|
|
m_wInnerPort = pServerEnv->ServerIoHandler.wPort;
|
|
|
|
|
|
m_pIOCPServer = new IOCPServer;
|
|
if( !m_pIOCPServer->Init( desc, 2 ) )
|
|
return FALSE;
|
|
|
|
MSGOUT( ">> client-side max connection: accept(%d), connect(%d)", desc[0].dwMaxAcceptSession, desc[0].dwMaxConnectSession );
|
|
MSGOUT( ">> server-side max connection: accept(%d), connect(%d)", desc[1].dwMaxAcceptSession, desc[1].dwMaxConnectSession );
|
|
|
|
//ServerListen Start
|
|
StartServerSideListen();
|
|
|
|
//UserListen Start
|
|
StartClientSideListen();
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL SunUpdateServer::Update()
|
|
{
|
|
if( IsShutDown() )
|
|
return FALSE;
|
|
|
|
m_pIOCPServer->Update();
|
|
|
|
UpdateFPS();
|
|
|
|
#ifdef _NA_006543_20130318_HEARTBEAT
|
|
ServerSessionManager::Instance()->update();
|
|
#endif
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
VOID SunUpdateServer::Run()
|
|
{
|
|
while( TRUE )
|
|
{
|
|
Sleep( 1 );
|
|
|
|
if( !Update() ) break;
|
|
if( !ProcessConsole() ) return;
|
|
}
|
|
}
|
|
|
|
VOID SunUpdateServer::UpdateFPS()
|
|
{
|
|
// FPS Check
|
|
static int cnt = 0;
|
|
static DWORD prevTick = GetTickCount();
|
|
|
|
cnt++;
|
|
|
|
DWORD curTick = GetTickCount();
|
|
|
|
if( prevTick + 1000 < curTick )
|
|
{
|
|
m_dwFPS = cnt;
|
|
//printf( "%d FPS", cnt );
|
|
prevTick = curTick;
|
|
cnt = 0;
|
|
|
|
if( m_dwFPS < 10 )
|
|
{
|
|
DISPMSG( "============================================================\n" );
|
|
DISPMSG( "[SunUpdateServer::UpdateFPS] FPS Warning!!! [%d] \n", m_dwFPS );
|
|
DISPMSG( "============================================================\n" );
|
|
}
|
|
}
|
|
}
|
|
|
|
VOID SunUpdateServer::DisplayServerInfo()
|
|
{
|
|
DISPMSG( "============== SunUpdateServer ==============\n" );
|
|
DISPMSG( "Frame Per Second : %d\n", m_dwFPS );
|
|
DISPMSG( "Server Connections : %d\n", m_pIOCPServer->GetNumberOfConnections( SERVER_IOHANDLER ) );
|
|
DISPMSG( "Player Connections : %d\n", UserManager::Instance()->GetNumberOfUsers() );
|
|
}
|
|
|
|
BOOL SunUpdateServer::ProcessConsole()
|
|
{
|
|
if( kbhit() )
|
|
{
|
|
char ch = getch();
|
|
ch = toupper(ch);
|
|
|
|
switch( ch )
|
|
{
|
|
case 0x1b:
|
|
return FALSE;
|
|
case ' ':
|
|
DisplayServerInfo();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
VOID SunUpdateServer::StartServerSideListen()
|
|
{
|
|
if( !m_pIOCPServer->IsListening( SERVER_IOHANDLER ) )
|
|
{
|
|
MSGOUT( "[SunUpdateServer::StartServerSideListen] Starting ServerSideListen(%s@%d)...", m_strInSideIP.c_str(), m_wInnerPort );
|
|
if( !m_pIOCPServer->StartListen( SERVER_IOHANDLER, const_cast<char *>(m_strInSideIP.c_str()), m_wInnerPort ) )
|
|
{
|
|
MSGOUT( "[SunUpdateServer::StartServerSideListen] Fail");
|
|
return ;
|
|
}
|
|
MSGOUT( "[SunUpdateServer::StartServerSideListen] Success");
|
|
}
|
|
}
|
|
|
|
|
|
VOID SunUpdateServer::StartClientSideListen()
|
|
{
|
|
if( !m_pIOCPServer->IsListening( CLIENT_IOHANDLER ) )
|
|
{
|
|
MSGOUT( "[SunUpdateServer::StartClientSideListen] Starting ClientSidelisten(%s@%d)...", m_strOutSideIP.c_str(), m_wOutSidePort );
|
|
if( !m_pIOCPServer->StartListen( CLIENT_IOHANDLER, const_cast<char *>(m_strOutSideIP.c_str()), m_wOutSidePort ) )
|
|
{
|
|
MSGOUT( "[SunUpdateServer::StartClientSideListen] Fail ");
|
|
return ;
|
|
}
|
|
|
|
MSGOUT( "[SunUpdateServer::StartClientSideListen] Success ");
|
|
}
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------------------------
|
|
// 클라이언트 콜백
|
|
//------------------------------------------------------------------------------------------------
|
|
NetworkObject * CreateClientSideAcceptedObject()
|
|
{
|
|
return (NetworkObject *)UserSessionFactory::Instance()->AllocUser( UT_TEMP_USER );
|
|
}
|
|
|
|
VOID DestroyClientSideAcceptedObject( NetworkObject * pNetworkObject )
|
|
{
|
|
UserSessionFactory::Instance()->FreeUser( (UserSession *)pNetworkObject );
|
|
}
|
|
|
|
VOID DestroyClientSideConnectedObject( NetworkObject * pNetworkObject )
|
|
{
|
|
}
|
|
|
|
//------------------------------------------------------------------------------------------------
|
|
// 서버 콜백
|
|
//------------------------------------------------------------------------------------------------
|
|
NetworkObject* CreateServerSideAcceptedObject()
|
|
{
|
|
//현재는 Agent서버만 있으므로,... 이렇게 한다.. 여러개의 서버가 필요할경우, TempServer를 만들자.
|
|
ServerSession * pServerSession = ServerSessionFactory::Instance()->AllocServerSession( UPDATE_TEMP );
|
|
return (NetworkObject*)pServerSession;
|
|
}
|
|
|
|
VOID DestroyServerSideAcceptedObject( NetworkObject * pNetworkObject )
|
|
{
|
|
ServerSession * pServerSession = (ServerSession *)pNetworkObject;
|
|
ServerSessionFactory::Instance()->FreeServerSession( (ServerSession *)pNetworkObject );
|
|
}
|
|
|
|
VOID DestroyServerSideConnectedObject( NetworkObject * pNetworkObject )
|
|
{
|
|
// Nothing to do
|
|
|
|
//ServerSession *pServerSession = (ServerSession*)pNetworkObject;
|
|
//ServerSessionFactory::Instance()->FreeServerSession( (ServerSession *)pNetworkObject );
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|