Files
Client/Server/ManageTool/ManageServer/ManageServer.cpp
LGram16 dd97ddec92 Restructure repository to include all source folders
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>
2025-11-29 20:17:20 +09:00

348 lines
10 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "stdafx.h"
#include "resource.h"
#include "ManageServer.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 <Network/Dispatch/ManageServer/ManageServerDispatch.h>
#include <Network/Dispatch/ManageServer/ManageToolServerDispatch.h>
#include <Network/Dispatch/ManageServer/StatServerMultiDispatch.h>
#include <Utility/ServerAppFramework/MsgProc/MsgProc.h>
#include <Network/Packet/ManagePacketCmd.h>
#include <Network/Packet/WrapPacket.h>
#include <Network/Dispatch/SendManagePacket.h>
#include <Pattern/CommandQueue.h>
#include <DB/ManageServerDB.h>
#include <Utility/Setup/ServerSetup.h>
#include <UserManage/UserStatistics.h>
#include <Setup/RylServerGroupSetup.h>
#include <Stream/Buffer/Buffer.h>
#include <UserManage/ToolUserManageTable.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("ManageServer", TRUE);
if(GetLastError() == ERROR_ALREADY_EXISTS)
{
ERRLOG0(g_Log, "ManageServer 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);
CManageServer& ManageServer = CManageServer::GetInstance();
if(ManageServer.Initialize(hInstance, "ManageServer", lpCmdLine,
IDI_MANAGESERVER, IDC_MANAGESERVER))
{
ManageServer.ProcessMessage();
}
return 0;
}
class CManageServerProcessThread : public CProcessThread
{
public:
enum Const
{
PROCESS_TPP = 200, ///< 200ms(0.2<EFBFBD><EFBFBD>) <20><> 1ƽ.
TPP_PER_SEC = 1000 / PROCESS_TPP,
CONNECT_CHECK = 2 * TPP_PER_SEC, ///< 2<>ʸ<EFBFBD><CAB8><EFBFBD> <20><><EFBFBD><EFBFBD> üũ
PRINT_CONSOLE = 2 * TPP_PER_SEC, ///< 2<>ʸ<EFBFBD><CAB8><EFBFBD> <20>ܼ<EFBFBD>â <20><><EFBFBD><EFBFBD>
STATSERVER_CONNECT = 30 * TPP_PER_SEC, ///< 30<33>ʸ<EFBFBD><CAB8><EFBFBD> <20><><EFBFBD><EFBFBD><E8BCAD> <20><><EFBFBD><EFBFBD>
HANGAME_USERNUM = 300 * TPP_PER_SEC, ///< 10<31><30>(600<30><30>)<29><><EFBFBD><EFBFBD> <20>Ѱ<EFBFBD><D1B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>޽<EFBFBD><DEBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
STATSERVER_USERNUM = 600 * TPP_PER_SEC ///< 10<31>и<EFBFBD><D0B8><EFBFBD> <20><><EFBFBD><EFBFBD><E8BCAD><EFBFBD><EFBFBD> <20><>Ŷ <20><><EFBFBD><EFBFBD>.
};
CManageServerProcessThread(CManageServer& ManageServer)
: CProcessThread(ManageServer, PROCESS_TPP),
m_ManageServer(ManageServer)
{
}
private:
virtual void Cleanup(CPulse& Pulse)
{
}
virtual void InternalRun(CPulse& Pulse)
{
unsigned long dwCurrentPulse = Pulse.GetCurrentPulse();
if(0 == (dwCurrentPulse % CONNECT_CHECK))
{
}
if(0 == (dwCurrentPulse % PRINT_CONSOLE))
{
m_ManageServer.UpdateConsole();
}
if(0 == (dwCurrentPulse % HANGAME_USERNUM))
{
CUserStatistics::GetInstance().SendStatisticsToHanGame();
}
if(0 == (dwCurrentPulse % STATSERVER_USERNUM))
{
CUserStatistics::GetInstance().SendStatisticsToStatServer();
}
if(0 == (dwCurrentPulse % STATSERVER_CONNECT))
{
m_ManageServer.ConnectToStatServer();
}
}
CManageServer& m_ManageServer;
};
CManageServer& CManageServer::GetInstance()
{
static CManageServer manageServer;
return manageServer;
}
CManageServer::CManageServer()
: m_lpServerSessionPolicy(SessionPolicy::CreateTCPPolicy<CManageServerDispatch>()),
m_lpToolSessionPolicy(SessionPolicy::CreateTCPPolicy<CManageToolServerDispatch>()),
m_lpStatServerSessionPolicy(SessionPolicy::CreateTCPPolicy<CStatServerMultiDispatch>()),
m_lpCommandQueueThread(0)
{
/*
m_lpMyBuffer = CREATE_BUFFER(
m_lpToolSessionPolicy->GetBufferFactory(), sizeof(ServerManage::StatServerStatus));
*/
}
CManageServer::~CManageServer()
{
//SAFE_RELEASE_BUFFER(m_lpMyBuffer);
if(0 != m_lpServerSessionPolicy)
{
m_lpServerSessionPolicy->Release();
m_lpServerSessionPolicy = 0;
}
if(0 != m_lpToolSessionPolicy)
{
m_lpToolSessionPolicy->Release();
m_lpToolSessionPolicy = 0;
}
}
bool CManageServer::ApplicationSpecificInit(const TCHAR* szCmdLine)
{
const TCHAR* szErrorMessage = 0;
if(!CManageServerDB::GetInstance().Initialize())
{
// <20><><EFBFBD><EFBFBD> DB<44>ε<EFBFBD> <20><> <20>ʱ<EFBFBD>ȭ <20><><EFBFBD><EFBFBD>
szErrorMessage = _T("ManageServerDB initialize failed");
}
else if(!GetIOCPNet()->AddListener(m_lpToolSessionPolicy, 0,
CServerSetup::ManageServerManageToolListen))
{
szErrorMessage = _T("ToolSessionListener add failed");
}
else if(!GetIOCPNet()->AddListener(m_lpServerSessionPolicy, 0,
CServerSetup::ManageServerManageClientListen))
{
szErrorMessage = _T("ManageServerListener add failed");
}
else if(!AddProcessThread(new CManageServerProcessThread(*this)))
{
szErrorMessage = _T("AddProcessThread failed(ManageServerProcessThread)");
}
else if(0 == (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");
}
if(!ConnectToStatServer())
{
ERRLOG0(g_Log, "StatServer connection failed");
}
if(0 != szErrorMessage)
{
ERRLOG2(g_Log, "this:0x%p/%s", this, szErrorMessage);
return false;
}
return true;
}
void CManageServer::UpdateConsole()
{
const int MAX_INFO = 4096;
const int MAX_BUFFER = 512;
char szInfo[MAX_INFO];
char szGlobalStatServerIP[MAX_BUFFER], szLocalStatServerIP[MAX_BUFFER];
GetPrivateProfileString("STATSERVER_INFO", "STAT_SERVER_1ST_IP", 0,
szGlobalStatServerIP, MAX_BUFFER, CRylServerGroupSetup::GetInstance().GetSetupFileName());
GetPrivateProfileString("STATSERVER_INFO", "STAT_SERVER_2ND_IP", 0,
szLocalStatServerIP, MAX_BUFFER, CRylServerGroupSetup::GetInstance().GetSetupFileName());
GET_MULTI_DISPATCH(lpGlobalStatDispatch, inet_addr(szGlobalStatServerIP),
CStatServerMultiDispatch, CStatServerMultiDispatch::GetDispatchTable());
GET_MULTI_DISPATCH(lpLocalStatDispatch, inet_addr(szLocalStatServerIP),
CStatServerMultiDispatch, CStatServerMultiDispatch::GetDispatchTable());
char szStatServerState[MAX_BUFFER];
_snprintf(szStatServerState, MAX_BUFFER,
"StatServer(1ST) : %s (%s:%d)\r\nStatServer(2ND) : %s (%s:%d)",
(NULL != lpGlobalStatDispatch) ? "Connected " : "Disconnected",
szGlobalStatServerIP, CServerSetup::StatServerManageServerListen,
(NULL != lpLocalStatDispatch) ? "Connected " : "Disconnected",
szLocalStatServerIP, CServerSetup::StatServerManageServerListen);
int nLength = _snprintf(szInfo, MAX_INFO - 1,
"[ROW Manager Server]\r\n\r\nTotal Player Num : %d\r\n\r\n%s",
CUserStatistics::GetInstance().GetTotalUserNum(), szStatServerState);
if(0 < nLength && nLength < MAX_INFO)
{
szInfo[nLength] = 0;
PrintInfo(szInfo);
}
// ManageTool<6F><6C> <20><><EFBFBD><EFBFBD><E8BCAD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
const int nSize = sizeof(PktBase) + (sizeof(bool) * 2);
char szBuffer[nSize];
ServerManage::StatServerStatus* lpStatServerStatus =
reinterpret_cast<ServerManage::StatServerStatus*>(szBuffer);
lpStatServerStatus->m_bGlobalStatServerOK = (NULL != lpGlobalStatDispatch) ? true : false;
lpStatServerStatus->m_bLocalStatServerOK = (NULL != lpLocalStatDispatch) ? true : false;
if (PacketWrap::WrapHeader(szBuffer, nSize, ServerManage::CMD::StatServerStatus, 0, 0))
{
CToolUserManager::GetInstance().SendToAllLoginUser(
szBuffer, nSize, ServerManage::CMD::StatServerStatus);
}
}
bool CManageServer::ConnectToStatServer()
{
const char* szSetupFileName = CRylServerGroupSetup::GetInstance().GetSetupFileName();
unsigned int dwSendToGlobalStatServer =
GetPrivateProfileInt("STATSERVER_INFO", "SEND_STAT_SERVER_1ST", 0, szSetupFileName);
unsigned int dwSendToLocalStatServer =
GetPrivateProfileInt("STATSERVER_INFO", "SEND_STAT_SERVER_2ND", 0, szSetupFileName);
if((0 == dwSendToGlobalStatServer) && (0 == dwSendToLocalStatServer))
{
return false;
}
CIOCPNet* lpIOCP = GetIOCPNet();
if(0 != lpIOCP && 0 != m_lpStatServerSessionPolicy)
{
const int MAX_BUFFER = 256;
char szGlobalStatServerIP[MAX_BUFFER], szLocalStatServerIP[MAX_BUFFER];
GetPrivateProfileString("STATSERVER_INFO", "STAT_SERVER_1ST_IP", 0,
szGlobalStatServerIP, MAX_BUFFER, szSetupFileName);
GetPrivateProfileString("STATSERVER_INFO", "STAT_SERVER_2ND_IP", 0,
szLocalStatServerIP, MAX_BUFFER, szSetupFileName);
if(0 == strcmp(szGlobalStatServerIP, szLocalStatServerIP))
{
ERRLOG2(g_Log, "StatServer Setup Error : 1ST_IP %s, 2ND_IP %s",
szGlobalStatServerIP, szLocalStatServerIP);
return false;
}
// <20>ѱ<EFBFBD> <20>۷ι<DBB7> <20><><EFBFBD><EFBFBD><E8BCAD> <20><><EFBFBD><EFBFBD>
GET_MULTI_DISPATCH(lpGlobalStatDispatch, inet_addr(szGlobalStatServerIP),
CStatServerMultiDispatch, CStatServerMultiDispatch::GetDispatchTable());
if((NULL == lpGlobalStatDispatch) && (1 == dwSendToGlobalStatServer))
{
if(!lpIOCP->Connect(m_lpStatServerSessionPolicy,
szGlobalStatServerIP, CServerSetup::StatServerManageServerListen))
{
ERRLOG2(g_Log, "Failed to connect StatServer_1st - IP(Port): %s(%d)",
szGlobalStatServerIP, CServerSetup::StatServerManageServerListen);
}
}
// <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><E8BCAD> <20><><EFBFBD><EFBFBD>
GET_MULTI_DISPATCH(lpLocalStatDispatch, inet_addr(szLocalStatServerIP),
CStatServerMultiDispatch, CStatServerMultiDispatch::GetDispatchTable());
if((NULL == lpLocalStatDispatch) && (1 == dwSendToLocalStatServer))
{
if(!lpIOCP->Connect(m_lpStatServerSessionPolicy,
szLocalStatServerIP, CServerSetup::StatServerManageServerListen))
{
ERRLOG2(g_Log, "Failed to connect StatServer_2nd - IP(Port): %s(%d)",
szLocalStatServerIP, CServerSetup::StatServerManageServerListen);
}
}
}
return true;
}