306 lines
7.0 KiB
C++
306 lines
7.0 KiB
C++
#include "StdAfx.h"
|
|
#include "WorldManager.h"
|
|
#include "World.h"
|
|
#include "ServerInfoParser.h"
|
|
#include "ServerInfo.h"
|
|
#include "UnitServer.h"
|
|
#include "Channel.h"
|
|
#include "PacketStruct_SMA.h"
|
|
#include "ServerSession.h"
|
|
#include "ServerSessionManager.h"
|
|
|
|
|
|
WorldManager::WorldManager()
|
|
{
|
|
m_WorldHash.Initialize( DEFAULT_WORLD_POOL_SIZE );
|
|
|
|
m_pWorldPool = new CMemoryPoolFactory<World>;
|
|
m_pWorldPool->Initialize( DEFAULT_WORLD_POOL_SIZE, DEFAULT_WORLD_POOL_SIZE/2 );
|
|
}
|
|
|
|
WorldManager::~WorldManager()
|
|
{
|
|
SAFE_RELEASENDELETE( m_pWorldPool );
|
|
}
|
|
|
|
VOID WorldManager::Release()
|
|
{
|
|
World * pWorld = NULL;
|
|
for( WORLD_HASH_ITR it = m_WorldHash.begin(); it != m_WorldHash.end(); ++it )
|
|
{
|
|
pWorld = *it;
|
|
pWorld->Release();
|
|
}
|
|
m_WorldHash.clear();
|
|
}
|
|
|
|
//파서를 통해 읽어드린 ServerInfo정보를 가지고, 트리구조의 서버정보를 구성한다.
|
|
VOID WorldManager::MakeWorld()
|
|
{
|
|
ServerInfo *pServerInfo = NULL;
|
|
for( SERVER_INFO_MAP_ITER it = ServerInfoParser::Instance()->Begin(); it != ServerInfoParser::Instance()->End(); ++it )
|
|
{
|
|
pServerInfo = it->second;
|
|
if( !pServerInfo ) continue;
|
|
|
|
SERVER_INFO_EX& ServerInfo = pServerInfo->GetServerInfoEx();
|
|
|
|
// 해당키의 World를 찾거나 없으면 생성한다.
|
|
World *pWorld = AllocWorld( ServerInfo.m_byWorld );
|
|
if( !pWorld ) continue;
|
|
|
|
// 채널을 추가한다.
|
|
Channel *pChannel = pWorld->AllocChannel( ServerInfo.m_byChannel );
|
|
if( !pChannel ) continue;
|
|
|
|
// 서버를 추가한다.
|
|
UnitServer *pUnitServer = pChannel->AllocUnitServer( ServerInfo.m_dwServerKey );
|
|
if( !pUnitServer ) continue;
|
|
|
|
pUnitServer->SetServerInfo( pServerInfo );
|
|
}
|
|
}
|
|
|
|
VOID WorldManager::SerializeServerInfoStream( SERVER_TOTAL_INFO & OUT rServerTotInfo )
|
|
{
|
|
World *pWorld = NULL;
|
|
for( WORLD_HASH_ITR it = m_WorldHash.begin(); it != m_WorldHash.end(); ++it )
|
|
{
|
|
pWorld = *it;
|
|
pWorld->SerializeServerInfoStream( rServerTotInfo );
|
|
}
|
|
}
|
|
|
|
|
|
VOID WorldManager::SerializeServerInfoStreamForUser( SERVER_TOTAL_INFO & OUT rServerTotInfo, DWORD dwUserGUID )
|
|
{
|
|
World *pWorld = NULL;
|
|
for( WORLD_HASH_ITR it = m_WorldHash.begin(); it != m_WorldHash.end(); ++it )
|
|
{
|
|
pWorld = *it;
|
|
pWorld->SerializeServerInfoStreamForUser( rServerTotInfo, dwUserGUID );
|
|
}
|
|
}
|
|
|
|
#ifdef __20080312__SOLARAUTH_SERVER_PATCH
|
|
VOID WorldManager::SerializeScriptFolderInfoStream( SCRIPTFOLDER_TOTAL_INFO& OUT rSCFolderTotInfo, DWORD dwUserGUID )
|
|
{
|
|
World *pWorld = NULL;
|
|
for( WORLD_HASH_ITR it = m_WorldHash.begin(); it != m_WorldHash.end(); ++it )
|
|
{
|
|
pWorld = *it;
|
|
pWorld->SerializeScriptFolderInfoStream( rSCFolderTotInfo, dwUserGUID );
|
|
}
|
|
}
|
|
#endif
|
|
|
|
World* WorldManager::AllocWorld( BYTE byWorldKey )
|
|
{
|
|
World *pWorld = FindWorld( byWorldKey );
|
|
if( pWorld )
|
|
return pWorld;
|
|
|
|
pWorld = m_pWorldPool->Alloc();
|
|
|
|
pWorld->Init( byWorldKey );
|
|
|
|
m_WorldHash.Add( pWorld, byWorldKey );
|
|
|
|
return pWorld;
|
|
}
|
|
|
|
VOID WorldManager::FreeWorld( World *pWorld )
|
|
{
|
|
m_WorldHash.Remove( pWorld->GetKey() );
|
|
m_pWorldPool->Free( pWorld );
|
|
}
|
|
|
|
Channel* WorldManager::FindChannel( BYTE byWorldKey, BYTE byChannelKey )
|
|
{
|
|
World *pWorld = FindWorld( byWorldKey );
|
|
if( !pWorld ) return NULL;
|
|
|
|
return pWorld->FindChannel( byChannelKey );
|
|
}
|
|
|
|
UnitServer* WorldManager::FindUnitServer( BYTE byWorldKey, BYTE byChannelKey, DWORD dwUnitServerKey )
|
|
{
|
|
Channel *pChannel = FindChannel( byWorldKey, byChannelKey );
|
|
if( !pChannel ) return NULL;
|
|
|
|
return pChannel->FindUnitServer( dwUnitServerKey );
|
|
}
|
|
|
|
UnitServer* WorldManager::FindUnitServer( DWORD dwAgentKey, BYTE byServerType )
|
|
{
|
|
UnitServer *pFindServer = NULL;
|
|
|
|
World *pWorld = NULL;
|
|
for( WORLD_HASH_ITR it = m_WorldHash.begin(); it != m_WorldHash.end(); ++it )
|
|
{
|
|
pWorld = *it;
|
|
|
|
pFindServer = pWorld->FindUnitServer( dwAgentKey, byServerType );
|
|
if( pFindServer ) return pFindServer;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
UnitServer* WorldManager::FindUnitServer( SERVER_KEY &ServerKey )
|
|
{
|
|
Channel *pChannel = FindChannel( ServerKey.GetWorldID(), ServerKey.GetChannelID() );
|
|
if( !pChannel ) return NULL;
|
|
|
|
return pChannel->FindUnitServer( (eGAME_SERVER_TYPE)ServerKey.GetServerType(), ServerKey.GetServerID() );
|
|
}
|
|
|
|
|
|
UnitServer * WorldManager::FindUnitServer( OLD_SERVER_KEY &ServerKey )
|
|
{
|
|
Channel *pChannel = FindChannel( ServerKey.GetWorldID(), ServerKey.GetChannelID() );
|
|
if( !pChannel ) return NULL;
|
|
|
|
return pChannel->FindUnitServer( (eGAME_SERVER_TYPE)ServerKey.GetServerType(), ServerKey.GetServerID() );
|
|
}
|
|
|
|
#ifdef _NA_006543_20130318_HEARTBEAT
|
|
UnitServer* WorldManager::FindFirstUnitServerByAgentKey(DWORD dwAgentKey)
|
|
{
|
|
UnitServer* find_server = NULL;
|
|
|
|
World* world = NULL;
|
|
for( WORLD_HASH_ITR it = m_WorldHash.begin(); it != m_WorldHash.end(); ++it )
|
|
{
|
|
world = *it;
|
|
if (world == NULL)
|
|
continue;
|
|
|
|
find_server = world->FindFirstUnitServerByAgentKey(dwAgentKey);
|
|
if(find_server)
|
|
{
|
|
return find_server;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
#endif
|
|
|
|
VOID WorldManager::ExecuteStart( DWORD dwUserKey )
|
|
{
|
|
World *pWorld = NULL;
|
|
for( WORLD_HASH_ITR it = m_WorldHash.begin(); it != m_WorldHash.end(); ++it )
|
|
{
|
|
pWorld = *it;
|
|
pWorld->ExecuteStart( dwUserKey );
|
|
}
|
|
}
|
|
|
|
VOID WorldManager::ExecuteEnd( DWORD dwUserKey )
|
|
{
|
|
MSG_MO_RTTG_SERVERSHUTDOWN_REQ ReqMsg;
|
|
ReqMsg.dwKey = dwUserKey;
|
|
ReqMsg.m_byWorldID = 0; ReqMsg.m_byChannelID = 0xff;
|
|
ReqMsg.m_byServerType = 0; ReqMsg.m_byServerID = 0;
|
|
|
|
ServerSession *pMasterSession = ServerSessionManager::Instance()->FindMasterSession();
|
|
if( !pMasterSession )
|
|
{
|
|
DISPMSG( "[WorldManager::ExecuteEnd] pMasterSession is disconnected!\n" );
|
|
return;
|
|
}
|
|
|
|
pMasterSession->SendPacket( (BYTE*)&ReqMsg, sizeof(ReqMsg) );
|
|
}
|
|
|
|
VOID WorldManager::ExecutePatch( DWORD dwUserKey )
|
|
{
|
|
World *pWorld = NULL;
|
|
for( WORLD_HASH_ITR it = m_WorldHash.begin(); it != m_WorldHash.end(); ++it )
|
|
{
|
|
pWorld = *it;
|
|
pWorld->ExecutePatch( dwUserKey );
|
|
}
|
|
}
|
|
|
|
VOID WorldManager::SerializeFtpInfoStreamForUser( FTP_TOTAL_INFO & OUT rFtpTotInfo, DWORD dwUserGUID )
|
|
{
|
|
World *pWorld = NULL;
|
|
for( WORLD_HASH_ITR it = m_WorldHash.begin(); it != m_WorldHash.end(); ++it )
|
|
{
|
|
pWorld = *it;
|
|
pWorld->SerializeFtpInfoStreamForUser( rFtpTotInfo, dwUserGUID );
|
|
}
|
|
}
|
|
|
|
VOID WorldManager::ExecuteForceDisconnect( DWORD dwUserKey )
|
|
{
|
|
World *pWorld = NULL;
|
|
for( WORLD_HASH_ITR it = m_WorldHash.begin(); it != m_WorldHash.end(); ++it )
|
|
{
|
|
pWorld = *it;
|
|
pWorld->ExecuteStart( dwUserKey );
|
|
}
|
|
}
|
|
|
|
VOID WorldManager::ChangeAllServerStatus( eSERVER_STATUS status )
|
|
{
|
|
World *pWorld = NULL;
|
|
for( WORLD_HASH_ITR it = m_WorldHash.begin(); it != m_WorldHash.end(); ++it )
|
|
{
|
|
pWorld = *it;
|
|
pWorld->SetServerStatus( status );
|
|
}
|
|
}
|
|
|
|
BOOL WorldManager::CheckServerStatus( BYTE byWorldKey, eSERVER_STATUS CheckStatus )
|
|
{
|
|
World* pWorld = FindWorld( byWorldKey );
|
|
if( !pWorld ) return FALSE;
|
|
|
|
return pWorld->CheckServerStatus( CheckStatus );
|
|
}
|
|
|
|
UnitServer* WorldManager::FindSunServer( BYTE byWorldKey )
|
|
{
|
|
World* pWorld = FindWorld( byWorldKey );
|
|
if( !pWorld ) return FALSE;
|
|
|
|
return pWorld->FindSunServer();
|
|
}
|
|
|
|
//해당 월드가 현재 패치중인지 확인한다.
|
|
BOOL WorldManager::CheckPatching( BYTE byWorldKey )
|
|
{
|
|
UnitServer* pUnitServer = FindSunServer( byWorldKey );
|
|
if( !pUnitServer ) return FALSE;
|
|
|
|
if( pUnitServer->GetServerStatus() == SERVER_STATUS_PATCHING )
|
|
return TRUE;
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|