Move git root from Client/ to src/ to track all source code: - Client: Game client source (moved to Client/Client/) - Server: Game server source - GameTools: Development tools - CryptoSource: Encryption utilities - database: Database scripts - Script: Game scripts - rylCoder_16.02.2008_src: Legacy coder tools - GMFont, Game: Additional resources 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
221 lines
5.2 KiB
C++
221 lines
5.2 KiB
C++
#include "stdafx.h"
|
|
#include "resource.h"
|
|
#include "StatServer.h"
|
|
#include "StatServerDispatch.h"
|
|
|
|
#include <time.h>
|
|
#include <shellapi.h>
|
|
|
|
#include <Thread/Lock.h> // CNamedMutex
|
|
#include <Log/ServerLog.h>
|
|
#include <Utility/Debug/ExceptionReport.h> // g_CExceptionReport
|
|
#include <Utility/Time/Pulse/Pulse.h>
|
|
|
|
#include <Network/Session/CreatePolicy.h>
|
|
#include <Network/Session/Session.h>
|
|
#include <Network/IOCP/IOCPNet.h>
|
|
|
|
#include <Network/Dispatch/SingleDispatchStorage.h>
|
|
#include <Utility/ServerAppFramework/MsgProc/MsgProc.h>
|
|
|
|
#include <Pattern/CommandQueue.h>
|
|
|
|
#include <Utility/Setup/ServerSetup.h>
|
|
|
|
#include "StatisticsDB.h"
|
|
|
|
|
|
int WINAPI ExceptionUserFunc(char* szBuffer, int nBufferLen)
|
|
{
|
|
g_Log.Flush();
|
|
g_SessionLog.Flush();
|
|
|
|
return _snprintf(szBuffer, nBufferLen, "Exception Occured. Flush all buffers.");
|
|
}
|
|
|
|
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
|
|
{
|
|
/*
|
|
CNamedMutex Mutex("StatServer", TRUE);
|
|
|
|
if(GetLastError() == ERROR_ALREADY_EXISTS)
|
|
{
|
|
ERRLOG0(g_Log, "StatServer already server operating now. please shutdown and restart");
|
|
return 0;
|
|
}
|
|
*/
|
|
unsigned long dwExceptionFeatures =
|
|
CExceptionReport::CATCH_EXCEPTION | CExceptionReport::USE_MINIDUMP | CExceptionReport::USE_REPORT;
|
|
|
|
CExceptionReport::GetInstance().Enable(dwExceptionFeatures);
|
|
CExceptionReport::GetInstance().SetUserFunc(ExceptionUserFunc);
|
|
|
|
CStatServer& StatServer = CStatServer::GetInstance();
|
|
|
|
if(StatServer.Initialize(hInstance, "StatServer", lpCmdLine, IDI_STATSERVER, IDC_STATSERVER))
|
|
{
|
|
StatServer.ProcessMessage();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
class CStatServerProcessThread : public CProcessThread
|
|
{
|
|
public:
|
|
|
|
enum Const
|
|
{
|
|
PROCESS_TPP = 200, // 200ms(0.2초) 에 1틱.
|
|
TPP_PER_SEC = 1000 / PROCESS_TPP,
|
|
CONNECT_CHECK = 2 * TPP_PER_SEC, // 2초마다 연결 체크
|
|
PRINT_CONSOLE = 2 * TPP_PER_SEC, // 2초마다 콘솔창 갱신
|
|
};
|
|
|
|
CStatServerProcessThread(CStatServer& StatServer)
|
|
: CProcessThread(StatServer, PROCESS_TPP)
|
|
, m_StatServer(StatServer)
|
|
{
|
|
|
|
}
|
|
|
|
~CStatServerProcessThread()
|
|
{
|
|
|
|
}
|
|
|
|
private:
|
|
|
|
virtual void InternalRun(CPulse& Pulse)
|
|
{
|
|
unsigned long dwCurrentPulse = Pulse.GetCurrentPulse();
|
|
|
|
if(0 == (dwCurrentPulse % CONNECT_CHECK))
|
|
{
|
|
|
|
}
|
|
|
|
if(0 == (dwCurrentPulse % PRINT_CONSOLE))
|
|
{
|
|
m_StatServer.UpdateConsole();
|
|
}
|
|
}
|
|
|
|
virtual void Cleanup(CPulse& Pulse)
|
|
{
|
|
|
|
}
|
|
|
|
CStatServer& m_StatServer;
|
|
};
|
|
|
|
|
|
CStatServer& CStatServer::GetInstance()
|
|
{
|
|
static CStatServer StatServer;
|
|
return StatServer;
|
|
}
|
|
|
|
|
|
CStatServer::CStatServer()
|
|
: m_lpCommandQueueThread(NULL)
|
|
, m_lpServerSessionPolicy(SessionPolicy::CreateTCPPolicy<CStatServerDispatch>())
|
|
, m_tServerStart(0)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
CStatServer::~CStatServer()
|
|
{
|
|
if(NULL != m_lpServerSessionPolicy)
|
|
{
|
|
m_lpServerSessionPolicy->Release();
|
|
m_lpServerSessionPolicy = NULL;
|
|
}
|
|
}
|
|
|
|
bool CStatServer::ApplicationSpecificInit(const TCHAR* szCmdLine)
|
|
{
|
|
const TCHAR* szErrorMessage = NULL;
|
|
|
|
if(!GetIOCPNet()->AddListener(m_lpServerSessionPolicy, NULL, CServerSetup::StatServerManageServerListen))
|
|
{
|
|
szErrorMessage = _T("StatServerListener add failed");
|
|
}
|
|
else if(!AddProcessThread(new CStatServerProcessThread(*this)))
|
|
{
|
|
szErrorMessage = _T("AddProcessThread failed(StatServerProcessThread)");
|
|
}
|
|
else if(NULL == (m_lpCommandQueueThread = new CCommandQueueThread))
|
|
{
|
|
szErrorMessage = _T("CCommandQueueThread create failed");
|
|
}
|
|
else if(!m_lpCommandQueueThread->IsValid())
|
|
{
|
|
szErrorMessage = _T("CCommandQueueThread is Invalid");
|
|
}
|
|
else if(!AddProcessThread(m_lpCommandQueueThread))
|
|
{
|
|
szErrorMessage = _T("AddProcessThread failed(CCommandQueueThread)");
|
|
}
|
|
else if(!InitializeMsgProc())
|
|
{
|
|
szErrorMessage = _T("Initialize message proc failed");
|
|
}
|
|
else if(!InitializeCommand())
|
|
{
|
|
szErrorMessage = _T("Initialize command failed");
|
|
}
|
|
else if(!CStatisticsDB::GetInstance().ConnectStatDB())
|
|
{
|
|
szErrorMessage = _T("Initialize StatDB failed");
|
|
}
|
|
|
|
m_tServerStart = time(NULL);
|
|
|
|
if(NULL != szErrorMessage)
|
|
{
|
|
ERRLOG2(g_Log, "this:0x%p / %s", this, szErrorMessage);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void CStatServer::UpdateConsole()
|
|
{
|
|
const int MAX_INFO = 4096;
|
|
char szInfo[MAX_INFO];
|
|
|
|
time_t tCurrent = time(NULL);
|
|
time_t tDiffTime = tCurrent - m_tServerStart;
|
|
|
|
time_t tDiffDay = tDiffTime / 3600 / 24;
|
|
time_t tDiffHour = (tDiffTime / 3600) % 24;
|
|
time_t tDiffMinute = (tDiffTime % 3600) / 60;
|
|
|
|
struct tm tmServerStart = *localtime(&m_tServerStart);
|
|
struct tm tmCurrent = *localtime(&tCurrent);
|
|
|
|
int nLength = _snprintf(szInfo, MAX_INFO - 1,
|
|
"[GAMA Statistics Server]\r\n\r\n"
|
|
"Server Start Time : %04d-%02d-%02d %02d:%02d:%02d\r\n"
|
|
"Current Server Time : %04d-%02d-%02d %02d:%02d:%02d\r\n"
|
|
"\r\n"
|
|
"Server Operate Time : %04d Days %02d Hours %02d Minutes",
|
|
|
|
tmServerStart.tm_year + 1900, tmServerStart.tm_mon + 1, tmServerStart.tm_mday,
|
|
tmServerStart.tm_hour, tmServerStart.tm_min, tmServerStart.tm_sec,
|
|
|
|
tmCurrent.tm_year + 1900, tmCurrent.tm_mon + 1, tmCurrent.tm_mday,
|
|
tmCurrent.tm_hour, tmCurrent.tm_min, tmCurrent.tm_sec,
|
|
|
|
tDiffDay, tDiffHour, tDiffMinute);
|
|
|
|
if(0 < nLength && nLength < MAX_INFO)
|
|
{
|
|
szInfo[nLength] = 0;
|
|
PrintInfo(szInfo, nLength);
|
|
}
|
|
} |