// ServiceManagerEx.cpp : ÀÀ¿ë ÇÁ·Î±×·¥¿¡ ´ëÇÑ Å¬·¡½º µ¿ÀÛÀ» Á¤ÀÇÇÕ´Ï´Ù. // #include "stdafx.h" #include "ServiceManagerEx.h" #include "MainFrm.h" #include "ServiceManagerExDoc.h" #include "ServiceManagerExView.h" #include "ServiceServer.h" #include "Log.h" #include "DataManager.h" #include "DNBAM.h" #include "IniFile.h" #include "Version.h" #include "MainSplit.h" #include "LogViewDisplayer.h" #include "LogBuilder.h" #include "LogSplit.h" #include "Scheduler.h" #include "ServerReporter.h" #include #ifdef _DEBUG #define new DEBUG_NEW #endif extern TServiceManagerConfig g_Config; extern CServiceServer * g_pServiceServer; extern CLog g_Log; extern CLog s_CountLog; extern CLog g_ExceptionReportLog; extern CLog g_DBDelayLog; extern CLog s_ExcuteLog; extern CLog g_GameDelayLog; extern CLog g_VillageDelayLog; extern CLog g_DBErrorLog; extern CLog g_DBSystemErrorLog; extern CLog g_MonitorLog; extern CLog g_FileLog; // ÀÀ¿ë ÇÁ·Î±×·¥ Á¤º¸¿¡ »ç¿ëµÇ´Â CAboutDlg ´ëÈ­ »óÀÚÀÔ´Ï´Ù. class CAboutDlg : public CDialog { public: CAboutDlg(); // ´ëÈ­ »óÀÚ µ¥ÀÌÅÍÀÔ´Ï´Ù. enum { IDD = IDD_ABOUTBOX }; protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV Áö¿øÀÔ´Ï´Ù. // ±¸ÇöÀÔ´Ï´Ù. protected: DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) END_MESSAGE_MAP() // CServiceManagerExApp BEGIN_MESSAGE_MAP(CServiceManagerExApp, CWinApp) ON_COMMAND(ID_APP_ABOUT, &CServiceManagerExApp::OnAppAbout) // Ç¥ÁØ ÆÄÀÏÀ» ±âÃÊ·Î ÇÏ´Â ¹®¼­ ¸í·ÉÀÔ´Ï´Ù. ON_COMMAND(ID_FILE_NEW, &CWinApp::OnFileNew) ON_COMMAND(ID_FILE_OPEN, &CWinApp::OnFileOpen) // Ç¥ÁØ Àμ⠼³Á¤ ¸í·ÉÀÔ´Ï´Ù. ON_COMMAND(ID_FILE_PRINT_SETUP, &CWinApp::OnFilePrintSetup) END_MESSAGE_MAP() // CServiceManagerExApp »ý¼º CServiceManagerExApp::CServiceManagerExApp() : m_pLogDisplayer(NULL), m_hMutex(NULL) { // TODO: ¿©±â¿¡ »ý¼º Äڵ带 Ãß°¡ÇÕ´Ï´Ù. // InitInstance¿¡ ¸ðµç Áß¿äÇÑ ÃʱâÈ­ ÀÛ¾÷À» ¹èÄ¡ÇÕ´Ï´Ù. } CServiceManagerExApp::~CServiceManagerExApp() { } // À¯ÀÏÇÑ CServiceManagerExApp °³Ã¼ÀÔ´Ï´Ù. CServiceManagerExApp theApp; int CServiceManagerExApp::ExitInstance(){ //·Î±× Ãâ·ÂºÎÅÍ ÀÏ´Ü ¸·°í ½ÃÀÛ g_Log.SetDisplayer(NULL); m_GSMServer.Close(); if(g_pServiceServer) g_pServiceServer->Close(); SAFE_DELETE(g_pServiceServer); SAFE_DELETE(m_pLogDisplayer); m_Scheduler.Clear(); m_ConfigEx.Reset(); ::ReleaseMutex(m_hMutex); return CWinApp::ExitInstance(); } // CServiceManagerExApp ÃʱâÈ­ BOOL CServiceManagerExApp::InitInstance() { m_hMutex = ::CreateMutex(NULL, TRUE, L"ServiceManagerEx"); if (::GetLastError() == ERROR_ALREADY_EXISTS) { ::AfxMessageBox(L"ServiceManagerEx is already running."); return FALSE; } SetMiniDump(); LoadConfigEx(); CLogBuilder::Initialize(); // ÀÀ¿ë ÇÁ·Î±×·¥ ¸Å´ÏÆä½ºÆ®°¡ ComCtl32.dll ¹öÀü 6 ÀÌ»óÀ» »ç¿ëÇÏ¿© ºñÁÖ¾ó ½ºÅ¸ÀÏÀ» // »ç¿ëÇϵµ·Ï ÁöÁ¤ÇÏ´Â °æ¿ì, Windows XP »ó¿¡¼­ ¹Ýµå½Ã InitCommonControlsEx()°¡ ÇÊ¿äÇÕ´Ï´Ù. // InitCommonControlsEx()¸¦ »ç¿ëÇÏÁö ¾ÊÀ¸¸é âÀ» ¸¸µé ¼ö ¾ø½À´Ï´Ù. INITCOMMONCONTROLSEX InitCtrls; InitCtrls.dwSize = sizeof(InitCtrls); // ÀÀ¿ë ÇÁ·Î±×·¥¿¡¼­ »ç¿ëÇÒ ¸ðµç °ø¿ë ÄÁÆ®·Ñ Ŭ·¡½º¸¦ Æ÷ÇÔÇϵµ·Ï // ÀÌ Ç׸ñÀ» ¼³Á¤ÇϽʽÿÀ. InitCtrls.dwICC = ICC_WIN95_CLASSES; InitCommonControlsEx(&InitCtrls); CWinApp::InitInstance(); // OLE ¶óÀ̺귯¸®¸¦ ÃʱâÈ­ÇÕ´Ï´Ù. if (!AfxOleInit()) { AfxMessageBox(IDP_OLE_INIT_FAILED); return FALSE; } AfxEnableControlContainer(); // Ç¥ÁØ ÃʱâÈ­ // ÀÌµé ±â´ÉÀ» »ç¿ëÇÏÁö ¾Ê°í ÃÖÁ¾ ½ÇÇà ÆÄÀÏÀÇ Å©±â¸¦ ÁÙÀÌ·Á¸é // ¾Æ·¡¿¡¼­ ÇÊ¿ä ¾ø´Â ƯÁ¤ ÃʱâÈ­ // ·çƾÀ» Á¦°ÅÇØ¾ß ÇÕ´Ï´Ù. // ÇØ´ç ¼³Á¤ÀÌ ÀúÀåµÈ ·¹Áö½ºÆ®¸® ۸¦ º¯°æÇϽʽÿÀ. // TODO: ÀÌ ¹®ÀÚ¿­À» ȸ»ç ¶Ç´Â Á¶Á÷ÀÇ À̸§°ú °°Àº // ÀûÀýÇÑ ³»¿ëÀ¸·Î ¼öÁ¤ÇØ¾ß ÇÕ´Ï´Ù. SetRegistryKey(_T("·ÎÄà ÀÀ¿ë ÇÁ·Î±×·¥ ¸¶¹ý»ç¿¡¼­ »ý¼ºµÈ ÀÀ¿ë ÇÁ·Î±×·¥")); LoadStdProfileSettings(4); // MRU¸¦ Æ÷ÇÔÇÏ¿© Ç¥ÁØ INI ÆÄÀÏ ¿É¼ÇÀ» ·ÎµåÇÕ´Ï´Ù. // ÀÀ¿ë ÇÁ·Î±×·¥ÀÇ ¹®¼­ ÅÛÇø´À» µî·ÏÇÕ´Ï´Ù. ¹®¼­ ÅÛÇø´Àº // ¹®¼­, ÇÁ·¹ÀÓ Ã¢ ¹× ºä »çÀÌÀÇ ¿¬°á ¿ªÇÒÀ» ÇÕ´Ï´Ù. CSingleDocTemplate* pDocTemplate; pDocTemplate = new CSingleDocTemplate( IDR_MAINFRAME, RUNTIME_CLASS(CServiceManagerExDoc), RUNTIME_CLASS(CMainFrame), // ÁÖ SDI ÇÁ·¹ÀÓ Ã¢ÀÔ´Ï´Ù. RUNTIME_CLASS(CServiceManagerExView)); if (!pDocTemplate) return FALSE; AddDocTemplate(pDocTemplate); // Ç¥ÁØ ¼Ð ¸í·É, DDE, ÆÄÀÏ ¿­±â¿¡ ´ëÇÑ ¸í·ÉÁÙÀ» ±¸¹® ºÐ¼®ÇÕ´Ï´Ù. CCommandLineInfo cmdInfo; ParseCommandLine(cmdInfo); // ¸í·ÉÁÙ¿¡ ÁöÁ¤µÈ ¸í·ÉÀ» µð½ºÆÐÄ¡ÇÕ´Ï´Ù. // ÀÀ¿ë ÇÁ·Î±×·¥ÀÌ /RegServer, /Register, /Unregserver ¶Ç´Â /Unregister·Î ½ÃÀÛµÈ °æ¿ì FALSE¸¦ ¹ÝȯÇÕ´Ï´Ù. if (!ProcessShellCommand(cmdInfo)) return FALSE; if (!InitServiceManager()) return FALSE; Sleep(1000); if (!CreateDisplayer()) return FALSE; BuildSchedule(); BuildView(); RefreshStateView(); // â Çϳª¸¸ ÃʱâÈ­µÇ¾úÀ¸¹Ç·Î À̸¦ Ç¥½ÃÇÏ°í ¾÷µ¥ÀÌÆ®ÇÕ´Ï´Ù. m_pMainWnd->SetWindowTextW(L"ServiceManagerEx"); m_pMainWnd->ShowWindow(SW_SHOW); m_pMainWnd->UpdateWindow(); // Á¢¹Ì»ç°¡ ÀÖÀ» °æ¿ì¿¡¸¸ DragAcceptFiles¸¦ È£ÃâÇÕ´Ï´Ù. // SDI ÀÀ¿ë ÇÁ·Î±×·¥¿¡¼­´Â ProcessShellCommand ÈÄ¿¡ ÀÌ·¯ÇÑ È£ÃâÀÌ ¹ß»ýÇØ¾ß ÇÕ´Ï´Ù. return TRUE; } bool CServiceManagerExApp::LoadConfig() { wstring wszFileName = L"./Config/DNServiceManager.ini"; // Çѱ¹ if (!g_IniFile.Open(wszFileName.c_str())){ g_Log.Log(LogType::_FILELOG, L"%s File not Found!!\n", wszFileName.c_str()); return false; } memset(&g_Config, 0, sizeof(TServiceManagerConfig)); g_IniFile.GetValue(L"Region", L"RegionInfo", g_Config.wszRegion); g_IniFile.GetValue(L"Connection", L"NetLauncherPort", &g_Config.nLauncherPort); g_IniFile.GetValue(L"Connection", L"ServicePort", &g_Config.nServicePort); g_IniFile.GetValue(L"Connection", L"ServicePatcherPort", &g_Config.nServicePatcherPort); g_IniFile.GetValue(L"Connection", L"GSMPort", &g_Config.nGSMPort); g_IniFile.GetValue(L"Connection", L"MonitorPort", &g_Config.nMonitorPort); g_IniFile.GetValue(L"GSMInfo", L"IP", g_Config.wszGSMIP, IPLENMAX); g_IniFile.GetValue(L"GSMInfo", L"CodePage", g_Config.wszGSMCodePage); g_IniFile.GetValue(L"PatchInfo", L"BaseUrl", g_Config.wszPatchBaseURL); g_IniFile.GetValue(L"PatchInfo", L"PatchUrl", g_Config.wszPatchURL); g_IniFile.GetValue(L"PatchInfo", L"PatchDir", g_Config.wszPatchDir); g_IniFile.GetValue(L"ReserveNoticeInfo", L"FileName", g_Config.wszNoticePath); strcpy_s(g_Config.szVersion, szServiceManagerVersion); g_Log.Log(LogType::_FILELOG, L"## LauncherPort:%d, ServicePort:%d GsmPort:%d ESMPort:%d MonitorPort:%d\r\n", g_Config.nLauncherPort, g_Config.nServicePort, g_Config.nGSMPort, g_Config.nServicePatcherPort, g_Config.nMonitorPort); g_Log.Log(LogType::_FILELOG, L"## ServiceManager Version : %S\r\n", szServiceManagerVersion); if (_access("./System", 0) == -1) { mkdir("./System"); } return true; } void CServiceManagerExApp::LoadConfigEx() { m_ConfigEx.SetDefault(); m_ConfigEx.LoadConfig(); } void CServiceManagerExApp::ReloadConfigEx() { LoadConfigEx(); ClearSchedule(); BuildSchedule(); } bool CServiceManagerExApp::CreateDisplayer() { CLogSplit& logSplit = ((CMainFrame*)GetMainWnd())->GetLogSplit(); m_pLogDisplayer = new CLogViewDisplayer(&logSplit); g_Log.SetDisplayer(m_pLogDisplayer); return true; } bool CServiceManagerExApp::InitServiceManager() { //SetMiniDump(); //ASSERT(m_pLogDisplayer); g_Log.Init(L"ServiceManager", LOGTYPE_CRT_FILE_DAY); s_CountLog.Init(L"LogCount", LOGTYPE_FILE_DAY); g_ExceptionReportLog.Init(L"ExceptionReport", LOGTYPE_FILE_DAY); g_DBDelayLog.Init(L"DBDelay", LOGTYPE_FILE_DAY); s_ExcuteLog.Init(L"Excute", LOGTYPE_FILE_DAY); g_GameDelayLog.Init(L"GameDelay", LOGTYPE_FILE_DAY); g_VillageDelayLog.Init(L"VillageDelay", LOGTYPE_FILE_DAY); g_DBErrorLog.Init(L"DBError", LOGTYPE_FILE_DAY); g_DBSystemErrorLog.Init(L"DBSystemError", LOGTYPE_FILE_DAY); g_MonitorLog.Init(L"MonitorLog", LOGTYPE_FILE_DAY); g_FileLog.Init(L"ServiceManager", LOGTYPE_FILE_DAY); if (LoadConfig() == false) return false; int nSocketCount = 1000; if (!_wcsicmp(g_Config.wszRegion, L"KR") || !_wcsicmp(g_Config.wszRegion, L"KOR") || !_wcsicmp(g_Config.wszRegion, L"DEV")) setlocale(LC_ALL, "Korean"); else if (!_wcsicmp(g_Config.wszRegion, L"CH") || !_wcsicmp(g_Config.wszRegion, L"CHN")) { setlocale(LC_ALL, "chinese-simplified"); nSocketCount = 3000; } else if (!_wcsicmp(g_Config.wszRegion, L"JP") || !_wcsicmp(g_Config.wszRegion, L"JPN")) setlocale(LC_ALL, "japanese"); else if (!_wcsicmp(g_Config.wszRegion, L"US") || !_wcsicmp(g_Config.wszRegion, L"USA")) setlocale(LC_ALL, "us"); //#if defined(_KR) // g_pBAM = new CDNBAM; // if (!g_pBAM) return; //#endif // #if defined(_KR) #ifdef _UNICODE g_pServiceManager = new CServiceManager(this); #else char szIP[IPLENMAX], szCode[256]; WideCharToMultiByte(CP_ACP, 0, g_Config.wszGSMIP, -1, szIP, IPLENMAX, NULL, NULL); WideCharToMultiByte(CP_ACP, 0, g_Config.wszGSMCodePage, -1, szCode, IPLENMAX, NULL, NULL); g_pServiceManager = new CServiceManager(szIP, szCode); #endif if (!g_pServiceManager) return false; //g_pServiceManager->InitializeCommand(); g_pServiceServer = new CServiceServer(); if (!g_pServiceServer) return false; if (!g_pServiceServer->Initialize(nSocketCount, g_Config.nLauncherPort, g_Config.nServicePort, g_Config.nServicePatcherPort, g_Config.nMonitorPort)) { ErrorMessage(L"Service server initialize failed."); return false; } if (!m_GSMServer.Open(g_Config.nGSMPort)) { ErrorMessage(L"Already used GSM port. Program will exit."); return false; } return true; } void CServiceManagerExApp::BuildView() { ((CMainFrame*)GetMainWnd())->BuildView(); } void CServiceManagerExApp::RefreshView() { ((CMainFrame*)GetMainWnd())->RefreshView(); } void CServiceManagerExApp::RefreshStateView() { ((CMainFrame*)GetMainWnd())->RefreshStateView(); } BOOL CServiceManagerExApp::OnIdle(LONG lCount) { m_Scheduler.Update(); CMainSplit& mainSplit = ((CMainFrame*)GetMainWnd())->GetMainSplit(); mainSplit.Update(); ::Sleep(1); return TRUE; } void CServiceManagerExApp::OnPatchStart() { CMainSplit& mainSplit = ((CMainFrame*)GetMainWnd())->GetMainSplit(); mainSplit.OnPatchStart(); } void CServiceManagerExApp::OnPatchProgress(int id, const wchar_t* key, unsigned long progress, unsigned long progressMax) { CMainSplit& mainSplit = ((CMainFrame*)GetMainWnd())->GetMainSplit(); mainSplit.OnPatchProgress(id, key, progress, progressMax); } void CServiceManagerExApp::OnPatchEnd(bool succeeded) { CMainSplit& mainSplit = ((CMainFrame*)GetMainWnd())->GetMainSplit(); mainSplit.OnPatchEnd(succeeded); } void CServiceManagerExApp::OnUnzipProgress(int id, const wchar_t* filename, unsigned long progress, unsigned long progressMax) { CMainSplit& mainSplit = ((CMainFrame*)GetMainWnd())->GetMainSplit(); mainSplit.OnUnzipProgress(id, filename, progress, progressMax); } void CServiceManagerExApp::OnWorldMaxUser(int id, int maxUser) { CMainSplit& mainSplit = ((CMainFrame*)GetMainWnd())->GetMainSplit(); mainSplit.OnWorldMaxUser(id, maxUser); } void CServiceManagerExApp::OnPatchFail(int id, const wchar_t* msg) { CMainSplit& mainSplit = ((CMainFrame*)GetMainWnd())->GetMainSplit(); mainSplit.OnPatchFail(id, msg); } void CServiceManagerExApp::OnPatchCompleted(int id) { CMainSplit& mainSplit = ((CMainFrame*)GetMainWnd())->GetMainSplit(); mainSplit.OnPatchCompleted(id); } void CServiceManagerExApp::OnCommandPatch() { CMainSplit& mainSplit = ((CMainFrame*)GetMainWnd())->GetMainSplit(); mainSplit.OnCommandPatch(); } // ´ëÈ­ »óÀÚ¸¦ ½ÇÇàÇϱâ À§ÇÑ ÀÀ¿ë ÇÁ·Î±×·¥ ¸í·ÉÀÔ´Ï´Ù. void CServiceManagerExApp::OnAppAbout() { CAboutDlg aboutDlg; aboutDlg.DoModal(); } BOOL CServiceManagerExApp::PreTranslateMessage(MSG* pMsg) { // TODO: ¿©±â¿¡ Ư¼öÈ­µÈ Äڵ带 Ãß°¡ ¹×/¶Ç´Â ±âº» Ŭ·¡½º¸¦ È£ÃâÇÕ´Ï´Ù. return CWinApp::PreTranslateMessage(pMsg); } bool CServiceManagerExApp::ReportExceptionToClipboard() { g_Log.Log(LogType::_NORMAL, L"Starting report build to clipboard.\n"); ServerReport::CServerReporter reporter; wstring report; reporter.Report(m_ConfigEx.serverReportDays, m_ConfigEx.serverReportDetail, report); if (!SaveToClipboard(report)) return false; g_Log.Log(LogType::_NORMAL, L"Copy to Clipboard completed.\n"); return true; } bool CServiceManagerExApp::ReportExceptionToBuffer(size_t days, OUT wstring& buffer) { g_Log.Log(LogType::_NORMAL, L"Starting report build to buffer.\n"); ServerReport::CServerReporter reporter; reporter.Report(days, m_ConfigEx.serverReportDetail, buffer); g_Log.Log(LogType::_NORMAL, L"Buffer set completed.\n"); return true; } bool CServiceManagerExApp::ReportExceptionToFile(const wstring& filename) { g_Log.Log(LogType::_NORMAL, L"Starting report build to file.\n"); ServerReport::CServerReporter reporter; wstring report; reporter.Report(m_ConfigEx.serverReportDays, m_ConfigEx.serverReportDetail, report); HANDLE file = 0; try { file = CreateFile(filename.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (file == INVALID_HANDLE_VALUE) throw; DWORD written_size; if (!WriteFile(file, report.c_str(), (DWORD)report.size(), &written_size, NULL)) throw; CloseHandle(file); } catch (...) { CloseHandle(file); g_Log.Log(LogType::_ERROR, L"Copy to file failed.\n"); return false; } g_Log.Log(LogType::_NORMAL, L"Copy to file completed.\n"); return true; } bool CServiceManagerExApp::SaveToClipboard(const wstring& report) { if (!OpenClipboard(NULL)) { g_Log.Log(LogType::_ERROR, L"Copy to Clipboard failed. (open)\n"); return false; } if (!EmptyClipboard()) { g_Log.Log(LogType::_ERROR, L"Copy to Clipboard failed. (empty)\n"); return false; } size_t size = report.length() * sizeof(wchar_t); HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, size + sizeof(wchar_t)); if (!hMem) { CloseClipboard(); g_Log.Log(LogType::_ERROR, L"Copy to Clipboard failed. (alloc)\n"); return false; } wchar_t* pBuf = (wchar_t*)GlobalLock(hMem); ::memcpy(pBuf, report.c_str(), size); GlobalUnlock(hMem); if (!::SetClipboardData(CF_UNICODETEXT, hMem)) { GlobalFree(hMem); CloseClipboard(); g_Log.Log(LogType::_ERROR, L"Copy to Clipboard failed. (set)\n"); return false; } GlobalFree(hMem); CloseClipboard(); return true; } void CServiceManagerExApp::BuildSchedule() { CTime curTime = CTime::GetCurrentTime(); for each (const ScheduleJob* pScheduleJob in m_ConfigEx.schedules) { SimpleScheduler::CScheduleObj* pScheduleObj = SimpleScheduler::CScheduler::GenerateScheduleObj(this, curTime, pScheduleJob); if (!pScheduleObj) continue; m_Scheduler.Register(pScheduleObj); } } void CServiceManagerExApp::ClearSchedule() { m_Scheduler.Clear(); }