Files
2022-10-26 12:25:11 +08:00

236 lines
6.2 KiB
C++

#include "StdAfx.h"
#include ".\serverinfoparser.h"
#include <ChangeIP.h>
#include "ServerInfo.h"
#include "DataInfo.h"
ServerInfoParser::ServerInfoParser(void)
{
m_XMLParser.Init();
m_mapServerInfo.clear();
}
ServerInfoParser::~ServerInfoParser(void)
{
UnLoad();
}
VOID ServerInfoParser::UnLoad()
{
ServerInfo * pServerInfo = NULL;
for( SERVER_INFO_MAP_ITER it = m_mapServerInfo.begin(); it != m_mapServerInfo.end(); ++it )
{
pServerInfo = it->second;
if( pServerInfo )
{
delete pServerInfo;
pServerInfo = NULL;
}
}
m_mapServerInfo.clear();
}
BOOL ServerInfoParser::Load( char* pszFileName )
{
if( !m_XMLParser.Load( pszFileName ) )
return FALSE;
long nWorldNum = 0;
NODELISTPtr pWorldList = m_XMLParser.FindNodeList( L"//WORLD", nWorldNum );
if( pWorldList == NULL )
return FALSE;
std::string strWorldName, strChannelName, strIP;
BYTE byWorld, byChannel, byServerType, byServerNum;
DWORD dwIPKey, dwServerKey, dwAgentKey;
for( int nWorld = 0; nWorld < nWorldNum; nWorld++ )
{
NODEPtr pWorldNode = m_XMLParser.FindNode( pWorldList, nWorld );
if( pWorldNode == NULL ) continue;
//월드의 이름과, 월드 번호를 얻는다.(속성정보를 얻는다.)
strWorldName.clear(); byWorld = 0;
if( !m_XMLParser.GetAttriDataStr( pWorldNode, L"NAME", strWorldName ) ) continue;
if( !m_XMLParser.GetAttriDataBYTE( pWorldNode, L"NUM", byWorld ) ) continue;
// 해당월드의 채널 정보를 얻는다.
long nChannelNum = 0;
NODELISTPtr pChannelList = m_XMLParser.FindChildNodeList( pWorldNode, nChannelNum );
if( pChannelList == NULL ) continue;
for( int nChannel = 0; nChannel < nChannelNum; nChannel++ )
{
NODEPtr pChannelNode = m_XMLParser.FindNode( pChannelList, nChannel ); //첫번째 채널부터 순차적으로.
if( pChannelNode == NULL ) continue;
strChannelName.clear(); byChannel = 0;
if( !m_XMLParser.GetAttriDataStr( pChannelNode, L"NAME", strChannelName ) ) continue;
if( !m_XMLParser.GetAttriDataBYTE( pChannelNode, L"NUM", byChannel ) ) continue;
// 해당 채널의 서버 정보를 얻는다.
long nServerNum= 0;
NODELISTPtr pServerList = m_XMLParser.FindChildNodeList( pChannelNode, nServerNum );
if( pServerList == NULL ) continue;
for( int nServer = 0; nServer < nServerNum; ++nServer )
{
NODEPtr pServerNode = m_XMLParser.FindNode( pServerList, nServer ); //첫번째 채널부터 순차적으로.
if( pServerNode == NULL ) continue;
byServerType = byServerNum = 0;
strIP.clear();
dwIPKey = dwServerKey = dwAgentKey = 0;
if( !m_XMLParser.GetAttriDataBYTE( pServerNode, L"TYPE", byServerType ) ) continue;
if( !m_XMLParser.GetAttriDataBYTE( pServerNode, L"NUM", byServerNum ) ) continue;
if( !m_XMLParser.GetAttriDataDWORD( pServerNode, L"AGENTKEY", dwAgentKey ) ) continue;
dwServerKey = MakeKey( byWorld, byChannel, byServerType, byServerNum );
if( GetServerInfo( dwServerKey ) )
{
FASSERT( !"데이터에 오류가 있습니다." );
return FALSE;
}
// 서버 정보를 추가한다.
ServerInfo *pServerInfo = new ServerInfo;
SERVER_INFO_EX ServerInfoEx;
ServerInfoEx.m_dwServerKey = dwServerKey;
ServerInfoEx.m_byWorld = byWorld;
ServerInfoEx.m_byChannel = byChannel;
ServerInfoEx.m_byServerType = byServerType;
ServerInfoEx.m_byServerNum = byServerNum;
ServerInfoEx.m_byStatus = SERVER_STATUS_OFFLINE;
_tcsncpy( ServerInfoEx.m_szWorldName, strWorldName.c_str(), MAX_WORLD_NAME_SIZE );
_tcsncpy( ServerInfoEx.m_szChannelName, strChannelName.c_str(), MAX_WORLD_NAME_SIZE );
pServerInfo->SerializeStream( ServerInfoEx, TRUE );
pServerInfo->SetAgentKey( dwAgentKey );
#ifdef __20080312__SOLARAUTH_SERVER_PATCH
// 해당 서버의 폴더 정보를 얻는다.
long nDataFolderNum = 0;
std::string strFolder, strPatchVer;
DWORD dwFolderKey = 0;
NODELISTPtr pFolderList = m_XMLParser.FindChildNodeList( pServerNode, nDataFolderNum );
if( pFolderList == NULL ) continue;
for( int nFolder = 0; nFolder < nDataFolderNum; ++nFolder )
{
NODEPtr pFolderNode = m_XMLParser.FindNode( pFolderList, nFolder );
if( pFolderNode == NULL )
continue;
if( !m_XMLParser.GetAttriDataDWORD( pFolderNode, L"KEY", dwFolderKey))
continue;
if( !m_XMLParser.GetAttriDataStr( pFolderNode, L"NAME", strFolder))
continue;
if( !m_XMLParser.GetAttriDataStr( pFolderNode, L"PATCHVER", strPatchVer))
continue;
DataInfo folderData( dwFolderKey, dwServerKey, strFolder, strPatchVer);
if( pServerInfo->IsHave( folderData) )
{
FASSERT( !"데이터에 오류가 있습니다." );
return FALSE;
}
pServerInfo->AddDataInfo( folderData);
}
#endif//__20080312__SOLARAUTH_SERVER_PATCH
m_mapServerInfo.insert( std::make_pair( dwServerKey, pServerInfo ) );
}
}
}
return TRUE;
}
VOID ServerInfoParser::SerializeServerInfoStream( SERVER_TOTAL_INFO & INOUT rServerTotInfo, BOOL bSave )
{
if( bSave )
{
for( BYTE byCount = 0; byCount < rServerTotInfo.m_Count; ++byCount )
{
ServerInfo * pServerInfo = GetServerInfo( rServerTotInfo.m_Data[byCount].m_dwServerKey );
if( !pServerInfo ) continue;
pServerInfo->SerializeStream( rServerTotInfo.m_Data[byCount], TRUE );
}
}
else
{
rServerTotInfo.m_Count = 0;
ServerInfo * pServerInfo = NULL;
for( SERVER_INFO_MAP_ITER iter = m_mapServerInfo.begin(); iter != m_mapServerInfo.end(); ++iter )
{
pServerInfo = iter->second;
if( pServerInfo )
{
pServerInfo->SerializeStream( rServerTotInfo.m_Data[rServerTotInfo.m_Count], FALSE );
rServerTotInfo.m_Count++;
}
else
{
MSGOUT( "ServerInfo Stream Error" );
}
}
}
}
DWORD ServerInfoParser::MakeKey( BYTE byWorld, BYTE byChannel, BYTE byType, BYTE byNum )
{
#ifdef __20080310__CHANGE_SET_SERVERKEY
return SERVER_KEY( byWorld, byChannel, byType, byNum);
#else
DWORD dwKey = (DWORD)( ((DWORD)byWorld << 24) | ((DWORD)byChannel << 16) | ((DWORD)byType << 8) | ((DWORD)byNum) );
return dwKey;
#endif //__20080310__CHANGE_SET_SERVERKEY
}
ServerInfo* ServerInfoParser::GetServerInfo( DWORD dwServerKey )
{
SERVER_INFO_MAP_ITER iter = m_mapServerInfo.find( dwServerKey );
if( iter != m_mapServerInfo.end() )
{
ServerInfo* pInfo = iter->second;
if( pInfo )
return pInfo;
}
return NULL;
}