[FastFiles] Introduce a new IW4x zone format

This commit is contained in:
momo5502 2017-01-01 16:45:30 +01:00
parent c4552ac921
commit 75158227fb
6 changed files with 62 additions and 10 deletions

View File

@ -6,6 +6,7 @@ namespace Components
symmetric_CTR FastFiles::CurrentCTR;
std::vector<std::string> FastFiles::ZonePaths;
bool FastFiles::IsIW4xZone = false;
bool FastFiles::StreamRead = false;
unsigned int FastFiles::CurrentZone;
@ -272,17 +273,22 @@ namespace Components
return file;
}
void FastFiles::ReadXFileHeader(void* buffer, int size)
{
if (FastFiles::IsIW4xZone)
{
char pad;
Game::DB_ReadXFile(&pad, 1);
}
Game::DB_ReadXFile(buffer, size);
}
void FastFiles::ReadVersionStub(unsigned int* version, int size)
{
FastFiles::CurrentZone++;
Game::DB_ReadXFileUncompressed(version, size);
// Allow loading of custom version
if (*version == XFILE_VERSION_IW4X)
{
*version = XFILE_VERSION;
}
Zones::SetVersion(*version);
// Allow loading of codo versions
@ -297,6 +303,30 @@ namespace Components
}
}
void FastFiles::ReadHeaderStub(unsigned int* header, int size)
{
FastFiles::IsIW4xZone = false;
Game::DB_ReadXFileUncompressed(header, size);
if (header[0] == XFILE_HEADER_IW4X)
{
FastFiles::IsIW4xZone = true;
if (header[1] < XFILE_VERSION_IW4X)
{
Logger::Error("The fastfile you are trying to load is outdated (%d, expected %d)", header[1], XFILE_VERSION_IW4X);
}
#ifdef DEBUG
else if (header[1] > XFILE_VERSION_IW4X)
{
Logger::Error("You are loading a fastfile that is too new (%d, expected %d), how's that possible?", header[1], XFILE_VERSION_IW4X);
}
#endif
*reinterpret_cast<unsigned __int64*>(header) = XFILE_MAGIC_UNSIGNED;
}
}
void FastFiles::AuthLoadInitCrypto()
{
if (Zones::Version() >= 319)
@ -407,6 +437,9 @@ namespace Components
// Allow loading 'newer' zones
Utils::Hook(0x4158E7, FastFiles::ReadVersionStub, HOOK_CALL).install()->quick();
// Allow loading IW4x zones
Utils::Hook(0x4157B8, FastFiles::ReadHeaderStub, HOOK_CALL).install()->quick();
// Allow custom zone loading
if (!ZoneBuilder::IsEnabled())
{
@ -457,6 +490,9 @@ namespace Components
Utils::Hook(0x589090, FastFiles::GetFullLoadedFraction, HOOK_CALL).install()->quick();
Utils::Hook(0x629FC0, FastFiles::GetFullLoadedFraction, HOOK_JUMP).install()->quick();
// XFile header loading
Utils::Hook(0x4159E2, FastFiles::ReadXFileHeader, HOOK_CALL).install()->quick();
// Add custom zone paths
FastFiles::AddZonePath("zone\\patch\\");
FastFiles::AddZonePath("zone\\dlc\\");

View File

@ -36,6 +36,7 @@ namespace Components
static unsigned int CurrentZone;
static unsigned int MaxZones;
static bool IsIW4xZone;
static bool StreamRead;
static Key CurrentKey;
@ -46,8 +47,11 @@ namespace Components
static void LoadDLCUIZones(Game::XZoneInfo *zoneInfo, unsigned int zoneCount, int sync);
static void LoadGfxZones(Game::XZoneInfo *zoneInfo, unsigned int zoneCount, int sync);
static void ReadHeaderStub(unsigned int* header, int size);
static void ReadVersionStub(unsigned int* version, int size);
static void ReadXFileHeader(void* buffer, int size);
static void AuthLoadInitCrypto();
static int AuthLoadInflateCompare(unsigned char* buffer, int length, unsigned char* ivValue);
static void AuthLoadInflateDecryptBase();

View File

@ -337,12 +337,12 @@ namespace Components
Game::XFileHeader header =
{
XFILE_MAGIC_UNSIGNED,
#ifdef DEBUG
XFILE_VERSION,
XFILE_MAGIC_UNSIGNED,
#else
XFILE_VERSION_IW4X,
XFILE_HEADER_IW4X | (static_cast<unsigned __int64>(XFILE_VERSION_IW4X) << 32),
#endif
XFILE_VERSION,
Game::XFileLanguage::XLANG_NONE,
fileTime.dwHighDateTime,
fileTime.dwLowDateTime
@ -352,6 +352,12 @@ namespace Components
outBuffer.append(reinterpret_cast<char*>(&header), sizeof(header));
std::string zoneBuffer = this->buffer.toBuffer();
#ifndef DEBUG
// Insert a random byte, this will destroy the whole alignment and result in a crash, if not handled
zoneBuffer.insert(zoneBuffer.begin(), static_cast<char>(Utils::Cryptography::Rand::GenerateInt()));
#endif
zoneBuffer = Utils::Compression::ZLib::Compress(zoneBuffer);
outBuffer.append(zoneBuffer);

View File

@ -1,6 +1,8 @@
#define XFILE_MAGIC_UNSIGNED 0x3030317566665749
#define XFILE_VERSION 276
#define XFILE_VERSION_IW4X 0x78345749 // 'IW4x'
#define XFILE_HEADER_IW4X 0x78345749 // 'IW4x'
#define XFILE_VERSION_IW4X 1
namespace Components
{

View File

@ -54,6 +54,7 @@ namespace Game
DB_IsXAssetDefault_t DB_IsXAssetDefault = (DB_IsXAssetDefault_t)0x48E6A0;
DB_LoadXAssets_t DB_LoadXAssets = (DB_LoadXAssets_t)0x4E5930;
DB_LoadXFileData_t DB_LoadXFileData = (DB_LoadXFileData_t)0x445460;
DB_ReadXFile_t DB_ReadXFile = (DB_ReadXFile_t)0x445460;
DB_ReadXFileUncompressed_t DB_ReadXFileUncompressed = (DB_ReadXFileUncompressed_t)0x4705E0;
DB_ReleaseXAssetHandler_t* DB_ReleaseXAssetHandlers = (DB_ReleaseXAssetHandler_t*)0x799AB8;
DB_XModelSurfsFixup_t DB_XModelSurfsFixup = (DB_XModelSurfsFixup_t)0x5BAC50;

View File

@ -132,6 +132,9 @@ namespace Game
typedef void(__cdecl * DB_ReadXFileUncompressed_t)(void* buffer, int size);
extern DB_ReadXFileUncompressed_t DB_ReadXFileUncompressed;
typedef void(__cdecl * DB_ReadXFile_t)(void* buffer, int size);
extern DB_ReadXFile_t DB_ReadXFile;
typedef void(__cdecl * DB_ReleaseXAssetHandler_t)(XAssetHeader header);
extern DB_ReleaseXAssetHandler_t* DB_ReleaseXAssetHandlers;