DragonNest/Client/DnLauncher2/DnPatchInfo.cpp

1039 lines
29 KiB
C++
Raw Normal View History

2024-12-19 09:48:26 +08:00
#include "stdafx.h"
#include "DnPatchInfo.h"
#include "VarArg.h"
#include "wininet.h"
#include "EtFileSystem.h"
#include "Stream.h"
#include "DnLauncher.h"
#include "DnControlData.h"
#include "DnFirstPatchInfo.h"
#include "DnExplorerDlg.h"
#include "DnFIrstPatchDlg.h"
#pragma comment ( lib, "Wininet.lib" )
#pragma warning ( disable : 4018 )
extern CString g_szCmdLine;
extern CString g_szCommandLinePatchURL;
extern int g_nInitErrorCode;
extern CDnFIrstPatchDlg g_FirstPatchDlg;
//////////////////////////////////////////////////////////////////////////
// CDnPatchInfo Class
//////////////////////////////////////////////////////////////////////////
CDnPatchInfo::CDnPatchInfo()
: m_bSetPatchInfo( FALSE )
, m_nClientVersion( -1 )
, m_nServerVersion( -1 )
#ifdef _USE_AUTOUPDATE
, m_nNextVersion( -1 )
#endif // _USE_AUTOUPDATE
, m_wOpen( 0 )
, m_nLanguageOffset( 0 )
{
}
CDnPatchInfo::~CDnPatchInfo()
{
m_vecChannelList.clear();
m_vecSkipVersion.clear();
m_vecLoginServerList.clear();
}
CDnPatchInfo& CDnPatchInfo::GetInstance()
{
static CDnPatchInfo global;
return global;
}
HRESULT CDnPatchInfo::Init()
{
LogWnd::TraceLog( L"PatchInfo Init Start!" );
// 1. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ο<EFBFBD><CEBF><EFBFBD> PATCHCONFIG_LIST <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ٿ<EFBFBD><D9BF>޴´<DEB4>.
if( FAILED( DownLoadPatchConfigList() ) )
return E_FAIL;
// 2. <20>ٿ<EFBFBD> <20><><EFBFBD><EFBFBD> xml <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Parsing
if( FAILED( ParsingPatchConfigList() ) )
return E_FAIL;
// Ŭ<><C5AC><EFBFBD>̾<EFBFBD>Ʈ <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
TCHAR szCurDir[ _MAX_PATH ]={0,};
GetCurrentDirectory( _MAX_PATH, szCurDir );
m_strClientPath = szCurDir;
int nLast = m_strClientPath.GetLength();
if ( m_strClientPath[nLast] != _T('\\') || m_strClientPath[nLast] != _T('/') )
m_strClientPath += _T('\\');
// <20>ٿ<EFBFBD><D9BF>޾Ҵ<DEBE> xml<6D><6C><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
ClientDeleteFile( m_strClientPath + PATCHCONFIG_LIST );
LogWnd::TraceLog( L"PatchInfo Init Success!" );
return S_OK;
}
#ifdef _USE_MULTILANGUAGE
void CDnPatchInfo::SetLanguageParam( CString strLanguageParam )
{
m_strLanguageParam = strLanguageParam;
m_nLanguageOffset = GetLanguageResourceIndexOffset( strLanguageParam );
DNCTRLDATA.SetLanguageParam(m_strLanguageParam);
}
#endif // _USE_MULTILANGUAGE
HRESULT CDnPatchInfo::DownLoadPatchConfigList()
{
// <20><><EFBFBD><EFBFBD> <20>ּ<EFBFBD><D6BC><EFBFBD><EFBFBD><EFBFBD> üũ
WCHAR LocalLoginListUrl[1024]={ 0, };
TCHAR szCurDir[ _MAX_PATH ]={0,};
bool bUseLocalURL = false;
GetCurrentDirectory( _MAX_PATH, szCurDir );
TCHAR szLocalURL[MAX_PATH]={0,};
swprintf_s( szLocalURL, L"%s\\%s", szCurDir, L"LocalURL.ini" );
FILE *stream = NULL;
char szString[256]={0,};
if( _wfopen_s( &stream, szLocalURL, L"r" ) == 0 )
{
fseek( stream, 0L, SEEK_SET );
fscanf_s( stream, "%s", szString, 256 );
fclose( stream );
MultiByteToWideChar( CP_ACP, 0, szString, -1, LocalLoginListUrl, _countof(LocalLoginListUrl) );
bUseLocalURL = true;
}
WCHAR PatchConfigListUrl[1024]={ 0, };
if( g_szCommandLinePatchURL.GetLength() > 0 ) // <20><>ġȯ<C4A1><C8AF> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ּҰ<D6BC> Ŀ<>ǵ<EFBFBD><C7B5><EFBFBD><EFBFBD><EFBFBD> <20>Ķ<EFBFBD><C4B6><EFBFBD><EFBFBD>ͷ<EFBFBD> <20>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> ( <20><><EFBFBD><EFBFBD> <20>ѱ<EFBFBD>, <20>̱<EFBFBD> <20><><EFBFBD><EFBFBD> )
wcscpy_s( PatchConfigListUrl, _countof(PatchConfigListUrl), g_szCommandLinePatchURL );
else
wcscpy_s( PatchConfigListUrl, _countof(PatchConfigListUrl), PATCHCONFIG_LIST_URL );
LogWnd::TraceLog( _T("DownLoad PatchConfigList (FileName %s)"), PATCHCONFIG_LIST );
// CString test;
// test.Format( L"%s%s", PatchConfigListUrl, PATCHCONFIG_LIST );
// ErrorMessageBoxLog( test );
// LogWnd::TraceLog( test );
HRESULT hr = S_FALSE;
for( int i=0; i<RETRY_MAX_COUNT; i++ )
{
if( bUseLocalURL ) // <20><><EFBFBD>ÿ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ּ<EFBFBD><D6BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ִ<EFBFBD> <20><><EFBFBD><EFBFBD> ( <20><><EFBFBD><EFBFBD> <20>߱<EFBFBD><DFB1><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>޻<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ؼ<EFBFBD> <20><><EFBFBD><EFBFBD> )
{
BOOL bResult = DeleteUrlCacheEntry( CVarArg<__MAX_PATH>(_T("%s"), LocalLoginListUrl) );
hr = DownloadToFile( CVarArg<__MAX_PATH>(_T("%s"), LocalLoginListUrl), CVarArg<__MAX_PATH>(_T(".\\%s"), PATCHCONFIG_LIST) );
}
else
{
BOOL bResult = DeleteUrlCacheEntry( CVarArg<__MAX_PATH>(_T("%s%s"), PatchConfigListUrl, PATCHCONFIG_LIST) );
hr = DownloadToFile( CVarArg<__MAX_PATH>(_T("%s%s"), PatchConfigListUrl, PATCHCONFIG_LIST), CVarArg<__MAX_PATH>(_T(".\\%s"), PATCHCONFIG_LIST) );
}
if( hr == S_OK )
break;
}
if( hr == S_FALSE )
hr = E_FAIL;
if( FAILED( hr ) )
{
ErrorMessageBoxLog( _S( STR_LOAD_PATCHCONFIGLIST_FAILED + DNPATCHINFO.GetLanguageOffset() ) );
g_nInitErrorCode = INIT_ERROR_PATCHCONFIGLIST_DOWNLOAD;
}
return hr;
}
HRESULT CDnPatchInfo::ParsingPatchConfigList()
{
LogWnd::TraceLog( L"ParsingPatchConfigList" );
if( ReadConfig() ) // <20><><EFBFBD><EFBFBD> config<69><67><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>д´<D0B4>. <20><> <20>о<EFBFBD><D0BE>ٸ<EFBFBD> <20>ٿ<EFBFBD><D9BF>ε<EFBFBD> <20><><EFBFBD><EFBFBD> xml<6D><6C><EFBFBD>Ͽ<EFBFBD><CFBF><EFBFBD> <20><><EFBFBD><EFBFBD>
return S_OK;
CXMLParser aParser;
{
USES_CONVERSION;
if( !aParser.Open( CVarArgA<__MAX_PATH>(".\\%s", T2CA(PATCHCONFIG_LIST)) ) )
{
LogWnd::Log( LogLevel::Error, _T("%s Files - Parsing Failed."), PATCHCONFIG_LIST );
g_nInitErrorCode = INIT_ERROR_PATCHCONFIGLIST_PARSING;
return E_FAIL;
}
}
WCHAR szChannellName[MAX_PATH] = { '\0', };
WCHAR szLocalName[MAX_PATH] = { '\0', };
WCHAR szLoginAddr[MAX_PATH] = { '\0', };
WCHAR szGuidepageAddr[1024] = { '\0', };
WCHAR szHomepageAddr[1024] = { '\0', };
WCHAR szUpdateAddr[1024] = { '\0', };
WCHAR szVersionAddr[1024] = { '\0', };
WCHAR szStateTestAddr[1024] = { '\0', };
WORD wLoginPort = 0;
WORD wNew = 0;
WORD wPartitionID = 0;
WORD wOpen = 0;
std::vector<stLoginServerSet> vecLoginServerList;
int nPartitionCount = 0;
if( aParser.FirstChildElement( "document", true ) ) {
if( aParser.FirstChildElement( "ChannelList", true ) ) {
do {
::wcsncpy_s( szChannellName, _countof(szChannellName), aParser.GetAttribute( "channel_name" ), _countof(szChannellName) );
stChannelListSet channellistset;
channellistset.m_strChannelName = szChannellName;
if( aParser.FirstChildElement( "Local", true ) ) {
do {
::wcsncpy_s( szLocalName, _countof(szLocalName), aParser.GetAttribute( "local_name" ), _countof(szLocalName) );
USES_CONVERSION;
if( aParser.GetAttribute( "new" ) )
wNew = _wtoi( aParser.GetAttribute( "new" ) );
if( aParser.GetAttribute( "partitionid" ) )
wPartitionID = _wtoi( aParser.GetAttribute( "partitionid" ) );
if( aParser.GetAttribute("open") )
wOpen = _wtoi( aParser.GetAttribute("open") );
if( aParser.FirstChildElement( "guidepage", false ) )
::wcsncpy_s( szGuidepageAddr, _countof(szGuidepageAddr), aParser.GetAttribute( "addr" ), _countof(szGuidepageAddr) );
if( aParser.FirstChildElement( "homepage", false ) )
::wcsncpy_s( szHomepageAddr, _countof(szHomepageAddr), aParser.GetAttribute( "addr" ), _countof(szHomepageAddr) );
if( aParser.FirstChildElement( "version", false ) )
::wcsncpy_s( szVersionAddr, _countof(szVersionAddr), aParser.GetAttribute( "addr" ), _countof(szVersionAddr) );
if( aParser.FirstChildElement( "update", false ) )
::wcsncpy_s( szUpdateAddr, _countof(szUpdateAddr), aParser.GetAttribute( "addr" ), _countof(szUpdateAddr) );
if( aParser.FirstChildElement( "statetest", false ) )
::wcsncpy_s( szStateTestAddr, _countof(szStateTestAddr), aParser.GetAttribute( "addr" ), _countof(szStateTestAddr) );
if( aParser.FirstChildElement( "login", false ) ) {
do {
::wcsncpy_s( szLoginAddr, _countof(szLoginAddr), aParser.GetAttribute( "addr" ), _countof(szLoginAddr) );
wLoginPort = _wtoi( aParser.GetAttribute( "port" ) );
if( L'\0' == szLoginAddr[0] || !wLoginPort )
continue;
stLoginServerSet loginserverset;
loginserverset.m_strLoginUrl = szLoginAddr;
loginserverset.m_wLoginPort = wLoginPort;
vecLoginServerList.push_back( loginserverset );
} while( aParser.NextSiblingElement( "login" ) );
}
SetPartitionList( channellistset, wNew, wPartitionID, wOpen, szGuidepageAddr, szHomepageAddr,
szLocalName, szVersionAddr, szUpdateAddr, szStateTestAddr, vecLoginServerList );
nPartitionCount++;
vecLoginServerList.clear();
} while( aParser.NextSiblingElement( "Local" ) );
}
m_vecChannelList.push_back( channellistset );
aParser.GoParent();
} while( aParser.NextSiblingElement( "ChannelList" ) );
}
aParser.GoParent();
}
return S_OK;
}
BOOL CDnPatchInfo::ReadConfig()
{
CHAR szCurDir[ _MAX_PATH ]= { 0, };
CHAR szPatchInfoName[128]={0,};
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>˾Ƴ<CBBE><C6B3><EFBFBD>.
CHAR ModuleName[MAX_PATH] ={0,};
::GetModuleFileNameA( NULL, ModuleName , MAX_PATH );
CHAR drive[_MAX_DRIVE];
CHAR dir[_MAX_DIR];
CHAR fname[_MAX_FNAME];
CHAR ext[_MAX_EXT];
_splitpath( ModuleName , drive, dir, fname, ext );
CStringA Str;
#ifndef _DEBUG
Str = drive;
Str += dir;
#endif // !_DEBUG
Str += PATCHINFONAME;
CFileStream* pStream = new CFileStream( Str.GetBuffer() );
if( pStream == NULL || !pStream->IsValid() )
{
SAFE_DELETE( pStream );
return FALSE;
}
int nSize = pStream->Size()+ 3 ;
TCHAR *szCmdLine = new TCHAR[nSize];
char *szTemp = new char[nSize];
ZeroMemory( szCmdLine , sizeof(TCHAR)*nSize );
ZeroMemory( szTemp , sizeof(char)*nSize );
pStream->Read( szTemp, nSize );
SAFE_DELETE( pStream );
MultiByteToWideChar( CP_ACP, 0, szTemp, -1, szCmdLine, sizeof(TCHAR)*nSize );
ParseCommandLineDev( szCmdLine );
SAFE_DELETE_ARRAY( szCmdLine );
SAFE_DELETE_ARRAY( szTemp );
SAFE_DELETE( pStream );
return TRUE;
}
BOOL CDnPatchInfo::SetPatchInfo()
{
if( !SetBasePatchInfo() ) // <20><20><>ġ <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
{
g_nInitErrorCode = INIT_ERROR_SET_PATCHINFO;
m_bSetPatchInfo = FALSE;
return FALSE;
}
if( !SetParameter() ) // <20>Ķ<EFBFBD><C4B6><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
{
g_nInitErrorCode = INIT_ERROR_SET_PARAMETER;
m_bSetPatchInfo = FALSE;
return FALSE;
}
LoadPatchVersionInfo(); // Client & Server Version <20><><EFBFBD><EFBFBD> (Version<6F><6E> <20><><EFBFBD><EFBFBD><EFBFBD>ϸ<EFBFBD> Ǯ<><C7AE>ġ<EFBFBD><C4A1> <20>ѱ<EFBFBD><D1B1><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD> <20><>)
m_bSetPatchInfo = TRUE;
return TRUE;
}
BOOL CDnPatchInfo::SetFirstPatchInfo()
{
unsigned int nSelectChannelNum = 0;
unsigned int nSelectPartitionNum = 0;
if( m_vecChannelList.size() > 0 && nSelectChannelNum < m_vecChannelList.size() )
{
std::vector<stChannelListSet>::iterator iter1 = m_vecChannelList.begin();
iter1 += nSelectChannelNum;
if( (*iter1).m_vecPartitionList.size() > 0 && nSelectPartitionNum < (*iter1).m_vecPartitionList.size() )
{
// <20><>ġ <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
std::vector<stPartitionListSet>::iterator iter2 = (*iter1).m_vecPartitionList.begin();
ResetPatchInfo();
m_strGuidepageUrl = (*iter2).m_strGuidepageUrl;
m_strHomepageUrl = (*iter2).m_strHomepageUrl;
m_strPartitionName = (*iter2).m_strPartitionName;
m_strVersionUrl = (*iter2).m_strVersionUrl;
m_strPatchUrl = (*iter2).m_strPatchUrl;
m_wOpen = (*iter2).m_wOpen;
std::vector<stLoginServerSet>::iterator iter3 = (*iter2).m_vecLoginServerList.begin();
for( ; iter3 != (*iter2).m_vecLoginServerList.end(); iter3++ )
{
m_vecLoginServerList.push_back( (*iter3) );
// Ip & Port List <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
CString strIP;
CString strPort;
strIP.Format( _T("%s"), (*iter3).m_strLoginUrl.GetBuffer() );
strPort.Format( _T("%d"), (*iter3).m_wLoginPort );
if( iter3+1 != (*iter2).m_vecLoginServerList.end() )
{
strIP += ";";
strPort += ";";
}
m_strIPList += strIP;
m_strPortList += strPort;
}
if( m_vecLoginServerList.size() == 0 )
{
LogWnd::Log( LogLevel::Error, _T("LoginServerList is Empty!") );
return FALSE; // <20><>Ƽ<EFBFBD><C6BC> <20><><EFBFBD><EFBFBD> <20><> <20>α<EFBFBD><CEB1>θ<EFBFBD><CEB8><EFBFBD>Ʈ<EFBFBD><C6AE> <20><><EFBFBD>ٸ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
}
}
return TRUE;
}
BOOL CDnPatchInfo::SetBasePatchInfo()
{
unsigned int nSelectChannelNum = 0;
unsigned int nSelectPartitionNum = 0;
#ifdef _USE_PARTITION_SELECT
if( DNOPTIONDATA.m_nSelectChannelNum <= 0 || DNOPTIONDATA.m_nSelectPartitionId <= 0 )
return FALSE;
// 1 base to 0 base
nSelectChannelNum = DNOPTIONDATA.m_nSelectChannelNum - 1;
#endif // _USE_PARTITION_SELECT
if( m_vecChannelList.size() > 0 && nSelectChannelNum < m_vecChannelList.size() )
{
std::vector<stChannelListSet>::iterator iter1 = m_vecChannelList.begin();
iter1 += nSelectChannelNum;
if( (*iter1).m_vecPartitionList.size() > 0 && nSelectPartitionNum < (*iter1).m_vecPartitionList.size() )
{
// <20><>ġ <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
std::vector<stPartitionListSet>::iterator iter2 = (*iter1).m_vecPartitionList.begin();
#ifdef _USE_PARTITION_SELECT
bool bFindPartition = false;
for( ; iter2 != (*iter1).m_vecPartitionList.end(); iter2++ )
{
if( (*iter2).m_wPartitionId == DNOPTIONDATA.m_nSelectPartitionId )
{
bFindPartition = true;
break;
}
}
if( !bFindPartition )
return FALSE;
#endif // _USE_PARTITION_SELECT
ResetPatchInfo();
m_strGuidepageUrl = (*iter2).m_strGuidepageUrl;
m_strHomepageUrl = (*iter2).m_strHomepageUrl;
m_strPartitionName = (*iter2).m_strPartitionName;
m_strVersionUrl = (*iter2).m_strVersionUrl;
m_strPatchUrl = (*iter2).m_strPatchUrl;
m_wOpen = (*iter2).m_wOpen;
std::vector<stLoginServerSet>::iterator iter3 = (*iter2).m_vecLoginServerList.begin();
for( ; iter3 != (*iter2).m_vecLoginServerList.end(); iter3++ )
{
m_vecLoginServerList.push_back( (*iter3) );
// Ip & Port List <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
CString strIP;
CString strPort;
strIP.Format( _T("%s"), (*iter3).m_strLoginUrl.GetBuffer() );
strPort.Format( _T("%d"), (*iter3).m_wLoginPort );
if( iter3+1 != (*iter2).m_vecLoginServerList.end() )
{
strIP += ";";
strPort += ";";
}
m_strIPList += strIP;
m_strPortList += strPort;
}
if( m_vecLoginServerList.size() == 0 )
{
LogWnd::Log( LogLevel::Error, _T("LoginServerList is Empty!") );
return FALSE; // <20><>Ƽ<EFBFBD><C6BC> <20><><EFBFBD><EFBFBD> <20><> <20>α<EFBFBD><CEB1>θ<EFBFBD><CEB8><EFBFBD>Ʈ<EFBFBD><C6AE> <20><><EFBFBD>ٸ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
}
}
return TRUE;
}
#ifdef _USE_PARTITION_SELECT
CString CDnPatchInfo::GetBaseGuidePageUrl()
{
CString strGuidepageUrl;
if( m_vecChannelList.size() > 0 )
{
std::vector<stChannelListSet>::iterator iter1 = m_vecChannelList.begin();
if( (*iter1).m_vecPartitionList.size() > 0 )
{
std::vector<stPartitionListSet>::iterator iter2 = (*iter1).m_vecPartitionList.begin();
strGuidepageUrl = (*iter2).m_strGuidepageUrl;
}
}
return strGuidepageUrl;
}
#endif // _USE_PARTITION_SELECT
void CDnPatchInfo::LoadPatchVersionInfo()
{
LogWnd::TraceLog( L"LoadPatchVersionInfo" );
if( m_nClientVersion == -1 )
LoadClientVersion();
if( m_nServerVersion == -1 )
LoadServerVersion();
LogWnd::TraceLog( L"LoadPatchVersionInfo Complete : Client Ver[%d] / Server Ver[%d]", m_nClientVersion, m_nServerVersion );
}
void CDnPatchInfo::LoadClientVersion()
{
#ifdef _USE_SINGLE_CLIENT
LoadClientVersionFromResourceFile();
#else
LoadClientVersionFromVersionFile();
#endif // _USE_SINGLE_CLIENT
}
#ifdef _USE_SINGLE_CLIENT
void CDnPatchInfo::LoadClientVersionFromResourceFile()
{
CString szFindPackingFile;
szFindPackingFile = m_strClientPath;
szFindPackingFile += _T("Resource00.pak");
CEtPackingFile *pPackingFile = new CEtPackingFile();
CEtFileHandle *FileHandle = NULL;
char StrVersionName[32] = "\\version.cfg";
char szTemp[ _MAX_PATH ] = {0,};
char *pBuff = NULL;
int nFileSize = 0;
WideCharToMultiByte( CP_ACP, 0, szFindPackingFile.GetBuffer(), -1, szTemp, _MAX_PATH, NULL, NULL );
if( pPackingFile->OpenFileSystem( szTemp ) )
{
FileHandle = pPackingFile->OpenFile( StrVersionName );
if( FileHandle )
{
nFileSize = FileHandle->GetFileContext()->dwAllocSize;
pBuff = new char[nFileSize];
FileHandle->Read( pBuff, nFileSize );
char arg1[256]={0,}, arg2[256]={0,};
char *szToken = NULL, *nextToken = NULL;
char delimiters[] = "\r\n";
szToken = strtok_s( pBuff, delimiters, &nextToken );
while( szToken != NULL )
{
if( sscanf_s( szToken, "%s %s", &arg1, sizeof(arg1), &arg2, sizeof(arg2) ) )
{
_strlwr_s( arg1 );
if( _stricmp( arg1, "version" ) == 0 ) // version <20><><EFBFBD><EFBFBD> Ŭ<><C5AC> <20><><EFBFBD><EFBFBD><EFBFBD≯<EFBFBD> <20><><EFBFBD><EFBFBD>
{
m_nClientVersion = atol( arg2 );
//break;
}
else if( _stricmp( arg1, "module") == 0 ) // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>Ľ<EFBFBD>.
{
DNFIRSTPATCHINFO.SetLocalModuleVersion(atol( arg2 ));
}
}
szToken = strtok_s( NULL, delimiters, &nextToken );
}
SAFE_DELETE( pBuff );
}
else
{
CString strFilePath;
strFilePath = m_strClientPath;
strFilePath += CLIENT_VERSION_NAME;
CString strTempName;
strTempName = _T("Version");
m_nClientVersion = LoadVersion( strFilePath , strTempName);
strTempName = _T("Module");
int nModuleVersion = LoadVersion( strFilePath , strTempName);
DNFIRSTPATCHINFO.SetLocalModuleVersion(nModuleVersion);
if( nModuleVersion <= -1 )
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> -1<>̶<EFBFBD><CCB6><EFBFBD>, <20><>ó<EFBFBD><C3B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ش<EFBFBD>. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ѵ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>̹Ƿ<CCB9>.
if( m_nClientVersion != -1 )
{
nModuleVersion = m_nClientVersion;
DNFIRSTPATCHINFO.SetLocalModuleVersion(nModuleVersion);
}
else
DNFIRSTPATCHINFO.SetFirstPatchStatus(DNFIRSTPATCHINFO.EM_FIRSTPATCH_VERSION_FAIL);
}
if( m_nClientVersion == -1 || nModuleVersion == -1 )
{
ErrorMessageBoxLog( _T("Fail to load client version") );
}
else
{
//<2F>Ѿȿ<D1BE> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>־<EFBFBD><D6BE><EFBFBD><EFBFBD><EFBFBD>.
char strVersion[256] = {0,};
sprintf_s( strVersion, sizeof(strVersion), "Version %d\r\nModule %d", m_nClientVersion, DNFIRSTPATCHINFO.GetLocalModuleVersion() );
char StrVersionName[32] = "\\version.cfg";
pPackingFile->AddFile( StrVersionName, strVersion, sizeof(strVersion) );
}
}
pPackingFile->CloseFile( FileHandle );
pPackingFile->CloseFileSystem();
}
else
{
LogWnd::Log( LogLevel::Error, _T("%s : %d"), szFindPackingFile, GetLastError() );
ErrorMessageBoxLog( _T("Fail to read resource pak") );
m_nClientVersion = -1;
DNFIRSTPATCHINFO.SetLocalModuleVersion(-1);
}
SAFE_DELETE( pPackingFile );
}
#else // _USE_SINGLE_CLIENT
void CDnPatchInfo::LoadClientVersionFromVersionFile()
{
CString szVersionFile;
szVersionFile = m_strClientPath;
szVersionFile += _T("\\version.cfg");
CString strTempName;
strTempName = _T("Version");
m_nClientVersion = LoadVersion( szVersionFile , strTempName);
strTempName = _T("Module");
int nModuleVersion = LoadVersion( szVersionFile , strTempName);
DNFIRSTPATCHINFO.SetLocalModuleVersion( nModuleVersion );
if( nModuleVersion <= -1 )
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> -1<>̶<EFBFBD><CCB6><EFBFBD>, <20><>ó<EFBFBD><C3B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ش<EFBFBD>. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ѵ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>̹Ƿ<CCB9>.
if( m_nClientVersion != -1 )
{
nModuleVersion = m_nClientVersion;
DNFIRSTPATCHINFO.SetLocalModuleVersion(nModuleVersion);
}
else
DNFIRSTPATCHINFO.SetFirstPatchStatus(DNFIRSTPATCHINFO.EM_FIRSTPATCH_VERSION_FAIL);
}
if( m_nClientVersion == -1 || nModuleVersion == -1)
{
LogWnd::Log( LogLevel::Error, _T("%s : %d"), szVersionFile, m_nClientVersion );
ErrorMessageBoxLog( _T("Fail to read resource pak") );
}
}
#endif // _USE_SINGLE_CLIENT
void CDnPatchInfo::LoadServerVersion()
{
CString strFilePath;
strFilePath = m_strClientPath;
strFilePath += SERVER_VERSION_NAME;
HRESULT hr = E_FAIL;
for( int i=0; i<RETRY_MAX_COUNT; i++ )
{
CString strVersionUrlFile = m_strVersionUrl + SERVER_VERSION_NAME;
BOOL bResult = DeleteUrlCacheEntry( strVersionUrlFile.GetBuffer() ); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ϱ<EFBFBD> PatchInfoServer.cfg <20><> <20>ٿ<EFBFBD><D9BF>ε<EFBFBD>
hr = DownloadToFile( strVersionUrlFile.GetBuffer(), strFilePath.GetBuffer() );
if( hr == S_OK )
break;
}
if( hr == S_OK )
{
CString strTempName;
strTempName = _T("Version");
m_nServerVersion = LoadVersion( strFilePath, strTempName );
DeleteFile( strFilePath );
}
else
LogWnd::Log( LogLevel::Error, _T("PatchInfoServer.cfg download Failed!") );
if( m_nClientVersion <= 0 || m_nServerVersion <= 0 )
{
ErrorMessageBoxLog( _S( STR_CONFIRM_PATCH_VER_FAILED + DNPATCHINFO.GetLanguageOffset() ) );
}
}
int CDnPatchInfo::LoadVersion( CString& szFilePath )
{
char* buffer = NULL;
HANDLE hFile = INVALID_HANDLE_VALUE;
int nVersion = 0;
hFile = CreateFile( szFilePath.GetBuffer(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
if( hFile == INVALID_HANDLE_VALUE )
return -1;
DWORD tmp = 0;
DWORD nFileSize = 0;
nFileSize = GetFileSize( hFile, &tmp );
nFileSize++;
// 7 byte <20≯<EFBFBD><CCB8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ŭ<><C5AC><EFBFBD>̾<EFBFBD>Ʈ version.cfg <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ο<EFBFBD><CEBF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ü<EFBFBD>Ѵ<EFBFBD>.
if( nFileSize < 5 )
{
AfxMessageBox( _T("Error the old version.cfg.") );
CloseHandle(hFile);
return -1;
}
buffer = new char[nFileSize+1];
if( buffer == NULL )
return -1;
ZeroMemory( buffer, nFileSize+1 );
DWORD nReadSize = 0;
ReadFile( hFile, buffer, nFileSize, &nReadSize, NULL );
CloseHandle( hFile );
char arg1[256]={0,}, arg2[256]={0,};
char *szToken = NULL, *nextToken = NULL;
char delimiters[] = "\r\n";
szToken = strtok_s( buffer, delimiters, &nextToken );
while( szToken != NULL )
{
if( sscanf_s( szToken, "%s %s", &arg1, sizeof(arg1), &arg2, sizeof(arg2) ) )
{
_strlwr_s( arg1 );
// version <20><><EFBFBD><EFBFBD> Ŭ<><C5AC> <20><><EFBFBD><EFBFBD><EFBFBD≯<EFBFBD> <20><><EFBFBD><EFBFBD>
if( _stricmp( arg1, "version" ) == 0 )
nVersion = atol( arg2 );
else if( _stricmp( arg1, "skipnum" ) == 0 )
{
int nValue = atol( arg2 );
std::vector<int>::iterator itSkip = std::find( m_vecSkipVersion.begin(), m_vecSkipVersion.end(), nValue );
if( itSkip == m_vecSkipVersion.end() )
m_vecSkipVersion.push_back( nValue );
}
#ifdef _USE_AUTOUPDATE
else if( _stricmp( arg1, "nextversion" ) == 0 )
m_nNextVersion = atol( arg2 );
#endif // _USE_AUTOUPDATE
}
szToken = strtok_s( NULL, delimiters, &nextToken );
}
SAFE_DELETE_ARRAY( buffer );
return nVersion;
}
int CDnPatchInfo::LoadVersion( CString& szFilePath, CString szTypeName )
{
char* buffer = NULL;
HANDLE hFile = INVALID_HANDLE_VALUE;
int nVersion = -1;
hFile = CreateFile( szFilePath.GetBuffer(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
if( hFile == INVALID_HANDLE_VALUE )
return -1;
DWORD tmp = 0;
DWORD nFileSize = 0;
nFileSize = GetFileSize( hFile, &tmp );
nFileSize++;
// 7 byte <20≯<EFBFBD><CCB8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ŭ<><C5AC><EFBFBD>̾<EFBFBD>Ʈ version.cfg <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ο<EFBFBD><CEBF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ü<EFBFBD>Ѵ<EFBFBD>.
if( nFileSize < 5 )
{
AfxMessageBox( _T("Error the old version.cfg.") );
CloseHandle(hFile);
return -1;
}
buffer = new char[nFileSize+1];
if( buffer == NULL )
return -1;
ZeroMemory( buffer, nFileSize+1 );
DWORD nReadSize = 0;
ReadFile( hFile, buffer, nFileSize, &nReadSize, NULL );
CloseHandle( hFile );
char arg1[256]={0,}, arg2[256]={0,};
char *szToken = NULL, *nextToken = NULL;
char delimiters[] = "\r\n";
szToken = strtok_s( buffer, delimiters, &nextToken );
int nValue = 0;
while( szToken != NULL )
{
if( sscanf_s( szToken, "%s %s", &arg1, sizeof(arg1), &arg2, sizeof(arg2) ) )
{
_strlwr_s( arg1 );
char szTemp[ _MAX_PATH ] = {0,};
WideCharToMultiByte( CP_ACP, 0, szTypeName.GetBuffer(), -1, szTemp, _MAX_PATH, NULL, NULL );
if( _stricmp( arg1, szTemp ) == 0 )
{
nVersion = atol( arg2 );
}
}
szToken = strtok_s( NULL, delimiters, &nextToken );
}
SAFE_DELETE_ARRAY( buffer );
return nVersion;
}
void CDnPatchInfo::SetClientPath( CString strClientPath )
{
// Ŭ<><C5AC><EFBFBD>̾<EFBFBD>Ʈ <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
m_strClientPath = strClientPath;
int nLast = m_strClientPath.GetLength();
if ( m_strClientPath[nLast] != _T('\\') || m_strClientPath[nLast] != _T('/') )
m_strClientPath += _T('\\');
}
BOOL CDnPatchInfo::SetParameter()
{
if( m_strIPList.GetLength() == 0 || m_strPortList.GetLength() == 0 )
return FALSE;
m_strOptionParam.Format( _T("/ip:%s /port:%s /Lver:%d /use_packing"), m_strIPList, m_strPortList, LAUNCHER_VERSION );
#ifdef _USA // Nexon USA Stand-Alone Mode <20>Ķ<EFBFBD><C4B6><EFBFBD><EFBFBD>Ϳ<EFBFBD> <20>߰<EFBFBD>
if( g_szCmdLine.GetLength() == 0 )
m_strOptionParam += L" /stand_alone";
#endif // _USA
#ifdef _JPN
DnNHNService::GetInstance().UpdateString();
m_strTotalParam.Format( _T( "%s mid:%s %s" ), DnNHNService::GetInstance().GetGameString(), DnNHNService::GetInstance().GetMemberID(), DNPATCHINFO.GetOptionParameter().GetBuffer() );
#else // _JPN
m_strTotalParam.Format( _T( "%s %s" ), g_szCmdLine.GetBuffer(), m_strOptionParam.GetBuffer() );
#endif // _JPN
#ifdef _USE_MULTILANGUAGE
if( m_strLanguageParam.GetLength() > 0 )
{
CString strLanguageParam;
strLanguageParam.Format( _T( " /language:%s" ), m_strLanguageParam );
m_strOptionParam += strLanguageParam;
}
#endif // _USE_MULTILANGUAGE
return TRUE;
}
void CDnPatchInfo::ResetPatchInfo()
{
m_strGuidepageUrl.Empty();
m_strHomepageUrl.Empty();
m_strPartitionName.Empty();
m_strVersionUrl.Empty();
m_strPatchUrl.Empty();
m_nClientVersion = -1;
m_nServerVersion = -1;
m_wOpen = 0;
m_vecLoginServerList.clear();
m_strIPList.Empty();
m_strPortList.Empty();
m_strOptionParam.Empty();
m_strTotalParam.Empty();
}
void CDnPatchInfo::SetPartitionList( stChannelListSet& channellistset, WORD dwNew, WORD wPartitionId, WORD wOpen, CString strGuidepageUrl, CString strHomepageUrl,
CString strPartitionName, CString strVersionUrl, CString strPatchUrl, CString strStateTestUrl, std::vector<stLoginServerSet>& vecLoginServerList )
{
stPartitionListSet serverlistset;
serverlistset.m_wNew = dwNew;
serverlistset.m_wPartitionId = wPartitionId;
serverlistset.m_wOpen = wOpen;
serverlistset.m_strGuidepageUrl = strGuidepageUrl;
serverlistset.m_strHomepageUrl = strHomepageUrl;
serverlistset.m_strPartitionName = strPartitionName;
serverlistset.m_strVersionUrl = strVersionUrl;
serverlistset.m_strPatchUrl = strPatchUrl;
serverlistset.m_strStateTestUrl = strStateTestUrl;
std::vector<stLoginServerSet>::iterator iter = vecLoginServerList.begin();
for( ; iter != vecLoginServerList.end(); iter++ )
serverlistset.m_vecLoginServerList.push_back( *iter );
channellistset.m_vecPartitionList.push_back( serverlistset );
}
void CDnPatchInfo::ParseCommandLineDev( LPCTSTR szCommandLine )
{
if( !szCommandLine )
return;
LPCTSTR szlpURL = L"urlpatch:";
LPCTSTR szlpVersion = L"urlversion:";
LPCTSTR szlpGuidepage = L"guidepage:";
LPCTSTR szlpHomepage = L"homepage:";
LPCTSTR szlpIP = L"ip:";
LPCTSTR szlpPort = L"port:";
std::wstring wszCmdLine = szCommandLine;
std::vector<std::wstring> tokens;
TokenizeW( wszCmdLine, tokens, std::wstring(L"\r\n"));
std::vector<stLoginServerSet> vecLoginServerList;
WCHAR szLoginAddr[MAX_PATH] = { '\0', };
WCHAR szGuidepageAddr[1024] = { '\0', };
WCHAR szHomepageAddr[1024] = { '\0', };
WCHAR szUpdateAddr[1024] = { '\0', };
WCHAR szVersionAddr[1024] = { '\0', };
WORD wLoginPort = 0;
for( int i=0; i<(int)tokens.size(); i++ )
{
RemoveSpaceW( tokens[i] );
if( NULL != StrStr(tokens[i].c_str(), szlpURL ) )
{
tokens[i].erase( 0, tokens[i].find(L":") + 1 );
::wcsncpy_s( szUpdateAddr, _countof(szUpdateAddr), tokens[i].c_str(), _countof(szUpdateAddr) );
}
if( NULL != StrStr(tokens[i].c_str(), szlpVersion ) )
{
tokens[i].erase( 0, tokens[i].find(L":") + 1 );
::wcsncpy_s( szVersionAddr, _countof(szVersionAddr), tokens[i].c_str(), _countof(szVersionAddr) );
}
if( NULL != StrStr(tokens[i].c_str(), szlpGuidepage) )
{
tokens[i].erase( 0, tokens[i].find(L":") + 1 );
::wcsncpy_s( szGuidepageAddr, _countof(szGuidepageAddr), tokens[i].c_str(), _countof(szGuidepageAddr) );
}
if( NULL != StrStr(tokens[i].c_str(), szlpHomepage) )
{
tokens[i].erase( 0, tokens[i].find(L":") + 1 );
::wcsncpy_s( szHomepageAddr, _countof(szHomepageAddr), tokens[i].c_str(), _countof(szHomepageAddr) );
}
if( NULL != StrStr(tokens[i].c_str(), szlpIP) )
{
tokens[i].erase( 0, tokens[i].find(L":") + 1 );
::wcsncpy_s( szLoginAddr, _countof(szLoginAddr), tokens[i].c_str(), _countof(szLoginAddr) );
}
if( NULL != StrStr(tokens[i].c_str(), szlpPort) )
{
tokens[i].erase( 0, tokens[i].find(L":") + 1 );
wLoginPort = _wtoi( tokens[i].c_str() );
}
}
tokens.clear();
stLoginServerSet loginserverset;
loginserverset.m_strLoginUrl = szLoginAddr;
loginserverset.m_wLoginPort = wLoginPort;
vecLoginServerList.push_back( loginserverset );
stChannelListSet channellistset;
channellistset.m_strChannelName = L"CustomChannel";
SetPartitionList( channellistset, 0, 100, 1, szGuidepageAddr, szHomepageAddr, L"CustomConfig", szVersionAddr, szUpdateAddr, L"", vecLoginServerList );
m_vecChannelList.push_back( channellistset );
}
#ifdef _USE_PARTITION_SELECT
int CDnPatchInfo::GetPartitionId( int nChannelNum, int nPartitionNum )
{
if( nChannelNum <= 0 || nPartitionNum <= 0 )
return 0;
// 1 base to 0 base
nChannelNum--;
nPartitionNum--;
int nPartitionId = 0;
if( m_vecChannelList.size() > 0 && nChannelNum < m_vecChannelList.size() )
{
std::vector<stChannelListSet>::iterator iter1 = m_vecChannelList.begin();
iter1 += nChannelNum;
if( (*iter1).m_vecPartitionList.size() > 0 && nPartitionNum < (*iter1).m_vecPartitionList.size() )
{
// <20><>ġ <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
std::vector<stPartitionListSet>::iterator iter2 = (*iter1).m_vecPartitionList.begin();
iter2 += nPartitionNum;
nPartitionId = (*iter2).m_wPartitionId;
}
}
return nPartitionId;
}
bool CDnPatchInfo::LoadVersionData()
{
DNOPTIONDATA.LoadPartitionOption( NULL );
if(DNOPTIONDATA.m_nSelectChannelNum <= 0 || DNOPTIONDATA.m_nSelectPartitionId <= 0 )
{
// <20><>Ƽ<EFBFBD><C6BC><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ġ<EFBFBD><C4A1> <20><><EFBFBD><EFBFBD><EFBFBD>Ҽ<EFBFBD><D2BC><EFBFBD> <20><><EFBFBD><EFBFBD>.
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ġ<EFBFBD><C4A1> <20>޾ƾ<DEBE> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ҽ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. <20><><EFBFBD><20><>Ƽ<EFBFBD><C6BC><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
CDnSelectPartitionDlg DnSelectPartitionDlg(&g_FirstPatchDlg);
WCHAR szUrl[4096]={0,};
TCHAR szCurDir[ _MAX_PATH ]={0,};
GetCurrentDirectory( _MAX_PATH, szCurDir );
swprintf_s( szUrl , _T("%s\\Html\\HTMLPage1.htm"), szCurDir );
DnSelectPartitionDlg.SetURL(szUrl);
DnSelectPartitionDlg.DoModal();
}
else
{
if( DNOPTIONDATA.m_nSelectChannelNum > 0 && DNOPTIONDATA.m_nSelectPartitionId > 0 )
{
if( !DNPATCHINFO.SetPatchInfo() )
{
DNOPTIONDATA.m_nSelectChannelNum = 0;
DNOPTIONDATA.m_nSelectPartitionId = 0;
DNOPTIONDATA.SavePartitionOption( NULL );
}
}
}
return true;
}
#endif // _USE_PARTITION_SELECT