#include "stdafx.h" #include #include #include //========================================================================================================= // GuildServer Include Files // #include "GuildServer.h" #include "PacketHandler/PacketHandler.h" #include #include #include #include // Internal Function Headers #include "Guild/GuildManager.h" #include "GuildScriptParserManager.h" #include #include #include "DominationManager.h" //#define temp_for_test #define CHECK_PARAM_NUMBER( variable_type, variable, szSectionName, keyName, defValue ) \ variable_type variable = 0; \ __READ_CONFIG_NUMBER( variable, szSectionName, keyName, defValue, GetDescFileName() ); \ if( variable == defValue ) return FALSE #define CHECK_PARAM_STRING( variable, szSectionName, keyName, defValue ) \ char variable [128] = {0,}; \ __READ_CONFIG_STRING( variable, szSectionName, keyName, defValue, GetDescFileName() ); \ if( variable == defValue ) return FALSE #include /// @brief ȯ°æ ¼³Á¤ ÆÄÀÏ¿¡¼­ ¹®ÀÚ¿­ °ªÀ» ¾ÈÀüÇÏ°Ô Àоî¿Â´Ù. /// @param section_name ¼½¼Ç À̸§ /// @param key_name ۰ª À̸§ /// @param default_value ±âº»°ª /// @param ini_file_name ȯ°æ¼³Á¤ ÆÄÀÏ À̸§ /// @param min_read_count Àоî¿Ã ¹®ÀÚ¿­ÀÇ ÃÖ¼Ò °³¼ö /// @param max_read_count Àоî¿Ã ¹®ÀÚ¿­ÀÇ ÃÖ´ë °³¼ö /// @return Á¤»óÀûÀ¸·Î ÀÐ¾î ¿ÔÀ¸¸é Àоî¿Â ¹®ÀÚ¿­, ¾Æ´Ï¸é NULL°ªÀ» ¹ÝȯÇÑ´Ù. boost::shared_array ReadConfigStringFromIni( const TCHAR* section_name, const TCHAR* key_name, const TCHAR* default_value, const TCHAR* ini_file_name, int min_read_count = 0, int max_read_count = 1000 ) { boost::shared_array read_string_ptr; // ÀԷ°ªÀ» °Ë»çÇÑ´Ù. if (NULL == section_name || NULL == key_name || NULL == ini_file_name || min_read_count < 0 || min_read_count > max_read_count) { return read_string_ptr; } read_string_ptr.reset(new TCHAR[MAX_PATH]); // ¸ÕÀú Àоî¿Ã ¹®ÀÚ¿­ ±æÀ̸¦ °Ë»çÇÑ´Ù. int read_character_count = ::GetPrivateProfileString(section_name, key_name, default_value, read_string_ptr.get(), MAX_PATH, ini_file_name); if (read_character_count < min_read_count || read_character_count > max_read_count) { read_string_ptr.reset(NULL); return read_string_ptr; } read_string_ptr.reset(new TCHAR[read_character_count+1]); // Àоî¿Â´Ù. DWORD new_read_character_count = ::GetPrivateProfileString(section_name, key_name, default_value, read_string_ptr.get(), MAX_PATH, ini_file_name); // ¼º°øÀûÀ¸·Î ÀÐ¾î ¿Ô´ÂÁö °Ë»çÇÑ´Ù. if (new_read_character_count != read_character_count) { read_string_ptr.reset(NULL); return read_string_ptr; } return read_string_ptr; } // ReadConfigStringFromIni GuildServer::GuildServer() { SetPhaseStatus( PHASE_UNKNOWN ); ConnectSessions.Init(); m_pPoolRouter = new SERVER_SESSION_ROUTER; SERVER_SESSION_ROUTER& rRouter = GetPoolRouter(); rRouter.Register(AGENT_SERVER); rRouter.Register(GAME_DBPROXY); rRouter.Register(WORLD_SERVER); rRouter.Register(MASTER_SERVER); rRouter.Register(GAME_SERVER); //rRouter.Register(TEMP_SERVER); rRouter.Initialize( AGENT_SERVER, 5, 1 ); rRouter.Initialize( GAME_DBPROXY, 1, 1 ); rRouter.Initialize( WORLD_SERVER, 1, 1 ); rRouter.Initialize( MASTER_SERVER, 1, 1 ); //rRouter.Initialize( TEMP_SERVER, 10, 5 ); rRouter.Initialize( GAME_SERVER, 15, 5 ); m_TempServerSessionPool.Initialize( 10, 5 ); TempServerSession::SetPool( &m_TempServerSessionPool ); // Register Object Code } GuildServer::~GuildServer() { SetPhaseStatus(PHASE_UNKNOWN); ConnectSessions.Init(); SAFE_DELETE( m_pPoolRouter ); } BOOL GuildServer::Init() { InitializeLogger(); MessageOut( eCRITICAL_LOG, "*** GuildServer Start *** " ); MessageOut( eCRITICAL_LOG, "*** GuildServer Server Version = %d ***", SERVER_RELEASE_BUILD_NO ); // (¼­ºñ½º/ÄܼÖ)¸ðµå Á¦¾î È®ÀÎÇÒ °Í. __READ_CONFIG_NUMBER( m_bServiceMode, "COMMON", "SERVICE_MODE", 0, GUILD_SERVER_INFO_FILE_NAME ); WorkLoadManager::CreateInstance(); PacketHandler::RegisterHandler(); if( !Init_ScriptData( this->IsServerInfoFromFile() ) ) { P_FAILED; return FALSE; } P_SUCCESS; DISPMSG( "Creating GuildLog File..." ); g_pLOG = new GuildLog(); CHECK_PARAM_STRING( pszGameLogfilePath, "LOGFILE", "WOPS_LOGFILE_PATH", NULL ); if( _access( pszGameLogfilePath, 0 ) == -1 ) //Æú´õ°¡ Á¸ÀçÇÏÁö ¾ÊÀ¸¸é.. { if( !CreateDirectory( pszGameLogfilePath, NULL) ) printf( "CreateDirectory Fail, path = %s \n", pszGameLogfilePath ); } TCHAR szBinPath[MAX_PATH], szTextPath[MAX_PATH]; _sntprintf( szBinPath, MAX_PATH, "%s\\\\GUILD", pszGameLogfilePath ); _sntprintf( szTextPath, MAX_PATH, "%s\\\\GUILD_TEXT", pszGameLogfilePath ); CHECK_PARAM_NUMBER( BYTE, byWopsLogOption, "LOGFILE", "WOPS_LOGFILE_OPTION", 0xFF ); #ifdef __NA_0_ADD_VERSION_TO_LOG_FILE_NAME TCHAR szFileName[MAX_PATH]; _sntprintf( szFileName, MAX_PATH, "%d_SUN_GUILD", NATION_BUILD_VERSION ); if( !g_pLOG->Init( byWopsLogOption, szFileName, _T(szBinPath), _T(szTextPath) ) ) #else if( !g_pLOG->Init( byWopsLogOption, _T("SUN_GUILD"), _T(szBinPath), _T(szTextPath) ) ) #endif { P_FAILED; } else { P_SUCCESS; } #if !defined(__WAVERIX_SOLAR_AUTH_SERVER_IMPLEMENTATION__) StartServer(); #endif return TRUE; } VOID GuildServer::Release() { WorkLoadManager::DestroyInstance(); PacketHandler::ReleaseHandler(); MessageOut( eCRITICAL_LOG, "*** GuildServer Close *** " ); if( m_pGuildScriptParserManager ) { m_pGuildScriptParserManager->Release(); m_pGuildScriptParserManager->DestroyInstanceEx(); SAFE_DELETE( m_pGuildScriptParserManager ); } DominationManager::DestroyInstance(); SAFE_DELETE(g_pSunLog); SAFE_DELETE(g_pLOG); } BOOL GuildServer::Update( DWORD tick ) { // <2> Server Session °ü¸® WorkLoadManager::Update(); // SunLog Update À§Ä¡³ª Á¾·á½ÃÁ¡ÀÇ ·Î±× ¾²±â µîÀ» °í·ÁÇØ¼­ Àç¼³Á¤ÇÒ °Í. g_pSunLog->Update(); if(m_GuildDestroyTimer.IsExpired()) g_GuildManager.UpdateForGuildDestroy(); DominationManager::Instance()->LoadDominationInfo(); return TRUE; } // ServerSession* GuildServer::AllocServerSession( eSERVER_TYPE serverType ) { ServerSession* pServerSession = NULL; if( TEMP_SERVER != serverType ) { SERVER_SESSION_ROUTER& rRouter = GetPoolRouter(); if( BATTLE_SERVER == serverType || FIELD_SERVER == serverType ) serverType = GAME_SERVER; pServerSession = (ServerSession*)rRouter.Alloc( serverType ); switch( serverType ) { case GAME_DBPROXY: ConnectSessions.SessionDBProxy() = (DBProxyServerSession*)pServerSession; break; case MASTER_SERVER: ConnectSessions.SessionMaster() = (MasterServerSession*)pServerSession; break; case WORLD_SERVER: ConnectSessions.SessionWorld() = (WorldServerSession*)pServerSession; break; } } else { pServerSession = (ServerSession*)TempServerSession::ALLOC(); } if( !pServerSession ) { ASSERT(!"Á¸ÀçÇÏÁö ¾Ê´Â ¼­¹öŸÀÔÀÔ´Ï´Ù."); return NULL; } pServerSession->Init( this ); return pServerSession; } // VOID GuildServer::FreeServerSession( ServerSession* pServerSession ) { if( !pServerSession ) return; eSERVER_TYPE serverType = pServerSession->GetServerType(); pServerSession->Release(); if( TEMP_SERVER != serverType ) { SERVER_SESSION_ROUTER& rRouter = GetPoolRouter(); eSERVER_TYPE serverType = pServerSession->GetServerType(); if( BATTLE_SERVER == serverType || FIELD_SERVER == serverType ) serverType = GAME_SERVER; rRouter.Free( (DWORD)serverType, pServerSession ); } else { TempServerSession::FREE( (TempServerSession*)pServerSession ); } } VOID GuildServer::SendToAllGameServers( MSG_BASE* pMsg, WORD wSize ) { const DWORD cdwBitMask = (DWORD)( (1<second; if( ((DWORD)(1<GetServerType())) & cdwBitMask ) { pSession->SendPacket( pMsg, wSize ); } } } BOOL GuildServer::ConnectTo( eSERVER_TYPE serverType ) { ServerSession* pSession = NULL; switch( serverType ) { case GAME_DBPROXY: pSession = ConnectSessions.SessionDBProxy(); break; case WORLD_SERVER: pSession = ConnectSessions.SessionWorld(); break; } if( !pSession ) return FALSE; #ifndef __WAVERIX_SOLAR_AUTH_SERVER_IMPLEMENTATION__ if( pSession->IsConnecting() || pSession->IsConnected() ) { ASSERT( !"Áߺ¹ Connect ½Ãµµ" ); return FALSE; } Connect(pSession); return TRUE; #else //__WAVERIX_SOLAR_AUTH_SERVER_IMPLEMENTATION__ if( ! IsServerInfoFromFile() ) { if( (MASTER_SERVER != serverType) && (GetPhaseStatus() != PHASE_SERVICE) ) return FALSE; } if( !( pSession->IsConnecting() || pSession->IsConnected() ) ) { if( (MASTER_SERVER != serverType) && (! IsServerInfoFromFile() ) && (GetPhaseStatus() != PHASE_SERVICE) ) return FALSE; Connect( pSession ); return TRUE; } ASSERT( !"Áߺ¹ Connect ½Ãµµ" ); return FALSE; #endif //__WAVERIX_SOLAR_AUTH_SERVER_IMPLEMENTATION__ } // // // // // #include VOID GuildServer::StartServer() { // <ÇØ¾ß ÇÒ ÀÏ> // // // À̰ÍÀÌ È£ÃâµÇ¾ú´Ù´Â Àǹ̴ ÇÊ¿äÇÑ ¸ðµç µ¥ÀÌÅ͸¦ ¹Þ¾Ò´Ù´Â Àǹ̴Ù. // GuildServer* pGuildServer = GuildServer::GetMainFrame(); #ifdef __WAVERIX_SOLAR_AUTH_SERVER_IMPLEMENTATION__ // Çö ½ÃÁ¡ PHASE_EXCHANGEÀÏ °ÍÀÌ´Ù. MSG_SERVERCOMMON_DATA_TRANSFER_SENDDATA_NTF msgNTF; pGuildServer->ConnectSessions.SendToMaster( &msgNTF, sizeof(msgNTF) ); #else if (pGuildServer->IsServerInfoFromFile()) #endif // { pGuildServer->Listen(SERVER_IOHANDLER); }; } BOOL GuildServer::InitializeLogger() { // ·Î±× ÆÄÀÏ ¿É¼ÇÀ» Àд´Ù. BYTE sun_log_option = 0; __READ_CONFIG_NUMBER(sun_log_option, TEXT("LOGFILE"), TEXT("SUN_LOGFILE_OPTION"), 0, TEXT(GUILD_SERVER_INFO_FILE_NAME)); // ·Î±× ÆÄÀÏ ·¹º§À» Àд´Ù. BYTE sun_log_file_level = 0; __READ_CONFIG_NUMBER(sun_log_file_level, TEXT("LOGFILE"), TEXT("SUN_LOGFILE_LEVEL"), 0, TEXT(GUILD_SERVER_INFO_FILE_NAME)); // ·Î±× ÆÄÀÏ °æ·Î¸¦ Àд´Ù. typedef boost::shared_array CharSmartPtr; const CharSmartPtr& sun_log_file_path_ptr = ReadConfigStringFromIni(TEXT("LOGFILE"), TEXT("SUN_LOGFILE_PATH"), NULL, GUILD_SERVER_INFO_FILE_NAME, 3); if (!sun_log_file_path_ptr) { DISPMSG(TEXT("Fail to loading 'SUN_LOGFILE_PATH' from ini file.\n")); return FALSE; } // ·Î±×¸¦ ÃʱâÈ­ ÇÑ´Ù. DISPMSG( "SUNLOG.Guild Initializing...\t" ); g_pSunLog = new CSunLog; BOOL is_success = g_pSunLog->Init(sun_log_option, sun_log_file_level, sun_log_file_path_ptr.get(), TEXT("Guild")); if (is_success) { P_SUCCESS; } else { P_FAILED; } return is_success; } BOOL GuildServer::Init_ScriptData( BOOL bReadFromFile ) { m_pGuildScriptParserManager = new GuildScriptParserManager; m_pGuildScriptParserManager->InitParserPool( NULL ); m_pGuildScriptParserManager->RegisterParser(); #ifdef __WAVERIX_SOLAR_AUTH_SERVER_IMPLEMENTATION__ return TRUE; #else return m_pGuildScriptParserManager->Load(); #endif } // //======================================================================================================= BOOL GuildServer::sConnectSession::SendToMaster( MSG_BASE* pMsg, WORD wSize ) { if( m_pMasterServerSession && m_pMasterServerSession->IsConnected() ) { return m_pMasterServerSession->SendPacket( pMsg, wSize ); } return FALSE; } BOOL GuildServer::sConnectSession::SendToDBProxy( MSG_BASE* pMsg, WORD wSize ) { if( m_pDBProxyServerSession && m_pDBProxyServerSession->IsConnected() ) { return m_pDBProxyServerSession->SendPacket( pMsg, wSize ); } return FALSE; } BOOL GuildServer::sConnectSession::SendToWorld( MSG_BASE* pMsg, WORD wSize ) { if( m_pWorldServerSession && m_pWorldServerSession->IsConnected() ) { return m_pWorldServerSession->SendPacket( pMsg, wSize ); } return FALSE; } //======================================================================================================= // // // Callback Handlers NetworkObject* GuildServer::CreateServerSideAcceptedObject() { return GuildServer::GetMainFrame()->AllocServerSession( TEMP_SERVER ); } VOID GuildServer::DestroyServerSideAcceptedObject( NetworkObject* pNetworkObject ) { GuildServer::GetMainFrame()->FreeServerSession( (ServerSession*)pNetworkObject ); } VOID GuildServer::DestroyServerSideConnectedObject( NetworkObject* pNetworkObject ) { } BOOL GuildServer::KeyEvent( CHAR ch ) { switch(ch) { case ' ': DisplayServerInfo(); break; } return TRUE; } VOID GuildServer::DisplayServerInfo() { g_GuildManager.DisplayGuildInfo(); } //================================================================================================== //================================================================================================== //==================================================================================================