#include "StdAfx.h" #include "UnitServer.h" #include "PacketStruct_SA.h" #include "ServerSessionManager.h" #include "ServerSession.h" #include "PacketStruct_SMA.h" #include "PacketStruct_SM.h" #include "User.h" #include "UserManager.h" #include "AccessInfo.h" #include "AccessInfoParser.h" #include "FtpInfo.h" #include "FtpInfoParser.h" UnitServer::UnitServer() { } UnitServer::~UnitServer() { } VOID UnitServer::Release() { } VOID UnitServer::ExecuteStart( DWORD dwUserKey ) { User* pUser = (User*)UserManager::Instance()->GetUser( dwUserKey ); if( !pUser ) return; //¸ÕÀú ÇØ´ç ¼­¹öÀÇ ÇöÀç »óŰ¡ ÄÑÁ® ÀÖÀ¸¸é... if( !IsEnableStart() ) { MSG_SM_SERVER_EXECUTE_ACK ack; ack.m_byResult = GetResultServerStatus( m_ServerInfo.GetServerStatus() ); m_ServerInfo.GetServerInfo( &ack.m_ServerInfo ); pUser->SendPacket( &ack, sizeof( ack ) ); return; } ServerSession *pAgentSession = ServerSessionManager::Instance()->FindAgentSession( m_ServerInfo.GetAgentKey() ); if( !pAgentSession ) { MSG_SM_SERVER_EXECUTE_ACK AckMsg; AckMsg.m_byResult = RC_SERVER_EXECUTE_FAIL_UPDATEAGENT_NOT_CONNECT; memcpy( &AckMsg.m_ServerInfo, &m_ServerInfo, sizeof(SERVER_INFO) ); pUser->SendPacket( &AckMsg, sizeof(AckMsg) ); return; } else { MSG_SA_SERVER_EXECUTE_SYN SynMsg; SynMsg.m_dwUserKey = dwUserKey; #ifdef __20080312__SOLARAUTH_SERVER_PATCH m_ServerInfo.GetServerInfo( &SynMsg.m_ServerInfo); #else memcpy( &SynMsg.m_ServerInfo, &m_ServerInfo, sizeof(SERVER_INFO) ); #endif pAgentSession->SendPacket( (BYTE*)&SynMsg, sizeof(SynMsg) ); } } //¸¶½ºÅÍ¿¡ ÀÇÇÑ ¼­¹öÁ¾·á VOID UnitServer::ExecuteEnd( DWORD dwUserKey ) { User* pUser = (User*)UserManager::Instance()->GetUser( dwUserKey ); if( !pUser ) return; if( !IsEnableEnd() ) { MSG_SM_SERVER_SHUTDOWN_ACK ack; ack.m_byResult = GetResultServerStatus( m_ServerInfo.GetServerStatus() ); m_ServerInfo.GetServerInfo( &ack.m_ServerInfo ); pUser->SendPacket( &ack, sizeof( ack ) ); return; } ServerSession *pMasterSession = ServerSessionManager::Instance()->FindMasterSession(); if( !pMasterSession ) { MSG_SM_SERVER_SHUTDOWN_ACK ack; m_ServerInfo.GetServerInfo( &ack.m_ServerInfo ); ack.m_byResult = RC_SERVER_SHUTDOWN_START_FAIL_MASTER_SERVER_NOT_CONNECT; MSGOUT( "[¼­¹öÁ¾·á½ÇÇà½ÇÆÐ] pMasterSession is disconnected!" ); pUser->SendPacket( &ack, sizeof(ack) ); return; } else { MSG_MO_RTTG_SERVERSHUTDOWN_REQ ReqMsg; ReqMsg.dwKey = dwUserKey; ReqMsg.m_byWorldID = m_ServerInfo.GetServerInfoEx().m_byWorld; ReqMsg.m_byChannelID = m_ServerInfo.GetServerInfoEx().m_byChannel; ReqMsg.m_byServerType = m_ServerInfo.GetServerInfoEx().m_byServerType; ReqMsg.m_byServerID = m_ServerInfo.GetServerInfoEx().m_byServerNum; pMasterSession->SendPacket( (BYTE*)&ReqMsg, sizeof(ReqMsg) ); MSG_SM_SERVER_SHUTDOWN_ACK ack; m_ServerInfo.GetServerInfo( &ack.m_ServerInfo ); ack.m_byResult = RC_SERVER_SHUTDOWN_START_SUCCESS; //¼­¹öÁ¾·á ½ÃÀÛ ¼º°ø pUser->SendPacket( &ack, sizeof(ack) ); //¼­¹ö Á¾·á ·Î±× MSGOUT( "[¼­¹öÁ¾·á½ÃÀÛ] ID = %s, IP = %s, World = %d, Channel = %d, ServerType = %d " , pUser->GetID(), pUser->GetIP(), ReqMsg.m_byWorldID, ReqMsg.m_byChannelID, ReqMsg.m_byServerType , ReqMsg.m_byServerID ); } } BOOL UnitServer::ExecutePatch( DWORD dwUserKey ) { //½ÇÇà½ÃŲ À¯Àú¸¦ °Ë»çÇÑ´Ù. User* pUser = (User*)UserManager::Instance()->GetUser( dwUserKey ); if( !pUser ) return FALSE; if( !IsEnablePatch() ) { MSG_SM_PATCH_EXECUTE_ACK ack; ack.m_byResult = GetResultServerStatus( m_ServerInfo.GetServerStatus() ); m_ServerInfo.GetServerInfo( &ack.m_ServerInfo ); pUser->SendPacket( &ack, sizeof( ack ) ); return FALSE; } // SUN_SERVER¸é ÆÐÄ¡ ½ÇÇà ¸í·ÉÀ» ³»¸®°í, SUN_SERVER°¡ ¾Æ´Ï¸é, ÇöÀç ¼­¹ö»óŰ¡ º¯°æµÇ¾ú´Ù°í Á¢¼ÓµÈ À¯Àúµé¿¡°Ô ¾Ë·ÁÁØ´Ù. if( GetServerType() == SUN_SERVER ) { ServerSession *pAgentSession = ServerSessionManager::Instance()->FindAgentSession( m_ServerInfo.GetAgentKey() ); if( !pAgentSession ) { //À¯Àú¿¡°Ô ÇØ´ç Agent°¡ ÄÑÁ® ÀÖÁö ¾Ê¾Æ¼­, ÆÐÄ¡½ÇÇà ½ÇÆÐ Çß´Ù°í ÀüÇÑ´Ù. MSG_SM_PATCH_EXECUTE_ACK AckMsg; AckMsg.m_byResult = RC_SERVER_PATCH_EXECUTE_FAIL_UPDATEAGENT_NOT_CONNECT; #ifdef __20080312__SOLARAUTH_SERVER_PATCH m_ServerInfo.GetServerInfo( &AckMsg.m_ServerInfo); #else memcpy( &SynMsg.m_ServerInfo, &m_ServerInfo, sizeof(SERVER_INFO) ); #endif pUser->SendPacket( &AckMsg, sizeof(AckMsg) ); return FALSE; } else { SetServerStatus( SERVER_STATUS_PATCHING ); MSG_SA_PATCH_EXECUTE_SYN SynMsg; SynMsg.m_dwUserKey = dwUserKey; #ifdef __20080312__SOLARAUTH_SERVER_PATCH m_ServerInfo.GetServerInfo( &SynMsg.m_ServerInfo); #else memcpy( &SynMsg.m_ServerInfo, &m_ServerInfo, sizeof(SERVER_INFO) ); #endif pAgentSession->SendPacket( (BYTE*)&SynMsg, sizeof(SynMsg) ); MSGOUT( "[ÆÐÄ¡½ÇÇà] ID = %s, IP = %s, World = %d, Channel = %d, ServerType = %d " , pUser->GetID(), pUser->GetIP(), m_ServerInfo.GetServerInfoEx().m_byWorld, m_ServerInfo.GetServerInfoEx().m_byChannel, m_ServerInfo.GetServerInfoEx().m_byServerType, m_ServerInfo.GetServerInfoEx().m_byServerNum ); } } return TRUE; } VOID UnitServer::SerializeServerInfoStream( SERVER_TOTAL_INFO & OUT rServerTotInfo ) { m_ServerInfo.SerializeStream( rServerTotInfo.m_Data[rServerTotInfo.m_Count], FALSE ); rServerTotInfo.m_Count++; } VOID UnitServer::SerializeServerInfoStreamForUser( SERVER_TOTAL_INFO & OUT rServerTotInfo, DWORD dwUserGUID ) { //ÇöÀç ¼­¹ö°¡ À¯Àú¿¡°Ô Á¢±Ù±ÇÇÑÀÌ ÀÖ´Â ¼­¹öÀÎÁö üũ. AccessInfo* pAccessInfo = AccessInfoParser::Instance()->GetAccessInfo( dwUserGUID ); if( !pAccessInfo ) return; ACCESS_SERVER* pAccessServer = pAccessInfo->GetAccessServer( m_ServerInfo.GetServerInfoEx().m_dwServerKey ); if( !pAccessServer ) return; // int nOnlineServer = 0; if( pAccessServer->m_bAccess ) { m_ServerInfo.SerializeStream( rServerTotInfo.m_Data[rServerTotInfo.m_Count], FALSE ); rServerTotInfo.m_Count++; } } #ifdef __20080312__SOLARAUTH_SERVER_PATCH VOID UnitServer::SerializeScriptFolderInfoStream( SCRIPTFOLDER_TOTAL_INFO& OUT rSCFolderInfo, DWORD dwUserGUID ) { //ÇöÀç ¼­¹ö°¡ À¯Àú¿¡°Ô Á¢±Ù±ÇÇÑÀÌ ÀÖ´Â ¼­¹öÀÎÁö üũ. AccessInfo* pAccessInfo = AccessInfoParser::Instance()->GetAccessInfo( dwUserGUID ); if( !pAccessInfo ) return; ACCESS_SERVER* pAccessServer = pAccessInfo->GetAccessServer( m_ServerInfo.GetServerInfoEx().m_dwServerKey ); if( !pAccessServer ) return; // int nOnlineServer = 0; if( pAccessServer->m_bAccess ) m_ServerInfo.SerializeScriptFolderStream( rSCFolderInfo); } #endif VOID UnitServer::SetServerStatus( eSERVER_STATUS status ) { m_ServerInfo.SetServerStatus( status ); //SUN_SERVER´Â ŸÀÔ¸¸ ¹Ù²Ù°í, Client¿¡´Â ¾Ë·ÁÁÖÁö ¾Ê´Â´Ù. if( GetServerType() == SUN_SERVER ) return; //SUN_SERVER°¡ À̳ª°í, ÇöÀç MSG_SM_CHECK_GAMEPROCESS_NTF msg; m_ServerInfo.GetServerInfo( &msg.m_ServerInfo ); UserManager::Instance()->SendPacketAll( &msg, sizeof(msg) ); } VOID UnitServer::SerializeFtpInfoStreamForUser( FTP_TOTAL_INFO & OUT rFtpTotInfo, DWORD dwUserGUID ) { //ÇöÀç ¼­¹ö°¡ À¯Àú¿¡°Ô Á¢±Ù±ÇÇÑÀÌ ÀÖ´Â ¼­¹öÀÎÁö üũ. AccessInfo* pAccessInfo = AccessInfoParser::Instance()->GetAccessInfo( dwUserGUID ); if( !pAccessInfo ) return; ACCESS_SERVER* pAccessServer = pAccessInfo->GetAccessServer( m_ServerInfo.GetServerInfoEx().m_dwServerKey ); if( !pAccessServer || !pAccessServer->m_bAccess ) return; // ÇöÀç ¼­¹ö°¡ °¡Áö°í ÀÖ´Â FTP ¿¬°áÁ¤º¸¸¦ °¡Áö°í ¿Â´Ù. FtpInfo* pFtpInfo = FtpInfoParser::Instance()->GetFtpInfo( m_ServerInfo.GetServerInfoEx().m_byWorld ); if( !pFtpInfo ) return; // ÇöÀç SerializeÇÏ·Á´Â FTPÁ¤º¸°¡ ±âÁ¸¿¡ ÀÖ¾ú´ÂÁö üũÇÑ´Ù. for( int i = 0; i < rFtpTotInfo.m_Count; i++ ) { FTP_CONNECT_INFO& rFtpConnectInfo = rFtpTotInfo.m_Data[i]; //±âÁ¸ÀÇ FTP World ¿Í ÇöÀç FTP World°¡ °°À¸¸é ¸®ÅÏÇÑ´Ù. if( rFtpConnectInfo.m_byWorld == pFtpInfo->GetWorld() ) return; } pFtpInfo->SerializeStream( rFtpTotInfo.m_Data[rFtpTotInfo.m_Count], FALSE ); rFtpTotInfo.m_Count++; } VOID UnitServer::ExecuteForceDisconnect( DWORD dwUserKey ) { User* pUser = (User*)UserManager::Instance()->GetUser( dwUserKey ); if( !pUser ) return; if( !IsEnableForceDisconnect() ) { MSG_SM_SERVER_FORCE_DISCONNECT_ACK ack; ack.m_byResult = GetResultServerStatus( m_ServerInfo.GetServerStatus() ); m_ServerInfo.GetServerInfo( &ack.m_ServerInfo ); pUser->SendPacket( &ack, sizeof( ack ) ); return; } ServerSession *pAgentSession = ServerSessionManager::Instance()->FindAgentSession( m_ServerInfo.GetAgentKey() ); if( !pAgentSession ) { //À¯Àú¿¡°Ô ÇØ´ç Agent°¡ ÄÑÁ® ÀÖÁö ¾Ê¾Æ¼­, ÆÐÄ¡½ÇÇà ½ÇÆÐ Çß´Ù°í ÀüÇÑ´Ù. MSG_SM_SERVER_FORCE_DISCONNECT_ACK AckMsg; AckMsg.m_byResult = RC_SERVER_FORCE_DISCONNECT_FAIL_UPDATEAGENT_NOT_CONNECT; m_ServerInfo.GetServerInfo( &AckMsg.m_ServerInfo ); pUser->SendPacket( &AckMsg, sizeof(AckMsg) ); return; } else { MSG_SA_SERVER_FORCE_DISCONNECT_SYN SynMsg; SynMsg.m_dwUserKey = dwUserKey; m_ServerInfo.GetServerInfo( &SynMsg.m_ServerInfo ); pAgentSession->SendPacket( (BYTE*)&SynMsg, sizeof(SynMsg) ); } //°­Á¦Á¾·á ·Î±× MSGOUT( "[¼­¹ö°­Á¦Á¾·á] ID = %s, IP = %s, World = %d, Channel = %d, ServerType = %d " , pUser->GetID(), pUser->GetIP(), m_ServerInfo.GetServerInfoEx().m_byWorld, m_ServerInfo.GetServerInfoEx().m_byChannel, m_ServerInfo.GetServerInfoEx().m_byServerType, m_ServerInfo.GetServerInfoEx().m_byServerNum ); } BOOL UnitServer::IsEnablePatch() { #ifdef _NA_006543_20130318_HEARTBEAT //SunServer°¡ UnknownÀÎ »óȲÀº ¿¹¿Ü if(m_ServerInfo.GetServerInfoEx().m_byServerType == SUN_SERVER && m_ServerInfo.GetServerStatus() == SERVER_STATUS_UNKNOWN) return TRUE; #endif if( m_ServerInfo.GetServerStatus() != SERVER_STATUS_OFFLINE ) return FALSE; return TRUE; } BOOL UnitServer::IsEnableEnd() { eSERVER_STATUS status = m_ServerInfo.GetServerStatus(); if( status == SERVER_STATUS_ONLINE || status == SERVER_STATUS_LIVE_PROCESS ) return TRUE; return FALSE; } BOOL UnitServer::IsEnableStart() { eSERVER_STATUS status = m_ServerInfo.GetServerStatus(); if( status != SERVER_STATUS_OFFLINE ) return FALSE; return TRUE; } BOOL UnitServer::IsEnableForceDisconnect() { eSERVER_STATUS status = m_ServerInfo.GetServerStatus(); if( status == SERVER_STATUS_ONLINE || status == SERVER_STATUS_LIVE_PROCESS ) return TRUE; return FALSE; } eRC_SERVER_CONSTANT UnitServer::GetResultServerStatus( eSERVER_STATUS status ) { eRC_SERVER_CONSTANT result = (eRC_SERVER_CONSTANT)0; switch( status ) { case SERVER_STATUS_OFFLINE: result = RC_SERVER_STATUS_OFFLINE; break; case SERVER_STATUS_ONLINE: result = RC_SERVER_STATUS_ONLINE; break; case SERVER_STATUS_LIVE_PROCESS: result = RC_SERVER_STATUS_LIVE_PROCESS; break; case SERVER_STATUS_PATCHING: result = RC_SERVER_STATUS_PATCHING; break; #ifdef _NA_006543_20130318_HEARTBEAT case SERVER_STATUS_UNKNOWN: result = RC_SERVER_STATUS_UNKNOWN; break; #endif } return result; }