#include "stdafx.h" #include "resource.h" #include "ManageServer.h" #include #include // CNamedMutex #include #include // g_CExceptionReport #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include 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ÃÊ) ¿¡ 1ƽ. TPP_PER_SEC = 1000 / PROCESS_TPP, CONNECT_CHECK = 2 * TPP_PER_SEC, ///< 2Ãʸ¶´Ù ¿¬°á üũ PRINT_CONSOLE = 2 * TPP_PER_SEC, ///< 2Ãʸ¶´Ù ÄܼÖâ °»½Å STATSERVER_CONNECT = 30 * TPP_PER_SEC, ///< 30Ãʸ¶´Ù Åë°è¼­¹ö ¿¬°á HANGAME_USERNUM = 300 * TPP_PER_SEC, ///< 10ºÐ(600ÃÊ)¸¶´Ù ÇѰÔÀÓÀ¸·Î ¸Þ½ÃÁö º¸³¿. STATSERVER_USERNUM = 600 * TPP_PER_SEC ///< 10ºÐ¸¶´Ù Åë°è¼­¹ö·Î ÆÐŶ Àü¼Û. }; 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()), m_lpToolSessionPolicy(SessionPolicy::CreateTCPPolicy()), m_lpStatServerSessionPolicy(SessionPolicy::CreateTCPPolicy()), 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()) { // °ü¸® DB·Îµå ¹× ÃʱâÈ­ ½ÇÆÐ 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·Î Åë°è¼­¹ö ¿¬°á Á¤º¸ Àü¼Û. const int nSize = sizeof(PktBase) + (sizeof(bool) * 2); char szBuffer[nSize]; ServerManage::StatServerStatus* lpStatServerStatus = reinterpret_cast(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; } // Çѱ¹ ±Û·Î¹ú Åë°è¼­¹ö ¿¬°á 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); } } // °¢ ±¹°¡º° ·ÎÄà Åë°è¼­¹ö ¿¬°á 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; }