DragonNest/Common/EtFileSystem/EtFileSystem.h
Cussrro 47f7895977 Revert "修复编码问题"
This reverts commit 9e69c01767.
2024-12-21 10:04:04 +08:00

215 lines
No EOL
6.4 KiB
C++

#pragma once
#include <list>
#include <vector>
#include <map>
#include "Singleton.h"
#include "CriticalSection.h"
#include "StringUtil.h"
#define PACKING_FILE_STRING "EyedentityGames Packing File 0.1"
#define PACKING_FILE_VERSION 11 //RLKT_pak was 11
#define PACKING_FILE_NOCHECKSUM_VERSION 10
#define PACKING_HEADER_RESERVED ( 1024 - sizeof( SPackingFileHeader ) )
#define DEFAULT_PACKING_FILE_SIZE 512 * 1024 * 1024
struct SPackingFileHeader
{
char szHeaderString[ 256 ];
int nVersion;
int nFileCount;
DWORD dwFileInfoOffset;
bool bRequireHeaderWrite;
char cPadding[ 3 ];
};
//----------------------------------------------------------------------------------------
struct SPackingFileInfo
{
char szFileName[ _MAX_FNAME ];
DWORD dwCompressSize;
DWORD dwOriginalSize;
DWORD dwAllocSize;
DWORD dwOffset;
DWORD dwSeedValue;
DWORD dwChecksum;
BOOL dwCrypted; //rlkt_CRYPT
char cReserved[ 32 ]; //rlkt_CRYPT was 36!
};
class CEtFileHandle
{
friend class CEtPackingFile;
friend class CEtFileSystem;
public:
CEtFileHandle();
virtual ~CEtFileHandle();
SPackingFileInfo *GetFileContext() { return &m_FileInfo; }
protected:
SPackingFileInfo m_FileInfo;
char *m_pData;
DWORD m_dwCurPos;
public:
DWORD Read(void* pBuff, DWORD nSize);
int Seek(int lOffset, int iOrigin);
bool ExportFile();
};
//------------------------------------------------------------------------------------
// 빈공간 주소 정보
class CPatchCallback
{
public:
enum
{
None = 0,
SrcPackOpenFailed, // 패치할 소스팩을 열지 못했다.
SrcPackFileSizeZero, // 소스팩의 파일이 없다.
SrcPackFileNotFound, // 소스팩에서 파일을 찾을수 없다.
DstPackAddFailed, // 대상팩에 파일 추가가 실패했다.
PatchFailed, // 패치도중 실패했다.
};
virtual void OnPatch(int nCurrentCnt, int nMaxCount, CFileNameString szFilename) { }
virtual void OnError(int nErrorCode, CFileNameString szMsg) { }
};
class CEtFileSystemLog
{
public:
virtual void Log(const CHAR* fmt, ...) { }
};
class CEtPackingFile
{
public:
CEtPackingFile();
virtual ~CEtPackingFile();
public:
const char *GetCurDir() { return m_strCurDir; }
void SetRootPath( const char *szPath );
DWORD CalcChecksum( int nFileIndex );
void GenerateChecksum();
void CloseFileSystem();
bool OpenFileSystem(const char* strPath, bool bReadOnly = false );
bool NewFileSystem(const char* strPath);
bool OptimizeFileSystem(const char* strPath);
DWORD GetFileSystemSize();
int GetFileCount() { return ( int )m_vecPackingFileInfo.size(); }
SPackingFileInfo *GetFileInfo( int nIndex ) { return ( SPackingFileInfo * )&m_vecPackingFileInfo[ nIndex ]; }
void GetFileInfoListCurDir( std::vector< SPackingFileInfo * > &vecFileInfo );
void GetDirListCurDir( std::vector< std::string > &vecDirList );
// 현재 패킹 파일에 패치 한다.
bool Patch(const char* strPatchPath, CPatchCallback* pCallpack, std::vector< CFileNameString > *pvecSkipList );
void SetLogger(CEtFileSystemLog* pLog) { m_pLog = pLog; }
public:
void CloseFile( CEtFileHandle* pFileHandle ) { SAFE_DELETE( pFileHandle ); }
CEtFileHandle *OpenFile(const char *strPath);
CEtFileHandle *OpenOnly( const char *strPath );
int FindFile( const char *pFileName );
void AddPackingMap( int nFileInfoIndex );
void RemovePackingMap( int nFileInfoIndex );
void GeneratePackingMap();
int FindSuitableEmptySpace( DWORD dwSize );
bool AddFile(const char* strPath);
bool AddFile(const char* strName, char *pData, DWORD nSize);
bool PatchFile( CEtFileHandle *pFileHandle );
bool PatchFileIndex( CEtFileHandle *pFileHandle, int nFileIndex, BOOL bSaveFileInfo = TRUE );
int ReservePatchFile( SPackingFileInfo *pFileInfo );
void WriteReserveFileInfo();
void RemoveFileInfo( int nFileIndex );
bool Remove(const char* strName);
bool Rename(const char* strName, const char* strRename);
public:
bool ChangeDir(const char* strPath);
void GetNameOnly(char* strDst, const char* strPath);
void GetPathOnly(char* strDst, const char* strPath);
private:
void SetCurDir(const char* pTok);
void GetSafeName(char* strDst, const char* strName);
private:
void _Encode(IN BYTE* pBuffer, int nBufSize, DWORD nCode);
void _Decode(IN BYTE* pBuffer, int nBufSize, DWORD nCode);
// 이 함수들은 Win32 API 가 길어서 타이핑 하기가 귀찮아서..
bool _Read(HANDLE hFile, IN void* pBuffer, DWORD ToReadSize);
bool _Write(HANDLE hFile, IN void* pBuffer, DWORD ToWriteSize);
LONGLONG _Seek(HANDLE hFile, LONGLONG nDistance, DWORD SeekType);
// string 관련
void _Tokenize( const std::string& str, std::vector<std::string>& tokens, const std::string& delimiters /* = " " */ );
void _AllReplace( std::string& str, std::string& szOld, std::string& szNew );
protected:
bool m_bIsReadOnly;
HANDLE m_hFile;
SPackingFileHeader m_PackingFileHeader;
char m_strCurDir[_MAX_PATH];
CFileNameString m_strPackingFileName;
CFileNameString m_szRootPath;
std::vector< SPackingFileInfo > m_vecPackingFileInfo;
std::map< INT64, int > m_mapPackingFileIndex;
CEtFileSystemLog* m_pLog;
};
class CEtFileSystem : public CSingleton<CEtFileSystem>
{
public:
CEtFileSystem( bool bDynamicPath = true );
virtual ~CEtFileSystem();
void AddPackingFolder(const char* szPackingFileName, const char* szExt = "pak" );
void AddPackingFolder(const WCHAR* szPackingFileName, const char* szExt = "pak" ); // 처음 루트폴더 처리를 위해 추가.
bool AddPackingFile(const char* szPackingFileName, const char *szRootPath);
void RemoveAll();
void FindFileListInFolder( const char *szFolderName, const char *szExt, std::vector<CFileNameString> &szVecResult);
CEtFileHandle *OpenFile( const char* strPath, bool bOpenOnly = false );
void CloseFile(CEtFileHandle* pFH);
CEtPackingFile *FindFile( const char *pFileName, int &nFindIndex );
CFileNameString GetFullName( const char *szFileName, bool *bFind = NULL );
CFileNameString GetFullPath( const char *szPath );
void FindFullPathList( const char *szPath, std::vector<CFileNameString> &szVecResult );
void AddResourcePath( const char *szPath, bool bIncludeSubDir = false );
void RemoveResourcePath( const char *szPath, bool bIncludeSubDir = false );
bool IsEmpty() {return m_PackingFileMap.empty() ;}
protected:
void CacheFileList( int nIndex, bool bAdd );
private:
std::map< CFileNameString, CEtPackingFile * > m_PackingFileMap;
struct OffsetStruct {
std::vector<CFileNameString> szVecFileList;
};
std::map< std::string, std::vector<std::string> > m_szMapCacheFileListInFolder;
CSyncLock m_SyncLock;
bool m_bDynamicPath;
};