// DNFieldServer.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "FireWall.h" #include "IniFile.h" #include "DNIocpManager.h" #include "DNDBConnectionManager.h" #include "DNMasterConnectionManager.h" #include "DNGameServerManager.h" #include "DNGameDataManager.h" #include "Log.h" #include "Util.h" #include "DnMainFrame.h" #include "DNQuestManager.h" #include "ExceptionReport.h" #include "MAAiScript.h" #include "DnScriptManager.h" #include "DNRUDPGameServer.h" #include "DNTalk.h" #include "DNLogConnection.h" #if defined( PRE_WORLDUSERSTATE_OPTIMIZE ) #include "DNGameWorldUserState.hpp" #else #include "DNWorldUserState.h" #endif // #if defined( PRE_WORLDUSERSTATE_OPTIMIZE ) #include "DNGameServerScriptAPI.h" #include "BugReporter.h" #include "DNServiceConnection.h" #include "DNQuest.h" #include "DNEvent.h" #include "Version.h" #include "MemPool.h" #include "DNMissionScheduler.h" #include "NoticeSystem.h" #include "PerfCheck.h" #include "DNAuthManager.h" #include "DNGuildSystem.h" #include "MAScanner.h" #ifdef _USE_VOICECHAT #include "DNVoiceChat.h" #endif #include "ServiceUtil.h" #include "CloseSystem.h" #include "MasterSystemCacheRepository.h" #include "DNSecure.h" #if defined(_WORK) #include "PsUpdater.h" #include "EtActionCoreMng.h" #endif // #if defined(_WORK) #include "DNCashConnection.h" #include "DNChatRoomManager.h" #include "DNPeriodQuestSystem.h" #include "DNGuildRecruitCacheRepository.h" #ifdef PRE_ADD_LIMITED_CASHITEM #include "DNLimitedCashItemRepository.h" #endif //#ifdef PRE_ADD_LIMITED_CASHITEM #if defined( PRE_PRIVATECHAT_CHANNEL ) #include "DNPrivateChatChannel.h" #include "DnPrivateChatManager.h" #endif #if defined(_KRAZ) #include "DNActozShield.h" #endif // #if defined(_KRAZ) #ifdef _AUTH_ #include "RLKTAuth.h" #endif #include "rlkt_Revision.h" //#include "../../Server/RLKT_LICENSE/license_rlkt.h" struct AssertReportMode { AssertReportMode() { _set_error_mode( _OUT_TO_MSGBOX ); } }assertReportMode; #if !defined(_FINAL_BUILD) CLog g_ScriptLog; #endif TGameConfig g_Config; #if defined (_WORK) ConfigWork g_ConfigWork; #endif // #if defined (_WORK) #ifdef _DEBUG #define new new(_NORMAL_BLOCK,__FILE__,__LINE__) #endif int AddToFirewall() { HRESULT hr = S_OK; HRESULT comInit = E_FAIL; INetFwProfile* fwProfile = NULL; // Initialize COM. comInit = CoInitializeEx( 0, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE ); // Ignore RPC_E_CHANGED_MODE; this just means that COM has already been // initialized with a different mode. Since we don't care what the mode is, // we'll just use the existing mode. if (comInit != RPC_E_CHANGED_MODE) { hr = comInit; if (FAILED(hr)) { printf("CoInitializeEx failed: 0x%08lx\n", hr); goto error; } } // Retrieve the firewall profile currently in effect. hr = WindowsFirewallInitialize(&fwProfile); if (FAILED(hr)) { printf("WindowsFirewallInitialize failed: 0x%08lx\n", hr); goto error; } WCHAR wszFileName[ _MAX_PATH ]; HMODULE hModule; hModule = GetModuleHandle( NULL ); GetModuleFileNameW( hModule, wszFileName, _MAX_PATH ); // Add Windows Messenger to the authorized application collection. hr = WindowsFirewallAddApp( fwProfile, wszFileName, L"Dragon Nest" ); if (FAILED(hr)) { printf("WindowsFirewallAddApp failed: 0x%08lx\n", hr); goto error; } error: // Release the firewall profile. WindowsFirewallCleanup(fwProfile); // Uninitialize COM. if (SUCCEEDED(comInit)) { CoUninitialize(); } return 0; } bool LoadConfig(int argc, TCHAR * argv[]) { #if defined(_HSHIELD) g_Config.hHSServer = ANTICPX_INVALID_HANDLE_VALUE; #endif // _HSHIELD memset(&g_Config, 0, sizeof(TGameConfig)); WCHAR wszBuf[128] = { 0, }, wszStr[64] = { 0, }; char szData[128] = { 0, }; memset(wszBuf, 0, sizeof(wszBuf)); memset(szData, 0, sizeof(szData)); //Version _strcpy(g_Config.szVersion, _countof(g_Config.szVersion), szGameVersion, (int)strlen(szGameVersion)); _strcpy(g_Config.szResVersion, _countof(g_Config.szResVersion), "Unknown Version", (int)strlen("Unknown Version")); wstring wszFileName = L"./Config/DNGame.ini"; if (!g_IniFile.Open(wszFileName.c_str())){ g_Log.Log(LogType::_FILELOG, L"DNGame.ini File not Found!!\r\n"); return false; } //rlkt_assert int iEnableAssert = 0; g_IniFile.GetValue(L"Debug", L"Assert", &iEnableAssert); if (iEnableAssert > 0) EnableAssert(true); #if defined( _WORK ) int iEnableAssert=0; g_IniFile.GetValue(L"Debug", L"Assert", &iEnableAssert ); if( iEnableAssert > 0 ) EnableAssert( true ); int iDisableFarm=0; g_IniFile.GetValue(L"Debug", L"DisableFarm", &iDisableFarm ); if( iDisableFarm > 0 ) g_Config.bDisableFarm = true; #endif // #if defined( _WORK ) g_Config.cAffinityType = _GAMESERVER_AFFINITYTYPE_HYBRYD; g_Config.bUseCmd = argc >= 2 ? IsUseCmd(argv[1]) : false; if (g_Config.bUseCmd) { std::wstring wstrTempConfig; std::string strTempConfig; GetFirstRightValue(L"nation", argv[1], wstrTempConfig); if (wstrTempConfig.size() > 0 && wstrTempConfig != L"dev") { ToMultiString(wstrTempConfig, g_Config.szResourceNation); g_Log.Log(LogType::_FILELOG, L"ResourceNation String [%s]\r\n", wstrTempConfig.empty() ? L"None or Dev" : wstrTempConfig.c_str()); } GetDefaultInfo(argv[1], g_Config.nManagedID, g_Config.szResourcePath, g_Config.szResVersion, g_Config.ServiceInfo.szIP, g_Config.ServiceInfo.nPort); g_Log.Log(LogType::_FILELOG, L"ManagedID(SID) [%d]\n", g_Config.nManagedID); g_Log.Log(LogType::_FILELOG, L"ResourcePath [%S] \nResourceRevision [%S]\n", g_Config.szResourcePath.c_str(), g_Config.szResVersion); g_Log.Log(LogType::_FILELOG, L"ServiceManager [IP:%S][Port:%d]\n", g_Config.ServiceInfo.szIP, g_Config.ServiceInfo.nPort); if (GetFirstRightValue(L"pcc", argv[1], wstrTempConfig)) g_Config.nCreateCount = _wtoi(wstrTempConfig.c_str()); else _ASSERT(0); if (GetFirstRightValue(L"pci", argv[1], wstrTempConfig)) g_Config.nCreateIndex = _wtoi(wstrTempConfig.c_str()); else _ASSERT(0); if (g_Config.nCreateCount - 1 < g_Config.nCreateIndex) { g_Log.Log(LogType::_FILELOG, L"Process CreateInfo Error (Count:%d, Index:%d)\r\n", g_Config.nCreateCount, g_Config.nCreateIndex); return false; } g_Log.Log(LogType::_FILELOG, L"Process CreateInfo (Count:%d, Index:%d)\r\n", g_Config.nCreateCount, g_Config.nCreateIndex); if (GetFirstRightValue(L"smc", argv[1], wstrTempConfig)) g_Config.nIocpMax = _wtoi(wstrTempConfig.c_str()); else _ASSERT(0); if (GetFirstRightValue(L"gpl", argv[1], wstrTempConfig)) g_Config.bPreLoad = _wtoi(wstrTempConfig.c_str()) > 0 ? true : false; else _ASSERT(0); if (GetFirstRightValue(L"gucp", argv[1], wstrTempConfig)) g_Config.nGameAcceptPortBegin = _wtoi(wstrTempConfig.c_str()); else _ASSERT(0); if (GetFirstRightValue(L"title", argv[1], wstrTempConfig)) SetConsoleTitleW(wstrTempConfig.c_str()); if (GetFirstRightValue(L"gtcp", argv[1], wstrTempConfig)) g_Config.nClientAcceptPort = _wtoi(wstrTempConfig.c_str()); else _ASSERT(0); g_Log.Log(LogType::_FILELOG, L"SocketMax:%d PreLoad:%s RUDPStartPort:%d TCPPort:%d\n", g_Config.nIocpMax, g_Config.bPreLoad == true ? L"TRUE" : L"FALSE", g_Config.nGameAcceptPortBegin, g_Config.nClientAcceptPort); #ifdef PRE_MOD_OPERATINGFARM if (GetFirstRightValue(L"gsat", argv[1], wstrTempConfig)) g_Config.cAffinityType = _wtoi(wstrTempConfig.c_str()); #endif //#ifdef PRE_MOD_OPERATINGFARM GetDefaultConInfo(argv[1], L"log", &g_Config.LogInfo, 1); g_Log.Log(LogType::_FILELOG, L"LogInfo (Ip:%S, Port:%d)\r\n", g_Config.LogInfo.szIP, g_Config.LogInfo.nPort); GetDefaultConInfo(argv[1], L"cash", &g_Config.CashInfo, 1); g_Log.Log(LogType::_FILELOG, L"CashInfo (Ip:%S, Port:%d)\r\n", g_Config.CashInfo.szIP, g_Config.CashInfo.nPort); GetDefaultConInfo(argv[1], L"master", g_Config.MasterInfo, WORLDCOUNTMAX); for (int h = 0; h < WORLDCOUNTMAX; h++) { if (g_Config.MasterInfo[h].nPort <= 0) continue; g_Log.Log(LogType::_FILELOG, L"MasterCon Ip:%S, Port:%d\r\n", g_Config.MasterInfo[h].szIP, g_Config.MasterInfo[h].nPort); g_Config.nMasterCount++; } GetDefaultConInfo(argv[1], L"db", g_Config.DBInfos, DBSERVERMAX); for (int h = 0; h < DBSERVERMAX; h++) { if (g_Config.DBInfos[h].nPort <= 0) continue; g_Log.Log(LogType::_FILELOG, L"DBCon Ip:%S, Port:%d\r\n", g_Config.DBInfos[h].szIP, g_Config.DBInfos[h].nPort); g_Config.nDBCount++; } #if defined( PRE_FIX_WORLDCOMBINEPARTY ) if (GetFirstRightValue(L"gcwg", argv[1], wstrTempConfig)) g_Config.bWorldCombineGameServer = _wtoi(wstrTempConfig.c_str()) > 0 ? true : false; #endif GetDolbyAxonInfo(argv[1], g_Config.szPrivateDolbyIp, g_Config.szPublicDolbyIp, g_Config.nAudioPort, g_Config.nControlPort); g_Log.Log(LogType::_FILELOG, L"DolbyAxon Info PrivateIP:%S, PublicIP:%S, APort:%d CPort:%d\r\n", g_Config.szPrivateDolbyIp, g_Config.szPublicDolbyIp, g_Config.nAudioPort, g_Config.nControlPort); } else { int nTemp = 1; g_IniFile.GetValue(L"Info", L"PreLoad", &nTemp); g_Config.bPreLoad = ( nTemp == 0 ) ? false : true; g_IniFile.GetValue(L"Info", L"OpenCount", &g_Config.nGameServerOpenCount); g_IniFile.GetValue(L"Info", L"StartPort", &g_Config.nGameAcceptPortBegin); g_IniFile.GetValue(L"Info", L"TcpPort", &g_Config.nClientAcceptPort); _ASSERT(g_Config.nClientAcceptPort != 0 && "Check Game.ini needs TcpPort"); g_IniFile.GetValue(L"Info", L"IocpMax", &g_Config.nIocpMax); g_Log.Log(LogType::_FILELOG, L"IocpMax:%d\r\n", g_Config.nIocpMax); std::vector Tokens; g_IniFile.GetValue(L"Connection", L"Cash", wszBuf); if (wszBuf[0] != '\0'){ WideCharToMultiByte(CP_ACP, NULL, wszBuf, -1, szData, sizeof(szData), NULL, NULL); Tokens.clear(); TokenizeA(szData, Tokens, ":"); if (!Tokens.empty()){ _strcpy(g_Config.CashInfo.szIP, _countof(g_Config.CashInfo.szIP), Tokens[0].c_str(), (int)strlen(Tokens[0].c_str())); g_Config.CashInfo.nPort = atoi(Tokens[1].c_str()); } } g_Log.Log(LogType::_FILELOG, L"Cash(%S, %d)\r\n", g_Config.CashInfo.szIP, g_Config.CashInfo.nPort); g_IniFile.GetValue(L"Connection", L"MasterCount", &g_Config.nMasterCount); for (int i = 0; i < g_Config.nMasterCount; i++){ swprintf(wszStr, L"Master%d", i + 1); g_IniFile.GetValue(L"Connection", wszStr, wszBuf); if (wszBuf[0] != '\0'){ WideCharToMultiByte(CP_ACP, NULL, wszBuf, -1, szData, sizeof(szData), NULL, NULL); Tokens.clear(); TokenizeA(szData, Tokens, ":"); if (!Tokens.empty()){ _strcpy(g_Config.MasterInfo[i].szIP, _countof(g_Config.MasterInfo[i].szIP), Tokens[0].c_str(), (int)strlen(Tokens[0].c_str())); g_Config.MasterInfo[i].nPort = atoi(Tokens[1].c_str()); } } } g_IniFile.GetValue(L"Connection", L"DBCount", &g_Config.nDBCount); for (int i = 0; i < g_Config.nDBCount; i++){ swprintf(wszStr, L"DB%d", i + 1); g_IniFile.GetValue(L"Connection", wszStr, wszBuf); if (wszBuf[0] != '\0'){ WideCharToMultiByte(CP_ACP, NULL, wszBuf, -1, szData, sizeof(szData), NULL, NULL); Tokens.clear(); TokenizeA(szData, Tokens, ":"); if (!Tokens.empty()){ _strcpy(g_Config.DBInfos[i].szIP, _countof(g_Config.DBInfos[i].szIP), Tokens[0].c_str(), (int)strlen(Tokens[0].c_str())); g_Config.DBInfos[i].nPort = atoi(Tokens[1].c_str()); } } } WCHAR wszLogStr[128] = {0,}; g_IniFile.GetValue(L"Connection", L"Log", wszLogStr); if (wszLogStr[0] != '\0'){ WideCharToMultiByte(CP_ACP, NULL, wszLogStr, -1, szData, sizeof(szData), NULL, NULL); Tokens.clear(); TokenizeA(szData, Tokens, ":"); if (!Tokens.empty()){ _strcpy(g_Config.LogInfo.szIP, _countof(g_Config.LogInfo.szIP), Tokens[0].c_str(), (int)strlen(Tokens[0].c_str())); g_Config.LogInfo.nPort = atoi(Tokens[1].c_str()); } } g_Log.Log(LogType::_FILELOG, L"LogInfo (Ip:%S, Port:%d)\r\n", g_Config.LogInfo.szIP, g_Config.LogInfo.nPort); WCHAR wszProbeStr[128] = {0,}; g_IniFile.GetValue(L"Probe", L"ProbePort", &g_Config.nProbePort); g_IniFile.GetValue(L"Probe", L"ProbeIP", wszProbeStr); if (wszProbeStr[0] != '\0') WideCharToMultiByte(CP_ACP, 0, wszProbeStr, (int)wcslen(wszProbeStr), g_Config.szProbeIP, sizeof(g_Config.szProbeIP), NULL, NULL); // ResourcePath 등록해준다. WCHAR wszPath[_MAX_PATH] = { 0, }; char szPath[_MAX_PATH] = { 0, }; g_IniFile.GetValue( L"Resource", L"Path", wszPath ); if (wszPath[0] != '\0') WideCharToMultiByte(CP_ACP, NULL, wszPath, -1, szPath, sizeof(szPath), NULL, NULL); g_Config.szResourcePath = szPath; if( g_Config.szResourcePath.empty() ) g_Config.szResourcePath = "."; WCHAR wszResNation[128] = { 0, }; char szResNation[128] = { 0, }; g_IniFile.GetValue( L"Resource", L"Nation", wszResNation ); if (wszResNation[0] != '\0'){ WideCharToMultiByte(CP_ACP, NULL, wszResNation, -1, szResNation, sizeof(szResNation), NULL, NULL); if( strlen(szResNation) > 0 ) { g_Config.szResourceNation = "_"; g_Config.szResourceNation += szResNation; } } g_IniFile.GetValue(L"DolbyInfo", L"PrivateIp", wszBuf); if (wszBuf[0] != '\0') WideCharToMultiByte(CP_ACP, NULL, wszBuf, -1, szData, sizeof(szData), NULL, NULL); _strcpy(g_Config.szPrivateDolbyIp, _countof(g_Config.szPrivateDolbyIp), szData, (int)strlen(szData)); g_IniFile.GetValue(L"DolbyInfo", L"PublicIp", wszBuf); if (wszBuf[0] != '\0') WideCharToMultiByte(CP_ACP, NULL, wszBuf, -1, szData, sizeof(szData), NULL, NULL); _strcpy(g_Config.szPublicDolbyIp, _countof(g_Config.szPublicDolbyIp), szData, (int)strlen(szData)); g_IniFile.GetValue(L"DolbyInfo", L"ControlPort", &g_Config.nControlPort); g_IniFile.GetValue(L"DolbyInfo", L"AudioPort", &g_Config.nAudioPort); g_Log.Log(LogType::_FILELOG, L"DolbyInfo (PrivateIp:%S, PublicIP:%S, CPort:%d, APort:%d)\r\n", g_Config.szPrivateDolbyIp, g_Config.szPublicDolbyIp, g_Config.nControlPort, g_Config.nAudioPort); #if defined (_WORK) && defined (PRE_ADD_SERVER_LOAD_SHORTENING) int nCommandMax = 0; g_IniFile.GetValue(L"Work", L"CommandMax", &nCommandMax); wchar_t wszValueName[128] = {0}; for (int i = 1; i <= nCommandMax; ++i) { wsprintf(wszValueName, L"Command%d", i); g_IniFile.GetValue(L"Work", wszValueName, wszBuf); if (wszBuf[0] == 0) continue; g_ConfigWork.AddCommand(wszBuf); } #endif // #if defined (_WORK) && defined (PRE_ADD_SERVER_LOAD_SHORTENING) #if defined( PRE_FIX_WORLDCOMBINEPARTY ) g_IniFile.GetValue(L"Info", L"WorldCombineServer", &nTemp); g_Config.bWorldCombineGameServer = ( nTemp == 0 ) ? false : true; #endif } g_IniFile.GetValue(L"ServerManagerEx", L"sid", &g_Config.nManagedID); g_IniFile.GetValue(L"ServerManagerEx", L"ip", wszBuf); WideCharToMultiByte(CP_ACP, NULL, wszBuf, -1, g_Config.ServiceInfo.szIP, sizeof(g_Config.ServiceInfo.szIP), NULL, NULL); g_IniFile.GetValue(L"ServerManagerEx", L"port", &g_Config.ServiceInfo.nPort); return true; } bool LoadNpcQuest() { #if defined (_WORK) && defined (PRE_ADD_SERVER_LOAD_SHORTENING) if (g_ConfigWork.HasCommand(L"ExceptScript")) return true; #endif // #if defined (_WORK) && defined (PRE_ADD_SERVER_LOAD_SHORTENING) g_pNpcQuestScriptManager->CreateLuaState(g_pGameServerManager->GetThreadCount()); // 각 쓰레드별로 npc 대화 & 퀘스트 관련 스크립트들을 전부 로딩 한다. for ( int i = 0 ; i < g_pGameServerManager->GetThreadCount(); i++ ) { lua_State* pLuaState = g_pNpcQuestScriptManager->OpenStateByIndex(i); DefAllAPIFunc(pLuaState); //----------------------------------------------------------------------------------------------------------- // 스크립트 공통 파일 먼저 로드 std::vector CommonFileList; g_Log.Log(LogType::_FILELOG, L"QuestNPC_Common...Folder : %S\n", CEtResourceMng::GetInstance().GetFullPath( "QuestNPC_Common" ).c_str()); CEtResourceMng::GetInstance().FindFileListAll_IgnoreExistFile( "QuestNPC_Common", "*.lua", CommonFileList ); for ( int j = 0 ; j < (int)CommonFileList.size() ; j++ ) { bool bResult = g_pNpcQuestScriptManager->LoadScript(CEtResourceMng::GetInstance().GetFullName(CommonFileList[j].c_str()).c_str(), false, i, false); if ( !bResult ) { g_Log.Log(LogType::_FILELOG, L"CommonLuaFile Load FAILED...\n"); g_Log.Log(LogType::_FILELOG, L"%S\n", CEtResourceMng::GetInstance().GetFullName(CommonFileList[j].c_str()).c_str()); } } //----------------------------------------------------------------------------------------------------------- g_Log.Log(LogType::_FILELOG, L"LoadScript Data...\n"); g_Log.Log(LogType::_FILELOG, L"Talk_Quest...Folder : %S\n", CEtResourceMng::GetInstance().GetFullPath( "Talk_Quest" ).c_str()); std::vector FileList; // FindFileListInDirectory(CEtResourceMng::GetInstance().GetFullPath( "Talk_Quest" ).c_str(), "*.lua", FileList); CEtResourceMng::GetInstance().FindFileListAll_IgnoreExistFile( "Talk_Quest", "*.lua", FileList ); for ( int j = 0 ; j < (int)FileList.size() ; j++ ) { bool aRetVal = g_pNpcQuestScriptManager->LoadScript(CEtResourceMng::GetInstance().GetFullName(FileList[j].c_str()).c_str(), true, i, true); if (!aRetVal) { g_Log.Log(LogType::_FILELOG, L"LoadNpcQuest() Failed !!! - g_pNpcQuestScriptManager->LoadScript(...)\n"); return false; // DN_RETURN(false); } } int nColor = _GREEN; if ( FileList.empty() ) { nColor = _RED; } g_Log.Log(LogType::_FILELOG, L"Talk_Quest...Size : %d\n", (int)FileList.size()); g_Log.Log(LogType::_FILELOG, L"LoadScript Data...\n"); g_Log.Log(LogType::_FILELOG, L"Talk_Npc...Folder : %S\n", CEtResourceMng::GetInstance().GetFullPath( "Talk_Npc" ).c_str()); FileList.clear(); // FindFileListInDirectory(CEtResourceMng::GetInstance().GetFullPath( "Talk_Npc" ).c_str(), "*.lua", FileList); CEtResourceMng::GetInstance().FindFileListAll_IgnoreExistFile( "Talk_Npc", "*.lua", FileList ); for ( int j = 0 ; j < (int)FileList.size() ; j++ ) { g_pNpcQuestScriptManager->LoadScript(CEtResourceMng::GetInstance().GetFullName(FileList[j].c_str()).c_str(), true, i, false); } nColor = _GREEN; if ( FileList.empty() ) { nColor = _RED; } g_Log.Log(LogType::_FILELOG, L"Talk_Npc...Size : %d\n", (int)FileList.size()); } return true; } bool InitApp(int argc, TCHAR * argv[]) { //if (!CheckSerial()) return false; WCHAR wszLogName[128], wszScriptLogName[128] = { 0, }; memset(wszLogName, 0, sizeof(wszLogName)); #if defined( PRE_TRIGGER_LOG ) WCHAR wszTriggerLogName[128]; #endif // #if defined( PRE_TRIGGER_LOG ) if (argc >= 2) { if (IsUseCmd(argv[1])) { int nSID = 0; std::wstring wstrTempArgv; if (GetFirstRightValue(L"sid", argv[1], wstrTempArgv)) nSID = _wtoi(wstrTempArgv.c_str()); swprintf(wszLogName, L"GameServer_%d", nSID); swprintf(wszScriptLogName, L"GameServerScript_%d", nSID); #if defined( PRE_TRIGGER_LOG ) swprintf(wszTriggerLogName, L"TriggerLog_%d", nSID); #endif // #if defined( PRE_TRIGGER_LOG ) } else { swprintf(wszLogName, L"GameServer"); swprintf(wszScriptLogName, L"GameServerScript"); #if defined( PRE_TRIGGER_LOG ) swprintf(wszTriggerLogName, L"TriggerLog"); #endif // #if defined( PRE_TRIGGER_LOG ) } } else { swprintf(wszLogName, L"GameServer"); swprintf(wszScriptLogName, L"GameServerScript"); #if defined( PRE_TRIGGER_LOG ) swprintf(wszTriggerLogName, L"TriggerLog"); #endif // #if defined( PRE_TRIGGER_LOG ) } #if defined(_FINAL_BUILD) g_Log.Init(wszLogName, LOGTYPE_FILE_HOUR); #else g_Log.Init(wszLogName, LOGTYPE_CRT_FILE_HOUR); #endif g_Log.SetServerID(g_Config.nManagedID); #if defined( PRE_TRIGGER_LOG ) g_TriggerLog.Init( wszTriggerLogName, LOGTYPE_CRT_FILE_TRIGGER_TEST ); #endif // #if defined( PRE_TRIGGER_LOG ) #if defined( PRE_TRIGGER_UNITTEST_LOG ) WCHAR wszTriggerUnitTestLogName[MAX_PATH]; if (argc > 14) swprintf( wszTriggerUnitTestLogName, L"TriggerUnitTestLog_%s", argv[4] ); else swprintf( wszTriggerUnitTestLogName, L"TriggerUnitTestLog" ); g_TriggerUnitTestLog.Init( wszTriggerUnitTestLogName, LOGTYPE_FILE_HOUR ); #endif // #if defined( PRE_TRIGGER_UNITTEST_LOG ) #if defined( PRE_QUESTSCRIPT_LOG ) WCHAR wszQuestLogName[MAX_PATH]; if (argc > 14) swprintf( wszQuestLogName, L"QuestLog_%s", argv[4] ); else swprintf( wszQuestLogName, L"QuestLog" ); g_QuestLog.Init( wszQuestLogName, LOGTYPE_FILE_HOUR ); #endif // #if defined( PRE_QUESTSCRIPT_LOG ) #if !defined(_FINAL_BUILD) g_ScriptLog.Init(wszScriptLogName, LOGTYPE_FILE_HOUR); #endif #if defined(_HSHIELD) g_Config.hHSServer = _AhnHS_CreateServerObject("./DragonNest.hsb"); if (g_Config.hHSServer == ANTICPX_INVALID_HANDLE_VALUE){ g_Log.Log(LogType::_FILELOG, L"_AhnHS_CreateServerObject Failed %d\n", g_Config.hHSServer); return false; } #endif // _HSHIELD //RLKT AUTH #ifdef _AUTH_ RLKTAuth::GetInstance().Main(); #endif // CDNSecure::CreateInstance(); CDnActorActionStateCache::CreateInstance(); g_pQuestManager = new CDNQuestManager(); if ( !g_pQuestManager ) return false; g_pQuestManager->LoadAllQuest("QuestTable.ext", g_pNpcQuestScriptManager); g_pDataManager = new CDNGameDataManager; if (!g_pDataManager) return false; if( !g_pDataManager->AllLoad() ) return false; if( !g_AiScriptLoader.AllLoadScript() ) return false; g_pIocpManager = new CDNIocpManager; if (!g_pIocpManager) return false; g_pGuildManager = new CDNGuildSystem; if (!g_pGuildManager) { return false; } DWORD aRetVal = g_pGuildManager->Open(); if (NOERROR != aRetVal) { return false; } #if defined( PRE_WORLDUSERSTATE_OPTIMIZE ) g_pWorldUserState = new CDNGameWorldUserState; #else g_pWorldUserState = new CDNWorldUserState; #endif // #if defined( PRE_WORLDUSERSTATE_OPTIMIZE ) if (!g_pWorldUserState) return false; g_pEvent = new CDNEvent; if (!g_pEvent) return false; // PeriodQuest System g_pPeriodQuestSystem = new CDNPeriodQuestSystem; if (!g_pPeriodQuestSystem) return false; if( !g_pPeriodQuestSystem->Initialize() ) return false; g_pNoticeSystem = new CDNNoticeSystem; if (!g_pNoticeSystem) return false; g_pCloseSystem = new CCloseSystem; if (!g_pCloseSystem) return false; g_pMasterConnectionManager = new CDNMasterConnectionManager; if (!g_pMasterConnectionManager) return false; g_pDBConnectionManager = new CDNDBConnectionManager; if (!g_pDBConnectionManager) return false; g_pCashConnection = new CDNCashConnection; if (!g_pCashConnection) return false; #ifdef PRE_ADD_LIMITED_CASHITEM g_pLimitedCashItemRepository = new CDNLimitedCashItemRepository; if (!g_pLimitedCashItemRepository) return false; #endif //#ifdef PRE_ADD_LIMITED_CASHITEM #if defined( PRE_PRIVATECHAT_CHANNEL ) g_pPrivateChatChannelManager = new CDNPrivateChatManager; if(!g_pPrivateChatChannelManager) return false; #endif g_pAuthManager = new CDNAuthManager; if (!g_pAuthManager) return false; if (!g_pAuthManager->Init()) return false; g_pNpcQuestScriptManager = new DnScriptManager(); if ( !g_pNpcQuestScriptManager ) return false; g_pGameServerManager = new CDNGameServerManager; if (!g_pGameServerManager) return false; CDNMissionScheduler::CreateInstance(); MasterSystem::CCacheRepository::CreateInstance(); MAScanner::CreateInstance(); g_pGameServerManager->PreOpenGameServer(); CDNTalk::SetScriptManager(g_pNpcQuestScriptManager); if (!LoadNpcQuest()) { g_Log.Log(LogType::_FILELOG, L"LoadNpcQuest() Failed !!!\r\n"); return false; } //init rudp gameserver if (g_pGameServerManager->StartGameServer(g_Config.nGameAcceptPortBegin, g_Config.szProbeIP, g_Config.nProbePort) == false) { g_Log.Log(LogType::_FILELOG, L"RUDP GameServer Start Failed\n"); return false; } g_Log.Log(LogType::_FILELOG, L"RUDP GameServer Start ThreadCount : %d\n", g_pGameServerManager->GetThreadCount() ); if (g_Config.nIocpMax <= 0) g_Config.nIocpMax = 100; #ifdef _FINAL_BUILD if (g_Config.nIocpMax < 2000) { g_Config.nIocpMax = 2000; g_Log.Log(LogType::_FILELOG, L"Iocp Initialize NeedMore socket check serverStruct.xml\r\n"); } #endif if (g_pIocpManager->Init(g_Config.nIocpMax, (2)) < 0){ g_Log.Log(LogType::_FILELOG,L"Iocp Initialize Fail\r\n"); return false; } // Master Connection for (int i = 0; i < g_Config.nMasterCount; i++){ if (!g_pMasterConnectionManager->AddConnection(g_Config.MasterInfo[i].szIP, g_Config.MasterInfo[i].nPort)) g_Log.Log(LogType::_FILELOG, L"Master (Ip:%S, Port:%d) AddConnection Fail!!!!\r\n", g_Config.MasterInfo[i].szIP, g_Config.MasterInfo[i].nPort); else g_Log.Log(LogType::_FILELOG, L"Master (Ip:%S, Port:%d) AddConnection Success\r\n", g_Config.MasterInfo[i].szIP, g_Config.MasterInfo[i].nPort); } // DB Connection for (int i = 0; i < g_Config.nDBCount; i++){ if (!g_pDBConnectionManager->AddConnection(g_Config.DBInfos[i].szIP, g_Config.DBInfos[i].nPort)){ g_Log.Log(LogType::_FILELOG, L"DBInfos (Ip:%S, Port:%d) AddConnection Fail!!!!\r\n", g_Config.DBInfos[i].szIP, g_Config.DBInfos[i].nPort); } g_Log.Log(LogType::_FILELOG, L"DBInfos (Ip:%S, Port:%d) AddConnection Success\r\n", g_Config.DBInfos[i].szIP, g_Config.DBInfos[i].nPort); } g_pLogConnection = new CDNLogConnection; if( !g_pLogConnection ) return false; g_pLogConnection->SetIp(g_Config.LogInfo.szIP); g_pLogConnection->SetPort(g_Config.LogInfo.nPort); // 혹시나 해서.. 쓰레드 일단 다 생성되고. Sleep(1000); if (g_Config.nManagedID > 0) { g_pServiceConnection = new CDNServiceConnection(g_Config.nManagedID); if (!g_pServiceConnection) return false; g_pServiceConnection->SetIp(g_Config.ServiceInfo.szIP); g_pServiceConnection->SetPort(g_Config.ServiceInfo.nPort); } #ifdef _USE_VOICECHAT if (g_Config.nControlPort > 0) { g_pVoiceChat = new CDNVoiceChat(); if (!g_pVoiceChat) return false; if (g_pVoiceChat->Initialize(0, "DragonNest", g_Config.szPrivateDolbyIp, g_Config.nControlPort) == false) return false; } else { g_Log.Log(LogType::_FILELOG, L"_USE_VOICECHAT check VoiceInfo\n"); } #endif #if defined(_GPK) // Shanda 보안 g_Config.pDynCode = GPKCreateSvrDynCode(); if (!g_Config.pDynCode){ g_Log.Log(LogType::_FILELOG, L"SvrDynCode NULL!!!\r\n"); return false; } char szSvrDir[MAX_PATH] = { 0, }; char szCltDir[MAX_PATH] = { 0, }; #if defined(WIN64) sprintf(szSvrDir, "./DynCodeBin64/Server"); sprintf(szCltDir, "./DynCodeBin64/Client"); #else #if defined(BIT64) sprintf(szSvrDir, "./DynCodeBin/Server64"); #else sprintf(szSvrDir, "./DynCodeBin/Server"); #endif sprintf(szCltDir, "./DynCodeBin/Client"); #endif int nBinCount = g_Config.pDynCode->LoadBinary(szSvrDir, szCltDir); if (nBinCount == 0){ g_Log.Log(LogType::_FILELOG, L"Load DynCode failed!!!\r\n"); return false; } g_Config.pGpkCmd = g_Config.pDynCode->AllocAuthObject(); if (g_Config.pGpkCmd == NULL) { g_Log.Log(LogType::_FILELOG, L"AllocAuthObject Failed!\n"); return false; } bool bChAuthRet = g_Config.pDynCode->LoadAuthFile("AuthData.dat"); // CSAuth관련된 애 if (bChAuthRet == false) { g_Log.Log(LogType::_FILELOG, L"LoadAuthFile [AuthData.dat] failed!!!\r\n"); return false; } #endif // _GPK #if defined(_KRAZ) && defined(_FINAL_BUILD) g_pActozShield = new CDNActozShield; if (!g_pActozShield) return false; if (!g_pActozShield->Init()) return false; #endif // #if defined(_KRAZ) g_Log.Log(LogType::_FILEDBLOG, L"Application Initialize Success\r\n"); return true; } void ClearApp() { #if defined(_KRAZ) SAFE_DELETE(g_pActozShield); #endif // #if defined(_KRAZ) // 2008.01.20 김밥 // Connection 과 ReconnectThread 간에 동기화 이슈로 ReconnectThread 먼저 종료 if( g_pIocpManager ) { g_pIocpManager->CloseAcceptors(); g_pIocpManager->ThreadStop(); g_pIocpManager->FinalReconnectThread(); } SAFE_DELETE(g_pServiceConnection); SAFE_DELETE(g_pLogConnection); SAFE_DELETE(g_pQuestManager); SAFE_DELETE(g_pNpcQuestScriptManager); SAFE_DELETE(g_pCashConnection); if (g_pIocpManager) g_pIocpManager->Final(); SAFE_DELETE(g_pDBConnectionManager); SAFE_DELETE(g_pMasterConnectionManager); SAFE_DELETE( g_pNoticeSystem ); SAFE_DELETE( g_pCloseSystem ); SAFE_DELETE(g_pGameServerManager); SAFE_DELETE(g_pWorldUserState); SAFE_DELETE(g_pEvent); if (g_pGuildManager) { g_pGuildManager->Close(); delete g_pGuildManager; g_pGuildManager = NULL; } SAFE_DELETE(g_pIocpManager); SAFE_DELETE(g_pDataManager); SAFE_DELETE(g_pAuthManager); #ifdef _USE_VOICECHAT SAFE_DELETE(g_pVoiceChat); #endif SAFE_DELETE(g_pPeriodQuestSystem); if( MAScanner::IsActive() ) MAScanner::DestroyInstance(); if( CDNMissionScheduler::GetInstancePtr() ) CDNMissionScheduler::DestroyInstance(); if( MasterSystem::CCacheRepository::GetInstancePtr() ) MasterSystem::CCacheRepository::DestroyInstance(); #if defined(_HSHIELD) if (g_Config.hHSServer != ANTICPX_INVALID_HANDLE_VALUE){ _AhnHS_CloseServerHandle(g_Config.hHSServer); g_Config.hHSServer = ANTICPX_INVALID_HANDLE_VALUE; } #endif // #if defined(_HSHIELD) #if defined(_GPK) if (g_Config.pDynCode) g_Config.pDynCode->Release(); if (g_Config.pGpkCmd) g_Config.pGpkCmd->Release(); #endif // #if defined(_GPK) if( CDNSecure::IsActive() ) CDNSecure::DestroyInstance(); if( CDnActorActionStateCache::IsActive() ) CDnActorActionStateCache::DestroyInstance(); } #ifndef _FINAL_BUILD bool bIsGTest( int argc, TCHAR* argv[] ) { for( int i=0 ; iAsyncUpdate (); #endif // #if defined(_WORK) */ #ifndef _FINAL_BUILD if( bIsGTest( argc, argv )) return RUN_ALL_TESTS(); #endif #if defined(_WORK) _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); _CrtSetBreakAlloc(7311617); #endif #if defined(_CH) setlocale(LC_ALL, "chinese-simplified"); #elif defined(_TW) setlocale(LC_ALL, "chinese-traditional"); #elif defined(_JP) setlocale(LC_ALL, "japanese"); #elif defined(_US) setlocale(LC_ALL, "us"); #else setlocale(LC_ALL, "Korean"); #endif // 예외 처리자 준비 //#if !defined(_FINAL_BUILD) //unhandledexception 인경우에는 항상 풀메모리덤프 DWORD dwRetVal = CExceptionReport::GetInstancePtr()->Open(_T(".\\"), TRUE, TRUE, MiniDumpWithFullMemory); // Release 모드 컴파일 시 C4744 경고가 발생하여 Singleton 구현 변경, CExceptionReport::GetInstancePtr() 을 inline 화 하지 않음 (참고 : http://msdn.microsoft.com/ko-kr/library/a7za416f.aspx) //#else // _FINAL_BUILD // DWORD dwRetVal = CExceptionReport::GetInstancePtr()->Open(_T(".\\"), TRUE, TRUE); // Release 모드 컴파일 시 C4744 경고가 발생하여 Singleton 구현 변경, CExceptionReport::GetInstancePtr() 을 inline 화 하지 않음 (참고 : http://msdn.microsoft.com/ko-kr/library/a7za416f.aspx) //#endif // _FINAL_BUILD if (NOERROR != dwRetVal) { DWORD dwErrNo = ::GetLastError(); DN_RETURN(dwErrNo); } ::srand(timeGetTime()); if (!LoadConfig(argc, argv)){ g_Log.Log(LogType::_FILELOG, L"LoadConfig Failed\r\n"); return 0; } AddToFirewall(); #ifdef NDEBUG // SetOutputDebugFuncPtr( NULL ); #endif g_Config.bAllLoaded = false; if (!CLfhHeap::GetInstance()->InitPool()) { g_Log.Log(LogType::_FILELOG, L"** InitPool Failed!!! Check!!!!!\r\n"); return 0; } CDnMainFrame *pMainFrame = new CDnMainFrame; pMainFrame->PreInitialize(); pMainFrame->InitializeDevice(); if (!InitApp(argc, argv)){ g_Log.Log(LogType::_FILELOG, L"** InitApp Failed!!! Check!!!!!\r\n"); ClearApp(); delete pMainFrame; return 0; } pMainFrame->Initialize(); g_pIocpManager->VerifyAccept(ACCEPTOPEN_VERIFY_TYPE_APPINITCOMPLETE); g_Config.bAllLoaded = true; wprintf(L"exit 명령을 치면 종료\r\n"); //SetConsoleTitleA(FormatA("GameServer Rev.%s", revDNGameServer).c_str()); //rlkt_revision char szCmd[256] = {0,}; while (1) { if (strcmp(szCmd, "exit") == 0) break; if (strcmp(szCmd, "assert") == 0) { EnableAssert(true); printf("Asserts Enabled.\n"); } if (strcmp(szCmd, "disable_assert") == 0) { EnableAssert(false); printf("Asserts Disabled.\n"); } if (strcmp(szCmd, "reload") == 0) { #if defined (_WORK) && defined (PRE_ADD_SERVER_LOAD_SHORTENING) g_ConfigWork.RemoveCommand(L"ExceptScript"); #endif // #if defined (_WORK) && defined (PRE_ADD_SERVER_LOAD_SHORTENING) g_pDataManager->LoadTalkData(); g_pQuestManager->LoadAllQuest("QuestTable.ext", g_pNpcQuestScriptManager); g_pNpcQuestScriptManager->CloseAllState(); LoadNpcQuest(); printf("Reload all script..\n"); } if ( strcmp(szCmd, "quest_list") == 0 ) { std::vector questList; g_pQuestManager->DumpAllQuest(questList); wprintf(L"Quest list size = %d\n", questList.size()); for ( size_t i = 0; i < questList.size() ; i++ ) { CDNQuest* pQuest = questList[i]; wprintf(L"Cnt %d: QuestIndex[%d]\nTitle[%s]\nXML[%s]\nLUA[%s]\n\n", i, pQuest->GetQuestInfo().nQuestIndex, pQuest->GetQuestInfo().szQuestName.c_str(), pQuest->GetQuestInfo().szTalkFileName.c_str(), pQuest->GetQuestInfo().szScriptFileName.c_str()); } } if ( strcmp(szCmd, "talk_list") == 0 ) { std::vector talklist; g_pDataManager->GetTalkFileList(talklist); wprintf(L"talk list size = %d\n", talklist.size()); for ( size_t i = 0 ; i < talklist.size() ; i++ ) { wprintf(L"%s\n", talklist[i].c_str()); } } if (strcmp(szCmd, "enableprofile") == 0) { s_pPrevOutputDebugFunc = s_pProfileOutputDebugFunc; // SetProfileOutputDebugFuncPtr( ConsoleOutputDebug ); g_bEnableProfile = true; } if (strcmp(szCmd, "disableprofile") == 0) { if( s_pPrevOutputDebugFunc ) SetProfileOutputDebugFuncPtr( s_pPrevOutputDebugFunc ); g_bEnableProfile = false; } #if !defined( _FINAL_BUILD ) if( strcmp( szCmd, "logtest" ) == 0 ) { CPerformanceLog Perf("LogTest"); HANDLE hThread[TESTTHREADCOUNT]; for( int i=0 ; iAllLoad() == false) { _DANGER_POINT_MSG(L"reloadext 실패!"); break; } } if (!strcmp(szCmd, "reloadact")) { g_ActionCoreMng.ReleaseAllContainer(); } #endif //#ifdef _WORK printf("CMD>"); std::cin >> szCmd; } SAFE_DELETE( pMainFrame ); ClearApp(); #if defined(_WORK) SAFE_DELETE(g_PsUpdater); #endif // #if defined(_WORK) return 0; }