#include "StdAfx.h" #include "Channel.h" #include "UnitServer.h" #include "PacketStruct_SMA.h" #include "ServerSession.h" #include "ServerSessionManager.h" Channel::Channel() { m_byChannelKey = 0; m_UnitServerHash.Initialize( DEFAULT_UNITSERVER_POOL_SIZE ); m_pUnitServerPool = new CMemoryPoolFactory; m_pUnitServerPool->Initialize( DEFAULT_UNITSERVER_POOL_SIZE, DEFAULT_UNITSERVER_POOL_SIZE/2 ); } Channel::~Channel() { SAFE_RELEASENDELETE( m_pUnitServerPool ); } VOID Channel::Init( BYTE byWorldKey, BYTE byChannelKey ) { m_byWorldKey = byWorldKey; m_byChannelKey = byChannelKey; } VOID Channel::Release() { UnitServer * pUnitServer = NULL; for( UNITSERVER_HASH_ITR it = m_UnitServerHash.begin(); it != m_UnitServerHash.end(); ++it ) { pUnitServer = *it; pUnitServer->Release(); } m_UnitServerHash.clear(); } UnitServer* Channel::AllocUnitServer( DWORD dwUnitServerKey ) { UnitServer *pUnitServer = FindUnitServer( dwUnitServerKey ); if( pUnitServer ) return pUnitServer; pUnitServer = m_pUnitServerPool->Alloc(); m_UnitServerHash.Add( pUnitServer, dwUnitServerKey ); return pUnitServer; } VOID Channel::FreeUnitServer( UnitServer *pUnitServer ) { m_UnitServerHash.Remove( pUnitServer->GetKey() ); m_pUnitServerPool->Free( pUnitServer ); } UnitServer* Channel::FindUnitServerByAgent( DWORD dwAgentKey, eGAME_SERVER_TYPE byServerType ) { UnitServer * pUnitServer = NULL; for( UNITSERVER_HASH_ITR it = m_UnitServerHash.begin(); it != m_UnitServerHash.end(); ++it ) { pUnitServer = *it; if( pUnitServer->GetServerInfo().GetAgentKey() != dwAgentKey ) continue; if( pUnitServer->GetServerInfo().GetServerInfoEx().m_byServerType != byServerType ) continue; return pUnitServer; } return NULL; } UnitServer* Channel::FindUnitServer( eGAME_SERVER_TYPE byServerType, BYTE byServerNum ) { UnitServer * pUnitServer = NULL; for( UNITSERVER_HASH_ITR it = m_UnitServerHash.begin(); it != m_UnitServerHash.end(); ++it ) { pUnitServer = *it; if( pUnitServer->GetServerInfo().GetServerInfoEx().m_byServerType != byServerType ) continue; if( pUnitServer->GetServerInfo().GetServerInfoEx().m_byServerNum != byServerNum ) continue; return pUnitServer; } return NULL; } #ifdef _NA_006543_20130318_HEARTBEAT UnitServer* Channel::FindFirstUnitServerByAgentKey( DWORD dwAgentKey ) { UnitServer * pUnitServer = NULL; for( UNITSERVER_HASH_ITR it = m_UnitServerHash.begin(); it != m_UnitServerHash.end(); ++it ) { pUnitServer = *it; if( pUnitServer->GetServerInfo().GetAgentKey() != dwAgentKey ) continue; return pUnitServer; } return NULL; } #endif VOID Channel::ExecuteStart( DWORD dwUserKey ) { UnitServer * pUnitServer = NULL; for( UNITSERVER_HASH_ITR it = m_UnitServerHash.begin(); it != m_UnitServerHash.end(); ++it ) { pUnitServer = *it; pUnitServer->ExecuteStart( dwUserKey ); } } VOID Channel::ExecuteEnd( DWORD dwUserKey ) { MSG_MO_RTTG_SERVERSHUTDOWN_REQ ReqMsg; ReqMsg.dwKey = dwUserKey; ReqMsg.m_byWorldID = m_byWorldKey; ReqMsg.m_byChannelID = m_byChannelKey; ReqMsg.m_byServerType = 0; ReqMsg.m_byServerID = 0; ServerSession *pMasterSession = ServerSessionManager::Instance()->FindMasterSession(); if( !pMasterSession ) { DISPMSG( "[Channel::ExecuteEnd] pMasterSession is disconnected!\n" ); return; } pMasterSession->SendPacket( (BYTE*)&ReqMsg, sizeof(ReqMsg) ); } BOOL Channel::ExecutePatch( DWORD dwUserKey ) { UnitServer * pUnitServer = NULL; for( UNITSERVER_HASH_ITR it = m_UnitServerHash.begin(); it != m_UnitServerHash.end(); ++it ) { pUnitServer = *it; if( !pUnitServer->ExecutePatch( dwUserKey ) ) return FALSE; } return TRUE; } VOID Channel::SerializeServerInfoStream( SERVER_TOTAL_INFO & OUT rServerTotInfo ) { UnitServer * pUnitServer = NULL; for( UNITSERVER_HASH_ITR it = m_UnitServerHash.begin(); it != m_UnitServerHash.end(); ++it ) { pUnitServer = *it; pUnitServer->SerializeServerInfoStream( rServerTotInfo ); } } #ifdef __20080312__SOLARAUTH_SERVER_PATCH VOID Channel::SerializeScriptFolderInfoStream( SCRIPTFOLDER_TOTAL_INFO& OUT rSCFolderTotInfo, DWORD dwUserGUID ) { UnitServer * pUnitServer = NULL; for( UNITSERVER_HASH_ITR it = m_UnitServerHash.begin(); it != m_UnitServerHash.end(); ++it ) { pUnitServer = *it; pUnitServer->SerializeScriptFolderInfoStream( rSCFolderTotInfo, dwUserGUID ); } } #endif VOID Channel::SerializeServerInfoStreamForUser( SERVER_TOTAL_INFO & OUT rServerTotInfo, DWORD dwUserGUID ) { UnitServer * pUnitServer = NULL; int nCount = 0; for( UNITSERVER_HASH_ITR it = m_UnitServerHash.begin(); it != m_UnitServerHash.end(); ++it ) { pUnitServer = *it; pUnitServer->SerializeServerInfoStreamForUser( rServerTotInfo, dwUserGUID ); if( pUnitServer->GetServerStatus() == SERVER_STATUS_ONLINE ) nCount++; } MSGOUT( "Online Server Count Per Channel = %d, UserGuid = %u", nCount, dwUserGUID ); } VOID Channel::SerializeFtpInfoStreamForUser( FTP_TOTAL_INFO & OUT rFtpTotInfo, DWORD dwUserGUID ) { UnitServer * pUnitServer = NULL; for( UNITSERVER_HASH_ITR it = m_UnitServerHash.begin(); it != m_UnitServerHash.end(); ++it ) { pUnitServer = *it; pUnitServer->SerializeFtpInfoStreamForUser( rFtpTotInfo, dwUserGUID ); } } VOID Channel::ExecuteForceDisconnect( DWORD dwUserKey ) { UnitServer * pUnitServer = NULL; for( UNITSERVER_HASH_ITR it = m_UnitServerHash.begin(); it != m_UnitServerHash.end(); ++it ) { pUnitServer = *it; pUnitServer->ExecuteForceDisconnect( dwUserKey ); } } VOID Channel::SetServerStatus( eSERVER_STATUS status ) { UnitServer * pUnitServer = NULL; for( UNITSERVER_HASH_ITR it = m_UnitServerHash.begin(); it != m_UnitServerHash.end(); ++it ) { pUnitServer = *it; pUnitServer->SetServerStatus( status ); } } BOOL Channel::CheckServerStatus( eSERVER_STATUS CheckStatus ) { UnitServer * pUnitServer = NULL; for( UNITSERVER_HASH_ITR it = m_UnitServerHash.begin(); it != m_UnitServerHash.end(); ++it ) { pUnitServer = *it; eSERVER_STATUS Status = pUnitServer->GetServerStatus(); if( CheckStatus != Status ) return FALSE; } return TRUE; }