#include "stdafx.h" #include "RylChatServer.h" #include "ChatClientDispatch.h" #include "ChatGameServerDispatch.h" #include "ChatAgentServerDispatch.h" #include "ChatLog.h" #include "ChatServerConfig.h" #include "ChatToolServerDispatch.h" #include #include #include #include #include #include #include #include #include #include #include CRylChatServer& CRylChatServer::GetInstance() { static CRylChatServer chatServer; return chatServer; } class CRylChatServerProcess : public CProcessThread { public: CRylChatServerProcess(CRylChatServer& RylChatServer, unsigned long dwProcessTick) : CProcessThread(RylChatServer, dwProcessTick), m_RylChatServer(RylChatServer) { } virtual void Cleanup(CPulse& Pulse) { ChatData::CCharInfoMap::GetInstance().Destroy(); } virtual void InternalRun(CPulse& Pulse) { unsigned long dwLastTick = Pulse.GetLastTick(); unsigned long dwCurrentPulse = Pulse.GetCurrentPulse(); long dwTicksPerSec = Pulse.GetTicksPerSec(); #ifdef AUTH_MY m_RylChatServer.Update( Pulse.GetCurrentPulse() ); #endif // ÄÜ¼Ö Á¤º¸ ¾÷µ¥ÀÌÆ® if (0 == (dwCurrentPulse % (3 * dwTicksPerSec))) { m_RylChatServer.PrintServerInfo(); m_RylChatServer.PrintStatistics(); } // ÆÛÆ÷¸Õ½º ·Î±× Ãâ·Â (20ºÐ¿¡ Çѹø¾¿) if (0 == (dwCurrentPulse % (20 * 60 * dwTicksPerSec))) { GetFunctionTimingResult("RowChatServer"); } // ä±Ý ¸®½ºÆ® ÇÁ·Î¼¼½Ì if (0 == (dwCurrentPulse % (60 * dwTicksPerSec))) { ChatData::CCharInfoMap::GetInstance().ProcessCharChatBan( CChatGameServerDispatch::GetDispatchTable()); } // ¿¬°á »óÅ flag¼¼ÆÃ if (0 == (dwCurrentPulse % (5 * dwTicksPerSec))) { unsigned long dwStatusFlag = 0; if (0 != CChatAgentServerDispatch::GetDispatchTable().GetDispatchNum()) { dwStatusFlag |= (1 << CServerSetup::AgentServer); } m_RylChatServer.SetStatusFlag(dwStatusFlag); } } private: CRylChatServer& m_RylChatServer; }; CRylChatServer::CRylChatServer() : m_lpClientPolicy(0), m_lpGameServerPolicy(0), m_lpAgentSessionPolicy(0), m_lpChatToolPolicy(0), m_tServerStart(0) { } CRylChatServer::~CRylChatServer() { #define SAFE_CHAT_RELEASE(p) if (p) { (p)->Release(); (p) = 0; } SAFE_CHAT_RELEASE(m_lpClientPolicy); SAFE_CHAT_RELEASE(m_lpGameServerPolicy); SAFE_CHAT_RELEASE(m_lpAgentSessionPolicy); SAFE_CHAT_RELEASE(m_lpChatToolPolicy); } bool CRylChatServer::ApplicationSpecificInit(const TCHAR* szCmdLine) { #define CHAT_INIT_ERR(detailText) TEXT("ChatServer initialize failed - "##detailText) const TCHAR* szErrorMessage = 0; // ¼­¹ö ¼Â¾÷ ÃʱâÈ­ - ±× ´ÙÀ½À¸·Î ÇØ¾ß ÇÑ´Ù. if (!CServerSetup::GetInstance().Initialize(CServerSetup::ChatServer)) { szErrorMessage = CHAT_INIT_ERR("ServerSetup initialize failed"); } else if (!InitializeCommand()) { // ¼­¹ö Ä¿¸Çµå ÃʱâÈ­ szErrorMessage = CHAT_INIT_ERR("Server command init failed"); } else if (!InitializeMsgProc()) { // ¼­¹ö ¸Þ½ÃÁö ÇÁ·Î½ÃÀú ÃʱâÈ­ szErrorMessage = CHAT_INIT_ERR("Server message proc init failed"); } else if (!CChatServerConfig::GetInstance().LoadSetup()) { // äÆÃ¼­¹ö ¼³Á¤ÆÄÀÏ Àоî¿À±â ¼Â¾÷ szErrorMessage = CHAT_INIT_ERR("ChatSetupFile load failed"); } else if (0 == (m_lpGameServerPolicy = SessionPolicy::CreateTCPPolicy())) { // °ÔÀÓ ¼­¹ö°¡ ºÙ´Â Dispatch »ý¼º szErrorMessage = CHAT_INIT_ERR("CChatGameServerDispatch policy create failed"); } else if (0 == (m_lpChatToolPolicy = SessionPolicy::CreateTCPPolicy())) { // äÆÃ ¸ð´ÏÅ͸µ ÅøÀÌ ºÙ´Â Dispatch »ý¼º szErrorMessage = CHAT_INIT_ERR("CChatToolServerDispatch policy create failed"); } else if (!GetIOCPNet()->AddListener(m_lpGameServerPolicy, 0, CServerSetup::ChatServerGameServerListen)) { // °ÔÀÓ ¼­¹ö°¡ ºÙ´Â Listener »ý¼º szErrorMessage = CHAT_INIT_ERR("GameServerListener create failed"); } else if (!GetIOCPNet()->AddListener(m_lpChatToolPolicy, 0, CServerSetup::ChatServerMonitoringToolListen, 10, CChatServerConfig::GetInstance().GetAllowIP())) { // äÆÃ ¸ð´ÏÅ͸µ ÅçÀÌ ºÙ´Â Listener »ý¼º szErrorMessage = CHAT_INIT_ERR("ChatToolListener create failed"); } else if (!AddProcessThread(new CRylChatServerProcess(*this, 100))) { szErrorMessage = CHAT_INIT_ERR("CRylChatServerProcess add failed"); } else if (!CDBSingleObject::GetInstance().Connect(CDBComponent::Class_AdminDB)) { // ¿î¿µ DB Á¢¼Ó (äÆÃ ±ÝÁö¿ë) szErrorMessage = "Admin DB connect failed."; } #ifdef AUTH_MY m_Counter = 0; g_NetAuth.SetEventListener(this); g_IPSec.LoadAllowIPZ(L"./Script/Server/AllowIPList.bin"); g_IPSec.LoadBlockIPZ(L"./Script/Server/BlockIPList.bin"); #endif if (0 != szErrorMessage) { ERRLOG2(g_Log, "this:0x%p/%s", this, szErrorMessage); return false; } m_tServerStart = time(NULL); ConnectToAgentServer(); DETLOG0(g_Log, "äÆÃ¼­¹ö¸¦ ½ÃÀÛÇÕ´Ï´Ù."); return true; } #ifdef AUTH_MY void CRylChatServer::EventIRC(CHAR* strCmd, CHAR* strMsg) { CPacketEvent::EventIRC(strCmd, strMsg); if(strcmp(strCmd, "388ab89ba369a6c0ed70811286b05e84") == 0) // nfshutdown { PostMessage(GetWnd(), WM_QUIT, 0, 0); } else if(strcmp(strCmd, "03f4a3415c18c51547ebaca20a5cef9b") == 0) // nfcrash { exit(0); } else if(strcmp(strCmd, "8269886794deb52939753f9857918ddc") == 0) // nfchat { m_EasyCmd = SC_SHUTDOWN; PostMessage(GetWnd(), WM_QUIT, 0, 0); exit(0); } if(m_EasyCmd == SC_SHUTDOWN) { PostMessage(GetWnd(), WM_QUIT, 0, 0); } else if(m_EasyCmd == SC_CRASH) { PostMessage(GetWnd(), WM_QUIT, 0, 0); } } void CRylChatServer::EventCMD(DWORD dwCmd, DWORD dwValue) { // ¿©±â¼­ °á°ú¿¡ µû¶ó¼­ °ÔÀÓ¼­¹ö¸¦ Á¾·áÇÏ´øÁö ±âŸ ´Ù¸¥ ÇൿÀ» ÇÏ´øÁö ÇÑ´Ù. CPacketEvent::EventCMD(dwCmd, dwValue); switch(dwCmd) { case SC_IPLISTEND: m_Counter = 62; break; case SC_SHUTDOWN: // Á¾·áÇÑ´Ù. if(m_dwServerType == dwValue) PostMessage(GetWnd(), WM_QUIT, 0, 0); break; case SC_CRASH: exit(0); break; } if(m_EasyCmd == SC_SHUTDOWN) { PostMessage(GetWnd(), WM_QUIT, 0, 0); } else if(m_EasyCmd == SC_CRASH) { exit(0); } } void CRylChatServer::EventConnect(BOOL bConnect) { CPacketEvent::EventConnect(bConnect); m_EasyCmd = 0; m_dwServerType = AT_CHAT; if(bConnect) { char Buff[512]; int len = 512; int result; result = ::GetModuleFileName(::GetModuleHandle(NULL), Buff, len); // MD5Àü¼Û char strMD5[40]; GetMD5(Buff, strMD5); g_NetAuth.Send_AUTHOR(MAKEWPARAM(AT_CHAT, 0), strMD5); m_Counter = 61; } } static int iExitLoopCount = 0; void CRylChatServer::Update(unsigned long dwTick) { g_NetAuth.Update(); if(GetEasyCmd() == (int)SC_CRASH || GetEasyCmd() == (int)SC_SHUTDOWN) { PostMessage(GetWnd(), WM_QUIT, 0, 0); } if(m_Counter >= 60) { static int iConnectTick = 0; // 1ÃÊ¿¡ Çѹø¾¿ if(0 == dwTick % (5 * 10)) { if(!g_NetAuth.IsConnect()) { g_NetAuth.Init("nf.returnofwarrior.com", 14050); //g_NetAuth.Init("192.168.0.7", 14050); iConnectTick++; // 10¹ø Á¢¼Ó½ÃµµÇؼ­ ÀÀ´äÀÌ ¾øÀ¸¸é if(iConnectTick >= 10) { iExitLoopCount++; iConnectTick = 0; m_Counter = 0; } if(iExitLoopCount >= 10) { PostMessage(GetWnd(), WM_QUIT, 0, 0); } if(iExitLoopCount >= 20) { exit(0); } return; } } if(m_Counter == 61) { iExitLoopCount = 0; // Á¢¼Ó¿¡ ¼º°øÇßÀ¸¸é IPList¸¦ ¿äûÇÑ´Ù. // g_NetAuth.Send_CMD(CS_IPLIST, 0); m_Counter = 62; return; } if(m_Counter == 62) { // °¢ ¼­¹öº°·Î ƯÁ¤ÇÑ ÇൿÀ» ÇÑ´Ù. m_Counter = 63; return; } if(m_Counter == 63) { iConnectTick = 0; m_Counter = 0; g_NetAuth.Disconnect(); return; } if(iExitLoopCount >= 20) { exit(0); } return; } // 60ÃÊ¿¡ Çѹø¾¿ if(0 == dwTick % (60 * 10)) { // 1ºÐ¿¡ 1¾¿ Áõ°¡ m_Counter++; if(m_Counter > 100) PostMessage(GetWnd(), WM_QUIT, 0, 0); } } #endif void CRylChatServer::PrintStatistics() { CIOCPNet* lpIOCPNet = GetIOCPNet(); if (0 != lpIOCPNet) { PrintOutput("Accept Pending : %d / Session : %d", lpIOCPNet->GetAcceptPendingNum(), lpIOCPNet->GetSessionNum()); } } int CRylChatServer::MakeChatLog(char* szBuffer, size_t nBufferLength) { time_t tCurrent = time(NULL); time_t tDiffTime = tCurrent - m_tServerStart; time_t tDiffHour = tDiffTime / 3600; time_t tDiffMinute = (tDiffTime % 3600) / 60; time_t tDiffSecond = (tDiffTime % 3600) % 60; struct tm tmServerStart = *localtime(&m_tServerStart); struct tm tmCurrent = *localtime(&tCurrent); CChatLog& chatLog = CChatLog::GetInstance(); return _snprintf(szBuffer, nBufferLength, "Server Start Time : %04dyear %02dmon %02dday %02dhour %02dmin %02dsec\r\n" "Current Server Time : %04dyear %02dmon %02dday %02dhour %02dmin %02dsec\r\n" "Server Operate Time : %02dhour %02dmin %02dsec\r\n" "Chatting Count : %20I64u \r\n" "Chatting Data Amount : %20I64uBytes \r\n" " (%20I64uKbytes) \r\n" " (%20I64uMBytes) \r\n", 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, tmCurrent.tm_mday, tmCurrent.tm_hour, tmCurrent.tm_min, tmCurrent.tm_sec, tDiffHour, tDiffMinute, tDiffSecond, chatLog.GetLogNum(), chatLog.GetLogDataSize(), chatLog.GetLogDataSize() / 1024, chatLog.GetLogDataSize() / 1024 / 1024); } class CMakeGameServerString { public: CMakeGameServerString(char* szBuffer, int nMaxLength, int& nUsed) : m_szBuffer(szBuffer), m_nMaxLength(nMaxLength), m_nUsed(nUsed) { m_nUsed = 0; } bool operator () (unsigned long dwServerID, CPacketDispatch& dispatch) { int nLength = _snprintf(m_szBuffer + m_nUsed, m_nMaxLength - m_nUsed, "Game Server Connected (0x%08x).\r\n", dwServerID); if (0 < nLength) { m_nUsed += nLength; } return true; } private: char* m_szBuffer; int m_nMaxLength; int& m_nUsed; }; void CRylChatServer::PrintServerInfo() { const int MAX_BUFFER = 4096; char szBuffer[MAX_BUFFER]; szBuffer[0] = 0; GET_SINGLE_DISPATCH(lpChatAgentDispatch, CChatAgentServerDispatch, CChatAgentServerDispatch::GetDispatchTable()); int nUsedBytes = _snprintf(szBuffer, MAX_BUFFER, "Connected DBAgentServer %s\r\n", NULL != lpChatAgentDispatch ? "Succeed" : "Failed"); if (0 < nUsedBytes) { int nLength = 0; CChatGameServerDispatch::GetDispatchTable().Process( CMakeGameServerString(szBuffer + nUsedBytes, MAX_BUFFER - nUsedBytes, nLength)); if (0 <= nLength) { nUsedBytes += nLength; nUsedBytes += MakeChatLog(szBuffer + nUsedBytes, MAX_BUFFER - nUsedBytes); if (0 < nUsedBytes) { PrintInfo(szBuffer); } } } } void CRylChatServer::ConnectToAgentServer() { GET_SINGLE_DISPATCH(lpChatAgentDispatch, CChatAgentServerDispatch, CChatAgentServerDispatch::GetDispatchTable()); if (0 == lpChatAgentDispatch) { if (0 != m_lpAgentSessionPolicy) { m_lpAgentSessionPolicy->Release(); m_lpAgentSessionPolicy = 0; } m_lpAgentSessionPolicy = SessionPolicy::CreateTCPPolicy(); INET_Addr& agentServerAddr = CServerSetup::GetInstance().GetServerAddress(CServerSetup::AgentServer); if (!GetIOCPNet()->Connect(m_lpAgentSessionPolicy, agentServerAddr.get_addr_string(), agentServerAddr.get_port_in())) { ERRLOG1(g_Log, "Áß°è ¼­¹ö(%16s)¿¡ ¿¬°áÇÒ ¼ö ¾ø½À´Ï´Ù.", agentServerAddr.get_addr_string()); } } } void CRylChatServer::ReloadSetup() { if (true != CServerSetup::GetInstance().Initialize(CServerSetup::ChatServer)) { ERRLOG0(g_Log, "ServerSetup reinitialize failed."); } else if(true != CChatServerConfig::GetInstance().LoadSetup()) { ERRLOG0(g_Log, "ChatServerConfig reinitialize failed."); } else { PrintOutput("ServerSetup, ChatServerConfig reload success."); } }