Compare commits
6 Commits
master
...
experiment
Author | SHA1 | Date | |
---|---|---|---|
603f2207ef | |||
6564e417f9 | |||
e7b6680895 | |||
187ecd53f2 | |||
8d27c24328 | |||
955c2a8fd9 |
1
bin/.gitignore
vendored
1
bin/.gitignore
vendored
@ -18,6 +18,7 @@ syserr.txt
|
||||
# Game files
|
||||
pack/*.eix
|
||||
pack/*.epk
|
||||
pack/*.zip
|
||||
|
||||
# Guild images
|
||||
mark/
|
||||
|
14
bin/pack/pack.bat
Normal file
14
bin/pack/pack.bat
Normal file
@ -0,0 +1,14 @@
|
||||
@echo off
|
||||
|
||||
setlocal enabledelayedexpansion
|
||||
FOR /d %%i IN ("*") DO (
|
||||
echo Packing %%i
|
||||
rem "C:\Program Files\7-Zip\7z.exe" a "%%i.zip" ".\%%i\*" -m0=LZMA
|
||||
rem "C:\Program Files\7-Zip-Zstandard\7za.exe" a "%%i.zip" ".\%%i\*" -m0=Zstd
|
||||
"C:\Program Files\7-Zip\7z.exe" a "%%i.zip" ".\%%i\*"
|
||||
if !errorlevel! neq 0 exit /b !errorlevel!
|
||||
|
||||
cls
|
||||
)
|
||||
|
||||
pause
|
@ -3,7 +3,7 @@
|
||||
#include <d3d9.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <math.h>
|
||||
#include <vector>
|
||||
|
||||
#define APP_NAME _T("Metin2 Config")
|
||||
#define FILENAME_CONFIG "metin2.cfg"
|
||||
@ -164,12 +164,24 @@ BOOL CMainDialog::OnInitDialog(CWindow wndFocus, LPARAM lInitParam)
|
||||
m_comboShadow.SetCurSel(m_stConfig.iShadowLevel);
|
||||
|
||||
// Language
|
||||
ATL::CString language;
|
||||
|
||||
// Load the languages into an array
|
||||
std::vector<ATL::CString> languages;
|
||||
for (int i = 0; i < kLanguageMax; ++i) {
|
||||
ATL::CString language;
|
||||
language.LoadString(kLanguageConfig[i].stringId);
|
||||
m_comboLanguage.InsertString(i, language);
|
||||
languages.push_back(language);
|
||||
}
|
||||
|
||||
// Sort the array
|
||||
std::sort(languages.begin(), languages.end(), [](const ATL::CString& a, const ATL::CString& b) {
|
||||
return a.CompareNoCase(b) < 0;
|
||||
});
|
||||
|
||||
// Add the languages to the combo
|
||||
for (auto& language : languages)
|
||||
m_comboLanguage.AddString(language);
|
||||
|
||||
m_stConfig.language = std::clamp((int) m_stConfig.language, 0, kLanguageMax - 1);
|
||||
|
||||
m_comboLanguage.SetCurSel(m_stConfig.language);
|
||||
@ -229,10 +241,66 @@ void CMainDialog::InitDefaultConfig()
|
||||
|
||||
auto lang = PRIMARYLANGID(LANGIDFROMLCID(GetUserDefaultLCID()));
|
||||
switch (lang) {
|
||||
case LANG_CZECH:
|
||||
m_stConfig.language = kLanguageCzech;
|
||||
break;
|
||||
|
||||
case LANG_DANISH:
|
||||
m_stConfig.language = kLanguageDanish;
|
||||
break;
|
||||
|
||||
case LANG_DUTCH:
|
||||
m_stConfig.language = kLanguageDutch;
|
||||
break;
|
||||
|
||||
case LANG_ENGLISH:
|
||||
m_stConfig.language = kLanguageEnglish;
|
||||
break;
|
||||
|
||||
case LANG_FRENCH:
|
||||
m_stConfig.language = kLanguageFrench;
|
||||
break;
|
||||
|
||||
case LANG_GERMAN:
|
||||
m_stConfig.language = kLanguageGerman;
|
||||
break;
|
||||
|
||||
case LANG_GREEK:
|
||||
m_stConfig.language = kLanguageGreek;
|
||||
break;
|
||||
|
||||
case LANG_HUNGARIAN:
|
||||
m_stConfig.language = kLanguageHungarian;
|
||||
break;
|
||||
|
||||
case LANG_ITALIAN:
|
||||
m_stConfig.language = kLanguageItalian;
|
||||
break;
|
||||
|
||||
case LANG_POLISH:
|
||||
m_stConfig.language = kLanguagePolish;
|
||||
break;
|
||||
|
||||
case LANG_PORTUGUESE:
|
||||
m_stConfig.language = kLanguagePortuguese;
|
||||
break;
|
||||
|
||||
case LANG_ROMANIAN:
|
||||
m_stConfig.language = kLanguageRomanian;
|
||||
break;
|
||||
|
||||
case LANG_RUSSIAN:
|
||||
m_stConfig.language = kLanguageRussian;
|
||||
break;
|
||||
|
||||
case LANG_SPANISH:
|
||||
m_stConfig.language = kLanguageSpanish;
|
||||
break;
|
||||
|
||||
case LANG_TURKISH:
|
||||
m_stConfig.language = kLanguageTurkish;
|
||||
break;
|
||||
|
||||
default:
|
||||
m_stConfig.language = kLanguageEnglish;
|
||||
break;
|
||||
|
15
src/Config/Metin2Config.exe.manifest
Normal file
15
src/Config/Metin2Config.exe.manifest
Normal file
@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||
<dependency>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity
|
||||
type="win32"
|
||||
name="Microsoft.Windows.Common-Controls"
|
||||
version="6.0.0.0"
|
||||
processorArchitecture="*"
|
||||
publicKeyToken="6595b64144ccf1df"
|
||||
language="*"
|
||||
/>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
</assembly>
|
@ -17,3 +17,6 @@ IDR_MAINFRAME ICON "metin2.ico"
|
||||
#define METIN2_COMPONENT_TYPE VFT_APP
|
||||
|
||||
#include <version_info.rc>
|
||||
|
||||
// Visual Styles manifest
|
||||
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "Metin2Config.exe.manifest"
|
||||
|
@ -31,18 +31,18 @@
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Distribute|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
|
BIN
src/Config/ui.rc
BIN
src/Config/ui.rc
Binary file not shown.
@ -7,7 +7,6 @@
|
||||
|
||||
#include "EterPack.h"
|
||||
#include "Inline.h"
|
||||
#include "EterPackPolicy_CSHybridCrypt.h"
|
||||
|
||||
#pragma warning(push, 3)
|
||||
#include <cryptopp/cryptlib.h>
|
||||
@ -199,16 +198,12 @@ FILE * CEterPack::ms_PackLogFile = NULL;
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
CEterPack::CEterPack() : m_indexCount(0), m_indexData(NULL), m_FragmentSize(0), m_bEncrypted(false), m_bReadOnly(false), m_bDecrypedIV(false)
|
||||
{
|
||||
m_pCSHybridCryptPolicy = new EterPackPolicy_CSHybridCrypt;
|
||||
|
||||
}
|
||||
|
||||
CEterPack::~CEterPack()
|
||||
{
|
||||
Destroy();
|
||||
|
||||
delete m_pCSHybridCryptPolicy;
|
||||
m_pCSHybridCryptPolicy = NULL;
|
||||
}
|
||||
|
||||
void CEterPack::Destroy()
|
||||
@ -229,11 +224,6 @@ void CEterPack::Destroy()
|
||||
memset(m_indexFileName, 0, sizeof(m_indexFileName));
|
||||
}
|
||||
|
||||
const std::string& CEterPack::GetPathName()
|
||||
{
|
||||
return m_stPathName;
|
||||
}
|
||||
|
||||
bool CEterPack::Create(CEterFileDict& rkFileDict, const char * dbname, const char* pathName, bool bReadOnly, const BYTE* iv)
|
||||
{
|
||||
if (iv)
|
||||
@ -242,8 +232,6 @@ bool CEterPack::Create(CEterFileDict& rkFileDict, const char * dbname, const cha
|
||||
m_bDecrypedIV = false;
|
||||
}
|
||||
|
||||
m_stPathName = pathName;
|
||||
|
||||
strncpy(m_dbName, dbname, DBNAME_MAX_LEN);
|
||||
|
||||
strncpy(m_indexFileName, dbname, MAX_PATH);
|
||||
@ -572,40 +560,6 @@ bool CEterPack::Get(CMappedFile& out_file, const char * filename, LPCVOID * data
|
||||
out_file.BindLZObject(zObj);
|
||||
*data = zObj->GetBuffer();
|
||||
}
|
||||
else if (COMPRESSED_TYPE_PANAMA == index->compressed_type)
|
||||
{
|
||||
CLZObject * zObj = new CLZObject;
|
||||
__Decrypt_Panama(filename, static_cast<const BYTE*>(*data), index->data_size, *zObj);
|
||||
out_file.BindLZObjectWithBufferedSize(zObj);
|
||||
*data = zObj->GetBuffer();
|
||||
}
|
||||
else if (COMPRESSED_TYPE_HYBRIDCRYPT == index->compressed_type || COMPRESSED_TYPE_HYBRIDCRYPT_WITHSDB == index->compressed_type)
|
||||
{
|
||||
CLZObject * zObj = new CLZObject;
|
||||
|
||||
if( !m_pCSHybridCryptPolicy->DecryptMemory( std::string(filename), static_cast<const BYTE*>(*data), index->data_size, *zObj) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
out_file.BindLZObjectWithBufferedSize(zObj);
|
||||
if( COMPRESSED_TYPE_HYBRIDCRYPT_WITHSDB == index->compressed_type)
|
||||
{
|
||||
BYTE* pSDBData;
|
||||
int iSDBSize;
|
||||
|
||||
if( !m_pCSHybridCryptPolicy->GetSupplementaryDataBlock( std::string(filename), pSDBData, iSDBSize) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
*data = out_file.AppendDataBlock( pSDBData, iSDBSize );
|
||||
}
|
||||
else
|
||||
{
|
||||
*data = zObj->GetBuffer();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -678,41 +632,6 @@ bool CEterPack::Get2(CMappedFile& out_file, const char * filename, TEterPackInde
|
||||
out_file.BindLZObject(zObj);
|
||||
*data = zObj->GetBuffer();
|
||||
}
|
||||
else if (COMPRESSED_TYPE_PANAMA == index->compressed_type)
|
||||
{
|
||||
CLZObject * zObj = new CLZObject;
|
||||
__Decrypt_Panama(filename, static_cast<const BYTE*>(*data), index->data_size, *zObj);
|
||||
out_file.BindLZObjectWithBufferedSize(zObj);
|
||||
*data = zObj->GetBuffer();
|
||||
}
|
||||
else if (COMPRESSED_TYPE_HYBRIDCRYPT == index->compressed_type || COMPRESSED_TYPE_HYBRIDCRYPT_WITHSDB == index->compressed_type)
|
||||
{
|
||||
CLZObject * zObj = new CLZObject;
|
||||
|
||||
if( !m_pCSHybridCryptPolicy->DecryptMemory( std::string(filename), static_cast<const BYTE*>(*data), index->data_size, *zObj) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
out_file.BindLZObjectWithBufferedSize(zObj);
|
||||
|
||||
if( COMPRESSED_TYPE_HYBRIDCRYPT_WITHSDB == index->compressed_type)
|
||||
{
|
||||
BYTE* pSDBData;
|
||||
int iSDBSize;
|
||||
|
||||
if( !m_pCSHybridCryptPolicy->GetSupplementaryDataBlock( std::string(filename), pSDBData, iSDBSize) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
*data = out_file.AppendDataBlock( pSDBData, iSDBSize );
|
||||
}
|
||||
else
|
||||
{
|
||||
*data = zObj->GetBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -784,36 +703,6 @@ bool CEterPack::Extract()
|
||||
writeFile.Write(zObj.GetBuffer(), zObj.GetSize());
|
||||
zObj.Clear();
|
||||
}
|
||||
else if (COMPRESSED_TYPE_PANAMA == index->compressed_type)
|
||||
{
|
||||
__Decrypt_Panama(index->filename, (const BYTE *) data + index->data_position, index->data_size, zObj);
|
||||
writeFile.Write(zObj.GetBuffer(), zObj.GetBufferSize());
|
||||
zObj.Clear();
|
||||
}
|
||||
else if (COMPRESSED_TYPE_HYBRIDCRYPT == index->compressed_type || COMPRESSED_TYPE_HYBRIDCRYPT_WITHSDB == index->compressed_type)
|
||||
{
|
||||
if( !m_pCSHybridCryptPolicy->DecryptMemory( std::string(index->filename), (const BYTE *) data + index->data_position, index->data_size, zObj) )
|
||||
return false;
|
||||
|
||||
if( COMPRESSED_TYPE_HYBRIDCRYPT_WITHSDB == index->compressed_type)
|
||||
{
|
||||
dataMapFile.BindLZObjectWithBufferedSize(&zObj);
|
||||
|
||||
BYTE* pSDBData;
|
||||
int iSDBSize;
|
||||
|
||||
if( !m_pCSHybridCryptPolicy->GetSupplementaryDataBlock( std::string(index->filename), pSDBData, iSDBSize) )
|
||||
return false;
|
||||
|
||||
dataMapFile.AppendDataBlock( pSDBData, iSDBSize );
|
||||
writeFile.Write(dataMapFile.AppendDataBlock( pSDBData, iSDBSize ),dataMapFile.Size());
|
||||
}
|
||||
else
|
||||
{
|
||||
writeFile.Write(zObj.GetBuffer(), zObj.GetBufferSize());
|
||||
}
|
||||
zObj.Clear();
|
||||
}
|
||||
else if (COMPRESSED_TYPE_NONE == index->compressed_type)
|
||||
writeFile.Write((const char *) data + index->data_position, index->data_size);
|
||||
|
||||
@ -865,19 +754,6 @@ bool CEterPack::Put(const char * filename, const char * sourceFilename, BYTE pac
|
||||
BYTE* pMappedData = (BYTE*)data;
|
||||
int iMappedDataSize = mapFile.Size();
|
||||
|
||||
if( packType == COMPRESSED_TYPE_HYBRIDCRYPT || packType == COMPRESSED_TYPE_HYBRIDCRYPT_WITHSDB )
|
||||
{
|
||||
m_pCSHybridCryptPolicy->GenerateCryptKey( std::string(filename) );
|
||||
|
||||
if( packType == COMPRESSED_TYPE_HYBRIDCRYPT_WITHSDB )
|
||||
{
|
||||
if( !m_pCSHybridCryptPolicy->GenerateSupplementaryDataBlock( std::string(filename), strRelateMapName, (const BYTE*)data, mapFile.Size(), pMappedData, iMappedDataSize ))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Put(filename, pMappedData, iMappedDataSize, packType);
|
||||
}
|
||||
|
||||
@ -952,26 +828,6 @@ bool CEterPack::Put(const char * filename, LPCVOID data, long len, BYTE packType
|
||||
data = zObj.GetBuffer();
|
||||
len = zObj.GetSize();
|
||||
}
|
||||
else if (packType == COMPRESSED_TYPE_PANAMA)
|
||||
{
|
||||
if (!__Encrypt_Panama(filename, (const BYTE *) data, len, zObj))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
data = zObj.GetBuffer();
|
||||
len = zObj.GetBufferSize();
|
||||
}
|
||||
else if (packType == COMPRESSED_TYPE_HYBRIDCRYPT || packType == COMPRESSED_TYPE_HYBRIDCRYPT_WITHSDB )
|
||||
{
|
||||
if( !m_pCSHybridCryptPolicy->EncryptMemory( std::string(filename), (const BYTE *)data, len, zObj ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
data = zObj.GetBuffer();
|
||||
len = zObj.GetBufferSize();
|
||||
}
|
||||
|
||||
|
||||
#ifdef CHECKSUM_CHECK_MD5
|
||||
@ -1503,11 +1359,6 @@ bool CEterPack::__Decrypt_Panama(const char* filename, const BYTE* data, SIZE_T
|
||||
return true;
|
||||
}
|
||||
|
||||
EterPackPolicy_CSHybridCrypt* CEterPack::GetPackPolicy_HybridCrypt() const
|
||||
{
|
||||
return m_pCSHybridCryptPolicy;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////
|
||||
|
||||
|
@ -100,8 +100,6 @@ private:
|
||||
TDict m_dict;
|
||||
};
|
||||
|
||||
class EterPackPolicy_CSHybridCrypt;
|
||||
|
||||
class CEterPack
|
||||
{
|
||||
public:
|
||||
@ -112,7 +110,6 @@ class CEterPack
|
||||
bool Create(CEterFileDict& rkFileDict, const char * dbname, const char * pathName, bool bReadOnly = true, const BYTE* iv = NULL);
|
||||
bool DecryptIV(DWORD dwPanamaKey);
|
||||
|
||||
const std::string& GetPathName();
|
||||
const char * GetDBName();
|
||||
|
||||
bool Get(CMappedFile & mappedFile, const char * filename, LPCVOID * data);
|
||||
@ -138,8 +135,6 @@ class CEterPack
|
||||
|
||||
bool GetNames(std::vector<std::string>* retNames);
|
||||
|
||||
EterPackPolicy_CSHybridCrypt* GetPackPolicy_HybridCrypt() const;
|
||||
|
||||
private:
|
||||
bool __BuildIndex(CEterFileDict& rkFileDict, bool bOverwirte=false);
|
||||
|
||||
@ -180,10 +175,6 @@ class CEterPack
|
||||
TFreeIndexList m_FreeIndexList[FREE_INDEX_MAX_SIZE + 1]; // MAX 도 억세스 하므로 + 1 크기만큼 만든다.
|
||||
|
||||
std::string m_stDataFileName;
|
||||
std::string m_stPathName;
|
||||
|
||||
|
||||
EterPackPolicy_CSHybridCrypt* m_pCSHybridCryptPolicy;
|
||||
|
||||
private:
|
||||
void __CreateFileNameKey_Panama(const char * filename, BYTE * key, unsigned int keySize);
|
||||
|
@ -191,7 +191,8 @@
|
||||
<Optimization Condition="'$(Configuration)|$(Platform)'=='Distribute|Win32'">MaxSpeed</Optimization>
|
||||
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
|
||||
</ClCompile>
|
||||
<ClCompile Include="EterPackPolicy_CSHybridCrypt.cpp" />
|
||||
<ClCompile Include="FileProvider.cpp" />
|
||||
<ClCompile Include="Folder.cpp" />
|
||||
<ClCompile Include="md5.c" />
|
||||
<ClCompile Include="StdAfx.cpp">
|
||||
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
|
||||
@ -201,15 +202,18 @@
|
||||
<Optimization Condition="'$(Configuration)|$(Platform)'=='Distribute|Win32'">MaxSpeed</Optimization>
|
||||
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ZIP.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="EterPack.h" />
|
||||
<ClInclude Include="EterPackCursor.h" />
|
||||
<ClInclude Include="EterPackManager.h" />
|
||||
<ClInclude Include="EterPackPolicy_CSHybridCrypt.h" />
|
||||
<ClInclude Include="FileProvider.h" />
|
||||
<ClInclude Include="Folder.h" />
|
||||
<ClInclude Include="Inline.h" />
|
||||
<ClInclude Include="md5.h" />
|
||||
<ClInclude Include="StdAfx.h" />
|
||||
<ClInclude Include="ZIP.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
|
@ -9,6 +9,9 @@
|
||||
<UniqueIdentifier>{c156ef19-8b61-496c-a499-8bf66e9ca80d}</UniqueIdentifier>
|
||||
<Extensions>h;hpp;hxx;hm;inl</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="File Providers">
|
||||
<UniqueIdentifier>{6348898e-222d-4516-8d4e-e37f9e17d872}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="EterPack.cpp">
|
||||
@ -20,15 +23,21 @@
|
||||
<ClCompile Include="EterPackManager.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="EterPackPolicy_CSHybridCrypt.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="md5.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="StdAfx.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="FileProvider.cpp">
|
||||
<Filter>File Providers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Folder.cpp">
|
||||
<Filter>File Providers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ZIP.cpp">
|
||||
<Filter>File Providers</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="EterPack.h">
|
||||
@ -40,9 +49,6 @@
|
||||
<ClInclude Include="EterPackManager.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="EterPackPolicy_CSHybridCrypt.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Inline.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
@ -52,5 +58,14 @@
|
||||
<ClInclude Include="StdAfx.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Folder.h">
|
||||
<Filter>File Providers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ZIP.h">
|
||||
<Filter>File Providers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="FileProvider.h">
|
||||
<Filter>File Providers</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -4,38 +4,16 @@
|
||||
#include <assert.h>
|
||||
|
||||
#include "EterPackManager.h"
|
||||
#include "EterPackPolicy_CSHybridCrypt.h"
|
||||
|
||||
#include "../eterBase/Debug.h"
|
||||
#include "../eterBase/CRC32.h"
|
||||
|
||||
#include "Folder.h"
|
||||
#include "ZIP.h"
|
||||
|
||||
#define PATH_ABSOLUTE_YMIRWORK1 "d:/ymir work/"
|
||||
#define PATH_ABSOLUTE_YMIRWORK2 "d:\\ymir work\\"
|
||||
|
||||
CEterPack* CEterPackManager::FindPack(const char* c_szPathName)
|
||||
{
|
||||
std::string strFileName;
|
||||
|
||||
if (0 == ConvertFileName(c_szPathName, strFileName))
|
||||
{
|
||||
return &m_RootPack;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (TEterPackMap::iterator itor = m_DirPackMap.begin(); itor != m_DirPackMap.end(); ++itor)
|
||||
{
|
||||
const std::string & c_rstrName = itor->first;
|
||||
CEterPack * pEterPack = itor->second;
|
||||
|
||||
if (CompareName(c_rstrName.c_str(), c_rstrName.length(), strFileName.c_str()))
|
||||
{
|
||||
return pEterPack;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void CEterPackManager::SetCacheMode()
|
||||
{
|
||||
@ -49,25 +27,18 @@ void CEterPackManager::SetRelativePathMode()
|
||||
|
||||
|
||||
// StringPath std::string ¹öÀü
|
||||
int CEterPackManager::ConvertFileName(const char * c_szFileName, std::string & rstrFileName)
|
||||
std::string CEterPackManager::ConvertFileName(std::string fileName)
|
||||
{
|
||||
rstrFileName = c_szFileName;
|
||||
stl_lowers(rstrFileName);
|
||||
std::string convertedFileName = fileName;
|
||||
stl_lowers(convertedFileName);
|
||||
|
||||
int iCount = 0;
|
||||
|
||||
for (DWORD i = 0; i < rstrFileName.length(); ++i)
|
||||
for (DWORD i = 0; i < convertedFileName.length(); i++)
|
||||
{
|
||||
if (rstrFileName[i] == '/')
|
||||
++iCount;
|
||||
else if (rstrFileName[i] == '\\')
|
||||
{
|
||||
rstrFileName[i] = '/';
|
||||
++iCount;
|
||||
}
|
||||
if (convertedFileName[i] == '\\')
|
||||
convertedFileName[i] = '/';
|
||||
}
|
||||
|
||||
return iCount;
|
||||
return convertedFileName;
|
||||
}
|
||||
|
||||
bool CEterPackManager::CompareName(const char * c_szDirectoryName, DWORD /*dwLength*/, const char * c_szFileName)
|
||||
@ -92,11 +63,7 @@ void CEterPackManager::LoadStaticCache(const char* c_szFileName)
|
||||
if (!m_isCacheMode)
|
||||
return;
|
||||
|
||||
std::string strFileName;
|
||||
if (0 == ConvertFileName(c_szFileName, strFileName))
|
||||
{
|
||||
return;
|
||||
}
|
||||
std::string strFileName = ConvertFileName(c_szFileName);
|
||||
|
||||
DWORD dwFileNameHash = GetCRC32(strFileName.c_str(), strFileName.length());
|
||||
|
||||
@ -192,14 +159,8 @@ bool CEterPackManager::GetFromPack(CMappedFile & rMappedFile, const char * c_szF
|
||||
{
|
||||
FinderLock lock(m_csFinder);
|
||||
|
||||
static std::string strFileName;
|
||||
std::string strFileName = ConvertFileName(c_szFileName);
|
||||
|
||||
if (0 == ConvertFileName(c_szFileName, strFileName))
|
||||
{
|
||||
return m_RootPack.Get(rMappedFile, strFileName.c_str(), pData);
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD dwFileNameHash = GetCRC32(strFileName.c_str(), strFileName.length());
|
||||
SCache* pkCache = __FindCache(dwFileNameHash);
|
||||
|
||||
@ -209,41 +170,28 @@ bool CEterPackManager::GetFromPack(CMappedFile & rMappedFile, const char * c_szF
|
||||
return true;
|
||||
}
|
||||
|
||||
CEterFileDict::Item* pkFileItem = m_FileDict.GetItem(dwFileNameHash, strFileName.c_str());
|
||||
auto pkFileItem = m_FileDict.find(dwFileNameHash);
|
||||
|
||||
if (pkFileItem)
|
||||
if (pkFileItem->pkPack)
|
||||
{
|
||||
bool r = pkFileItem->pkPack->Get2(rMappedFile, strFileName.c_str(), pkFileItem->pkInfo, pData);
|
||||
//pkFileItem->pkPack->ClearDataMemoryMap();
|
||||
return r;
|
||||
}
|
||||
}
|
||||
if (pkFileItem == m_FileDict.end()) {
|
||||
#ifdef _DEBUG
|
||||
TraceError("CANNOT_FIND_PACK_FILE [%s]", strFileName.c_str());
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
auto data = std::make_shared<std::vector<char>>();
|
||||
bool r = pkFileItem->second->getFile(strFileName, data);
|
||||
|
||||
// Keep the file loaded by always forcing a reference in the smart pointer (temporary hack)
|
||||
keepDataReferencedArray.push_back(data);
|
||||
|
||||
rMappedFile.Link(data->size(), data->data());
|
||||
*pData = (LPCVOID *) data->data();
|
||||
return r;
|
||||
}
|
||||
|
||||
const time_t g_tCachingInterval = 10; // 10ÃÊ
|
||||
void CEterPackManager::ArrangeMemoryMappedPack()
|
||||
{
|
||||
//time_t curTime = time(NULL);
|
||||
//CEterFileDict::TDict dict = m_FileDict.GetDict();
|
||||
//for (CEterFileDict::TDict::iterator it = dict.begin(); it != dict.end(); ++it)
|
||||
//{
|
||||
// CEterFileDict::Item &rFileItem = it->second;
|
||||
// CEterPack* pkPack = rFileItem.pkPack;
|
||||
// if (pkPack)
|
||||
// {
|
||||
// if (curTime - pkPack->GetLastAccessTime() > g_tCachingInterval)
|
||||
// {
|
||||
// pkPack->ClearDataMemoryMap();
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
bool CEterPackManager::GetFromFile(CMappedFile & rMappedFile, const char * c_szFileName, LPCVOID * pData)
|
||||
{
|
||||
@ -273,24 +221,16 @@ bool CEterPackManager::GetFromFile(CMappedFile & rMappedFile, const char * c_szF
|
||||
|
||||
bool CEterPackManager::isExistInPack(const char * c_szFileName)
|
||||
{
|
||||
std::string strFileName;
|
||||
std::string strFileName = ConvertFileName(c_szFileName);
|
||||
|
||||
if (0 == ConvertFileName(c_szFileName, strFileName))
|
||||
{
|
||||
return m_RootPack.IsExist(strFileName.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD dwFileNameHash = GetCRC32(strFileName.c_str(), strFileName.length());
|
||||
CEterFileDict::Item* pkFileItem = m_FileDict.GetItem(dwFileNameHash, strFileName.c_str());
|
||||
auto pkFileItem = m_FileDict.find(dwFileNameHash);
|
||||
|
||||
if (pkFileItem)
|
||||
if (pkFileItem->pkPack)
|
||||
return pkFileItem->pkPack->IsExist(strFileName.c_str());
|
||||
}
|
||||
|
||||
// NOTE : 매치 되는 팩이 없다면 false - [levites]
|
||||
if (pkFileItem == m_FileDict.end())
|
||||
return false;
|
||||
|
||||
if (pkFileItem->second)
|
||||
return pkFileItem->second->fileExists(strFileName.c_str());
|
||||
}
|
||||
|
||||
bool CEterPackManager::isExist(const char * c_szFileName)
|
||||
@ -317,82 +257,38 @@ bool CEterPackManager::isExist(const char * c_szFileName)
|
||||
}
|
||||
|
||||
|
||||
void CEterPackManager::RegisterRootPack(const char * c_szName)
|
||||
{
|
||||
if (!m_RootPack.Create(m_FileDict, c_szName, ""))
|
||||
{
|
||||
TraceError("%s: Pack file does not exist", c_szName);
|
||||
}
|
||||
}
|
||||
|
||||
const char * CEterPackManager::GetRootPackFileName()
|
||||
{
|
||||
return m_RootPack.GetDBName();
|
||||
}
|
||||
|
||||
bool CEterPackManager::DecryptPackIV(DWORD dwPanamaKey)
|
||||
{
|
||||
TEterPackMap::iterator itor = m_PackMap.begin();
|
||||
while (itor != m_PackMap.end())
|
||||
{
|
||||
itor->second->DecryptIV(dwPanamaKey);
|
||||
itor++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CEterPackManager::RegisterPackWhenPackMaking(const char * c_szName, const char * c_szDirectory, CEterPack* pPack)
|
||||
{
|
||||
m_PackMap.insert(TEterPackMap::value_type(c_szName, pPack));
|
||||
m_PackList.push_front(pPack);
|
||||
|
||||
m_DirPackMap.insert(TEterPackMap::value_type(c_szDirectory, pPack));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CEterPackManager::RegisterPack(const char * c_szName, const char * c_szDirectory, const BYTE* c_pbIV)
|
||||
{
|
||||
CEterPack * pEterPack = NULL;
|
||||
{
|
||||
TEterPackMap::iterator itor = m_PackMap.find(c_szName);
|
||||
auto it = m_PackMap.find(c_szName);
|
||||
|
||||
if (m_PackMap.end() == itor)
|
||||
{
|
||||
if (it != m_PackMap.end())
|
||||
return true;
|
||||
|
||||
try {
|
||||
bool bReadOnly = true;
|
||||
|
||||
pEterPack = new CEterPack;
|
||||
if (pEterPack->Create(m_FileDict, c_szName, c_szDirectory, bReadOnly, c_pbIV))
|
||||
{
|
||||
m_PackMap.insert(TEterPackMap::value_type(c_szName, pEterPack));
|
||||
std::shared_ptr<FileProvider> pack;
|
||||
|
||||
// TODO: allow configurable containers
|
||||
|
||||
//pack = std::make_shared<Folder>(c_szName);
|
||||
pack = std::make_shared<ZIP>(std::string(c_szName) + ".zip");
|
||||
|
||||
auto packFiles = pack->listFiles();
|
||||
|
||||
for (auto const& fileName : packFiles) {
|
||||
DWORD dwFileNameHash = GetCRC32(fileName.c_str(), fileName.length());
|
||||
m_FileDict.insert({ dwFileNameHash, pack });
|
||||
}
|
||||
else
|
||||
|
||||
m_PackMap.insert(TEterPackMap::value_type(c_szName, pack));
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
Tracef("The eterpack doesn't exist [%s]\n", c_szName);
|
||||
#endif
|
||||
delete pEterPack;
|
||||
pEterPack = NULL;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pEterPack = itor->second;
|
||||
}
|
||||
}
|
||||
|
||||
if (c_szDirectory && c_szDirectory[0] != '*')
|
||||
{
|
||||
TEterPackMap::iterator itor = m_DirPackMap.find(c_szDirectory);
|
||||
if (m_DirPackMap.end() == itor)
|
||||
{
|
||||
m_PackList.push_front(pEterPack);
|
||||
m_DirPackMap.insert(TEterPackMap::value_type(c_szDirectory, pEterPack));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CEterPackManager::SetSearchMode(bool bPackFirst)
|
||||
@ -414,200 +310,5 @@ CEterPackManager::~CEterPackManager()
|
||||
{
|
||||
__ClearCacheMap();
|
||||
|
||||
TEterPackMap::iterator i = m_PackMap.begin();
|
||||
TEterPackMap::iterator e = m_PackMap.end();
|
||||
while (i != e)
|
||||
{
|
||||
delete i->second;
|
||||
i++;
|
||||
}
|
||||
DeleteCriticalSection(&m_csFinder);
|
||||
}
|
||||
|
||||
void CEterPackManager::RetrieveHybridCryptPackKeys(const BYTE *pStream)
|
||||
{
|
||||
////dump file format
|
||||
//total packagecnt (4byte)
|
||||
// for packagecntpackage
|
||||
// db name hash ( stl.h stringhash )
|
||||
// extension cnt( 4byte)
|
||||
// for extension cnt
|
||||
// ext hash ( stl.h stringhash )
|
||||
// key-16byte
|
||||
// iv-16byte
|
||||
int iMemOffset = 0;
|
||||
|
||||
int iPackageCnt;
|
||||
DWORD dwPackageNameHash;
|
||||
|
||||
memcpy( &iPackageCnt, pStream + iMemOffset, sizeof(int) );
|
||||
iMemOffset += sizeof(iPackageCnt);
|
||||
|
||||
for( int i = 0; i < iPackageCnt; ++i )
|
||||
{
|
||||
int iRecvedCryptKeySize = 0;
|
||||
memcpy( &iRecvedCryptKeySize, pStream + iMemOffset, sizeof(iRecvedCryptKeySize) );
|
||||
iRecvedCryptKeySize -= sizeof(dwPackageNameHash); // 서버에서 받은 key stream에는 filename hash가 포함되어 있으므로, hash 사이즈 만큼 배줌.
|
||||
iMemOffset += sizeof(iRecvedCryptKeySize);
|
||||
|
||||
memcpy( &dwPackageNameHash, pStream + iMemOffset, sizeof(dwPackageNameHash) );
|
||||
iMemOffset += sizeof(dwPackageNameHash);
|
||||
|
||||
TEterPackMap::const_iterator cit;
|
||||
for( cit = m_PackMap.begin(); cit != m_PackMap.end(); ++cit )
|
||||
{
|
||||
std::string noPathName = CFileNameHelper::NoPath(std::string(cit->first));
|
||||
if( dwPackageNameHash == stringhash().GetHash(noPathName) )
|
||||
{
|
||||
EterPackPolicy_CSHybridCrypt* pCryptPolicy = cit->second->GetPackPolicy_HybridCrypt();
|
||||
int iHavedCryptKeySize = pCryptPolicy->ReadCryptKeyInfoFromStream( pStream + iMemOffset );
|
||||
if (iRecvedCryptKeySize != iHavedCryptKeySize)
|
||||
{
|
||||
TraceError("CEterPackManager::RetrieveHybridCryptPackKeys cryptokey length of file(%s) is not matched. received(%d) != haved(%d)", noPathName.c_str(), iRecvedCryptKeySize, iHavedCryptKeySize);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
iMemOffset += iRecvedCryptKeySize;
|
||||
}
|
||||
}
|
||||
|
||||
void CEterPackManager::RetrieveHybridCryptPackSDB( const BYTE* pStream )
|
||||
{
|
||||
//cnt
|
||||
//for cnt
|
||||
//DWORD dwPackageIdentifier;
|
||||
//DWORD dwFileIdentifier;
|
||||
//std::vector<BYTE> vecSDBStream;
|
||||
int iReadOffset = 0;
|
||||
int iSDBInfoCount = 0;
|
||||
|
||||
memcpy( &iSDBInfoCount, pStream+iReadOffset, sizeof(int) );
|
||||
iReadOffset += sizeof(int);
|
||||
|
||||
for( int i = 0; i < iSDBInfoCount; ++i )
|
||||
{
|
||||
DWORD dwPackgeIdentifier;
|
||||
memcpy( &dwPackgeIdentifier, pStream+iReadOffset, sizeof(DWORD) );
|
||||
iReadOffset += sizeof(DWORD);
|
||||
|
||||
TEterPackMap::const_iterator cit;
|
||||
for( cit = m_PackMap.begin(); cit != m_PackMap.end(); ++cit )
|
||||
{
|
||||
std::string noPathName = CFileNameHelper::NoPath(std::string(cit->first));
|
||||
if( dwPackgeIdentifier == stringhash().GetHash(noPathName) )
|
||||
{
|
||||
EterPackPolicy_CSHybridCrypt* pCryptPolicy = cit->second->GetPackPolicy_HybridCrypt();
|
||||
iReadOffset += pCryptPolicy->ReadSupplementatyDataBlockFromStream( pStream+iReadOffset );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CEterPackManager::WriteHybridCryptPackInfo(const char* pFileName)
|
||||
{
|
||||
//NOTE : this file format contains a little bit of redundant data.
|
||||
//however it`s better for seperating cryptkey & supplementary data block.
|
||||
|
||||
//dump file format
|
||||
|
||||
//SDB data offset(4)
|
||||
|
||||
// about cryptkey
|
||||
//total packagecnt (4byte)
|
||||
// for packagecnt
|
||||
// db name hash 4byte( stl.h stringhash )
|
||||
// extension cnt( 4byte)
|
||||
// for extension cnt
|
||||
// ext hash ( stl.h stringhash )
|
||||
// key-16byte
|
||||
// iv-16byte
|
||||
|
||||
//about SDB data
|
||||
//total packagecnt (4byte)
|
||||
// for packagecnt
|
||||
// db name hash 4byte( stl.h stringhash ) +child node size(4byte)
|
||||
// sdb file cnt( 4byte )
|
||||
// for sdb file cnt
|
||||
// filename hash ( stl.h stringhash )
|
||||
// related map name size(4), relate map name
|
||||
// sdb block size( 1byte )
|
||||
// sdb blocks
|
||||
|
||||
CFileBase keyFile;
|
||||
|
||||
if( !keyFile.Create( pFileName, CFileBase::FILEMODE_WRITE) )
|
||||
{
|
||||
//TODO : write log
|
||||
return;
|
||||
}
|
||||
|
||||
int iKeyPackageCount = 0;
|
||||
|
||||
//write later ( SDB Offset & PackageCnt for Key )
|
||||
keyFile.SeekCur(2*sizeof(int));
|
||||
|
||||
TEterPackMap::const_iterator cit;
|
||||
for( cit = m_PackMap.begin(); cit != m_PackMap.end(); ++cit )
|
||||
{
|
||||
EterPackPolicy_CSHybridCrypt* pPolicy = cit->second->GetPackPolicy_HybridCrypt();
|
||||
if( !pPolicy || !pPolicy->IsContainingCryptKey() )
|
||||
continue;
|
||||
|
||||
iKeyPackageCount++;
|
||||
|
||||
std::string noPathName = CFileNameHelper::NoPath(std::string(cit->first));
|
||||
|
||||
DWORD dwPackNamehash = stringhash().GetHash(noPathName);
|
||||
|
||||
CMakePackLog::GetSingleton().Writef("CEterPackManager::WriteHybridCryptPackInfo PackName : %s, Hash : %x", noPathName.c_str(), dwPackNamehash);
|
||||
keyFile.Write( &dwPackNamehash, sizeof(DWORD) );
|
||||
|
||||
pPolicy->WriteCryptKeyToFile( keyFile );
|
||||
}
|
||||
|
||||
//Write SDB Data
|
||||
int iSDBDataOffset = keyFile.GetPosition();
|
||||
int iSDBPackageCnt = 0;
|
||||
|
||||
//Write SDB PackageCnt Later
|
||||
keyFile.SeekCur(sizeof(int));
|
||||
for( cit = m_PackMap.begin(); cit != m_PackMap.end(); ++cit )
|
||||
{
|
||||
EterPackPolicy_CSHybridCrypt* pPolicy = cit->second->GetPackPolicy_HybridCrypt();
|
||||
if( !pPolicy || !pPolicy->IsContainingSDBFile() )
|
||||
continue;
|
||||
|
||||
iSDBPackageCnt++;
|
||||
|
||||
std::string noPathName = CFileNameHelper::NoPath(std::string(cit->first));
|
||||
|
||||
DWORD dwPackNamehash = stringhash().GetHash(noPathName);
|
||||
keyFile.Write( &dwPackNamehash, sizeof(DWORD) );
|
||||
|
||||
int iSDBSizeWriteOffset = keyFile.GetPosition();
|
||||
keyFile.SeekCur(sizeof(int));
|
||||
|
||||
pPolicy->WriteSupplementaryDataBlockToFile( keyFile );
|
||||
int iSDBSizeAfterWrite = keyFile.GetPosition();
|
||||
|
||||
keyFile.Seek(iSDBSizeWriteOffset);
|
||||
|
||||
int iSDBSize = iSDBSizeAfterWrite-(iSDBSizeWriteOffset+4);
|
||||
keyFile.Write( &iSDBSize, sizeof(int) );
|
||||
|
||||
keyFile.Seek(iSDBSizeAfterWrite);
|
||||
}
|
||||
|
||||
//write sdb data start offset & package cnt
|
||||
keyFile.Seek(0);
|
||||
keyFile.Write( &iSDBDataOffset, sizeof(int));
|
||||
keyFile.Write( &iKeyPackageCount, sizeof(int));
|
||||
|
||||
keyFile.Seek(iSDBDataOffset);
|
||||
keyFile.Write( &iSDBPackageCnt, sizeof(int));
|
||||
|
||||
keyFile.Close();
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "../eterBase/Singleton.h"
|
||||
#include "../eterBase/Stl.h"
|
||||
|
||||
#include "FileProvider.h"
|
||||
#include "EterPack.h"
|
||||
|
||||
class CEterPackManager : public CSingleton<CEterPackManager>
|
||||
@ -22,8 +23,8 @@ class CEterPackManager : public CSingleton<CEterPackManager>
|
||||
SEARCH_PACK_FIRST
|
||||
};
|
||||
|
||||
typedef std::list<CEterPack*> TEterPackList;
|
||||
typedef std::unordered_map<std::string, CEterPack*, stringhash> TEterPackMap;
|
||||
typedef std::list<std::shared_ptr<FileProvider>> TEterPackList;
|
||||
typedef std::unordered_map<std::string, std::shared_ptr<FileProvider>, stringhash> TEterPackMap;
|
||||
|
||||
public:
|
||||
CEterPackManager();
|
||||
@ -46,29 +47,12 @@ class CEterPackManager : public CSingleton<CEterPackManager>
|
||||
bool isExistInPack(const char * c_szFileName);
|
||||
|
||||
bool RegisterPack(const char * c_szName, const char * c_szDirectory, const BYTE* c_pbIV = NULL);
|
||||
void RegisterRootPack(const char * c_szName);
|
||||
bool RegisterPackWhenPackMaking(const char * c_szName, const char * c_szDirectory, CEterPack* pPack);
|
||||
|
||||
|
||||
bool DecryptPackIV(DWORD key);
|
||||
|
||||
const char * GetRootPackFileName();
|
||||
|
||||
//for hybridcrypt
|
||||
void WriteHybridCryptPackInfo(const char* pFileName);
|
||||
|
||||
void RetrieveHybridCryptPackKeys( const BYTE* pStream );
|
||||
void RetrieveHybridCryptPackSDB( const BYTE* pStream );
|
||||
|
||||
// 메모리에 매핑된 팩들 가운데, 정리해야할 것들 정리.
|
||||
public:
|
||||
void ArrangeMemoryMappedPack();
|
||||
std::string ConvertFileName(std::string fileName);
|
||||
|
||||
protected:
|
||||
int ConvertFileName(const char * c_szFileName, std::string & rstrFileName); // StringPath std::string 버전
|
||||
bool CompareName(const char * c_szDirectoryName, DWORD iLength, const char * c_szFileName);
|
||||
|
||||
CEterPack* FindPack(const char* c_szPathName);
|
||||
std::shared_ptr<FileProvider> FindPack(const char* c_szPathName);
|
||||
|
||||
SCache* __FindCache(DWORD dwFileNameHash);
|
||||
void __ClearCacheMap();
|
||||
@ -78,13 +62,12 @@ class CEterPackManager : public CSingleton<CEterPackManager>
|
||||
bool m_isCacheMode;
|
||||
int m_iSearchMode;
|
||||
|
||||
CEterFileDict m_FileDict;
|
||||
CEterPack m_RootPack;
|
||||
TEterPackList m_PackList;
|
||||
std::unordered_map<DWORD, std::shared_ptr<FileProvider>> m_FileDict;
|
||||
TEterPackMap m_PackMap;
|
||||
TEterPackMap m_DirPackMap;
|
||||
|
||||
std::unordered_map<DWORD, SCache> m_kMap_dwNameKey_kCache;
|
||||
|
||||
std::vector<std::shared_ptr<std::vector<char>>> keepDataReferencedArray;
|
||||
|
||||
CRITICAL_SECTION m_csFinder;
|
||||
};
|
||||
|
1
src/EterPack/FileProvider.cpp
Normal file
1
src/EterPack/FileProvider.cpp
Normal file
@ -0,0 +1 @@
|
||||
#include "FileProvider.h"
|
16
src/EterPack/FileProvider.h
Normal file
16
src/EterPack/FileProvider.h
Normal file
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <memory>
|
||||
|
||||
|
||||
class FileProvider
|
||||
{
|
||||
public:
|
||||
virtual std::vector<std::string> listFiles() = 0;
|
||||
virtual bool fileExists(const std::string& fileName) = 0;
|
||||
virtual bool getFile(const std::string& fileName, std::shared_ptr<std::vector<char>>& fileData) = 0;
|
||||
};
|
||||
|
111
src/EterPack/Folder.cpp
Normal file
111
src/EterPack/Folder.cpp
Normal file
@ -0,0 +1,111 @@
|
||||
#include "Folder.h"
|
||||
#include "EterPackManager.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <Windows.h>
|
||||
#include "../eterBase/Stl.h"
|
||||
|
||||
void Folder::ListFiles(const std::string& directory, const std::string& relativePath = "") {
|
||||
WIN32_FIND_DATA findData;
|
||||
HANDLE hFind;
|
||||
|
||||
std::string searchPath = directory + "\\*";
|
||||
|
||||
// Start searching for files and directories
|
||||
hFind = FindFirstFile(searchPath.c_str(), &findData);
|
||||
if (hFind == INVALID_HANDLE_VALUE) {
|
||||
std::cerr << L"Failed to open directory: " << directory << L"\n";
|
||||
return;
|
||||
}
|
||||
|
||||
do {
|
||||
const std::string fileOrDirName = findData.cFileName;
|
||||
|
||||
// Skip the "." and ".." directories
|
||||
if (fileOrDirName == "." || fileOrDirName == "..") {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Construct the full and relative paths
|
||||
std::string fullPath = directory + "\\" + fileOrDirName;
|
||||
std::string currentRelativePath = relativePath + fileOrDirName;
|
||||
|
||||
// Check if the current entry is a directory
|
||||
if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
||||
// Recurse into the subdirectory
|
||||
ListFiles(fullPath, currentRelativePath + "\\");
|
||||
}
|
||||
else {
|
||||
if (currentRelativePath.rfind("ymir work\\", 0) == 0) {
|
||||
currentRelativePath = "d:\\" + currentRelativePath;
|
||||
}
|
||||
|
||||
currentRelativePath = CEterPackManager::Instance().ConvertFileName(currentRelativePath);
|
||||
|
||||
// Print the file's relative path
|
||||
this->fileList.insert(currentRelativePath);
|
||||
}
|
||||
} while (FindNextFile(hFind, &findData) != 0);
|
||||
|
||||
FindClose(hFind);
|
||||
}
|
||||
|
||||
|
||||
Folder::Folder(const std::string& folderPath)
|
||||
{
|
||||
this->folderPath = folderPath;
|
||||
ListFiles(folderPath);
|
||||
}
|
||||
|
||||
std::vector<std::string> Folder::listFiles()
|
||||
{
|
||||
std::vector<std::string> result;
|
||||
std::copy(fileList.begin(), fileList.end(), std::back_inserter(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Folder::fileExists(const std::string& fileName)
|
||||
{
|
||||
auto it = fileList.find(fileName);
|
||||
|
||||
if (it == fileList.end())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Folder::getFile(const std::string& fileName, std::shared_ptr<std::vector<char>>& fileData)
|
||||
{
|
||||
std::string realFileName = fileName;
|
||||
std::string ymirPrefix = "d:/";
|
||||
|
||||
if (fileName.find(ymirPrefix) == 0)
|
||||
realFileName = realFileName.substr(ymirPrefix.length());
|
||||
|
||||
realFileName = this->folderPath + "/" + realFileName;
|
||||
|
||||
// open the file:
|
||||
std::ifstream file(realFileName, std::ios::binary);
|
||||
|
||||
// Stop eating new lines in binary mode!!!
|
||||
file.unsetf(std::ios::skipws);
|
||||
|
||||
// get its size:
|
||||
std::streampos fileSize;
|
||||
|
||||
file.seekg(0, std::ios::end);
|
||||
fileSize = file.tellg();
|
||||
file.seekg(0, std::ios::beg);
|
||||
|
||||
// reserve capacity
|
||||
fileData->reserve(fileSize);
|
||||
|
||||
// read the data:
|
||||
fileData->insert(fileData->begin(),
|
||||
std::istream_iterator<BYTE>(file),
|
||||
std::istream_iterator<BYTE>());
|
||||
|
||||
return true;
|
||||
}
|
23
src/EterPack/Folder.h
Normal file
23
src/EterPack/Folder.h
Normal file
@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <set>
|
||||
|
||||
#include "FileProvider.h"
|
||||
|
||||
class Folder : public FileProvider
|
||||
{
|
||||
protected:
|
||||
std::string folderPath;
|
||||
std::set<std::string> fileList = {};
|
||||
|
||||
public:
|
||||
Folder(const std::string& folderPath);
|
||||
std::vector<std::string> listFiles();
|
||||
bool fileExists(const std::string& fileName);
|
||||
bool getFile(const std::string& fileName, std::shared_ptr<std::vector<char>>& fileData);
|
||||
|
||||
private:
|
||||
void ListFiles(const std::string& directory, const std::string& relativePath);
|
||||
};
|
||||
|
88
src/EterPack/ZIP.cpp
Normal file
88
src/EterPack/ZIP.cpp
Normal file
@ -0,0 +1,88 @@
|
||||
#include "ZIP.h"
|
||||
#include "EterPackManager.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <Windows.h>
|
||||
#include "../eterBase/Stl.h"
|
||||
|
||||
ZIP::ZIP(const std::string& archivePath)
|
||||
{
|
||||
int err;
|
||||
|
||||
if ((zipFile = zip_open(archivePath.c_str(), 0, &err)) == NULL) {
|
||||
zip_error_t error;
|
||||
zip_error_init_with_code(&error, err);
|
||||
fprintf(stderr, "Cannot open zip archive '%s': %s\n", archivePath.c_str(), zip_error_strerror(&error));
|
||||
zip_error_fini(&error);
|
||||
return;
|
||||
}
|
||||
|
||||
// Read the list of files in the archive
|
||||
zip_int64_t numEntries = zip_get_num_entries(zipFile, 0);
|
||||
for (int index = 0; index < numEntries; index++)
|
||||
{
|
||||
zip_stat_t fileData;
|
||||
zip_stat_index(zipFile, index, 0, &fileData);
|
||||
|
||||
std::string fileName(fileData.name);
|
||||
|
||||
if (fileData.size == 0) {
|
||||
// Folder
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fileName.rfind("ymir work/", 0) == 0) {
|
||||
fileName = "d:/" + fileName;
|
||||
}
|
||||
|
||||
fileName = CEterPackManager::Instance().ConvertFileName(fileName);
|
||||
|
||||
fileList.insert({ fileName, fileData.index });
|
||||
}
|
||||
}
|
||||
|
||||
ZIP::~ZIP()
|
||||
{
|
||||
zip_close(zipFile);
|
||||
zipFile = nullptr;
|
||||
}
|
||||
|
||||
std::vector<std::string> ZIP::listFiles()
|
||||
{
|
||||
std::vector<std::string> result;
|
||||
for (auto const& file : fileList)
|
||||
result.push_back(file.first);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool ZIP::fileExists(const std::string& fileName)
|
||||
{
|
||||
auto it = fileList.find(fileName);
|
||||
if (it == fileList.end())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool ZIP::getFile(const std::string& fileName, std::shared_ptr<std::vector<char>>& fileData)
|
||||
{
|
||||
auto it = fileList.find(fileName);
|
||||
if (it == fileList.end())
|
||||
return false;
|
||||
|
||||
auto file = zip_fopen_index(zipFile, it->second, 0);
|
||||
if (file == NULL)
|
||||
return false;
|
||||
|
||||
zip_stat_t fileInfo;
|
||||
zip_stat_index(zipFile, it->second, 0, &fileInfo);
|
||||
|
||||
fileData->resize(fileInfo.size);
|
||||
auto retval = zip_fread(file, fileData->data(), fileData->size());
|
||||
if (retval == -1)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
20
src/EterPack/ZIP.h
Normal file
20
src/EterPack/ZIP.h
Normal file
@ -0,0 +1,20 @@
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <zip.h>
|
||||
|
||||
#include "FileProvider.h"
|
||||
|
||||
class ZIP : public FileProvider
|
||||
{
|
||||
protected:
|
||||
zip_t* zipFile = nullptr;
|
||||
std::map<std::string, zip_uint64_t> fileList;
|
||||
|
||||
public:
|
||||
ZIP(const std::string& archivePath);
|
||||
~ZIP();
|
||||
|
||||
std::vector<std::string> listFiles();
|
||||
bool fileExists(const std::string& fileName);
|
||||
bool getFile(const std::string& fileName, std::shared_ptr<std::vector<char>>& fileData);
|
||||
};
|
@ -141,13 +141,6 @@ bool CAccountConnector::__HandshakeState_Process()
|
||||
if (!__AnalyzePacket(HEADER_GC_PING, sizeof(TPacketGCPing), &CAccountConnector::__AuthState_RecvPing))
|
||||
return false;
|
||||
|
||||
// TODO : 차후 서버와 동일하게 가변길이 data serialize & deserialize 작업해야 한다.
|
||||
if (!__AnalyzeVarSizePacket(HEADER_GC_HYBRIDCRYPT_KEYS, &CAccountConnector::__AuthState_RecvHybridCryptKeys))
|
||||
return false;
|
||||
|
||||
if (!__AnalyzeVarSizePacket(HEADER_GC_HYBRIDCRYPT_SDB, &CAccountConnector::__AuthState_RecvHybridCryptSDB))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -185,16 +178,6 @@ bool CAccountConnector::__AuthState_Process()
|
||||
if (!__AnalyzePacket(HEADER_GC_HANDSHAKE, sizeof(TPacketGCHandshake), &CAccountConnector::__AuthState_RecvHandshake))
|
||||
return false;
|
||||
|
||||
if (!__AnalyzePacket(HEADER_GC_PANAMA_PACK, sizeof(TPacketGCPanamaPack), &CAccountConnector::__AuthState_RecvPanamaPack))
|
||||
return false;
|
||||
|
||||
// TODO : 차후 서버와 동일하게 가변길이 data serialize & deserialize 작업해야 한다.
|
||||
if (!__AnalyzeVarSizePacket(HEADER_GC_HYBRIDCRYPT_KEYS, &CAccountConnector::__AuthState_RecvHybridCryptKeys))
|
||||
return false;
|
||||
|
||||
if (!__AnalyzeVarSizePacket(HEADER_GC_HYBRIDCRYPT_SDB, &CAccountConnector::__AuthState_RecvHybridCryptSDB))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -345,50 +328,6 @@ bool CAccountConnector::__AuthState_RecvHandshake()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CAccountConnector::__AuthState_RecvPanamaPack()
|
||||
{
|
||||
TPacketGCPanamaPack kPacket;
|
||||
|
||||
if (!Recv(sizeof(TPacketGCPanamaPack), &kPacket))
|
||||
return false;
|
||||
|
||||
CEterPackManager::instance().RegisterPack(kPacket.szPackName, "*", kPacket.abIV);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CAccountConnector::__AuthState_RecvHybridCryptKeys(int iTotalSize)
|
||||
{
|
||||
int iFixedHeaderSize = TPacketGCHybridCryptKeys::GetFixedHeaderSize();
|
||||
|
||||
TPacketGCHybridCryptKeys kPacket(iTotalSize-iFixedHeaderSize);
|
||||
|
||||
if (!Recv(iFixedHeaderSize, &kPacket))
|
||||
return false;
|
||||
|
||||
if (!Recv(kPacket.iKeyStreamLen, kPacket.m_pStream))
|
||||
return false;
|
||||
|
||||
CEterPackManager::Instance().RetrieveHybridCryptPackKeys( kPacket.m_pStream );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CAccountConnector::__AuthState_RecvHybridCryptSDB(int iTotalSize)
|
||||
{
|
||||
int iFixedHeaderSize = TPacketGCHybridSDB::GetFixedHeaderSize();
|
||||
|
||||
TPacketGCHybridSDB kPacket(iTotalSize-iFixedHeaderSize);
|
||||
|
||||
if (!Recv(iFixedHeaderSize, &kPacket))
|
||||
return false;
|
||||
|
||||
if (!Recv(kPacket.iSDBStreamLen, kPacket.m_pStream))
|
||||
return false;
|
||||
|
||||
CEterPackManager::Instance().RetrieveHybridCryptPackSDB( kPacket.m_pStream );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CAccountConnector::__AuthState_RecvPing()
|
||||
{
|
||||
TPacketGCPing kPacketPing;
|
||||
@ -424,7 +363,6 @@ bool CAccountConnector::__AuthState_RecvAuthSuccess()
|
||||
else
|
||||
{
|
||||
DWORD dwPanamaKey = kAuthSuccessPacket.dwLoginKey ^ g_adwEncryptKey[0] ^ g_adwEncryptKey[1] ^ g_adwEncryptKey[2] ^ g_adwEncryptKey[3];
|
||||
CEterPackManager::instance().DecryptPackIV(dwPanamaKey);
|
||||
|
||||
CPythonNetworkStream & rkNet = CPythonNetworkStream::Instance();
|
||||
rkNet.SetLoginKey(kAuthSuccessPacket.dwLoginKey);
|
||||
|
@ -59,9 +59,6 @@ class CAccountConnector : public CNetworkStream, public CSingleton<CAccountConne
|
||||
bool __AuthState_RecvChinaMatrixCard();
|
||||
bool __AuthState_RecvRunupMatrixQuiz();
|
||||
bool __AuthState_RecvNEWCIBNPasspodRequest();
|
||||
bool __AuthState_RecvPanamaPack();
|
||||
bool __AuthState_RecvHybridCryptKeys(int VarSize);
|
||||
bool __AuthState_RecvHybridCryptSDB(int VarSize);
|
||||
|
||||
bool __AnalyzePacket(UINT uHeader, UINT uPacketSize, bool (CAccountConnector::*pfnDispatchPacket)());
|
||||
// TODO: 지금 현재는 임시다. header뒤에 size 4byte가 무조건 온다는 가정임.
|
||||
|
@ -264,9 +264,6 @@ class CPythonNetworkStream : public CNetworkStream, public CSingleton<CPythonNet
|
||||
bool RecvHandshakePacket();
|
||||
bool RecvHandshakeOKPacket();
|
||||
|
||||
bool RecvHybridCryptKeyPacket();
|
||||
bool RecvHybridCryptSDBPacket();
|
||||
|
||||
// ETC
|
||||
DWORD GetMainActorVID();
|
||||
DWORD GetMainActorRace();
|
||||
|
@ -591,16 +591,6 @@ void CPythonNetworkStream::GamePhase()
|
||||
return;
|
||||
break;
|
||||
|
||||
case HEADER_GC_HYBRIDCRYPT_KEYS:
|
||||
RecvHybridCryptKeyPacket();
|
||||
return;
|
||||
break;
|
||||
|
||||
case HEADER_GC_HYBRIDCRYPT_SDB:
|
||||
RecvHybridCryptSDBPacket();
|
||||
return;
|
||||
break;
|
||||
|
||||
case HEADER_GC_HS_REQUEST:
|
||||
ret = RecvHSCheckRequest();
|
||||
break;
|
||||
|
@ -61,16 +61,6 @@ void CPythonNetworkStream::HandShakePhase()
|
||||
RecvPingPacket();
|
||||
return;
|
||||
break;
|
||||
|
||||
case HEADER_GC_HYBRIDCRYPT_KEYS:
|
||||
RecvHybridCryptKeyPacket();
|
||||
return;
|
||||
break;
|
||||
|
||||
case HEADER_GC_HYBRIDCRYPT_SDB:
|
||||
RecvHybridCryptSDBPacket();
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
RecvErrorPacket(header);
|
||||
@ -145,46 +135,6 @@ bool CPythonNetworkStream::RecvHandshakeOKPacket()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CPythonNetworkStream::RecvHybridCryptKeyPacket()
|
||||
{
|
||||
int iFixedHeaderSize = TPacketGCHybridCryptKeys::GetFixedHeaderSize();
|
||||
|
||||
TDynamicSizePacketHeader header;
|
||||
if( !Peek( sizeof(header), &header) )
|
||||
return false;
|
||||
|
||||
TPacketGCHybridCryptKeys kPacket(header.size-iFixedHeaderSize);
|
||||
|
||||
if (!Recv(iFixedHeaderSize, &kPacket))
|
||||
return false;
|
||||
|
||||
if (!Recv(kPacket.iKeyStreamLen, kPacket.m_pStream))
|
||||
return false;
|
||||
|
||||
CEterPackManager::Instance().RetrieveHybridCryptPackKeys( kPacket.m_pStream );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CPythonNetworkStream::RecvHybridCryptSDBPacket()
|
||||
{
|
||||
int iFixedHeaderSize = TPacketGCHybridSDB::GetFixedHeaderSize();
|
||||
|
||||
TDynamicSizePacketHeader header;
|
||||
if( !Peek( sizeof(header), &header) )
|
||||
return false;
|
||||
|
||||
TPacketGCHybridSDB kPacket(header.size-iFixedHeaderSize);
|
||||
|
||||
if (!Recv(iFixedHeaderSize, &kPacket))
|
||||
return false;
|
||||
|
||||
if (!Recv(kPacket.iSDBStreamLen, kPacket.m_pStream))
|
||||
return false;
|
||||
|
||||
CEterPackManager::Instance().RetrieveHybridCryptPackSDB( kPacket.m_pStream );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CPythonNetworkStream::RecvHSCheckRequest()
|
||||
{
|
||||
TPacketHSCheck packet;
|
||||
|
@ -146,17 +146,6 @@ void CPythonNetworkStream::LoadingPhase()
|
||||
return;
|
||||
break;
|
||||
|
||||
case HEADER_GC_HYBRIDCRYPT_KEYS:
|
||||
RecvHybridCryptKeyPacket();
|
||||
return;
|
||||
break;
|
||||
|
||||
case HEADER_GC_HYBRIDCRYPT_SDB:
|
||||
RecvHybridCryptSDBPacket();
|
||||
return;
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
GamePhase();
|
||||
return;
|
||||
|
@ -68,16 +68,6 @@ void CPythonNetworkStream::LoginPhase()
|
||||
return;
|
||||
break;
|
||||
|
||||
case HEADER_GC_HYBRIDCRYPT_KEYS:
|
||||
RecvHybridCryptKeyPacket();
|
||||
return;
|
||||
break;
|
||||
|
||||
case HEADER_GC_HYBRIDCRYPT_SDB:
|
||||
RecvHybridCryptSDBPacket();
|
||||
return;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (RecvDefaultPacket(header))
|
||||
return;
|
||||
|
@ -99,16 +99,6 @@ void CPythonNetworkStream::SelectPhase()
|
||||
return;
|
||||
break;
|
||||
|
||||
case HEADER_GC_HYBRIDCRYPT_KEYS:
|
||||
RecvHybridCryptKeyPacket();
|
||||
return;
|
||||
break;
|
||||
|
||||
case HEADER_GC_HYBRIDCRYPT_SDB:
|
||||
RecvHybridCryptSDBPacket();
|
||||
return;
|
||||
break;
|
||||
|
||||
case HEADER_GC_PLAYER_POINT_CHANGE:
|
||||
TPacketGCPointChange PointChange;
|
||||
Recv(sizeof(TPacketGCPointChange), &PointChange);
|
||||
|
@ -277,7 +277,7 @@ bool PackInitialize(const char * c_pszFolder)
|
||||
CEterPackManager::Instance().RegisterPack(strTexCachePackName.c_str(), c_rstFolder.c_str());
|
||||
}
|
||||
|
||||
CEterPackManager::Instance().RegisterRootPack((stFolder + std::string("root")).c_str());
|
||||
CEterPackManager::Instance().RegisterPack((stFolder + "root").c_str(), (stFolder + "root").c_str());
|
||||
NANOEND
|
||||
return true;
|
||||
}
|
||||
|
@ -15,6 +15,13 @@
|
||||
"name": "directxsdk",
|
||||
"version>=": "jun10"
|
||||
},
|
||||
{
|
||||
"name": "libzip",
|
||||
"features": [
|
||||
"zstd"
|
||||
],
|
||||
"version>=": "1.10.1"
|
||||
},
|
||||
{
|
||||
"name": "lzo",
|
||||
"version>=": "2.10#7"
|
||||
|
Loading…
Reference in New Issue
Block a user