From 6564e417f95d1a6bb019038f4d33423875366d2f Mon Sep 17 00:00:00 2001 From: Exynox Date: Mon, 16 Dec 2024 20:00:39 +0200 Subject: [PATCH] Removed Panama & HybridCrypt, added experimental Folder and Zip archive providers --- bin/.gitignore | 1 + bin/pack/pack.bat | 7 + src/EterPack/EterPack.cpp | 149 ------ src/EterPack/EterPack.h | 9 - src/EterPack/EterPack.vcxproj | 8 +- src/EterPack/EterPack.vcxproj.filters | 27 +- src/EterPack/EterPackManager.cpp | 431 +++--------------- src/EterPack/EterPackManager.h | 37 +- src/EterPack/FileProvider.cpp | 1 + src/EterPack/FileProvider.h | 16 + src/EterPack/Folder.cpp | 111 +++++ src/EterPack/Folder.h | 23 + src/EterPack/ZIP.cpp | 88 ++++ src/EterPack/ZIP.h | 20 + src/UserInterface/AccountConnector.cpp | 62 --- src/UserInterface/AccountConnector.h | 3 - src/UserInterface/PythonNetworkStream.h | 3 - .../PythonNetworkStreamPhaseGame.cpp | 10 - .../PythonNetworkStreamPhaseHandShake.cpp | 50 -- .../PythonNetworkStreamPhaseLoading.cpp | 11 - .../PythonNetworkStreamPhaseLogin.cpp | 10 - .../PythonNetworkStreamPhaseSelect.cpp | 10 - src/UserInterface/UserInterface.cpp | 2 +- src/vcpkg.json | 7 + 24 files changed, 378 insertions(+), 718 deletions(-) create mode 100644 bin/pack/pack.bat create mode 100644 src/EterPack/FileProvider.cpp create mode 100644 src/EterPack/FileProvider.h create mode 100644 src/EterPack/Folder.cpp create mode 100644 src/EterPack/Folder.h create mode 100644 src/EterPack/ZIP.cpp create mode 100644 src/EterPack/ZIP.h diff --git a/bin/.gitignore b/bin/.gitignore index d8377271..04bd1a8a 100644 --- a/bin/.gitignore +++ b/bin/.gitignore @@ -18,6 +18,7 @@ syserr.txt # Game files pack/*.eix pack/*.epk +pack/*.zip # Guild images mark/ diff --git a/bin/pack/pack.bat b/bin/pack/pack.bat new file mode 100644 index 00000000..07cefc8c --- /dev/null +++ b/bin/pack/pack.bat @@ -0,0 +1,7 @@ +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 -mx20 + "C:\Program Files\7-Zip\7z.exe" a "%%i.zip" ".\%%i\*" +) + diff --git a/src/EterPack/EterPack.cpp b/src/EterPack/EterPack.cpp index 68b9def9..8858ff04 100644 --- a/src/EterPack/EterPack.cpp +++ b/src/EterPack/EterPack.cpp @@ -7,7 +7,6 @@ #include "EterPack.h" #include "Inline.h" -#include "EterPackPolicy_CSHybridCrypt.h" #pragma warning(push, 3) #include @@ -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(*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(*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(*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(*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; -} - ///////////////////////// diff --git a/src/EterPack/EterPack.h b/src/EterPack/EterPack.h index 8ab20589..0c2d0999 100644 --- a/src/EterPack/EterPack.h +++ b/src/EterPack/EterPack.h @@ -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); @@ -137,8 +134,6 @@ class CEterPack DWORD DeleteUnreferencedData(); // ¸î°³°¡ »èÁ¦ µÇ¾ú´ÂÁö ¸®ÅÏ ÇÑ´Ù. bool GetNames(std::vector* 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); diff --git a/src/EterPack/EterPack.vcxproj b/src/EterPack/EterPack.vcxproj index 82245bfb..ca5a5d18 100644 --- a/src/EterPack/EterPack.vcxproj +++ b/src/EterPack/EterPack.vcxproj @@ -191,7 +191,8 @@ MaxSpeed MaxSpeed - + + Disabled @@ -201,15 +202,18 @@ MaxSpeed MaxSpeed + - + + + diff --git a/src/EterPack/EterPack.vcxproj.filters b/src/EterPack/EterPack.vcxproj.filters index 78338a16..b42976f8 100644 --- a/src/EterPack/EterPack.vcxproj.filters +++ b/src/EterPack/EterPack.vcxproj.filters @@ -9,6 +9,9 @@ {c156ef19-8b61-496c-a499-8bf66e9ca80d} h;hpp;hxx;hm;inl + + {6348898e-222d-4516-8d4e-e37f9e17d872} + @@ -20,15 +23,21 @@ Source Files - - Source Files - Source Files Source Files + + File Providers + + + File Providers + + + File Providers + @@ -40,9 +49,6 @@ Header Files - - Header Files - Header Files @@ -52,5 +58,14 @@ Header Files + + File Providers + + + File Providers + + + File Providers + \ No newline at end of file diff --git a/src/EterPack/EterPackManager.cpp b/src/EterPack/EterPackManager.cpp index 075eca8d..b853861b 100644 --- a/src/EterPack/EterPackManager.cpp +++ b/src/EterPack/EterPackManager.cpp @@ -4,38 +4,16 @@ #include #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,58 +159,39 @@ bool CEterPackManager::GetFromPack(CMappedFile & rMappedFile, const char * c_szF { FinderLock lock(m_csFinder); - static std::string strFileName; - - if (0 == ConvertFileName(c_szFileName, strFileName)) + std::string strFileName = ConvertFileName(c_szFileName); + + DWORD dwFileNameHash = GetCRC32(strFileName.c_str(), strFileName.length()); + SCache* pkCache = __FindCache(dwFileNameHash); + + if (pkCache) { - return m_RootPack.Get(rMappedFile, strFileName.c_str(), pData); + rMappedFile.Link(pkCache->m_dwBufSize, pkCache->m_abBufData); + return true; } - else - { - DWORD dwFileNameHash = GetCRC32(strFileName.c_str(), strFileName.length()); - SCache* pkCache = __FindCache(dwFileNameHash); - if (pkCache) - { - rMappedFile.Link(pkCache->m_dwBufSize, pkCache->m_abBufData); - return true; - } + auto pkFileItem = m_FileDict.find(dwFileNameHash); - CEterFileDict::Item* pkFileItem = m_FileDict.GetItem(dwFileNameHash, strFileName.c_str()); - - 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()); + TraceError("CANNOT_FIND_PACK_FILE [%s]", strFileName.c_str()); #endif - return false; + return false; + } + + auto data = std::make_shared>(); + 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()); + DWORD dwFileNameHash = GetCRC32(strFileName.c_str(), strFileName.length()); + auto pkFileItem = m_FileDict.find(dwFileNameHash); - if (pkFileItem) - if (pkFileItem->pkPack) - return pkFileItem->pkPack->IsExist(strFileName.c_str()); - } + if (pkFileItem == m_FileDict.end()) + return false; - // NOTE : ¸ÅÄ¡ µÇ´Â ÆÑÀÌ ¾ø´Ù¸é false - [levites] - 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) - { - bool bReadOnly = true; + if (it != m_PackMap.end()) + return 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)); - } - else - { -#ifdef _DEBUG - Tracef("The eterpack doesn't exist [%s]\n", c_szName); -#endif - delete pEterPack; - pEterPack = NULL; - return false; - } + try { + bool bReadOnly = true; + + std::shared_ptr pack; + + // TODO: allow configurable containers + + //pack = std::make_shared(c_szName); + pack = std::make_shared(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 - { - pEterPack = itor->second; - } + + m_PackMap.insert(TEterPackMap::value_type(c_szName, pack)); } - - if (c_szDirectory && c_szDirectory[0] != '*') + catch (...) { - 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; +#ifdef _DEBUG + Tracef("The eterpack doesn't exist [%s]\n", c_szName); +#endif + } } 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 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(); -} diff --git a/src/EterPack/EterPackManager.h b/src/EterPack/EterPackManager.h index b202876f..051f6626 100644 --- a/src/EterPack/EterPackManager.h +++ b/src/EterPack/EterPackManager.h @@ -5,6 +5,7 @@ #include "../eterBase/Singleton.h" #include "../eterBase/Stl.h" +#include "FileProvider.h" #include "EterPack.h" class CEterPackManager : public CSingleton @@ -22,8 +23,8 @@ class CEterPackManager : public CSingleton SEARCH_PACK_FIRST }; - typedef std::list TEterPackList; - typedef std::unordered_map TEterPackMap; + typedef std::list> TEterPackList; + typedef std::unordered_map, stringhash> TEterPackMap; public: CEterPackManager(); @@ -45,30 +46,13 @@ class CEterPackManager : public CSingleton bool isExist(const char * c_szFileName); 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(); + bool RegisterPack(const char * c_szName, const char * c_szDirectory, const BYTE* c_pbIV = NULL); + 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 FindPack(const char* c_szPathName); SCache* __FindCache(DWORD dwFileNameHash); void __ClearCacheMap(); @@ -78,13 +62,12 @@ class CEterPackManager : public CSingleton bool m_isCacheMode; int m_iSearchMode; - CEterFileDict m_FileDict; - CEterPack m_RootPack; - TEterPackList m_PackList; - TEterPackMap m_PackMap; - TEterPackMap m_DirPackMap; + std::unordered_map> m_FileDict; + TEterPackMap m_PackMap; std::unordered_map m_kMap_dwNameKey_kCache; + std::vector>> keepDataReferencedArray; + CRITICAL_SECTION m_csFinder; }; diff --git a/src/EterPack/FileProvider.cpp b/src/EterPack/FileProvider.cpp new file mode 100644 index 00000000..c815c329 --- /dev/null +++ b/src/EterPack/FileProvider.cpp @@ -0,0 +1 @@ +#include "FileProvider.h" diff --git a/src/EterPack/FileProvider.h b/src/EterPack/FileProvider.h new file mode 100644 index 00000000..9f8aef6f --- /dev/null +++ b/src/EterPack/FileProvider.h @@ -0,0 +1,16 @@ +#pragma once + +#include +#include +#include +#include + + +class FileProvider +{ +public: + virtual std::vector listFiles() = 0; + virtual bool fileExists(const std::string& fileName) = 0; + virtual bool getFile(const std::string& fileName, std::shared_ptr>& fileData) = 0; +}; + diff --git a/src/EterPack/Folder.cpp b/src/EterPack/Folder.cpp new file mode 100644 index 00000000..95694750 --- /dev/null +++ b/src/EterPack/Folder.cpp @@ -0,0 +1,111 @@ +#include "Folder.h" +#include "EterPackManager.h" + +#include +#include +#include +#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 Folder::listFiles() +{ + std::vector 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>& 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(file), + std::istream_iterator()); + + return true; +} \ No newline at end of file diff --git a/src/EterPack/Folder.h b/src/EterPack/Folder.h new file mode 100644 index 00000000..60655dd2 --- /dev/null +++ b/src/EterPack/Folder.h @@ -0,0 +1,23 @@ +#pragma once + +#include +#include + +#include "FileProvider.h" + +class Folder : public FileProvider +{ +protected: + std::string folderPath; + std::set fileList = {}; + +public: + Folder(const std::string& folderPath); + std::vector listFiles(); + bool fileExists(const std::string& fileName); + bool getFile(const std::string& fileName, std::shared_ptr>& fileData); + +private: + void ListFiles(const std::string& directory, const std::string& relativePath); +}; + diff --git a/src/EterPack/ZIP.cpp b/src/EterPack/ZIP.cpp new file mode 100644 index 00000000..28b835c8 --- /dev/null +++ b/src/EterPack/ZIP.cpp @@ -0,0 +1,88 @@ +#include "ZIP.h" +#include "EterPackManager.h" + +#include +#include +#include +#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 ZIP::listFiles() +{ + std::vector 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>& 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; +} \ No newline at end of file diff --git a/src/EterPack/ZIP.h b/src/EterPack/ZIP.h new file mode 100644 index 00000000..ffd58cdf --- /dev/null +++ b/src/EterPack/ZIP.h @@ -0,0 +1,20 @@ +#include +#include +#include + +#include "FileProvider.h" + +class ZIP : public FileProvider +{ +protected: + zip_t* zipFile = nullptr; + std::map fileList; + +public: + ZIP(const std::string& archivePath); + ~ZIP(); + + std::vector listFiles(); + bool fileExists(const std::string& fileName); + bool getFile(const std::string& fileName, std::shared_ptr>& fileData); +}; diff --git a/src/UserInterface/AccountConnector.cpp b/src/UserInterface/AccountConnector.cpp index 6badd1c3..7a14ff3e 100644 --- a/src/UserInterface/AccountConnector.cpp +++ b/src/UserInterface/AccountConnector.cpp @@ -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); diff --git a/src/UserInterface/AccountConnector.h b/src/UserInterface/AccountConnector.h index 89337226..7c988592 100644 --- a/src/UserInterface/AccountConnector.h +++ b/src/UserInterface/AccountConnector.h @@ -59,9 +59,6 @@ class CAccountConnector : public CNetworkStream, public CSingleton=": "jun10" }, + { + "name": "libzip", + "features": [ + "zstd" + ], + "version>=": "1.10.1" + }, { "name": "lzo", "version>=": "2.10#7"