1775 lines
No EOL
94 KiB
C++
1775 lines
No EOL
94 KiB
C++
#include "stdafx.h"
|
||
|
||
#include <zlib.h>
|
||
#include <utility>
|
||
#include <algorithm>
|
||
#include "EtFileSystem.h"
|
||
#include "SundriesFunc.h"
|
||
#include "StringUtil.h"
|
||
#ifdef _x86
|
||
#include <lz4.h> //lz4!!
|
||
#endif
|
||
#include "Crypt.h"
|
||
/*
|
||
#ifdef _DEBUG
|
||
#define new new(_NORMAL_BLOCK,__FILE__,__LINE__)
|
||
#endif
|
||
*/
|
||
|
||
bool g_bUseCompress= true;
|
||
|
||
using namespace std;
|
||
typedef list<CEtFileHandle> CValueFileHandleList;
|
||
typedef list<CEtFileHandle>::iterator CValueFileHandleList_It;
|
||
|
||
|
||
//-------------------------------------------------------------------------------------
|
||
const DWORD ET_SEED_CNT = 50;
|
||
const DWORD ET_ENCRYPT_SEED[ET_SEED_CNT] =
|
||
{
|
||
0x67184865, 0x722c3d4a, 0x6d165f69, 0xa126415a, 0x15122e0b,
|
||
0xf39f397e, 0x49443001, 0x54154d4d, 0x4d072d39, 0x26426664,
|
||
|
||
0x767a5d70, 0x1e3b1245, 0x6b631a6e, 0x324e7f7f, 0xd36b2622,
|
||
0x57560b30, 0x22237501, 0x5c6b584b, 0x3b5f1a3e, 0x7d5f793a,
|
||
|
||
0x4d5e314c, 0x1c132e49, 0x7e426636, 0x54152c60, 0x4059083e,
|
||
0x73127912, 0x49362658, 0x7013577b, 0x16184a69, 0x40133c68,
|
||
|
||
0x4823335d, 0x3c5c6057, 0x946a2f0f, 0x5d365442, 0x2c467579,
|
||
0x286c2f3c, 0x267d223a, 0x6119485e, 0x7140326b, 0x36497f03,
|
||
|
||
0x506b1844, 0xcf6b1954, 0x78285f0e, 0x5d112b24, 0x5f4c5a6a,
|
||
0x97181220, 0x2e1a6d67, 0x3a0e0146, 0x69455760, 0x25591937,
|
||
};
|
||
|
||
//-------------------------------------------------------------------------------------
|
||
|
||
CEtFileSystemLog g_DummyLog;
|
||
|
||
CEtFileHandle::CEtFileHandle()
|
||
{
|
||
memset( &m_FileInfo, 0, sizeof( SPackingFileInfo ) );
|
||
m_pData = NULL;
|
||
m_dwCurPos = 0;
|
||
}
|
||
|
||
CEtFileHandle::~CEtFileHandle()
|
||
{
|
||
SAFE_DELETEA( m_pData );
|
||
}
|
||
|
||
DWORD CEtFileHandle::Read(void* pBuff, DWORD nSize)
|
||
{
|
||
if(!m_pData)
|
||
return 0;
|
||
|
||
if(m_FileInfo.dwOriginalSize <= m_dwCurPos)
|
||
return 0;
|
||
|
||
if(m_FileInfo.dwOriginalSize < m_dwCurPos+nSize)
|
||
nSize = m_FileInfo.dwOriginalSize-m_dwCurPos;
|
||
|
||
memcpy(pBuff,m_pData+m_dwCurPos,nSize);
|
||
m_dwCurPos += nSize;
|
||
|
||
return nSize;
|
||
}
|
||
|
||
int CEtFileHandle::Seek(int lOffset, int iOrigin)
|
||
{
|
||
if(!m_pData)
|
||
return -1;
|
||
|
||
DWORD lPos;
|
||
switch(iOrigin)
|
||
{
|
||
case SEEK_SET: lPos = lOffset; break;
|
||
case SEEK_CUR: lPos = lOffset+m_dwCurPos; break;
|
||
case SEEK_END: lPos = m_FileInfo.dwOriginalSize+lOffset; break;
|
||
default: return -1;
|
||
}
|
||
|
||
if(lPos > m_FileInfo.dwOriginalSize)
|
||
return -1;
|
||
|
||
m_dwCurPos = lPos;
|
||
|
||
return m_dwCurPos;
|
||
}
|
||
|
||
|
||
bool CEtFileHandle::ExportFile()
|
||
{
|
||
HANDLE hFile = INVALID_HANDLE_VALUE;
|
||
|
||
char szName[ _MAX_PATH ];
|
||
|
||
_GetFullFileName( szName, _countof(szName), m_FileInfo.szFileName );
|
||
|
||
DWORD dwAttr = ::GetFileAttributes( _T( szName ) );
|
||
if( dwAttr & FILE_ATTRIBUTE_READONLY )
|
||
{
|
||
dwAttr &= ~FILE_ATTRIBUTE_READONLY;
|
||
::SetFileAttributes( _T( szName ), dwAttr );
|
||
}
|
||
|
||
hFile = CreateFile(szName, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
|
||
FILE_ATTRIBUTE_NORMAL,NULL );
|
||
|
||
if( hFile == INVALID_HANDLE_VALUE )
|
||
return false;
|
||
|
||
DWORD nWriteSize = 0;
|
||
|
||
if( WriteFile(hFile, m_pData, m_FileInfo.dwOriginalSize, &nWriteSize, NULL) == false )
|
||
{
|
||
CloseHandle(hFile);
|
||
return false;
|
||
}
|
||
|
||
CloseHandle(hFile);
|
||
return true;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
// CEtPackingFile
|
||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
CEtPackingFile::CEtPackingFile()
|
||
{
|
||
|
||
m_hFile = INVALID_HANDLE_VALUE;
|
||
ZeroMemory(m_strCurDir, sizeof(m_strCurDir));
|
||
memset( &m_PackingFileHeader, 0, sizeof( SPackingFileHeader ) );
|
||
m_PackingFileHeader.dwFileInfoOffset = PACKING_HEADER_RESERVED + sizeof( SPackingFileHeader );
|
||
m_bIsReadOnly = true;
|
||
m_pLog = &g_DummyLog;
|
||
|
||
CloseFileSystem();
|
||
}
|
||
|
||
CEtPackingFile::~CEtPackingFile()
|
||
{
|
||
CloseFileSystem();
|
||
}
|
||
|
||
|
||
LONGLONG CEtPackingFile::_Seek(HANDLE hFile, LONGLONG nDistance, DWORD SeekType)
|
||
{
|
||
if( hFile == INVALID_HANDLE_VALUE )
|
||
return -1;
|
||
|
||
LARGE_INTEGER li;
|
||
|
||
li.QuadPart = nDistance;
|
||
li.LowPart = SetFilePointer (hFile, li.LowPart, &li.HighPart, SeekType);
|
||
|
||
if(li.LowPart == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR)
|
||
{
|
||
li.QuadPart = -1;
|
||
}
|
||
|
||
return li.QuadPart;
|
||
}
|
||
|
||
|
||
bool CEtPackingFile::_Read(HANDLE hFile, IN void* pBuffer, DWORD ToReadSize)
|
||
{
|
||
if( hFile == INVALID_HANDLE_VALUE )
|
||
return false;
|
||
|
||
DWORD nReadSize = 0;
|
||
if( ReadFile(hFile, pBuffer, ToReadSize, &nReadSize, NULL ) == false )
|
||
return false;
|
||
|
||
if( ToReadSize > 0 && nReadSize < 1 )
|
||
return false;
|
||
|
||
return true;
|
||
}
|
||
|
||
|
||
bool CEtPackingFile::_Write(HANDLE hFile, IN void* pBuffer, DWORD ToWriteSize)
|
||
{
|
||
if( hFile == INVALID_HANDLE_VALUE )
|
||
return false;
|
||
|
||
DWORD nWriteSize = 0;
|
||
if( WriteFile(hFile, pBuffer, ToWriteSize, &nWriteSize, NULL ) == false )
|
||
return false;
|
||
|
||
return true;
|
||
}
|
||
|
||
void CEtPackingFile::SetCurDir(const char* pTok)
|
||
{
|
||
if( strcmp( pTok, "." ) == 0 )
|
||
return;
|
||
|
||
if( strcmp( pTok, ".." ) == 0 )
|
||
{
|
||
if(strlen(m_strCurDir) == 1 && m_strCurDir[0] == '\\')
|
||
return;
|
||
|
||
char strCurDir[_MAX_PATH] = { 0, };
|
||
strcpy_s(strCurDir,m_strCurDir);
|
||
|
||
int iLen = (int)strlen(strCurDir);
|
||
|
||
if(strCurDir[iLen-1] == '\\' ) strCurDir[iLen-1] = '\0';
|
||
|
||
for(int i=0;i<_MAX_PATH;i++)
|
||
{
|
||
char* cp = strCurDir+(_MAX_PATH-1-i);
|
||
|
||
if(*cp == '\\')
|
||
break;
|
||
|
||
*cp = '\0';
|
||
}
|
||
|
||
strcpy(m_strCurDir,strCurDir);
|
||
return;
|
||
}
|
||
|
||
strcat(m_strCurDir,pTok);
|
||
strcat(m_strCurDir,"\\");
|
||
}
|
||
|
||
void CEtPackingFile::GetSafeName(char* strDst,const char* strName)
|
||
{
|
||
ZeroMemory(strDst, _MAX_FNAME);
|
||
|
||
int iLen = (int)strlen(strName);
|
||
|
||
if(iLen >= _MAX_FNAME)
|
||
iLen = _MAX_FNAME-1;
|
||
|
||
strncpy(strDst,strName,iLen);
|
||
}
|
||
|
||
DWORD CEtPackingFile::CalcChecksum( int nFileIndex )
|
||
{
|
||
char *pBuffer;
|
||
int i, nSize;
|
||
DWORD dwChecksum = 0, *pdwBuffer;
|
||
|
||
// nSize를 4의 배수로 바꾼다..
|
||
nSize = m_vecPackingFileInfo[ nFileIndex ].dwCompressSize / 4;
|
||
if( m_vecPackingFileInfo[ nFileIndex ].dwCompressSize % 4 )
|
||
{
|
||
nSize++;
|
||
}
|
||
nSize *= 4;
|
||
pBuffer = new char[ nSize ];
|
||
memset( pBuffer, 0, nSize );
|
||
pdwBuffer = ( DWORD * )pBuffer;
|
||
for( i = 0; i < nSize / 4; i++ )
|
||
{
|
||
dwChecksum = pdwBuffer[ i ] ^ dwChecksum;
|
||
}
|
||
|
||
delete [] pBuffer;
|
||
return dwChecksum;
|
||
}
|
||
|
||
void CEtPackingFile::GenerateChecksum()
|
||
{
|
||
int i;
|
||
int nSize = ( int )m_vecPackingFileInfo.size();
|
||
|
||
for( i = 0; i < nSize; i++ )
|
||
{
|
||
if( m_vecPackingFileInfo[ i ].dwCompressSize == 0 )
|
||
{
|
||
continue;
|
||
}
|
||
m_vecPackingFileInfo[ i ].dwChecksum = CalcChecksum( i );
|
||
}
|
||
}
|
||
|
||
void CEtPackingFile::CloseFileSystem()
|
||
{
|
||
m_strCurDir[ 0 ] = '\0';
|
||
|
||
if( m_hFile != INVALID_HANDLE_VALUE )
|
||
{
|
||
if( ( !m_bIsReadOnly ) && ( m_PackingFileHeader.nFileCount != m_vecPackingFileInfo.size() ) )
|
||
{
|
||
if( m_PackingFileHeader.nVersion <= PACKING_FILE_NOCHECKSUM_VERSION )
|
||
{
|
||
GenerateChecksum();
|
||
m_PackingFileHeader.bRequireHeaderWrite = true;
|
||
m_PackingFileHeader.nVersion = PACKING_FILE_VERSION;
|
||
}
|
||
|
||
m_PackingFileHeader.nFileCount = ( int )m_vecPackingFileInfo.size();
|
||
|
||
_Seek( m_hFile, 0, SEEK_SET );
|
||
_Write( m_hFile, &m_PackingFileHeader, sizeof( SPackingFileHeader ) );
|
||
}
|
||
if( ( !m_bIsReadOnly ) && ( m_PackingFileHeader.bRequireHeaderWrite ) )
|
||
{
|
||
_Seek( m_hFile, m_PackingFileHeader.dwFileInfoOffset, SEEK_SET );
|
||
_Write( m_hFile, &m_vecPackingFileInfo[ 0 ], ( DWORD )m_vecPackingFileInfo.size() * sizeof( SPackingFileInfo ) );
|
||
|
||
|
||
|
||
m_PackingFileHeader.bRequireHeaderWrite = false;
|
||
_Seek( m_hFile, 0, SEEK_SET );
|
||
_Write( m_hFile, &m_PackingFileHeader, sizeof( SPackingFileHeader ) );
|
||
}
|
||
}
|
||
|
||
m_vecPackingFileInfo.clear();
|
||
m_mapPackingFileIndex.clear();
|
||
|
||
if( m_hFile != INVALID_HANDLE_VALUE )
|
||
{
|
||
CloseHandle(m_hFile);
|
||
m_hFile = INVALID_HANDLE_VALUE;
|
||
}
|
||
}
|
||
|
||
|
||
void
|
||
CEtPackingFile::_Encode(IN BYTE* pBuffer, int nBufSize, DWORD nCode)
|
||
{
|
||
return;
|
||
for ( int i = 0 ; i < nBufSize ; i+=8 )
|
||
{
|
||
pBuffer[i] ^= nCode;
|
||
}
|
||
}
|
||
|
||
void
|
||
CEtPackingFile::_Decode(IN BYTE* pBuffer, int nBufSize, DWORD nCode)
|
||
{
|
||
return;
|
||
for ( int i = 0 ; i < nBufSize ; i+=8 )
|
||
{
|
||
pBuffer[i] ^= nCode;
|
||
}
|
||
}
|
||
|
||
bool CEtPackingFile::OpenFileSystem(const char* strPath, bool bReadOnly /* = false */ )
|
||
{
|
||
CloseFileSystem();
|
||
|
||
m_bIsReadOnly = bReadOnly;
|
||
if( bReadOnly )
|
||
{
|
||
m_hFile = CreateFile(strPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, // 중복 Read 가능하게 수정.
|
||
FILE_ATTRIBUTE_NORMAL,NULL);
|
||
}
|
||
else
|
||
{
|
||
m_hFile = CreateFile(strPath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,NULL);
|
||
}
|
||
|
||
|
||
DWORD nError;
|
||
if( m_hFile == INVALID_HANDLE_VALUE )
|
||
{
|
||
nError = GetLastError();
|
||
|
||
return false;
|
||
}
|
||
|
||
// 파일 시스템 헤더를 로드한다.
|
||
_Read( m_hFile, &m_PackingFileHeader, sizeof( SPackingFileHeader ) );
|
||
/*if( ( m_PackingFileHeader.nVersion < PACKING_FILE_NOCHECKSUM_VERSION ) || ( m_PackingFileHeader.nVersion > PACKING_FILE_VERSION ) )
|
||
{
|
||
|
||
return false;
|
||
}*/
|
||
if (m_PackingFileHeader.nVersion < PACKING_FILE_VERSION) return false;
|
||
|
||
|
||
// 구버전 파일시스템에는 파일인포 옵셋이 안들어 있어서 파일끝에서 Seek으로 찾아야 한다.
|
||
if( m_PackingFileHeader.nVersion > PACKING_FILE_NOCHECKSUM_VERSION )
|
||
{
|
||
// bRequireHeaderWrite 값이 셋팅 돼 있으면 패치때 제대로 종료 안됐것임.. 잘못된 파일 시스템으로 인정..
|
||
if( m_PackingFileHeader.bRequireHeaderWrite == true )
|
||
{
|
||
//rlkt_pak
|
||
//MessageBoxA(NULL, FormatA(" Open File System nVersion >PACKING_FILE_NOCHECKSUM_VERSION").c_str(), "AddPackingFile", MB_OK);
|
||
|
||
return false;
|
||
}
|
||
_Seek( m_hFile, m_PackingFileHeader.dwFileInfoOffset, SEEK_SET );
|
||
}
|
||
else
|
||
{
|
||
m_PackingFileHeader.dwFileInfoOffset = ( DWORD )_Seek( m_hFile, -( LONGLONG )( m_PackingFileHeader.nFileCount * sizeof( SPackingFileInfo ) ), SEEK_END );
|
||
}
|
||
if( m_PackingFileHeader.nFileCount )
|
||
{
|
||
m_vecPackingFileInfo.resize( m_PackingFileHeader.nFileCount );
|
||
_Read( m_hFile, &m_vecPackingFileInfo[ 0 ], sizeof( SPackingFileInfo ) * m_PackingFileHeader.nFileCount );
|
||
|
||
int i;
|
||
for( i = 0; i < ( int )m_vecPackingFileInfo.size(); i++ )
|
||
{
|
||
if( m_vecPackingFileInfo[ i ].dwCompressSize > m_vecPackingFileInfo[ i ].dwAllocSize )
|
||
{
|
||
//rlkt_pak TEST ONLY!!
|
||
//m_vecPackingFileInfo[i].dwAllocSize = m_vecPackingFileInfo[i].dwCompressSize;
|
||
//MessageBoxA(NULL, FormatA("File ID: %d\nFile offset : %X read size: %X Size of Array : %d\n file count: %d\n CompressSize > DWAllocSize (%d - %d)\n\nFile:%s\nOrig size: %d\noffset : %X",i, m_PackingFileHeader.dwFileInfoOffset, sizeof(SPackingFileInfo)* m_PackingFileHeader.nFileCount, m_vecPackingFileInfo.size() , m_PackingFileHeader.nFileCount, m_vecPackingFileInfo[i].dwCompressSize, m_vecPackingFileInfo[i].dwAllocSize, m_vecPackingFileInfo[i].szFileName, m_vecPackingFileInfo[i].dwOriginalSize, m_vecPackingFileInfo[i].dwOffset).c_str(), "AddPackingFile", MB_OK);
|
||
|
||
return false;
|
||
}
|
||
}
|
||
}
|
||
|
||
GeneratePackingMap();
|
||
|
||
// 현재 디렉토리를 최상위 디렉토리로 바꾼다.
|
||
ChangeDir("\\");
|
||
|
||
m_strPackingFileName = strPath;
|
||
|
||
return true;
|
||
}
|
||
|
||
bool CEtPackingFile::NewFileSystem(const char* strPath)
|
||
{
|
||
CloseFileSystem();
|
||
|
||
m_hFile = CreateFile(strPath, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
|
||
FILE_ATTRIBUTE_NORMAL,NULL);
|
||
|
||
DWORD nError;
|
||
if( m_hFile == INVALID_HANDLE_VALUE )
|
||
{
|
||
nError = GetLastError();
|
||
return false;
|
||
}
|
||
|
||
// 헤더 정보 만들기
|
||
memset( &m_PackingFileHeader, 0, sizeof( SPackingFileHeader ) );
|
||
strcpy_s( m_PackingFileHeader.szHeaderString, 256, PACKING_FILE_STRING );
|
||
m_PackingFileHeader.nVersion = PACKING_FILE_VERSION;
|
||
m_PackingFileHeader.nFileCount = 0;
|
||
m_PackingFileHeader.dwFileInfoOffset = PACKING_HEADER_RESERVED + sizeof( SPackingFileHeader );
|
||
|
||
// 헤더 기록
|
||
if( _Write( m_hFile, &m_PackingFileHeader, sizeof( SPackingFileHeader ) ) == false )
|
||
{
|
||
return false;
|
||
}
|
||
char cReserved[ PACKING_HEADER_RESERVED ];
|
||
memset( cReserved, 0, PACKING_HEADER_RESERVED );
|
||
_Write( m_hFile, cReserved, PACKING_HEADER_RESERVED );
|
||
|
||
m_bIsReadOnly = false;
|
||
|
||
return true;
|
||
}
|
||
|
||
bool CEtPackingFile::OptimizeFileSystem(const char* strPath)
|
||
{
|
||
if( m_hFile == INVALID_HANDLE_VALUE)
|
||
return false;
|
||
|
||
CEtPackingFile FileSystem;
|
||
|
||
if( !FileSystem.NewFileSystem(strPath) )
|
||
return false;
|
||
|
||
int i;
|
||
int nFileCount = GetFileCount();
|
||
for( i = 0; i < nFileCount; i++ )
|
||
{
|
||
SPackingFileInfo *pPackingFileInfo = GetFileInfo( i );
|
||
if( pPackingFileInfo == NULL )
|
||
{
|
||
continue;
|
||
}
|
||
CEtFileHandle *pFileHandle = OpenFile( pPackingFileInfo->szFileName );
|
||
if( pFileHandle == NULL )
|
||
{
|
||
continue;
|
||
}
|
||
AddFile( pPackingFileInfo->szFileName, pFileHandle->m_pData, pFileHandle->m_FileInfo.dwCompressSize );
|
||
CloseFile( pFileHandle );
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
DWORD CEtPackingFile::GetFileSystemSize()
|
||
{
|
||
LARGE_INTEGER liSeekCur, liSeekEnd;
|
||
liSeekCur.QuadPart = _Seek( m_hFile, 0, SEEK_CUR );
|
||
liSeekEnd.QuadPart = _Seek( m_hFile, 0, SEEK_END );
|
||
_Seek( m_hFile, liSeekCur.QuadPart, SEEK_SET );
|
||
return liSeekEnd.LowPart;
|
||
}
|
||
|
||
void CEtPackingFile::SetRootPath( const char *szPath )
|
||
{
|
||
m_szRootPath = szPath;
|
||
ToLowerA( m_szRootPath );
|
||
}
|
||
|
||
|
||
CEtFileHandle *CEtPackingFile::OpenFile( const char *strPath )
|
||
{
|
||
if( m_hFile == INVALID_HANDLE_VALUE)
|
||
return NULL;
|
||
|
||
int nFindIndex = FindFile( strPath );
|
||
if( nFindIndex == -1 )
|
||
{
|
||
return NULL;
|
||
}
|
||
SPackingFileInfo *pFileInfo = GetFileInfo( nFindIndex );
|
||
if( pFileInfo == NULL )
|
||
{
|
||
return NULL;
|
||
}
|
||
|
||
_Seek( m_hFile, pFileInfo->dwOffset, SEEK_SET );
|
||
|
||
char *pCompressBuffer = new char[ pFileInfo->dwCompressSize ];
|
||
_Read( m_hFile, pCompressBuffer, pFileInfo->dwCompressSize );
|
||
|
||
DWORD dwSeed = ET_ENCRYPT_SEED[ pFileInfo->dwSeedValue ];
|
||
_Decode( ( BYTE * )pCompressBuffer, pFileInfo->dwCompressSize, dwSeed );
|
||
|
||
DWORD dwOriginalSize = pFileInfo->dwOriginalSize;
|
||
char *pUncompressBuffer = new char[ dwOriginalSize ];
|
||
|
||
if( g_bUseCompress )
|
||
{
|
||
|
||
//rlkt_CRYPT
|
||
if (pFileInfo->dwCrypted)
|
||
{
|
||
Crypt::GetInstance().Decrypt((BYTE*)pCompressBuffer, pFileInfo->dwCompressSize);
|
||
}
|
||
|
||
//rlkt_pak 2016 added custom !!!
|
||
DWORD dwOrigin = dwOriginalSize;
|
||
/*int result = LZ4_decompress_fast(pCompressBuffer, pUncompressBuffer, dwOriginalSize);
|
||
//MessageBoxA(NULL, FormatA("Decompress %s\ndwOriginalSize %d\ndwCompressSize %d\nResult %d",pFileInfo->szFileName,dwOriginalSize,pFileInfo->dwCompressSize,result).c_str(), "OK!", MB_OK);
|
||
|
||
if (result < 0)
|
||
{
|
||
delete[] pCompressBuffer;
|
||
delete[] pUncompressBuffer;
|
||
return NULL;
|
||
}*/
|
||
if( uncompress( ( BYTE * )pUncompressBuffer, ( uLongf * )&dwOriginalSize, ( BYTE * )pCompressBuffer, pFileInfo->dwCompressSize ) != Z_OK )
|
||
{
|
||
delete [] pCompressBuffer;
|
||
delete [] pUncompressBuffer;
|
||
return NULL;
|
||
}
|
||
ASSERT( dwOrigin == dwOriginalSize );
|
||
}
|
||
else
|
||
{
|
||
CopyMemory( pUncompressBuffer, pCompressBuffer, pFileInfo->dwCompressSize );
|
||
}
|
||
|
||
|
||
delete [] pCompressBuffer;
|
||
|
||
CEtFileHandle *pFileHandle = new CEtFileHandle;
|
||
|
||
pFileHandle->m_FileInfo = *pFileInfo;
|
||
pFileHandle->m_pData = pUncompressBuffer;
|
||
pFileHandle->m_dwCurPos = 0;
|
||
|
||
return pFileHandle;
|
||
}
|
||
|
||
CEtFileHandle *CEtPackingFile::OpenOnly( const char *strPath )
|
||
{
|
||
if( m_hFile == INVALID_HANDLE_VALUE)
|
||
return NULL;
|
||
|
||
int nFindIndex = FindFile( strPath );
|
||
if( nFindIndex == -1 )
|
||
{
|
||
return NULL;
|
||
}
|
||
SPackingFileInfo *pFileInfo = GetFileInfo( nFindIndex );
|
||
if( pFileInfo == NULL )
|
||
{
|
||
return NULL;
|
||
}
|
||
|
||
_Seek( m_hFile, pFileInfo->dwOffset, SEEK_SET );
|
||
|
||
char *pCompressBuffer = new char[ pFileInfo->dwCompressSize ];
|
||
_Read( m_hFile, pCompressBuffer, pFileInfo->dwCompressSize );
|
||
|
||
CEtFileHandle *pFileHandle = new CEtFileHandle;
|
||
|
||
pFileHandle->m_FileInfo = *pFileInfo;
|
||
pFileHandle->m_pData = pCompressBuffer;
|
||
pFileHandle->m_dwCurPos = 0;
|
||
|
||
return pFileHandle;
|
||
}
|
||
|
||
void CEtPackingFile::_Tokenize( const std::string& str, std::vector<std::string>& tokens, const std::string& delimiters /* = " " */ )
|
||
{
|
||
// 맨 첫 글자가 구분자인 경우 무시
|
||
std::string::size_type lastPos = str.find_first_not_of( delimiters, 0 );
|
||
// 구분자가 아닌 첫 글자를 찾는다
|
||
std::string::size_type pos = str.find_first_of( delimiters, lastPos );
|
||
|
||
while( std::string::npos != pos || std::string::npos != lastPos )
|
||
{
|
||
// token을 찾았으니 vector에 추가한다
|
||
tokens.push_back( str.substr( lastPos, pos - lastPos ) );
|
||
// 구분자를 뛰어넘는다. "not_of"에 주의하라
|
||
lastPos = str.find_first_not_of( delimiters, pos );
|
||
// 다음 구분자가 아닌 글자를 찾는다
|
||
pos = str.find_first_of( delimiters, lastPos );
|
||
}
|
||
}
|
||
|
||
|
||
// str 문자열 중에서 szOld 가 있으면 전부 szNew 로 변경한다.
|
||
void CEtPackingFile::_AllReplace( std::string& str, std::string& szOld, std::string& szNew )
|
||
{
|
||
while (true)
|
||
{
|
||
std::string::size_type npos = str.find(szOld);
|
||
if( npos < str.size() )
|
||
{
|
||
str.replace(npos, szOld.size(), szNew);
|
||
}
|
||
else
|
||
break;
|
||
}
|
||
}
|
||
|
||
int CEtPackingFile::FindFile( const char *pFileName )
|
||
{
|
||
char szName[ _MAX_PATH ];
|
||
_GetFullFileName( szName, _countof(szName), pFileName );
|
||
_strlwr( szName );
|
||
TrimString( szName );
|
||
|
||
INT64 ulHashCode = GetHashCode64( szName );
|
||
std::map< INT64, int >::iterator it = m_mapPackingFileIndex.find( ulHashCode );
|
||
while( it != m_mapPackingFileIndex.end() )
|
||
{
|
||
char szFindName[ _MAX_PATH ];
|
||
DWORD dwIndex = it->second;
|
||
if( m_vecPackingFileInfo[ dwIndex ].dwCompressSize != 0 )
|
||
{
|
||
_GetFullFileName( szFindName, _countof(szFindName), m_vecPackingFileInfo[ dwIndex ].szFileName );
|
||
if( _stricmp( szName, szFindName ) == 0 )
|
||
{
|
||
char szPath[ _MAX_PATH ];
|
||
_GetPath( szPath, _countof(szPath), pFileName );
|
||
_strlwr( szPath );
|
||
TrimString( szPath );
|
||
if( szPath[ 0 ] == 0 )
|
||
{
|
||
return dwIndex;
|
||
}
|
||
else
|
||
{
|
||
char szFindPath[ _MAX_PATH ];
|
||
_GetPath( szFindPath, _countof(szFindPath), m_vecPackingFileInfo[ dwIndex ].szFileName );
|
||
if( _stricmp( szPath, szFindPath ) == 0 )
|
||
{
|
||
return dwIndex;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
ulHashCode++;
|
||
it = m_mapPackingFileIndex.find( ulHashCode );
|
||
}
|
||
|
||
return -1;
|
||
}
|
||
|
||
void CEtPackingFile::AddPackingMap( int nFileInfoIndex )
|
||
{
|
||
if( ( nFileInfoIndex < 0 ) || ( nFileInfoIndex >= ( int )m_vecPackingFileInfo.size() ) )
|
||
{
|
||
return;
|
||
}
|
||
|
||
char szName[ _MAX_PATH ], szPath[ _MAX_PATH ];
|
||
_GetFullFileName( szName, _countof(szName), m_vecPackingFileInfo[ nFileInfoIndex ].szFileName );
|
||
_strlwr( szName );
|
||
TrimString( szName );
|
||
_GetPath( szPath, _countof(szPath), m_vecPackingFileInfo[ nFileInfoIndex ].szFileName );
|
||
|
||
INT64 ulHashCode = GetHashCode64( szName );
|
||
std::map< INT64, int >::iterator it = m_mapPackingFileIndex.find( ulHashCode );
|
||
while( it != m_mapPackingFileIndex.end() )
|
||
{
|
||
ulHashCode++;
|
||
it = m_mapPackingFileIndex.find( ulHashCode );
|
||
}
|
||
m_mapPackingFileIndex.insert( std::make_pair( ulHashCode, nFileInfoIndex ) );
|
||
}
|
||
|
||
void CEtPackingFile::RemovePackingMap( int nFileInfoIndex )
|
||
{
|
||
if( ( nFileInfoIndex < 0 ) || ( nFileInfoIndex >= ( int )m_vecPackingFileInfo.size() ) )
|
||
{
|
||
return;
|
||
}
|
||
|
||
char szName[ _MAX_PATH ];
|
||
_GetFullFileName( szName, _countof(szName), m_vecPackingFileInfo[ nFileInfoIndex ].szFileName );
|
||
_strlwr( szName );
|
||
TrimString( szName );
|
||
|
||
INT64 ulHashCode = GetHashCode64( szName );
|
||
std::map< INT64, int >::iterator it = m_mapPackingFileIndex.find( ulHashCode );
|
||
while( it != m_mapPackingFileIndex.end() )
|
||
{
|
||
if( it->second == nFileInfoIndex )
|
||
{
|
||
m_mapPackingFileIndex.erase( it );
|
||
break;
|
||
}
|
||
ulHashCode++;
|
||
it = m_mapPackingFileIndex.find( ulHashCode );
|
||
}
|
||
}
|
||
|
||
void CEtPackingFile::GeneratePackingMap()
|
||
{
|
||
int i;
|
||
|
||
m_mapPackingFileIndex.clear();
|
||
|
||
for( i = 0; i < ( int )m_vecPackingFileInfo.size(); i++ )
|
||
{
|
||
AddPackingMap( i );
|
||
}
|
||
}
|
||
|
||
int CEtPackingFile::FindSuitableEmptySpace( DWORD dwSize )
|
||
{
|
||
int i, nMinAllocIndex = -1;
|
||
DWORD dwMinAllocSize = ULONG_MAX;
|
||
|
||
for( i = 0; i < ( int )m_vecPackingFileInfo.size(); i++ )
|
||
{
|
||
if( m_vecPackingFileInfo[ i ].dwCompressSize != 0 )
|
||
{
|
||
continue;
|
||
}
|
||
if( m_vecPackingFileInfo[ i ].dwAllocSize < dwSize )
|
||
{
|
||
continue;
|
||
}
|
||
if( m_vecPackingFileInfo[ i ].dwAllocSize == dwSize )
|
||
{
|
||
return i;
|
||
}
|
||
if( m_vecPackingFileInfo[ i ].dwAllocSize * 0.8f > dwSize )
|
||
{
|
||
continue;
|
||
}
|
||
if( m_vecPackingFileInfo[ i ].dwAllocSize < dwMinAllocSize )
|
||
{
|
||
dwMinAllocSize = m_vecPackingFileInfo[ i ].dwAllocSize;
|
||
nMinAllocIndex = i;
|
||
}
|
||
}
|
||
|
||
return nMinAllocIndex;
|
||
}
|
||
|
||
bool CEtPackingFile::AddFile(const char* strPath)
|
||
{
|
||
if( m_hFile == INVALID_HANDLE_VALUE) return false;
|
||
|
||
// 추가할 실제 파일 로드
|
||
HANDLE hFile = INVALID_HANDLE_VALUE;
|
||
|
||
hFile = CreateFile( strPath, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,NULL );
|
||
|
||
if( hFile == INVALID_HANDLE_VALUE )
|
||
return false;
|
||
|
||
// 파일 크기를 알아내서.
|
||
DWORD dwFileSize = GetFileSize(hFile, NULL);
|
||
if( dwFileSize == INVALID_FILE_SIZE )
|
||
{
|
||
CloseHandle(hFile);
|
||
return true;
|
||
}
|
||
|
||
_Seek(hFile, 0, FILE_BEGIN);
|
||
char *pData = new char[dwFileSize];
|
||
_Read(hFile, pData, dwFileSize);
|
||
|
||
CloseHandle(hFile);
|
||
|
||
char strName[_MAX_FNAME] = { 0, };
|
||
char szFullName[ _MAX_PATH ];
|
||
|
||
GetNameOnly(strName,strPath);
|
||
strcpy_s( szFullName, _MAX_PATH, m_strCurDir );
|
||
strcat_s( szFullName, _MAX_PATH, strName );
|
||
if(!AddFile(szFullName,pData,dwFileSize))
|
||
{
|
||
delete[] pData;
|
||
return false;
|
||
}
|
||
|
||
delete[] pData;
|
||
|
||
return true;
|
||
}
|
||
|
||
bool CEtPackingFile::AddFile(const char* strName, char *pData, DWORD nSize)
|
||
{
|
||
if( m_hFile == INVALID_HANDLE_VALUE)
|
||
return false;
|
||
|
||
if(nSize <= 0)
|
||
return true;
|
||
|
||
DWORD lDstSize = nSize + 12 + max( 1, ( nSize + 12 ) / 1000 );
|
||
char *pDstData = new char[lDstSize];
|
||
|
||
if( g_bUseCompress )
|
||
{
|
||
// 압축한다.
|
||
if(compress2( ( BYTE * )pDstData, (uLongf*)&lDstSize, ( BYTE * )pData, nSize, Z_BEST_SPEED) != Z_OK)
|
||
{
|
||
delete[] pDstData;
|
||
return false;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
CopyMemory(pDstData, pData, nSize);
|
||
lDstSize = nSize;
|
||
}
|
||
|
||
DWORD nSeedKey = 0;
|
||
|
||
CopyMemory(&nSeedKey, pDstData, sizeof(DWORD));
|
||
|
||
// 적당한 시드 인덱스를 하나 골라서..
|
||
DWORD nSeedCnt = nSeedKey%ET_SEED_CNT;
|
||
DWORD nSeed = ET_ENCRYPT_SEED[nSeedCnt];
|
||
|
||
// 적당히.. XOR 로 변경하자 -_-
|
||
_Encode( ( BYTE * )pDstData, lDstSize, nSeed );
|
||
|
||
char szName[ _MAX_PATH ];
|
||
strcpy_s( szName, _MAX_PATH, strName );
|
||
_strlwr( szName );
|
||
TrimString( szName );
|
||
int nFindFileIndex = FindFile( szName );
|
||
if( nFindFileIndex != -1 )
|
||
{
|
||
Remove( szName );
|
||
}
|
||
|
||
int nFindEmptyIndex = FindSuitableEmptySpace( lDstSize );
|
||
SPackingFileInfo PackingFileInfo;
|
||
if( nFindEmptyIndex == -1 )
|
||
{
|
||
memset( &PackingFileInfo, 0, sizeof( SPackingFileInfo ) );
|
||
strcpy_s( PackingFileInfo.szFileName, _MAX_FNAME, szName );
|
||
PackingFileInfo.dwCompressSize = lDstSize;
|
||
PackingFileInfo.dwOriginalSize = nSize;
|
||
PackingFileInfo.dwAllocSize = lDstSize;
|
||
PackingFileInfo.dwOffset = m_PackingFileHeader.dwFileInfoOffset;
|
||
PackingFileInfo.dwSeedValue = nSeedCnt;
|
||
m_vecPackingFileInfo.push_back( PackingFileInfo );
|
||
nFindEmptyIndex = ( int )m_vecPackingFileInfo.size() - 1;
|
||
|
||
_Seek( m_hFile, m_vecPackingFileInfo[ nFindEmptyIndex ].dwOffset, SEEK_SET );
|
||
_Write( m_hFile, pDstData,lDstSize );
|
||
// 파일 헤더 쓰는데 시간 많이 걸려서 표시만 해두고 CloseFileSystem()에서 헤더 한꺼번에 Write한다
|
||
m_PackingFileHeader.bRequireHeaderWrite = true;
|
||
m_PackingFileHeader.dwFileInfoOffset = ( DWORD )_Seek( m_hFile, 0, SEEK_CUR );
|
||
}
|
||
else
|
||
{
|
||
PackingFileInfo = m_vecPackingFileInfo[ nFindEmptyIndex ];
|
||
strcpy_s( PackingFileInfo.szFileName, _MAX_FNAME, szName );
|
||
PackingFileInfo.dwCompressSize = lDstSize;
|
||
PackingFileInfo.dwOriginalSize = nSize;
|
||
PackingFileInfo.dwSeedValue = nSeedCnt;
|
||
m_vecPackingFileInfo[ nFindEmptyIndex ] = PackingFileInfo;
|
||
|
||
_Seek( m_hFile, m_vecPackingFileInfo[ nFindEmptyIndex ].dwOffset, SEEK_SET );
|
||
_Write( m_hFile, pDstData,lDstSize );
|
||
|
||
LONGLONG nFindFileOffset = m_PackingFileHeader.dwFileInfoOffset + ( sizeof( SPackingFileInfo ) * nFindEmptyIndex );
|
||
_Seek( m_hFile, nFindFileOffset, SEEK_SET );
|
||
_Write( m_hFile, &m_vecPackingFileInfo[ nFindEmptyIndex ], sizeof( SPackingFileInfo ) );
|
||
}
|
||
|
||
m_PackingFileHeader.nFileCount = ( int )m_vecPackingFileInfo.size();
|
||
|
||
|
||
|
||
_Seek( m_hFile, 0, SEEK_SET );
|
||
_Write( m_hFile, &m_PackingFileHeader, sizeof( SPackingFileHeader ) );
|
||
|
||
delete [] pDstData;
|
||
|
||
AddPackingMap( nFindEmptyIndex );
|
||
CalcChecksum( nFindEmptyIndex );
|
||
|
||
return true;
|
||
}
|
||
|
||
void CEtPackingFile::WriteReserveFileInfo()
|
||
{
|
||
if( ( !m_bIsReadOnly ) && ( m_PackingFileHeader.bRequireHeaderWrite ) )
|
||
{
|
||
|
||
_Seek( m_hFile, m_PackingFileHeader.dwFileInfoOffset, SEEK_SET );
|
||
_Write( m_hFile, &m_vecPackingFileInfo[ 0 ], ( DWORD )m_vecPackingFileInfo.size() * sizeof( SPackingFileInfo ) );
|
||
|
||
|
||
|
||
m_PackingFileHeader.bRequireHeaderWrite = false;
|
||
_Seek( m_hFile, 0, SEEK_SET );
|
||
_Write( m_hFile, &m_PackingFileHeader, sizeof( SPackingFileHeader ) );
|
||
|
||
m_PackingFileHeader.bRequireHeaderWrite = false;
|
||
}
|
||
}
|
||
|
||
void CEtPackingFile::RemoveFileInfo( int nFileIndex )
|
||
{
|
||
if( nFileIndex < 0 || nFileIndex >= static_cast<int>(m_vecPackingFileInfo.size()) )
|
||
return;
|
||
|
||
m_vecPackingFileInfo[ nFileIndex ].dwCompressSize = 0;
|
||
m_vecPackingFileInfo[ nFileIndex ].dwOriginalSize = 0;
|
||
|
||
LONGLONG nFindFileOffset;
|
||
nFindFileOffset = m_PackingFileHeader.dwFileInfoOffset + ( sizeof( SPackingFileInfo ) * nFileIndex );
|
||
_Seek( m_hFile, nFindFileOffset, SEEK_SET );
|
||
_Write( m_hFile, &m_vecPackingFileInfo[ nFileIndex ], sizeof( SPackingFileInfo ) );
|
||
}
|
||
|
||
int CEtPackingFile::ReservePatchFile( SPackingFileInfo *pFileInfo )
|
||
{
|
||
if( m_hFile == INVALID_HANDLE_VALUE)
|
||
return -1;
|
||
|
||
if( pFileInfo->dwOriginalSize <= 0 )
|
||
return -1;
|
||
|
||
SPackingFileInfo PackingFileInfo;
|
||
PackingFileInfo = *pFileInfo;
|
||
PackingFileInfo.dwAllocSize = pFileInfo->dwCompressSize;
|
||
PackingFileInfo.dwOffset = m_PackingFileHeader.dwFileInfoOffset;
|
||
m_vecPackingFileInfo.push_back( PackingFileInfo );
|
||
|
||
// 예약만 걸고 헤더 Write는 예약이 다 끝난 후 패치 전 실행
|
||
m_PackingFileHeader.bRequireHeaderWrite = true;
|
||
m_PackingFileHeader.dwFileInfoOffset += PackingFileInfo.dwCompressSize;
|
||
|
||
|
||
return static_cast<int>( m_vecPackingFileInfo.size() - 1 );
|
||
}
|
||
|
||
bool CEtPackingFile::PatchFileIndex( CEtFileHandle *pFileHandle, int nFileIndex, BOOL bSaveFileInfo )
|
||
{
|
||
if( m_hFile == INVALID_HANDLE_VALUE || nFileIndex < 0 || nFileIndex >= static_cast<int>( m_vecPackingFileInfo.size() ) )
|
||
return false;
|
||
|
||
if( pFileHandle->m_FileInfo.dwOriginalSize <= 0 )
|
||
return true;
|
||
|
||
if( pFileHandle->GetFileContext()->dwCompressSize > m_vecPackingFileInfo[ nFileIndex ].dwAllocSize )
|
||
return false;
|
||
|
||
if( bSaveFileInfo )
|
||
{
|
||
char szName[ _MAX_PATH ];
|
||
strcpy_s( szName, _MAX_PATH, pFileHandle->m_FileInfo.szFileName );
|
||
_strlwr( szName );
|
||
TrimString( szName );
|
||
|
||
SPackingFileInfo PackingFileInfo;
|
||
PackingFileInfo = m_vecPackingFileInfo[ nFileIndex ];
|
||
strcpy_s( PackingFileInfo.szFileName, _MAX_FNAME, szName );
|
||
PackingFileInfo.dwCompressSize = pFileHandle->m_FileInfo.dwCompressSize;
|
||
PackingFileInfo.dwOriginalSize = pFileHandle->m_FileInfo.dwOriginalSize;
|
||
PackingFileInfo.dwSeedValue = pFileHandle->m_FileInfo.dwSeedValue;
|
||
m_vecPackingFileInfo[ nFileIndex ] = PackingFileInfo;
|
||
}
|
||
|
||
// File Write
|
||
_Seek( m_hFile, m_vecPackingFileInfo[ nFileIndex ].dwOffset, SEEK_SET );
|
||
_Write( m_hFile, pFileHandle->m_pData, pFileHandle->m_FileInfo.dwCompressSize );
|
||
|
||
// FileInfo Write
|
||
LONGLONG nFindFileOffset;
|
||
nFindFileOffset = m_PackingFileHeader.dwFileInfoOffset + ( sizeof( SPackingFileInfo ) * nFileIndex );
|
||
_Seek( m_hFile, nFindFileOffset, SEEK_SET );
|
||
_Write( m_hFile, &m_vecPackingFileInfo[ nFileIndex ], sizeof( SPackingFileInfo ) );
|
||
|
||
return true;
|
||
}
|
||
|
||
bool CEtPackingFile::PatchFile( CEtFileHandle *pFileHandle )
|
||
{
|
||
if( m_hFile == INVALID_HANDLE_VALUE)
|
||
return false;
|
||
|
||
if( pFileHandle->m_FileInfo.dwOriginalSize <= 0)
|
||
return true;
|
||
|
||
char szName[ _MAX_PATH ];
|
||
strcpy_s( szName, _MAX_PATH, pFileHandle->m_FileInfo.szFileName );
|
||
_strlwr( szName );
|
||
TrimString( szName );
|
||
int nFindFileIndex = FindFile( szName );
|
||
if( nFindFileIndex != -1 )
|
||
{
|
||
m_vecPackingFileInfo[ nFindFileIndex ].dwCompressSize = 0;
|
||
m_vecPackingFileInfo[ nFindFileIndex ].dwOriginalSize = 0;
|
||
}
|
||
|
||
int nFindEmptyIndex = FindSuitableEmptySpace( pFileHandle->m_FileInfo.dwCompressSize );
|
||
SPackingFileInfo PackingFileInfo;
|
||
if( nFindEmptyIndex == -1 )
|
||
{
|
||
PackingFileInfo = pFileHandle->m_FileInfo;
|
||
PackingFileInfo.dwAllocSize = pFileHandle->m_FileInfo.dwCompressSize;
|
||
PackingFileInfo.dwOffset = m_PackingFileHeader.dwFileInfoOffset;
|
||
m_vecPackingFileInfo.push_back( PackingFileInfo );
|
||
nFindEmptyIndex = ( int )m_vecPackingFileInfo.size() - 1;
|
||
|
||
_Seek( m_hFile, m_vecPackingFileInfo[ nFindEmptyIndex ].dwOffset, SEEK_SET );
|
||
_Write( m_hFile, pFileHandle->m_pData, pFileHandle->m_FileInfo.dwCompressSize );
|
||
// 파일 헤더 쓰는데 시간 많이 걸려서 표시만 해두고 CloseFileSystem()에서 헤더 한꺼번에 Write한다
|
||
m_PackingFileHeader.bRequireHeaderWrite = true;
|
||
m_PackingFileHeader.dwFileInfoOffset = ( DWORD )_Seek( m_hFile, 0, SEEK_CUR );
|
||
}
|
||
else
|
||
{
|
||
PackingFileInfo = m_vecPackingFileInfo[ nFindEmptyIndex ];
|
||
strcpy_s( PackingFileInfo.szFileName, _MAX_FNAME, szName );
|
||
PackingFileInfo.dwCompressSize = pFileHandle->m_FileInfo.dwCompressSize;
|
||
PackingFileInfo.dwOriginalSize = pFileHandle->m_FileInfo.dwOriginalSize;
|
||
PackingFileInfo.dwSeedValue = pFileHandle->m_FileInfo.dwSeedValue;
|
||
m_vecPackingFileInfo[ nFindEmptyIndex ] = PackingFileInfo;
|
||
|
||
_Seek( m_hFile, m_vecPackingFileInfo[ nFindEmptyIndex ].dwOffset, SEEK_SET );
|
||
_Write( m_hFile, pFileHandle->m_pData, pFileHandle->m_FileInfo.dwCompressSize );
|
||
|
||
LONGLONG nFindFileOffset;
|
||
if( ( nFindFileIndex != -1 ) && ( nFindFileIndex != nFindEmptyIndex ) )
|
||
{
|
||
nFindFileOffset = m_PackingFileHeader.dwFileInfoOffset + ( sizeof( SPackingFileInfo ) * nFindFileIndex );
|
||
_Seek( m_hFile, nFindFileOffset, SEEK_SET );
|
||
_Write( m_hFile, &m_vecPackingFileInfo[ nFindFileIndex ], sizeof( SPackingFileInfo ) );
|
||
}
|
||
nFindFileOffset = m_PackingFileHeader.dwFileInfoOffset + ( sizeof( SPackingFileInfo ) * nFindEmptyIndex );
|
||
_Seek( m_hFile, nFindFileOffset, SEEK_SET );
|
||
_Write( m_hFile, &m_vecPackingFileInfo[ nFindEmptyIndex ], sizeof( SPackingFileInfo ) );
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
bool CEtPackingFile::Remove(const char* strName)
|
||
{
|
||
if( m_hFile == INVALID_HANDLE_VALUE)
|
||
return false;
|
||
|
||
char szFileName[ _MAX_PATH ];
|
||
if( strName[ 0 ] == '\\' )
|
||
{
|
||
strcpy_s( szFileName, _MAX_PATH, strName );
|
||
}
|
||
else
|
||
{
|
||
strcpy_s( szFileName, _MAX_PATH, m_strCurDir );
|
||
strcat_s( szFileName, _MAX_PATH, strName );
|
||
}
|
||
|
||
int nFindFileIndex = FindFile( szFileName );
|
||
if( nFindFileIndex != -1 )
|
||
{
|
||
m_vecPackingFileInfo[ nFindFileIndex ].dwCompressSize = 0;
|
||
m_vecPackingFileInfo[ nFindFileIndex ].dwOriginalSize = 0;
|
||
LONGLONG nFindFileOffset = m_PackingFileHeader.dwFileInfoOffset + ( sizeof( SPackingFileInfo ) * nFindFileIndex );
|
||
_Seek( m_hFile, nFindFileOffset, SEEK_SET );
|
||
_Write( m_hFile, &m_vecPackingFileInfo[ nFindFileIndex ], sizeof( SPackingFileInfo ) );
|
||
_Seek( m_hFile, 0, SEEK_SET );
|
||
|
||
RemovePackingMap( nFindFileIndex );
|
||
AddPackingMap( nFindFileIndex );
|
||
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
bool CEtPackingFile::Rename(const char* strName,const char* strRename)
|
||
{
|
||
if( m_hFile == INVALID_HANDLE_VALUE)
|
||
return false;
|
||
|
||
int nFindFileIndex = FindFile( strName );
|
||
if( nFindFileIndex != -1 )
|
||
{
|
||
strcpy_s( m_vecPackingFileInfo[ nFindFileIndex ].szFileName, _MAX_FNAME, strRename );
|
||
LONGLONG nFindFileOffset = m_PackingFileHeader.dwFileInfoOffset + ( sizeof( SPackingFileInfo ) * nFindFileIndex );
|
||
_Seek( m_hFile, nFindFileOffset, SEEK_SET );
|
||
_Write( m_hFile, &m_vecPackingFileInfo[ nFindFileIndex ], sizeof( SPackingFileInfo ) );
|
||
_Seek( m_hFile, 0, SEEK_SET );
|
||
|
||
RemovePackingMap( nFindFileIndex );
|
||
AddPackingMap( nFindFileIndex );
|
||
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
bool CEtPackingFile::ChangeDir(const char* strPath)
|
||
{
|
||
if( m_hFile == INVALID_HANDLE_VALUE )
|
||
return false;
|
||
|
||
if( strPath[ 0 ] == '\\' )
|
||
{
|
||
strcpy_s( m_strCurDir, _MAX_PATH, strPath );
|
||
return true;
|
||
}
|
||
if( _stricmp( strPath, "." ) == 0 )
|
||
{
|
||
return true;
|
||
}
|
||
if( _stricmp( strPath, ".." ) == 0 )
|
||
{
|
||
int nStrLength = ( int )strlen( m_strCurDir );
|
||
if( nStrLength == 1 )
|
||
{
|
||
return false;
|
||
}
|
||
m_strCurDir[ nStrLength - 1 ] = 0;
|
||
char *pFindPtr = strrchr( m_strCurDir, '\\' );
|
||
if( pFindPtr )
|
||
{
|
||
*( pFindPtr + 1 ) = 0;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
strcat_s( m_strCurDir, _MAX_PATH, strPath );
|
||
if( strPath[ strlen( strPath ) - 1 ] != '\\' )
|
||
{
|
||
strcat_s( m_strCurDir, _MAX_PATH, "\\" );
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
void CEtPackingFile::GetNameOnly(char* strDst,const char* strPath)
|
||
{
|
||
char strTemp[_MAX_PATH] = { 0, };
|
||
strcpy_s(strTemp,strPath);
|
||
_strrev(strTemp);
|
||
|
||
char* cp = strtok(strTemp, "\\/\x0\n\r\t");
|
||
strcpy_s(strTemp,cp);
|
||
_strrev(strTemp);
|
||
GetSafeName(strDst,strTemp);
|
||
}
|
||
|
||
void CEtPackingFile::GetPathOnly(char* strDst, const char* strPath)
|
||
{
|
||
char strName[_MAX_FNAME] = { 0, };
|
||
GetNameOnly(strName,strPath);
|
||
|
||
size_t iLen = strlen(strPath)-strlen(strName);
|
||
|
||
if(!iLen)
|
||
{
|
||
strDst[0] = '\0';
|
||
}
|
||
else
|
||
{
|
||
//_tcsncpy_s(strDst, sizeof(strDst), strPath,iLen);
|
||
strncpy(strDst, strPath,iLen);
|
||
strDst[iLen] = '\0';
|
||
}
|
||
}
|
||
|
||
void CEtPackingFile::GetFileInfoListCurDir( std::vector< SPackingFileInfo * > &vecFileInfo )
|
||
{
|
||
int i;
|
||
|
||
for( i = 0; i < ( int )m_vecPackingFileInfo.size(); i++ )
|
||
{
|
||
if( m_vecPackingFileInfo[ i ].dwCompressSize == 0 )
|
||
{
|
||
continue;
|
||
}
|
||
char szPath[ _MAX_PATH ];
|
||
_GetPath( szPath, _countof(szPath), m_vecPackingFileInfo[ i ].szFileName );
|
||
if( _stricmp( szPath, m_strCurDir ) == 0 )
|
||
{
|
||
vecFileInfo.push_back( &m_vecPackingFileInfo[ i ] );
|
||
}
|
||
}
|
||
}
|
||
|
||
void CEtPackingFile::GetDirListCurDir( std::vector< std::string > &vecDirList )
|
||
{
|
||
int i, nStrLength;
|
||
|
||
vecDirList.push_back( "." );
|
||
if( _stricmp( m_strCurDir, "\\" ) != 0 )
|
||
{
|
||
vecDirList.push_back( ".." );
|
||
}
|
||
nStrLength = ( int )strlen( m_strCurDir );
|
||
for( i = 0; i < ( int )m_vecPackingFileInfo.size(); i++ )
|
||
{
|
||
char szPath[ _MAX_PATH ], szFindPath[ _MAX_PATH];
|
||
_GetPath( szPath, _countof(szPath), m_vecPackingFileInfo[ i ].szFileName );
|
||
if( strstr( szPath, m_strCurDir ) != szPath )
|
||
{
|
||
continue;
|
||
}
|
||
char *pFindPtr = strchr( szPath + nStrLength, '\\' );
|
||
if( pFindPtr == NULL )
|
||
{
|
||
continue;
|
||
}
|
||
*pFindPtr = 0;
|
||
strcpy_s( szFindPath, _MAX_PATH, szPath + nStrLength );
|
||
std::vector< std::string >::iterator it;
|
||
it = std::find( vecDirList.begin(), vecDirList.end(), szFindPath );
|
||
if( it == vecDirList.end() )
|
||
{
|
||
vecDirList.push_back( szFindPath );
|
||
}
|
||
}
|
||
}
|
||
|
||
bool CEtPackingFile::Patch( const char* strPatchPath, CPatchCallback* pCallpack, std::vector< CFileNameString > *pvecSkipList )
|
||
{
|
||
CEtPackingFile srcPack;
|
||
bool bResult = srcPack.OpenFileSystem(strPatchPath, true);
|
||
|
||
m_pLog->Log( "srcPack.OpenFileSystem : %s " , strPatchPath );
|
||
|
||
if( bResult == false )
|
||
{
|
||
if( pCallpack )
|
||
{
|
||
pCallpack->OnError( CPatchCallback::SrcPackOpenFailed, CFileNameString("SrcPackOpenFailed") );
|
||
|
||
}
|
||
m_pLog->Log( "OnError.SrcPackOpenFailed ");
|
||
return false;
|
||
}
|
||
|
||
int nSrcFileCount = srcPack.GetFileCount();
|
||
m_pLog->Log( "Get srcFileList : %u " , nSrcFileCount );
|
||
|
||
|
||
if( nSrcFileCount <= 0 )
|
||
{
|
||
if( pCallpack )
|
||
{
|
||
pCallpack->OnError( CPatchCallback::SrcPackFileSizeZero, CFileNameString("SrcPackFileSizeZero") );
|
||
}
|
||
m_pLog->Log( "OnError SrcPackFileSizeZero ");
|
||
|
||
return false;
|
||
}
|
||
|
||
int i;
|
||
for( i = 0; i < nSrcFileCount; i++ )
|
||
{
|
||
SPackingFileInfo *pPackingFileInfo = srcPack.GetFileInfo( i );
|
||
if( pPackingFileInfo == NULL )
|
||
{
|
||
continue;
|
||
}
|
||
|
||
bool bSkip = false;
|
||
if( pvecSkipList )
|
||
{
|
||
int j;
|
||
for( j = 0; j < ( int )pvecSkipList->size(); j++ )
|
||
{
|
||
// 파일이름 앞에.. \ 붙어 있어서 그거 제외한 이름으로 비교해야 제대로 된다.
|
||
if( _stricmp( pPackingFileInfo->szFileName + 1, ( *pvecSkipList )[ j ].c_str() ) == 0 )
|
||
{
|
||
bSkip = true;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
if( bSkip )
|
||
{
|
||
continue;
|
||
}
|
||
|
||
CEtFileHandle *pFileHandle = srcPack.OpenOnly( pPackingFileInfo->szFileName );
|
||
if( pFileHandle == NULL )
|
||
{
|
||
continue;
|
||
}
|
||
bool bResultInner = PatchFile( pFileHandle );
|
||
// bool bResult = AddFile( pPackingFileInfo->szFileName, pFileHandle->m_pData, pFileHandle->m_FileInfo.dwOriginalSize );
|
||
CloseFile( pFileHandle );
|
||
if( ( !bResultInner ) && ( pCallpack ) )
|
||
{
|
||
pCallpack->OnError( CPatchCallback::DstPackAddFailed, pPackingFileInfo->szFileName );
|
||
}
|
||
|
||
if( pCallpack )
|
||
{
|
||
pCallpack->OnPatch( i, nSrcFileCount, pPackingFileInfo->szFileName );
|
||
}
|
||
}
|
||
|
||
m_PackingFileHeader.nFileCount = ( int )m_vecPackingFileInfo.size();
|
||
|
||
|
||
|
||
_Seek( m_hFile, 0, SEEK_SET );
|
||
_Write( m_hFile, &m_PackingFileHeader, sizeof( SPackingFileHeader ) );
|
||
|
||
return true;
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------------------------------------------
|
||
|
||
CEtFileSystem::CEtFileSystem( bool bDynamicPath )
|
||
{
|
||
m_bDynamicPath = bDynamicPath;
|
||
}
|
||
|
||
CEtFileSystem::~CEtFileSystem()
|
||
{
|
||
RemoveAll();
|
||
}
|
||
|
||
void CEtFileSystem::AddPackingFolder( const char* szPackingFileName, const char* szExt )
|
||
{
|
||
WIN32_FIND_DATA FindFileData;
|
||
HANDLE hFind;
|
||
CFileNameString szFindFile;
|
||
szFindFile = szPackingFileName;
|
||
szFindFile += "\\*.";
|
||
szFindFile += szExt;
|
||
|
||
hFind = FindFirstFile( szFindFile.c_str() , &FindFileData );
|
||
|
||
while( hFind != INVALID_HANDLE_VALUE )
|
||
{
|
||
if( !( FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) )
|
||
{
|
||
CFileNameString szFullPath;
|
||
szFullPath = szPackingFileName;
|
||
szFullPath += "\\";
|
||
szFullPath += FindFileData.cFileName;
|
||
CEtFileSystem::AddPackingFile(szFullPath.c_str(), szPackingFileName);
|
||
}
|
||
if( !FindNextFile( hFind, &FindFileData ) ) break;
|
||
}
|
||
|
||
FindClose( hFind );
|
||
}
|
||
|
||
void CEtFileSystem::AddPackingFolder( const WCHAR* szPackingFileName, const char* szExt )
|
||
{
|
||
//rlkt_pak
|
||
//MessageBoxA(NULL, FormatA(" AddPackingFolder szPackingFileName: %s ext: %s", szPackingFileName, szExt).c_str(), "AddPackingFolder", MB_OK);
|
||
WIN32_FIND_DATAW FindFileData;
|
||
HANDLE hFind;
|
||
std::wstring szFindFile;
|
||
szFindFile = szPackingFileName;
|
||
szFindFile += L"\\*.";
|
||
|
||
std::string szTempExt = szExt;
|
||
std::wstring wszTempExt;
|
||
ToWideString(szTempExt, wszTempExt);
|
||
szFindFile += wszTempExt;
|
||
|
||
hFind = FindFirstFileW( szFindFile.c_str() , &FindFileData );
|
||
|
||
while( hFind != INVALID_HANDLE_VALUE )
|
||
{
|
||
if( !( FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) )
|
||
{
|
||
std::wstring szFullPath;
|
||
szFullPath = szPackingFileName;
|
||
szFullPath += L"\\";
|
||
szFullPath += FindFileData.cFileName;
|
||
|
||
std::string szTempBufferPath;
|
||
std::string szTempBufferName;
|
||
ToMultiString( szFullPath, szTempBufferPath );
|
||
ToMultiString( std::wstring(szPackingFileName), szTempBufferName );
|
||
CEtFileSystem::AddPackingFile(szTempBufferPath.c_str(), szTempBufferName.c_str());
|
||
}
|
||
if( !FindNextFileW( hFind, &FindFileData ) ) break;
|
||
}
|
||
|
||
FindClose( hFind );
|
||
}
|
||
|
||
bool CEtFileSystem::AddPackingFile(const char* szPackingFileName, const char *szRootPath)
|
||
{
|
||
//rlkt_pak
|
||
//MessageBoxA(NULL, FormatA(" AddPackingFile szPackingFileName: %s szRootPath: %s", szPackingFileName, szRootPath).c_str(), "AddPackingFile", MB_OK);
|
||
|
||
std::map<CFileNameString, CEtPackingFile*>::iterator it = m_PackingFileMap.find( CFileNameString(szPackingFileName) );
|
||
|
||
if( it != m_PackingFileMap.end() )
|
||
return false;
|
||
|
||
CEtPackingFile* pPackingFile = new CEtPackingFile();
|
||
pPackingFile->SetRootPath( szRootPath );
|
||
bool bResult = pPackingFile->OpenFileSystem(szPackingFileName, true);
|
||
if( !bResult )
|
||
{
|
||
//rlkt_pak
|
||
//MessageBoxA(NULL, FormatA(" OpenFileSystem read only false szPackingFileName: %s szRootPath: %s", szPackingFileName, szRootPath).c_str(), "AddPackingFile", MB_OK);
|
||
|
||
delete pPackingFile;
|
||
return false;
|
||
}
|
||
|
||
m_PackingFileMap.insert(make_pair(CFileNameString(szPackingFileName), pPackingFile));
|
||
|
||
return true;
|
||
}
|
||
|
||
void CEtFileSystem::RemoveAll()
|
||
{
|
||
std::map<CFileNameString, CEtPackingFile*>::iterator it = m_PackingFileMap.begin();
|
||
|
||
for ( ; it != m_PackingFileMap.end() ; it++ )
|
||
{
|
||
CEtPackingFile* pPackingFile = it->second;
|
||
delete pPackingFile;
|
||
}
|
||
|
||
m_PackingFileMap.clear();
|
||
}
|
||
|
||
CEtFileHandle *CEtFileSystem::OpenFile( const char* strPath, bool bOpenOnly )
|
||
{
|
||
int nFindIndex = -1;
|
||
CEtPackingFile *pFindPacking = FindFile( strPath, nFindIndex );
|
||
if( pFindPacking )
|
||
{
|
||
if( bOpenOnly )
|
||
{
|
||
return pFindPacking->OpenOnly( strPath );
|
||
}
|
||
else
|
||
{
|
||
return pFindPacking->OpenFile( strPath );
|
||
}
|
||
}
|
||
|
||
return NULL;
|
||
}
|
||
|
||
void CEtFileSystem::CloseFile( CEtFileHandle* pFileHandle )
|
||
{
|
||
SAFE_DELETE( pFileHandle );
|
||
}
|
||
|
||
CEtPackingFile *CEtFileSystem::FindFile( const char *pFileName, int &nFindIndex )
|
||
{
|
||
std::map< CFileNameString, CEtPackingFile * >::iterator it = m_PackingFileMap.begin();
|
||
for ( ; it != m_PackingFileMap.end() ; it++ )
|
||
{
|
||
CEtPackingFile *pPackingFile = it->second;
|
||
if( pPackingFile == NULL )
|
||
{
|
||
continue;
|
||
}
|
||
nFindIndex = pPackingFile->FindFile( pFileName );
|
||
if( nFindIndex != -1 )
|
||
{
|
||
return pPackingFile;
|
||
}
|
||
}
|
||
|
||
return NULL;
|
||
}
|
||
|
||
void CEtFileSystem::AddResourcePath( const char *szPath, bool bIncludeSubDir )
|
||
{
|
||
}
|
||
|
||
void CEtFileSystem::RemoveResourcePath( const char *szPath, bool bIncludeSubDir )
|
||
{
|
||
}
|
||
|
||
void CEtFileSystem::CacheFileList( int nIndex, bool bAdd )
|
||
{
|
||
}
|
||
|
||
CFileNameString CEtFileSystem::GetFullName( const char *szFileName, bool *bFind )
|
||
{
|
||
ScopeLock<CSyncLock> Lock(m_SyncLock, m_bDynamicPath);
|
||
if( bFind ) *bFind = false;
|
||
char szName[_MAX_PATH] = { 0, };
|
||
|
||
if( ( szFileName[ 0 ] == '\\' ) || ( IsFullName( szFileName ) ) )
|
||
{
|
||
strcpy_s( szName, szFileName );
|
||
}
|
||
else
|
||
{
|
||
_GetFullFileName( szName, _countof(szName), szFileName );
|
||
}
|
||
|
||
int nFindIndex = -1;
|
||
CEtPackingFile *pFindPacking = FindFile( szName, nFindIndex );
|
||
if( pFindPacking )
|
||
{
|
||
if( bFind ) *bFind = true;
|
||
return pFindPacking->GetFileInfo( nFindIndex )->szFileName;
|
||
}
|
||
|
||
return szFileName;
|
||
}
|
||
|
||
CFileNameString CEtFileSystem::GetFullPath( const char *szPath )
|
||
{
|
||
ScopeLock<CSyncLock> Lock(m_SyncLock, m_bDynamicPath);
|
||
CFileNameString szTemp = szPath;
|
||
ToLowerA( szTemp );
|
||
std::map< CFileNameString, CEtPackingFile * >::iterator it;
|
||
for ( it = m_PackingFileMap.begin(); it != m_PackingFileMap.end(); it++ )
|
||
{
|
||
CEtPackingFile *pPackingFile = it->second;
|
||
if( pPackingFile == NULL )
|
||
{
|
||
continue;
|
||
}
|
||
int i;
|
||
int nFileCount = pPackingFile->GetFileCount();
|
||
for( i = 0; i < nFileCount; i++ )
|
||
{
|
||
SPackingFileInfo *pPackingFileInfo = pPackingFile->GetFileInfo( i );
|
||
if( pPackingFileInfo == NULL )
|
||
{
|
||
continue;
|
||
}
|
||
char *pFindPtr = strstr( pPackingFileInfo->szFileName, szTemp.c_str() );
|
||
if( pFindPtr == NULL )
|
||
{
|
||
continue;
|
||
}
|
||
pFindPtr = strchr( pFindPtr, '\\' );
|
||
if( pFindPtr )
|
||
{
|
||
char szReturnPath[ _MAX_PATH ];
|
||
*pFindPtr = 0;
|
||
strcpy_s( szReturnPath, _MAX_PATH, pPackingFileInfo->szFileName );
|
||
*pFindPtr = '\\';
|
||
return szReturnPath;
|
||
}
|
||
}
|
||
}
|
||
|
||
return szPath;
|
||
}
|
||
|
||
void CEtFileSystem::FindFullPathList( const char *szPath, std::vector<CFileNameString> &szVecResult )
|
||
{
|
||
ScopeLock<CSyncLock> Lock(m_SyncLock, m_bDynamicPath);
|
||
CFileNameString szTemp = "\\";
|
||
szTemp += szPath;
|
||
ToLowerA( szTemp );
|
||
std::map< CFileNameString, CEtPackingFile * >::iterator it;
|
||
for ( it = m_PackingFileMap.begin(); it != m_PackingFileMap.end(); it++ )
|
||
{
|
||
CEtPackingFile *pPackingFile = it->second;
|
||
if( pPackingFile == NULL )
|
||
{
|
||
continue;
|
||
}
|
||
int i;
|
||
int nFileCount = pPackingFile->GetFileCount();
|
||
for( i = 0; i < nFileCount; i++ )
|
||
{
|
||
SPackingFileInfo *pPackingFileInfo = pPackingFile->GetFileInfo( i );
|
||
if( pPackingFileInfo == NULL )
|
||
{
|
||
continue;
|
||
}
|
||
char *pFindPtr = strstr( pPackingFileInfo->szFileName, szTemp.c_str() );
|
||
if( pFindPtr == NULL )
|
||
{
|
||
continue;
|
||
}
|
||
pFindPtr = strchr( pPackingFileInfo->szFileName, '\\' );
|
||
if( pFindPtr )
|
||
{
|
||
char szReturnPath[ _MAX_PATH ];
|
||
/*
|
||
*pFindPtr = 0;
|
||
strcpy_s( szReturnPath, _MAX_PATH, pPackingFileInfo->szFileName );
|
||
*pFindPtr = '\\';
|
||
*/
|
||
_GetPath( szReturnPath, _countof(szReturnPath), pPackingFileInfo->szFileName );
|
||
szReturnPath[ strlen(szReturnPath)-1] = 0;
|
||
bool bExist = false;
|
||
for( DWORD j=0; j<szVecResult.size(); j++ ) {
|
||
if( strcmp( szVecResult[j].c_str(), szReturnPath ) == NULL ) {
|
||
bExist = true;
|
||
break;
|
||
}
|
||
}
|
||
if( !bExist ) szVecResult.push_back( szReturnPath );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void CEtFileSystem::FindFileListInFolder( const char *szFolderName, const char *szExt, std::vector<CFileNameString> &szVecResult)
|
||
{
|
||
ScopeLock<CSyncLock> Lock(m_SyncLock, m_bDynamicPath);
|
||
std::string strFolder = szFolderName;
|
||
strFolder += "\\";
|
||
|
||
/*
|
||
UINT nCodePage = CEtResourceMng::GetInstance().GetCodePage();
|
||
CFileNameString sztemp;
|
||
const char *szCodePage = CEtResourceMng::GetInstance().FindCodePageString(nCodePage);
|
||
strFolder += szCodePage;
|
||
*/
|
||
|
||
std::vector<std::string> ResultArray;
|
||
std::map< std::string, std::vector<std::string> >::iterator iterFind = m_szMapCacheFileListInFolder.find( strFolder );
|
||
if( iterFind != m_szMapCacheFileListInFolder.end() ) {
|
||
ResultArray = iterFind->second;
|
||
}
|
||
else {
|
||
std::map< CFileNameString, CEtPackingFile * >::iterator it = m_PackingFileMap.begin();
|
||
for ( ; it != m_PackingFileMap.end() ; it++ )
|
||
{
|
||
int i;
|
||
CEtPackingFile *pPackingFile = it->second;
|
||
if( pPackingFile == NULL )
|
||
{
|
||
continue;
|
||
}
|
||
int nFileCount = pPackingFile->GetFileCount();
|
||
for( i = 0; i < nFileCount; i++ )
|
||
{
|
||
SPackingFileInfo *pPackingFileInfo = pPackingFile->GetFileInfo( i );
|
||
if( pPackingFileInfo == NULL || pPackingFileInfo->dwCompressSize == 0 || pPackingFileInfo->dwOriginalSize == 0 )
|
||
{
|
||
continue;
|
||
}
|
||
std::string szFolderKey = pPackingFileInfo->szFileName;
|
||
if( szFolderKey.find(strFolder.c_str()) < szFolderKey.size() )
|
||
{
|
||
RemoveStringA(szFolderKey, strFolder);
|
||
ResultArray.push_back(szFolderKey);
|
||
}
|
||
}
|
||
}
|
||
|
||
// 패킹파일 안에 있는 파일중에 \resource\ext로 시작하는 파일을 얻어오는 루틴인데,
|
||
// 모든 파일을 다 뒤지기때문에, 매번 150ms의 딜레이가 생긴다.
|
||
// 이게 점점 패킹파일안에 파일이 늘어나고, ext의 개수가 많아질수록 더 많은 수행시간이 필요하므로,
|
||
// 이렇게 캐시를 둬서 얻어오는 형태로 하겠다.
|
||
// 이렇게 하니 팩안쓰는 것과 비슷한 로딩속도를 보여준다.(TableDB로드 부분)
|
||
m_szMapCacheFileListInFolder.insert( make_pair( strFolder, ResultArray ) );
|
||
}
|
||
|
||
/*
|
||
std::string strExt = szExt;
|
||
RemoveStringA(strExt, std::string("*"));
|
||
|
||
for ( size_t i = 0 ; i < ResultArray.size() ; i++ )
|
||
{
|
||
std::string str = ResultArray[i];
|
||
if( str.find( strExt ) < str.size() )
|
||
{
|
||
szVecResult.push_back(str);
|
||
}
|
||
}
|
||
*/
|
||
std::vector<std::string> szVecNameStr;
|
||
std::vector<std::string> szVecExtStr;
|
||
|
||
char szTemp[256];
|
||
sprintf_s( szTemp, szExt );
|
||
_strlwr_s( szTemp );
|
||
|
||
char szNameTemp[256];
|
||
char szExtTemp[64];
|
||
_GetFileName( szNameTemp, _countof(szNameTemp), szTemp );
|
||
_GetExt( szExtTemp, _countof(szExtTemp), szTemp );
|
||
|
||
for( int i=0; ; i++ ) {
|
||
const char *szStr = _GetSubStrByCount( i, szNameTemp, '*' );
|
||
if( szStr == NULL || strlen(szStr) < 1 ) break;
|
||
szVecNameStr.push_back( szStr );
|
||
}
|
||
|
||
for( int i=0; ; i++ ) {
|
||
const char *szStr = _GetSubStrByCount( i, szExtTemp, '*' );
|
||
if( szStr == NULL || strlen(szStr) < 1 ) break;
|
||
szVecExtStr.push_back( szStr );
|
||
}
|
||
|
||
for ( size_t i = 0 ; i < ResultArray.size() ; i++ )
|
||
{
|
||
std::string str = ResultArray[i];
|
||
bool bResult = true;
|
||
char *pPtr;
|
||
for( DWORD j=0; j<szVecNameStr.size(); j++ ) {
|
||
pPtr = (char*)strstr( str.c_str(), szVecNameStr[j].c_str() );
|
||
if( pPtr == NULL ) {
|
||
// if( str.find( szVecNameStr[j] ) >= str.size() ) {
|
||
bResult = false;
|
||
break;
|
||
}
|
||
if( j == 0 && pPtr != str.c_str() ) {
|
||
bResult = false;
|
||
break;
|
||
}
|
||
}
|
||
if( !bResult ) continue;
|
||
|
||
bResult = true;
|
||
for( DWORD j=0; j<szVecExtStr.size(); j++ ) {
|
||
pPtr = (char*)strstr( str.c_str(), szVecExtStr[j].c_str() );
|
||
// if( str.find( szVecExtStr[j] ) >= str.size() ) {
|
||
if( pPtr == NULL ) {
|
||
bResult = false;
|
||
break;
|
||
}
|
||
}
|
||
if( !bResult ) continue;
|
||
|
||
szVecResult.push_back(str);
|
||
}
|
||
} |