mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-06-26 06:11:53 +00:00
Rename ZoneLoader and ZoneWriter components to ZoneLoading and ZoneWriting to make a difference between the executive class and the component class
This commit is contained in:
136
src/ZoneLoading/Game/T6/ContentLoaderT6.cpp
Normal file
136
src/ZoneLoading/Game/T6/ContentLoaderT6.cpp
Normal file
@ -0,0 +1,136 @@
|
||||
#include "ContentLoaderT6.h"
|
||||
#include "Game/T6/T6.h"
|
||||
#include "Loading/Exception/UnsupportedAssetTypeException.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include "Game/T6/XAssets/rawfile/rawfile_load_db.h"
|
||||
|
||||
using namespace T6;
|
||||
|
||||
ContentLoaderT6::ContentLoaderT6()
|
||||
{
|
||||
// Script String 0 is always empty string
|
||||
m_script_strings.emplace_back("");
|
||||
}
|
||||
|
||||
void ContentLoaderT6::LoadScriptStringList(ScriptStringList* scriptStringList)
|
||||
{
|
||||
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
|
||||
|
||||
if(scriptStringList->strings != nullptr)
|
||||
{
|
||||
assert(scriptStringList->strings == PTR_FOLLOWING);
|
||||
|
||||
scriptStringList->strings = m_stream->Alloc<const char*>();
|
||||
LoadXStringArray(scriptStringList->strings, scriptStringList->count, true);
|
||||
|
||||
for(int i = 0; i < scriptStringList->count; i++)
|
||||
{
|
||||
m_script_strings.emplace_back(scriptStringList->strings[i]);
|
||||
}
|
||||
}
|
||||
|
||||
m_stream->PopBlock();
|
||||
}
|
||||
|
||||
void ContentLoaderT6::LoadXAsset(XAsset* pXAsset, const bool atStreamStart)
|
||||
{
|
||||
assert(pXAsset != nullptr);
|
||||
|
||||
if(atStreamStart)
|
||||
m_stream->Load<XAsset>();
|
||||
|
||||
switch(pXAsset->type)
|
||||
{
|
||||
case ASSET_TYPE_RAWFILE:
|
||||
{
|
||||
RawFileLoader rawFileLoader(this, m_zone, m_stream);
|
||||
|
||||
rawFileLoader.LoadRawFilePtr(&pXAsset->header.rawfile);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
throw UnsupportedAssetTypeException(pXAsset->type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ContentLoaderT6::LoadXAssetArray(XAsset* pArray, const size_t count, const bool atStreamStart)
|
||||
{
|
||||
assert(pArray != nullptr);
|
||||
|
||||
if(atStreamStart)
|
||||
m_stream->Load<XAsset>(count);
|
||||
|
||||
size_t assetCounts[ASSET_TYPE_COUNT]{0};
|
||||
|
||||
for(size_t index = 0; index < count; index++)
|
||||
{
|
||||
assert(pArray[index].type >= 0 && pArray[index].type < ASSET_TYPE_COUNT);
|
||||
|
||||
if(pArray[index].type >= 0 && pArray[index].type < ASSET_TYPE_COUNT)
|
||||
{
|
||||
assetCounts[pArray[index].type]++;
|
||||
}
|
||||
}
|
||||
|
||||
// Special case: CLIPMAP and CLIPMAP_PVS are the same struct and therefore share the same asset pool
|
||||
assetCounts[ASSET_TYPE_CLIPMAP_PVS] += assetCounts[ASSET_TYPE_CLIPMAP];
|
||||
assetCounts[ASSET_TYPE_CLIPMAP] = 0;
|
||||
|
||||
for(asset_type_t assetType = 0; assetType < ASSET_TYPE_COUNT; assetType++)
|
||||
{
|
||||
m_zone->GetPools()->InitPoolStatic(assetType, assetCounts[assetType]);
|
||||
}
|
||||
|
||||
for(size_t index = 0; index < count; index++)
|
||||
{
|
||||
LoadXAsset(&pArray[index], false);
|
||||
}
|
||||
}
|
||||
|
||||
void ContentLoaderT6::Load(Zone* zone, IZoneInputStream* stream)
|
||||
{
|
||||
m_zone = zone;
|
||||
m_stream = stream;
|
||||
|
||||
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
|
||||
|
||||
auto* assetList = m_stream->Alloc<XAssetList>();
|
||||
m_stream->Load<XAssetList>();
|
||||
|
||||
LoadScriptStringList(&assetList->stringList);
|
||||
|
||||
if(assetList->depends != nullptr)
|
||||
{
|
||||
assert(assetList->depends == PTR_FOLLOWING);
|
||||
|
||||
assetList->depends = m_stream->Alloc<const char*>();
|
||||
LoadXStringArray(assetList->depends, assetList->dependCount, true);
|
||||
}
|
||||
|
||||
if(assetList->assets != nullptr)
|
||||
{
|
||||
assert(assetList->assets == PTR_FOLLOWING);
|
||||
|
||||
assetList->assets = m_stream->Alloc<XAsset>();
|
||||
LoadXAssetArray(assetList->assets, assetList->assetCount, true);
|
||||
}
|
||||
|
||||
m_stream->PopBlock();
|
||||
}
|
||||
|
||||
std::string& ContentLoaderT6::GetZoneScriptString(const scr_string_t scrString)
|
||||
{
|
||||
assert(scrString >= 0 && scrString < m_script_strings.size());
|
||||
|
||||
if(scrString < 0 || scrString >= m_script_strings.size())
|
||||
{
|
||||
return m_script_strings[0];
|
||||
}
|
||||
|
||||
return m_script_strings[scrString];
|
||||
}
|
21
src/ZoneLoading/Game/T6/ContentLoaderT6.h
Normal file
21
src/ZoneLoading/Game/T6/ContentLoaderT6.h
Normal file
@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
#include "Loading/ContentLoader.h"
|
||||
#include "Loading/IContentLoadingEntryPoint.h"
|
||||
#include "Game/T6/T6.h"
|
||||
#include "Loading/IZoneScriptStringProvider.h"
|
||||
|
||||
class ContentLoaderT6 final : public ContentLoader, public IContentLoadingEntryPoint, public IZoneScriptStringProvider
|
||||
{
|
||||
std::vector<std::string> m_script_strings;
|
||||
|
||||
void LoadScriptStringList(T6::ScriptStringList* scriptStringList);
|
||||
|
||||
void LoadXAsset(T6::XAsset* pXAsset, bool atStreamStart);
|
||||
void LoadXAssetArray(T6::XAsset* pArray, size_t count, bool atStreamStart);
|
||||
|
||||
public:
|
||||
ContentLoaderT6();
|
||||
|
||||
void Load(Zone* zone, IZoneInputStream* stream) override;
|
||||
std::string& GetZoneScriptString(scr_string_t scrString) override;
|
||||
};
|
70
src/ZoneLoading/Game/T6/XAssets/rawfile/rawfile_load_db.cpp
Normal file
70
src/ZoneLoading/Game/T6/XAssets/rawfile/rawfile_load_db.cpp
Normal file
@ -0,0 +1,70 @@
|
||||
#include "rawfile_load_db.h"
|
||||
#include <cassert>
|
||||
|
||||
using namespace T6;
|
||||
|
||||
RawFileLoader::RawFileLoader(IZoneScriptStringProvider* scriptStringProvider, Zone* zone, IZoneInputStream* stream)
|
||||
: AssetLoader(ASSET_TYPE_RAWFILE, scriptStringProvider, zone, stream){}
|
||||
|
||||
void RawFileLoader::LoadRawFile(RawFile* pRawFile, const bool atStreamStart)
|
||||
{
|
||||
assert(pRawFile != nullptr);
|
||||
|
||||
if(atStreamStart)
|
||||
m_stream->Load<RawFile>();
|
||||
|
||||
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
|
||||
|
||||
LoadXString(&pRawFile->name);
|
||||
|
||||
if(pRawFile->buffer != nullptr)
|
||||
{
|
||||
assert(pRawFile->buffer == PTR_FOLLOWING);
|
||||
|
||||
pRawFile->buffer = m_stream->Alloc<const char>(16);
|
||||
m_stream->Load<const char>(pRawFile->len + 1);
|
||||
}
|
||||
|
||||
m_stream->PopBlock();
|
||||
}
|
||||
|
||||
void RawFileLoader::LoadRawFileAsset(RawFile** pPtr)
|
||||
{
|
||||
assert(pPtr != nullptr);
|
||||
*pPtr = static_cast<RawFile*>(LinkAsset(GetRawFileName(*pPtr), *pPtr));
|
||||
}
|
||||
|
||||
void RawFileLoader::LoadRawFilePtr(RawFile** pPtr)
|
||||
{
|
||||
assert(pPtr != nullptr);
|
||||
|
||||
m_stream->PushBlock(XFILE_BLOCK_TEMP);
|
||||
|
||||
if(*pPtr != nullptr)
|
||||
{
|
||||
if(*pPtr == PTR_FOLLOWING || *pPtr == PTR_INSERT)
|
||||
{
|
||||
RawFile** toInsert = nullptr;
|
||||
if(*pPtr == PTR_INSERT)
|
||||
toInsert = m_stream->InsertPointer<RawFile>();
|
||||
|
||||
*pPtr = m_stream->Alloc<RawFile>();
|
||||
LoadRawFile(*pPtr, true);
|
||||
LoadRawFileAsset(pPtr);
|
||||
|
||||
if(toInsert != nullptr)
|
||||
*toInsert = *pPtr;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pPtr = m_stream->ConvertOffsetToAlias(*pPtr);
|
||||
}
|
||||
}
|
||||
|
||||
m_stream->PopBlock();
|
||||
}
|
||||
|
||||
std::string RawFileLoader::GetRawFileName(RawFile* pRawFile)
|
||||
{
|
||||
return pRawFile->name;
|
||||
}
|
18
src/ZoneLoading/Game/T6/XAssets/rawfile/rawfile_load_db.h
Normal file
18
src/ZoneLoading/Game/T6/XAssets/rawfile/rawfile_load_db.h
Normal file
@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
#include "Loading/AssetLoader.h"
|
||||
#include "Game/T6/T6.h"
|
||||
|
||||
namespace T6
|
||||
{
|
||||
class RawFileLoader final : public AssetLoader
|
||||
{
|
||||
void LoadRawFile(RawFile* pRawFile, bool atStreamStart);
|
||||
void LoadRawFileAsset(RawFile** pPtr);
|
||||
|
||||
public:
|
||||
RawFileLoader(IZoneScriptStringProvider* scriptStringProvider, Zone* zone, IZoneInputStream* stream);
|
||||
|
||||
void LoadRawFilePtr(RawFile** pPtr);
|
||||
static std::string GetRawFileName(RawFile* pRawFile);
|
||||
};
|
||||
}
|
240
src/ZoneLoading/Game/T6/ZoneLoaderFactoryT6.cpp
Normal file
240
src/ZoneLoading/Game/T6/ZoneLoaderFactoryT6.cpp
Normal file
@ -0,0 +1,240 @@
|
||||
#include "ZoneLoaderFactoryT6.h"
|
||||
#include "Game/T6/T6.h"
|
||||
|
||||
#include "Loading/Steps/StepVerifyMagic.h"
|
||||
#include "Loading/Steps/StepSkipBytes.h"
|
||||
#include "Loading/Steps/StepVerifyFileName.h"
|
||||
#include "Loading/Steps/StepLoadSignature.h"
|
||||
#include "Loading/Steps/StepVerifySignature.h"
|
||||
#include "Loading/Steps/StepAddProcessor.h"
|
||||
#include "Loading/Steps/StepAllocXBlocks.h"
|
||||
|
||||
#include "Loading/Processor/ProcessorXChunks.h"
|
||||
#include "Loading/Processor/XChunks/ChunkProcessorSalsa20.h"
|
||||
#include "Loading/Processor/XChunks/ChunkProcessorInflate.h"
|
||||
|
||||
#include "Utils/ClassUtils.h"
|
||||
#include <cassert>
|
||||
#include "Loading/Steps/StepLoadZoneContent.h"
|
||||
#include "ContentLoaderT6.h"
|
||||
#include "Game/T6/GameAssetPoolT6.h"
|
||||
#include "Game/T6/GameT6.h"
|
||||
|
||||
const std::string ZoneLoaderFactoryT6::MAGIC_SIGNED_TREYARCH = "TAff0100";
|
||||
const std::string ZoneLoaderFactoryT6::MAGIC_SIGNED_ASSET_BUILDER = "ABff0100";
|
||||
const std::string ZoneLoaderFactoryT6::MAGIC_UNSIGNED = "TAffu100";
|
||||
const int ZoneLoaderFactoryT6::VERSION = 147;
|
||||
|
||||
const int ZoneLoaderFactoryT6::STREAM_COUNT = 4;
|
||||
const int ZoneLoaderFactoryT6::XCHUNK_SIZE = 0x8000;
|
||||
const int ZoneLoaderFactoryT6::OFFSET_BLOCK_BIT_COUNT = 3;
|
||||
const block_t ZoneLoaderFactoryT6::INSERT_BLOCK = T6::XFILE_BLOCK_VIRTUAL;
|
||||
|
||||
const std::string ZoneLoaderFactoryT6::MAGIC_AUTH_HEADER = "PHEEBs71";
|
||||
const uint8_t ZoneLoaderFactoryT6::SALSA20_KEY_TREYARCH[]
|
||||
{
|
||||
0x64, 0x1D, 0x8A, 0x2F,
|
||||
0xE3, 0x1D, 0x3A, 0xA6,
|
||||
0x36, 0x22, 0xBB, 0xC9,
|
||||
0xCE, 0x85, 0x87, 0x22,
|
||||
0x9D, 0x42, 0xB0, 0xF8,
|
||||
0xED, 0x9B, 0x92, 0x41,
|
||||
0x30, 0xBF, 0x88, 0xB6,
|
||||
0x5E, 0xDC, 0x50, 0xBE
|
||||
};
|
||||
|
||||
const uint8_t ZoneLoaderFactoryT6::RSA_PUBLIC_KEY_TREYARCH[]
|
||||
{
|
||||
0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01,
|
||||
0x00, 0xc7, 0x9d, 0x33, 0xe0, 0x75, 0xaf, 0xef,
|
||||
0x08, 0x08, 0x2b, 0x89, 0xd9, 0x3b, 0xf3, 0xd5,
|
||||
0x9a, 0x65, 0xa6, 0xde, 0x3b, 0x1e, 0x20, 0xde,
|
||||
0x59, 0x19, 0x43, 0x88, 0x1a, 0x8b, 0x39, 0x13,
|
||||
0x60, 0x12, 0xd3, 0xb2, 0x77, 0x6d, 0xe1, 0x99,
|
||||
0x75, 0x24, 0xb4, 0x0d, 0x8c, 0xb7, 0x84, 0xf2,
|
||||
0x48, 0x8f, 0xd5, 0x4c, 0xb7, 0x64, 0x44, 0xa3,
|
||||
0xa8, 0x4a, 0xac, 0x2d, 0x54, 0x15, 0x2b, 0x1f,
|
||||
0xb3, 0xf4, 0x4c, 0x16, 0xa0, 0x92, 0x8e, 0xd2,
|
||||
0xfa, 0xcc, 0x11, 0x6a, 0x74, 0x6a, 0x70, 0xb8,
|
||||
0xd3, 0x34, 0x6b, 0x39, 0xc6, 0x2a, 0x69, 0xde,
|
||||
0x31, 0x34, 0xdf, 0xe7, 0x8b, 0x7e, 0x17, 0xa3,
|
||||
0x17, 0xd9, 0x5e, 0x88, 0x39, 0x21, 0xf8, 0x7d,
|
||||
0x3c, 0x29, 0x21, 0x6c, 0x0e, 0xf1, 0xb4, 0x09,
|
||||
0x54, 0xe8, 0x20, 0x34, 0x90, 0x2e, 0xb4, 0x1a,
|
||||
0x95, 0x95, 0x90, 0xe5, 0xfb, 0xce, 0xfe, 0x8a,
|
||||
0xbf, 0xea, 0xaf, 0x09, 0x0c, 0x0b, 0x87, 0x22,
|
||||
0xe1, 0xfe, 0x82, 0x6e, 0x91, 0xe8, 0xd1, 0xb6,
|
||||
0x35, 0x03, 0x4f, 0xdb, 0xc1, 0x31, 0xe2, 0xba,
|
||||
0xa0, 0x13, 0xf6, 0xdb, 0x07, 0x9b, 0xcb, 0x99,
|
||||
0xce, 0x9f, 0x49, 0xc4, 0x51, 0x8e, 0xf1, 0x04,
|
||||
0x9b, 0x30, 0xc3, 0x02, 0xff, 0x7b, 0x94, 0xca,
|
||||
0x12, 0x69, 0x1e, 0xdb, 0x2d, 0x3e, 0xbd, 0x48,
|
||||
0x16, 0xe1, 0x72, 0x37, 0xb8, 0x5f, 0x61, 0xfa,
|
||||
0x24, 0x16, 0x3a, 0xde, 0xbf, 0x6a, 0x71, 0x62,
|
||||
0x32, 0xf3, 0xaa, 0x7f, 0x28, 0x3a, 0x0c, 0x27,
|
||||
0xeb, 0xa9, 0x0a, 0x4c, 0x79, 0x88, 0x84, 0xb3,
|
||||
0xe2, 0x52, 0xb9, 0x68, 0x1e, 0x82, 0xcf, 0x67,
|
||||
0x43, 0xf3, 0x68, 0xf7, 0x26, 0x19, 0xaa, 0xdd,
|
||||
0x3f, 0x1e, 0xc6, 0x46, 0x11, 0x9f, 0x24, 0x23,
|
||||
0xa7, 0xb0, 0x1b, 0x79, 0xa7, 0x0c, 0x5a, 0xfe,
|
||||
0x96, 0xf7, 0xe7, 0x88, 0x09, 0xa6, 0x69, 0xe3,
|
||||
0x8b, 0x02, 0x03, 0x01, 0x00, 0x01
|
||||
};
|
||||
|
||||
class ZoneLoaderFactoryT6::ZoneLoaderFactoryT6Impl
|
||||
{
|
||||
static bool CanLoad(ZoneHeader& header, bool* isSecure, bool* isOfficial)
|
||||
{
|
||||
assert(isSecure != nullptr);
|
||||
assert(isOfficial != nullptr);
|
||||
|
||||
if(header.m_version != VERSION)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!memcmp(header.m_magic, MAGIC_SIGNED_TREYARCH.c_str(), 8))
|
||||
{
|
||||
*isSecure = true;
|
||||
*isOfficial = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
if(!memcmp(header.m_magic, MAGIC_SIGNED_ASSET_BUILDER.c_str(), 8))
|
||||
{
|
||||
*isSecure = true;
|
||||
*isOfficial = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if(!memcmp(header.m_magic, MAGIC_UNSIGNED.c_str(), 8))
|
||||
{
|
||||
*isSecure = false;
|
||||
*isOfficial = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void SetupBlock(ZoneLoader* zoneLoader)
|
||||
{
|
||||
#define XBLOCK_DEF(name, type) new XBlock(STR(name), name, type)
|
||||
|
||||
zoneLoader->AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_TEMP, XBlock::BLOCK_TYPE_TEMP));
|
||||
zoneLoader->AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_RUNTIME_VIRTUAL, XBlock::BLOCK_TYPE_RUNTIME));
|
||||
zoneLoader->AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_RUNTIME_PHYSICAL, XBlock::BLOCK_TYPE_RUNTIME));
|
||||
zoneLoader->AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_DELAY_VIRTUAL, XBlock::BLOCK_TYPE_DELAY));
|
||||
zoneLoader->AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_DELAY_PHYSICAL, XBlock::BLOCK_TYPE_DELAY));
|
||||
zoneLoader->AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_VIRTUAL, XBlock::BLOCK_TYPE_NORMAL));
|
||||
zoneLoader->AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_PHYSICAL, XBlock::BLOCK_TYPE_NORMAL));
|
||||
zoneLoader->AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_STREAMER_RESERVE, XBlock::BLOCK_TYPE_NORMAL));
|
||||
|
||||
#undef XBLOCK_DEF
|
||||
}
|
||||
|
||||
static IPublicKeyAlgorithm* SetupRSA(const bool isOfficial)
|
||||
{
|
||||
if(isOfficial)
|
||||
{
|
||||
auto* rsa = Crypto::CreateRSA(IPublicKeyAlgorithm::RSA_HASH_SHA256, Crypto::RSA_PADDING_PSS);
|
||||
|
||||
if(!rsa->SetKey(RSA_PUBLIC_KEY_TREYARCH, sizeof(RSA_PUBLIC_KEY_TREYARCH)))
|
||||
{
|
||||
printf("Invalid public key for signature checking\n");
|
||||
|
||||
delete rsa;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return rsa;
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(false);
|
||||
|
||||
// TODO: Load custom RSA key here
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
static ISignatureProvider* AddAuthHeaderSteps(const bool isSecure, ZoneLoader* zoneLoader, std::string& fileName)
|
||||
{
|
||||
// Unsigned zones do not have an auth header
|
||||
if(!isSecure)
|
||||
return nullptr;
|
||||
|
||||
zoneLoader->AddLoadingStep(new StepVerifyMagic(MAGIC_AUTH_HEADER.c_str()));
|
||||
zoneLoader->AddLoadingStep(new StepSkipBytes(4)); // Loading Flags which are always zero
|
||||
zoneLoader->AddLoadingStep(new StepVerifyFileName(fileName, 32));
|
||||
|
||||
auto* signatureLoadStep = new StepLoadSignature(256);
|
||||
zoneLoader->AddLoadingStep(signatureLoadStep);
|
||||
|
||||
return signatureLoadStep;
|
||||
}
|
||||
|
||||
static ISignatureDataProvider* AddXChunkProcessor(ZoneLoader* zoneLoader, std::string& fileName)
|
||||
{
|
||||
auto* xChunkProcessor = new ProcessorXChunks(STREAM_COUNT, XCHUNK_SIZE);
|
||||
|
||||
// First decrypt the chunks with Salsa20
|
||||
auto* chunkProcessorSalsa20 = new ChunkProcessorSalsa20(STREAM_COUNT, fileName, SALSA20_KEY_TREYARCH, sizeof(SALSA20_KEY_TREYARCH));
|
||||
xChunkProcessor->AddChunkProcessor(chunkProcessorSalsa20);
|
||||
|
||||
// Then decompress the chunks using zlib
|
||||
xChunkProcessor->AddChunkProcessor(new ChunkProcessorInflate());
|
||||
zoneLoader->AddLoadingStep(new StepAddProcessor(xChunkProcessor));
|
||||
|
||||
// The signed data of the zone is the final hash blocks provided by the Salsa20 IV adaption algorithm
|
||||
return chunkProcessorSalsa20;
|
||||
}
|
||||
|
||||
public:
|
||||
static ZoneLoader* CreateLoaderForHeader(ZoneHeader& header, std::string& fileName)
|
||||
{
|
||||
bool isSecure;
|
||||
bool isOfficial;
|
||||
|
||||
// Check if this file is a supported T6 zone.
|
||||
if(!CanLoad(header, &isSecure, &isOfficial))
|
||||
return nullptr;
|
||||
|
||||
// Create new zone
|
||||
auto* zone = new Zone(fileName, 0, new GameAssetPoolT6(0), &game_t6);
|
||||
|
||||
// File is supported. Now setup all required steps for loading this file.
|
||||
auto* zoneLoader = new ZoneLoader(zone);
|
||||
|
||||
SetupBlock(zoneLoader);
|
||||
|
||||
// If file is signed setup a RSA instance.
|
||||
IPublicKeyAlgorithm* rsa = isSecure ? SetupRSA(isOfficial) : nullptr;
|
||||
|
||||
// Add steps for loading the auth header which also contain the signature of the zone if it is signed.
|
||||
ISignatureProvider* signatureProvider = AddAuthHeaderSteps(isSecure, zoneLoader, fileName);
|
||||
|
||||
// Setup loading XChunks from the zone from this point on.
|
||||
ISignatureDataProvider* signatureDataProvider = AddXChunkProcessor(zoneLoader, fileName);
|
||||
|
||||
// Start of the XFile struct
|
||||
zoneLoader->AddLoadingStep(new StepSkipBytes(8)); // Skip size and externalSize fields since they are not interesting for us
|
||||
zoneLoader->AddLoadingStep(new StepAllocXBlocks());
|
||||
|
||||
// Start of the zone content
|
||||
zoneLoader->AddLoadingStep(new StepLoadZoneContent(new ContentLoaderT6(), zone, OFFSET_BLOCK_BIT_COUNT, INSERT_BLOCK));
|
||||
|
||||
if(isSecure)
|
||||
{
|
||||
zoneLoader->AddLoadingStep(new StepVerifySignature(rsa, signatureProvider, signatureDataProvider));
|
||||
}
|
||||
|
||||
// Return the fully setup zoneloader
|
||||
return zoneLoader;
|
||||
}
|
||||
};
|
||||
|
||||
ZoneLoader* ZoneLoaderFactoryT6::CreateLoaderForHeader(ZoneHeader& header, std::string& fileName)
|
||||
{
|
||||
return ZoneLoaderFactoryT6Impl::CreateLoaderForHeader(header, fileName);
|
||||
}
|
26
src/ZoneLoading/Game/T6/ZoneLoaderFactoryT6.h
Normal file
26
src/ZoneLoading/Game/T6/ZoneLoaderFactoryT6.h
Normal file
@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include "Loading/IZoneLoaderFactory.h"
|
||||
#include <string>
|
||||
|
||||
class ZoneLoaderFactoryT6 final : public IZoneLoaderFactory
|
||||
{
|
||||
static const std::string MAGIC_SIGNED_TREYARCH;
|
||||
static const std::string MAGIC_SIGNED_ASSET_BUILDER;
|
||||
static const std::string MAGIC_UNSIGNED;
|
||||
static const int VERSION;
|
||||
|
||||
static const int STREAM_COUNT;
|
||||
static const int XCHUNK_SIZE;
|
||||
static const int OFFSET_BLOCK_BIT_COUNT;
|
||||
static const block_t INSERT_BLOCK;
|
||||
|
||||
static const std::string MAGIC_AUTH_HEADER;
|
||||
static const uint8_t SALSA20_KEY_TREYARCH[];
|
||||
static const uint8_t RSA_PUBLIC_KEY_TREYARCH[];
|
||||
|
||||
class ZoneLoaderFactoryT6Impl;
|
||||
|
||||
public:
|
||||
ZoneLoader* CreateLoaderForHeader(ZoneHeader& header, std::string& fileName) override;
|
||||
};
|
53
src/ZoneLoading/Loading/AssetLoader.cpp
Normal file
53
src/ZoneLoading/Loading/AssetLoader.cpp
Normal file
@ -0,0 +1,53 @@
|
||||
#include "AssetLoader.h"
|
||||
|
||||
AssetLoader::AssetLoader(const asset_type_t assetType, IZoneScriptStringProvider* scriptStringProvider, Zone* zone, IZoneInputStream* stream)
|
||||
{
|
||||
m_asset_type = assetType;
|
||||
m_script_string_provider = scriptStringProvider;
|
||||
m_zone = zone;
|
||||
m_stream = stream;
|
||||
}
|
||||
|
||||
void AssetLoader::AddDependency(const asset_type_t type, std::string& name)
|
||||
{
|
||||
for(auto& existingDependency : m_dependencies)
|
||||
{
|
||||
if(existingDependency.m_type == type
|
||||
&& existingDependency.m_name == name)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
XAssetDependency dependency;
|
||||
dependency.m_type = type;
|
||||
dependency.m_name = name;
|
||||
|
||||
m_dependencies.push_back(dependency);
|
||||
}
|
||||
|
||||
scr_string_t AssetLoader::UseScriptString(const scr_string_t scrString)
|
||||
{
|
||||
std::string& scrStringValue = m_script_string_provider->GetZoneScriptString(scrString);
|
||||
|
||||
scr_string_t scriptStringIndex = 0;
|
||||
for(auto& existingScriptString : m_used_script_strings)
|
||||
{
|
||||
if(existingScriptString == scrStringValue)
|
||||
{
|
||||
return scriptStringIndex;
|
||||
}
|
||||
|
||||
scriptStringIndex++;
|
||||
}
|
||||
|
||||
scriptStringIndex = static_cast<scr_string_t>(m_used_script_strings.size());
|
||||
m_used_script_strings.push_back(scrStringValue);
|
||||
|
||||
return scriptStringIndex;
|
||||
}
|
||||
|
||||
void* AssetLoader::LinkAsset(std::string name, void* asset)
|
||||
{
|
||||
return m_zone->GetPools()->AddAsset(m_asset_type, std::move(name), asset, m_used_script_strings, m_dependencies);
|
||||
}
|
22
src/ZoneLoading/Loading/AssetLoader.h
Normal file
22
src/ZoneLoading/Loading/AssetLoader.h
Normal file
@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
#include "ContentLoader.h"
|
||||
#include "IZoneScriptStringProvider.h"
|
||||
#include "Zone/XAssetDependency.h"
|
||||
|
||||
class AssetLoader : public ContentLoader
|
||||
{
|
||||
asset_type_t m_asset_type;
|
||||
|
||||
IZoneScriptStringProvider* m_script_string_provider;
|
||||
std::vector<std::string> m_used_script_strings;
|
||||
|
||||
std::vector<XAssetDependency> m_dependencies;
|
||||
|
||||
protected:
|
||||
AssetLoader(asset_type_t assetType, IZoneScriptStringProvider* scriptStringProvider, Zone* zone, IZoneInputStream* stream);
|
||||
|
||||
void AddDependency(asset_type_t type, std::string& name);
|
||||
scr_string_t UseScriptString(scr_string_t scrString);
|
||||
|
||||
void* LinkAsset(std::string name, void* asset);
|
||||
};
|
42
src/ZoneLoading/Loading/ContentLoader.cpp
Normal file
42
src/ZoneLoading/Loading/ContentLoader.cpp
Normal file
@ -0,0 +1,42 @@
|
||||
#include "ContentLoader.h"
|
||||
#include <cassert>
|
||||
|
||||
const void* ContentLoader::PTR_FOLLOWING = reinterpret_cast<void*>(-1);
|
||||
const void* ContentLoader::PTR_INSERT = reinterpret_cast<void*>(-2);
|
||||
|
||||
ContentLoader::ContentLoader()
|
||||
{
|
||||
m_zone = nullptr;
|
||||
m_stream = nullptr;
|
||||
}
|
||||
|
||||
void ContentLoader::LoadXString(const char** pXString) const
|
||||
{
|
||||
assert(pXString != nullptr);
|
||||
|
||||
if(*pXString != nullptr)
|
||||
{
|
||||
if(*pXString == PTR_FOLLOWING)
|
||||
{
|
||||
*pXString = m_stream->Alloc<const char>();
|
||||
m_stream->LoadNullTerminated();
|
||||
}
|
||||
else
|
||||
{
|
||||
*pXString = m_stream->ConvertOffsetToPointer<const char>(*pXString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ContentLoader::LoadXStringArray(const char** pArray, const size_t count, const bool atStreamStart) const
|
||||
{
|
||||
assert(pArray != nullptr);
|
||||
|
||||
if(atStreamStart)
|
||||
m_stream->Load<const char*>(count);
|
||||
|
||||
for(size_t index = 0; index < count; index++)
|
||||
{
|
||||
LoadXString(&pArray[index]);
|
||||
}
|
||||
}
|
22
src/ZoneLoading/Loading/ContentLoader.h
Normal file
22
src/ZoneLoading/Loading/ContentLoader.h
Normal file
@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include "Zone/Zone.h"
|
||||
#include "Zone/Stream/IZoneInputStream.h"
|
||||
|
||||
class ContentLoader
|
||||
{
|
||||
protected:
|
||||
static const void* PTR_FOLLOWING;
|
||||
static const void* PTR_INSERT;
|
||||
|
||||
Zone* m_zone;
|
||||
IZoneInputStream* m_stream;
|
||||
|
||||
ContentLoader();
|
||||
|
||||
void LoadXString(const char** pXString) const;
|
||||
void LoadXStringArray(const char** pArray, size_t count, bool atStreamStart) const;
|
||||
|
||||
public:
|
||||
virtual ~ContentLoader() = default;
|
||||
};
|
16
src/ZoneLoading/Loading/Exception/BlockOverflowException.cpp
Normal file
16
src/ZoneLoading/Loading/Exception/BlockOverflowException.cpp
Normal file
@ -0,0 +1,16 @@
|
||||
#include "BlockOverflowException.h"
|
||||
|
||||
BlockOverflowException::BlockOverflowException(XBlock* block)
|
||||
{
|
||||
m_block = block;
|
||||
}
|
||||
|
||||
std::string BlockOverflowException::DetailedMessage()
|
||||
{
|
||||
return "XBlock " + m_block->m_name + " overflowed while trying to load zone.";
|
||||
}
|
||||
|
||||
char const* BlockOverflowException::what() const
|
||||
{
|
||||
return "Invalid Zone. XBlock overflowed.";
|
||||
}
|
14
src/ZoneLoading/Loading/Exception/BlockOverflowException.h
Normal file
14
src/ZoneLoading/Loading/Exception/BlockOverflowException.h
Normal file
@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
#include "LoadingException.h"
|
||||
#include "Zone/XBlock.h"
|
||||
|
||||
class BlockOverflowException final : public LoadingException
|
||||
{
|
||||
XBlock* m_block;
|
||||
|
||||
public:
|
||||
explicit BlockOverflowException(XBlock* block);
|
||||
|
||||
std::string DetailedMessage() override;
|
||||
char const* what() const override;
|
||||
};
|
@ -0,0 +1,30 @@
|
||||
#include "InvalidChunkSizeException.h"
|
||||
|
||||
InvalidChunkSizeException::InvalidChunkSizeException(const size_t size)
|
||||
{
|
||||
m_size = size;
|
||||
m_max = 0;
|
||||
}
|
||||
|
||||
InvalidChunkSizeException::InvalidChunkSizeException(const size_t size, const size_t max)
|
||||
{
|
||||
m_size = size;
|
||||
m_max = max;
|
||||
}
|
||||
|
||||
std::string InvalidChunkSizeException::DetailedMessage()
|
||||
{
|
||||
if(m_max > 0)
|
||||
{
|
||||
return "Zone chunk size has a chunk size of " + std::to_string(m_size) + " which is larger than the maximum of " + std::to_string(m_max);
|
||||
}
|
||||
else
|
||||
{
|
||||
return "Zone chunk size has an invalid chunk size of " + std::to_string(m_size);
|
||||
}
|
||||
}
|
||||
|
||||
char const* InvalidChunkSizeException::what() const
|
||||
{
|
||||
return "Zone has invalid chunk size";
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
#include "LoadingException.h"
|
||||
|
||||
class InvalidChunkSizeException final : public LoadingException
|
||||
{
|
||||
size_t m_size;
|
||||
size_t m_max;
|
||||
|
||||
public:
|
||||
explicit InvalidChunkSizeException(size_t size);
|
||||
InvalidChunkSizeException(size_t size, size_t max);
|
||||
|
||||
std::string DetailedMessage() override;
|
||||
char const* what() const override;
|
||||
};
|
@ -0,0 +1,11 @@
|
||||
#include "InvalidCompressionException.h"
|
||||
|
||||
std::string InvalidCompressionException::DetailedMessage()
|
||||
{
|
||||
return "Zone has invalid or unsupported compression. Inflate failed";
|
||||
}
|
||||
|
||||
char const* InvalidCompressionException::what() const
|
||||
{
|
||||
return "Zone has invalid or unsupported compression. Inflate failed";
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
#include "LoadingException.h"
|
||||
|
||||
class InvalidCompressionException final : public LoadingException
|
||||
{
|
||||
public:
|
||||
std::string DetailedMessage() override;
|
||||
char const* what() const override;
|
||||
};
|
@ -0,0 +1,17 @@
|
||||
#include "InvalidFileNameException.h"
|
||||
|
||||
InvalidFileNameException::InvalidFileNameException(std::string& actualFileName, std::string& expectedFileName)
|
||||
{
|
||||
m_actual_file_name = actualFileName;
|
||||
m_expected_file_name = expectedFileName;
|
||||
}
|
||||
|
||||
std::string InvalidFileNameException::DetailedMessage()
|
||||
{
|
||||
return "Name verification failed: The fastfile was created as '" + m_expected_file_name + "' but loaded as '" + m_actual_file_name + "'";
|
||||
}
|
||||
|
||||
char const* InvalidFileNameException::what() const
|
||||
{
|
||||
return "The filename when created and when loaded does not match";
|
||||
}
|
14
src/ZoneLoading/Loading/Exception/InvalidFileNameException.h
Normal file
14
src/ZoneLoading/Loading/Exception/InvalidFileNameException.h
Normal file
@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
#include "LoadingException.h"
|
||||
|
||||
class InvalidFileNameException final : public LoadingException
|
||||
{
|
||||
std::string m_actual_file_name;
|
||||
std::string m_expected_file_name;
|
||||
|
||||
public:
|
||||
InvalidFileNameException(std::string& actualFileName, std::string& expectedFileName);
|
||||
|
||||
std::string DetailedMessage() override;
|
||||
char const* what() const override;
|
||||
};
|
16
src/ZoneLoading/Loading/Exception/InvalidMagicException.cpp
Normal file
16
src/ZoneLoading/Loading/Exception/InvalidMagicException.cpp
Normal file
@ -0,0 +1,16 @@
|
||||
#include "InvalidMagicException.h"
|
||||
|
||||
InvalidMagicException::InvalidMagicException(const char* expectedMagic)
|
||||
{
|
||||
m_expected_magic = expectedMagic;
|
||||
}
|
||||
|
||||
std::string InvalidMagicException::DetailedMessage()
|
||||
{
|
||||
return "Expected magic '" + std::string(m_expected_magic) + "'";
|
||||
}
|
||||
|
||||
char const* InvalidMagicException::what() const
|
||||
{
|
||||
return "Encountered invalid magic when loading.";
|
||||
}
|
13
src/ZoneLoading/Loading/Exception/InvalidMagicException.h
Normal file
13
src/ZoneLoading/Loading/Exception/InvalidMagicException.h
Normal file
@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
#include "LoadingException.h"
|
||||
|
||||
class InvalidMagicException final : public LoadingException
|
||||
{
|
||||
const char* m_expected_magic;
|
||||
|
||||
public:
|
||||
explicit InvalidMagicException(const char* expectedMagic);
|
||||
|
||||
std::string DetailedMessage() override;
|
||||
char const* what() const override;
|
||||
};
|
@ -0,0 +1,16 @@
|
||||
#include "InvalidOffsetBlockException.h"
|
||||
|
||||
InvalidOffsetBlockException::InvalidOffsetBlockException(const block_t referencedBlock)
|
||||
{
|
||||
m_referenced_block = referencedBlock;
|
||||
}
|
||||
|
||||
std::string InvalidOffsetBlockException::DetailedMessage()
|
||||
{
|
||||
return "Zone tried to reference invalid block " + std::to_string(m_referenced_block);
|
||||
}
|
||||
|
||||
char const* InvalidOffsetBlockException::what() const
|
||||
{
|
||||
return "Zone referenced invalid block";
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
#include "LoadingException.h"
|
||||
#include "Zone/ZoneTypes.h"
|
||||
|
||||
class InvalidOffsetBlockException final : public LoadingException
|
||||
{
|
||||
block_t m_referenced_block;
|
||||
|
||||
public:
|
||||
explicit InvalidOffsetBlockException(block_t referencedBlock);
|
||||
|
||||
std::string DetailedMessage() override;
|
||||
char const* what() const override;
|
||||
};
|
@ -0,0 +1,18 @@
|
||||
#include "InvalidOffsetBlockOffsetException.h"
|
||||
|
||||
InvalidOffsetBlockOffsetException::InvalidOffsetBlockOffsetException(XBlock* block, const size_t referencedOffset)
|
||||
{
|
||||
m_referenced_block = block;
|
||||
m_referenced_offset = referencedOffset;
|
||||
}
|
||||
|
||||
std::string InvalidOffsetBlockOffsetException::DetailedMessage()
|
||||
{
|
||||
return "Zone referenced offset" + std::to_string(m_referenced_offset) + " of block " + m_referenced_block->m_name
|
||||
+ " which is larger than its size " + std::to_string(m_referenced_block->m_buffer_size);
|
||||
}
|
||||
|
||||
char const* InvalidOffsetBlockOffsetException::what() const
|
||||
{
|
||||
return "Zone referenced offset of block that is out of bounds";
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
#include "LoadingException.h"
|
||||
#include "Zone/XBlock.h"
|
||||
|
||||
class InvalidOffsetBlockOffsetException final : public LoadingException
|
||||
{
|
||||
XBlock* m_referenced_block;
|
||||
size_t m_referenced_offset;
|
||||
|
||||
public:
|
||||
InvalidOffsetBlockOffsetException(XBlock* block, size_t referencedOffset);
|
||||
|
||||
std::string DetailedMessage() override;
|
||||
char const* what() const override;
|
||||
};
|
@ -0,0 +1,11 @@
|
||||
#include "InvalidSignatureException.h"
|
||||
|
||||
std::string InvalidSignatureException::DetailedMessage()
|
||||
{
|
||||
return "Loaded fastfile has an invalid signature.";
|
||||
}
|
||||
|
||||
char const* InvalidSignatureException::what() const
|
||||
{
|
||||
return "Loaded fastfile has an invalid signature.";
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
#include "LoadingException.h"
|
||||
|
||||
class InvalidSignatureException final : public LoadingException
|
||||
{
|
||||
public:
|
||||
std::string DetailedMessage() override;
|
||||
char const* what() const override;
|
||||
};
|
@ -0,0 +1,17 @@
|
||||
#include "InvalidVersionException.h"
|
||||
|
||||
InvalidVersionException::InvalidVersionException(const unsigned int expectedVersion, const unsigned int actualVersion)
|
||||
{
|
||||
m_expected_version = expectedVersion;
|
||||
m_actual_version = actualVersion;
|
||||
}
|
||||
|
||||
std::string InvalidVersionException::DetailedMessage()
|
||||
{
|
||||
return "Expected version " + std::to_string(m_expected_version) + " but encountered version " + std::to_string(m_actual_version);
|
||||
}
|
||||
|
||||
char const* InvalidVersionException::what() const
|
||||
{
|
||||
return "Encountered invalid version when loading.";
|
||||
}
|
14
src/ZoneLoading/Loading/Exception/InvalidVersionException.h
Normal file
14
src/ZoneLoading/Loading/Exception/InvalidVersionException.h
Normal file
@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
#include "LoadingException.h"
|
||||
|
||||
class InvalidVersionException final : public LoadingException
|
||||
{
|
||||
unsigned int m_expected_version;
|
||||
unsigned int m_actual_version;
|
||||
|
||||
public:
|
||||
InvalidVersionException(unsigned int expectedVersion, unsigned int actualVersion);
|
||||
|
||||
std::string DetailedMessage() override;
|
||||
char const* what() const override;
|
||||
};
|
@ -0,0 +1,17 @@
|
||||
#include "InvalidXBlockSizeException.h"
|
||||
|
||||
InvalidXBlockSizeException::InvalidXBlockSizeException(const uint64_t size, const uint64_t max)
|
||||
{
|
||||
m_size = size;
|
||||
m_max = max;
|
||||
}
|
||||
|
||||
std::string InvalidXBlockSizeException::DetailedMessage()
|
||||
{
|
||||
return "Zone uses more XBlock memory than allowed: " + std::to_string(m_size) + " (max is " + std::to_string(m_max) + ")";
|
||||
}
|
||||
|
||||
char const* InvalidXBlockSizeException::what() const
|
||||
{
|
||||
return "Zone has invalid block size";
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
#include "LoadingException.h"
|
||||
|
||||
class InvalidXBlockSizeException final : public LoadingException
|
||||
{
|
||||
uint64_t m_size;
|
||||
uint64_t m_max;
|
||||
|
||||
public:
|
||||
InvalidXBlockSizeException(uint64_t size, uint64_t max);
|
||||
|
||||
std::string DetailedMessage() override;
|
||||
char const* what() const override;
|
||||
};
|
9
src/ZoneLoading/Loading/Exception/LoadingException.h
Normal file
9
src/ZoneLoading/Loading/Exception/LoadingException.h
Normal file
@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
#include <exception>
|
||||
#include <string>
|
||||
|
||||
class LoadingException : public std::exception
|
||||
{
|
||||
public:
|
||||
virtual std::string DetailedMessage() = 0;
|
||||
};
|
@ -0,0 +1,13 @@
|
||||
#include "UnexpectedEndOfFileException.h"
|
||||
|
||||
UnexpectedEndOfFileException::UnexpectedEndOfFileException() = default;
|
||||
|
||||
std::string UnexpectedEndOfFileException::DetailedMessage()
|
||||
{
|
||||
return "Unexpected end of file";
|
||||
}
|
||||
|
||||
char const* UnexpectedEndOfFileException::what() const
|
||||
{
|
||||
return "Unexpected end of file";
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
#include "LoadingException.h"
|
||||
|
||||
class UnexpectedEndOfFileException final : public LoadingException
|
||||
{
|
||||
public:
|
||||
UnexpectedEndOfFileException();
|
||||
|
||||
std::string DetailedMessage() override;
|
||||
char const* what() const override;
|
||||
};
|
@ -0,0 +1,16 @@
|
||||
#include "UnsupportedAssetTypeException.h"
|
||||
|
||||
UnsupportedAssetTypeException::UnsupportedAssetTypeException(const int assetType)
|
||||
{
|
||||
m_asset_type = assetType;
|
||||
}
|
||||
|
||||
std::string UnsupportedAssetTypeException::DetailedMessage()
|
||||
{
|
||||
return "Zone has an unsupported asset type " + std::to_string(m_asset_type) + " and therefore cannot be loaded.";
|
||||
}
|
||||
|
||||
char const* UnsupportedAssetTypeException::what() const
|
||||
{
|
||||
return "Zone has unsupported asset type.";
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
#include "LoadingException.h"
|
||||
|
||||
class UnsupportedAssetTypeException final : public LoadingException
|
||||
{
|
||||
int m_asset_type;
|
||||
|
||||
public:
|
||||
explicit UnsupportedAssetTypeException(int assetType);
|
||||
|
||||
std::string DetailedMessage() override;
|
||||
char const* what() const override;
|
||||
};
|
12
src/ZoneLoading/Loading/IContentLoadingEntryPoint.h
Normal file
12
src/ZoneLoading/Loading/IContentLoadingEntryPoint.h
Normal file
@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "Zone/Zone.h"
|
||||
#include "Zone/Stream/IZoneInputStream.h"
|
||||
|
||||
class IContentLoadingEntryPoint
|
||||
{
|
||||
public:
|
||||
virtual ~IContentLoadingEntryPoint() = default;
|
||||
|
||||
virtual void Load(Zone* zone, IZoneInputStream* stream) = 0;
|
||||
};
|
14
src/ZoneLoading/Loading/ILoadingStep.h
Normal file
14
src/ZoneLoading/Loading/ILoadingStep.h
Normal file
@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include "Loading/ZoneLoader.h"
|
||||
#include "ILoadingStream.h"
|
||||
|
||||
class ZoneLoader;
|
||||
|
||||
class ILoadingStep
|
||||
{
|
||||
public:
|
||||
virtual ~ILoadingStep() = default;
|
||||
|
||||
virtual void PerformStep(ZoneLoader* zoneLoader, ILoadingStream* stream) = 0;
|
||||
};
|
9
src/ZoneLoading/Loading/ILoadingStream.h
Normal file
9
src/ZoneLoading/Loading/ILoadingStream.h
Normal file
@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
class ILoadingStream
|
||||
{
|
||||
public:
|
||||
virtual ~ILoadingStream() = default;
|
||||
|
||||
virtual size_t Load(void* buffer, size_t length) = 0;
|
||||
};
|
8
src/ZoneLoading/Loading/ISignatureDataProvider.h
Normal file
8
src/ZoneLoading/Loading/ISignatureDataProvider.h
Normal file
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
|
||||
class ISignatureDataProvider
|
||||
{
|
||||
public:
|
||||
virtual void GetSignatureData(const uint8_t** pSignatureData, size_t* pSize) = 0;
|
||||
};
|
8
src/ZoneLoading/Loading/ISignatureProvider.h
Normal file
8
src/ZoneLoading/Loading/ISignatureProvider.h
Normal file
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
|
||||
class ISignatureProvider
|
||||
{
|
||||
public:
|
||||
virtual void GetSignature(const uint8_t** pSignature, size_t* pSize) = 0;
|
||||
};
|
12
src/ZoneLoading/Loading/IZoneLoaderFactory.h
Normal file
12
src/ZoneLoading/Loading/IZoneLoaderFactory.h
Normal file
@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "Zone/ZoneTypes.h"
|
||||
#include "ZoneLoader.h"
|
||||
|
||||
class IZoneLoaderFactory
|
||||
{
|
||||
public:
|
||||
virtual ~IZoneLoaderFactory() = default;
|
||||
|
||||
virtual ZoneLoader* CreateLoaderForHeader(ZoneHeader& header, std::string& fileName) = 0;
|
||||
};
|
10
src/ZoneLoading/Loading/IZoneScriptStringProvider.h
Normal file
10
src/ZoneLoading/Loading/IZoneScriptStringProvider.h
Normal file
@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "Zone/ZoneTypes.h"
|
||||
#include <string>
|
||||
|
||||
class IZoneScriptStringProvider
|
||||
{
|
||||
public:
|
||||
virtual std::string& GetZoneScriptString(scr_string_t scrString) = 0;
|
||||
};
|
11
src/ZoneLoading/Loading/LoadingFileStream.cpp
Normal file
11
src/ZoneLoading/Loading/LoadingFileStream.cpp
Normal file
@ -0,0 +1,11 @@
|
||||
#include "LoadingFileStream.h"
|
||||
|
||||
LoadingFileStream::LoadingFileStream(FileAPI::File* file)
|
||||
{
|
||||
m_file = file;
|
||||
}
|
||||
|
||||
size_t LoadingFileStream::Load(void* buffer, const size_t length)
|
||||
{
|
||||
return m_file->Read(buffer, 1, length);
|
||||
}
|
13
src/ZoneLoading/Loading/LoadingFileStream.h
Normal file
13
src/ZoneLoading/Loading/LoadingFileStream.h
Normal file
@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
#include "ILoadingStream.h"
|
||||
#include "Utils/FileAPI.h"
|
||||
|
||||
class LoadingFileStream : public ILoadingStream
|
||||
{
|
||||
FileAPI::File* m_file;
|
||||
|
||||
public:
|
||||
explicit LoadingFileStream(FileAPI::File* file);
|
||||
|
||||
size_t Load(void* buffer, size_t length) override;
|
||||
};
|
73
src/ZoneLoading/Loading/Processor/ProcessorInflate.cpp
Normal file
73
src/ZoneLoading/Loading/Processor/ProcessorInflate.cpp
Normal file
@ -0,0 +1,73 @@
|
||||
#include "ProcessorInflate.h"
|
||||
#include "zlib.h"
|
||||
#include <exception>
|
||||
#include "zutil.h"
|
||||
#include <cstdint>
|
||||
|
||||
class ProcessorInflate::ProcessorInflateImpl
|
||||
{
|
||||
z_stream m_stream{};
|
||||
uint8_t m_in_buffer[0x800];
|
||||
ProcessorInflate* m_base;
|
||||
|
||||
public:
|
||||
ProcessorInflateImpl(ProcessorInflate* baseClass)
|
||||
{
|
||||
m_base = baseClass;
|
||||
|
||||
m_stream.zalloc = Z_NULL;
|
||||
m_stream.zfree = Z_NULL;
|
||||
m_stream.opaque = Z_NULL;
|
||||
m_stream.avail_in = 0;
|
||||
m_stream.next_in = Z_NULL;
|
||||
|
||||
const int ret = inflateInit2(&m_stream, -DEF_WBITS);
|
||||
|
||||
if(ret != Z_OK)
|
||||
{
|
||||
throw std::exception("Initializing inflate failed");
|
||||
}
|
||||
}
|
||||
|
||||
~ProcessorInflateImpl()
|
||||
{
|
||||
inflateEnd(&m_stream);
|
||||
}
|
||||
|
||||
size_t Load(void* buffer, size_t length)
|
||||
{
|
||||
m_stream.next_out = static_cast<Bytef*>(buffer);
|
||||
m_stream.avail_out = length;
|
||||
|
||||
while(m_stream.avail_out > 0)
|
||||
{
|
||||
if(m_stream.avail_in == 0)
|
||||
{
|
||||
m_stream.avail_in = m_base->m_base_stream->Load(m_in_buffer, sizeof(m_in_buffer));
|
||||
|
||||
if(m_stream.avail_in == 0) // EOF
|
||||
return length - m_stream.avail_out;
|
||||
}
|
||||
|
||||
inflate(&m_stream, Z_FULL_FLUSH);
|
||||
}
|
||||
|
||||
return m_stream.avail_out;
|
||||
}
|
||||
};
|
||||
|
||||
ProcessorInflate::ProcessorInflate()
|
||||
{
|
||||
m_impl = new ProcessorInflateImpl(this);
|
||||
}
|
||||
|
||||
ProcessorInflate::~ProcessorInflate()
|
||||
{
|
||||
delete m_impl;
|
||||
m_impl = nullptr;
|
||||
}
|
||||
|
||||
size_t ProcessorInflate::Load(void* buffer, const size_t length)
|
||||
{
|
||||
return m_impl->Load(buffer, length);
|
||||
}
|
14
src/ZoneLoading/Loading/Processor/ProcessorInflate.h
Normal file
14
src/ZoneLoading/Loading/Processor/ProcessorInflate.h
Normal file
@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
#include "Loading/StreamProcessor.h"
|
||||
|
||||
class ProcessorInflate final : public StreamProcessor
|
||||
{
|
||||
class ProcessorInflateImpl;
|
||||
ProcessorInflateImpl* m_impl;
|
||||
|
||||
public:
|
||||
ProcessorInflate();
|
||||
~ProcessorInflate() override;
|
||||
|
||||
size_t Load(void* buffer, size_t length) override;
|
||||
};
|
28
src/ZoneLoading/Loading/Processor/ProcessorStreamCipher.cpp
Normal file
28
src/ZoneLoading/Loading/Processor/ProcessorStreamCipher.cpp
Normal file
@ -0,0 +1,28 @@
|
||||
#include "ProcessorStreamCipher.h"
|
||||
|
||||
ProcessorStreamCipher::ProcessorStreamCipher(IStreamCipher* cipher)
|
||||
{
|
||||
m_cipher = cipher;
|
||||
}
|
||||
|
||||
ProcessorStreamCipher::~ProcessorStreamCipher()
|
||||
{
|
||||
delete m_cipher;
|
||||
m_cipher = nullptr;
|
||||
}
|
||||
|
||||
|
||||
size_t ProcessorStreamCipher::Load(void* buffer, const size_t length)
|
||||
{
|
||||
if(m_base_stream != nullptr)
|
||||
{
|
||||
const size_t readSize = m_base_stream->Load(buffer, length);
|
||||
|
||||
if(readSize > 0)
|
||||
m_cipher->Process(buffer, buffer, readSize);
|
||||
|
||||
return readSize;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
14
src/ZoneLoading/Loading/Processor/ProcessorStreamCipher.h
Normal file
14
src/ZoneLoading/Loading/Processor/ProcessorStreamCipher.h
Normal file
@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
#include "Loading/StreamProcessor.h"
|
||||
#include "Crypto.h"
|
||||
|
||||
class ProcessorStreamCipher final : public StreamProcessor
|
||||
{
|
||||
IStreamCipher* m_cipher;
|
||||
|
||||
public:
|
||||
explicit ProcessorStreamCipher(IStreamCipher* cipher);
|
||||
~ProcessorStreamCipher() override;
|
||||
|
||||
size_t Load(void* buffer, size_t length) override;
|
||||
};
|
310
src/ZoneLoading/Loading/Processor/ProcessorXChunks.cpp
Normal file
310
src/ZoneLoading/Loading/Processor/ProcessorXChunks.cpp
Normal file
@ -0,0 +1,310 @@
|
||||
#include "ProcessorXChunks.h"
|
||||
#include "Zone/ZoneTypes.h"
|
||||
#include "Loading/Exception/InvalidChunkSizeException.h"
|
||||
|
||||
#include <vector>
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
#include <cassert>
|
||||
|
||||
class DBLoadStream
|
||||
{
|
||||
int m_index;
|
||||
|
||||
uint8_t* m_input_buffer;
|
||||
size_t m_input_size;
|
||||
|
||||
uint8_t* m_output_buffer;
|
||||
size_t m_output_size;
|
||||
|
||||
size_t m_chunk_size;
|
||||
|
||||
bool m_is_loading;
|
||||
std::mutex m_load_mutex;
|
||||
std::condition_variable m_loading_finished;
|
||||
std::thread m_load_thread;
|
||||
|
||||
std::vector<IXChunkProcessor*>& m_processors;
|
||||
|
||||
void Load()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_load_mutex);
|
||||
|
||||
bool firstProcessor = true;
|
||||
|
||||
for(auto processor : m_processors)
|
||||
{
|
||||
if(!firstProcessor)
|
||||
{
|
||||
uint8_t* previousInputBuffer = m_input_buffer;
|
||||
m_input_buffer = m_output_buffer;
|
||||
m_output_buffer = previousInputBuffer;
|
||||
|
||||
m_input_size = m_output_size;
|
||||
m_output_size = 0;
|
||||
}
|
||||
|
||||
m_output_size = processor->Process(m_index, m_input_buffer, m_input_size, m_output_buffer, m_chunk_size);
|
||||
|
||||
firstProcessor = false;
|
||||
}
|
||||
|
||||
m_is_loading = false;
|
||||
m_loading_finished.notify_all();
|
||||
}
|
||||
|
||||
public:
|
||||
DBLoadStream(const int streamIndex, const size_t chunkSize, std::vector<IXChunkProcessor*>& chunkProcessors) : m_processors(chunkProcessors)
|
||||
{
|
||||
m_index = streamIndex;
|
||||
m_chunk_size = chunkSize;
|
||||
|
||||
m_input_buffer = new uint8_t[chunkSize];
|
||||
m_output_buffer = new uint8_t[chunkSize];
|
||||
|
||||
m_input_size = 0;
|
||||
m_output_size = 0;
|
||||
|
||||
m_is_loading = false;
|
||||
}
|
||||
|
||||
~DBLoadStream()
|
||||
{
|
||||
delete[] m_input_buffer;
|
||||
m_input_buffer = nullptr;
|
||||
|
||||
delete[] m_output_buffer;
|
||||
m_output_buffer = nullptr;
|
||||
}
|
||||
|
||||
uint8_t* GetInputBuffer() const
|
||||
{
|
||||
return m_input_buffer;
|
||||
}
|
||||
|
||||
void StartLoading(const size_t inputSize)
|
||||
{
|
||||
if(inputSize > 0)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(m_load_mutex);
|
||||
|
||||
if(m_is_loading)
|
||||
{
|
||||
m_loading_finished.wait(lock);
|
||||
}
|
||||
|
||||
m_input_size = inputSize;
|
||||
m_is_loading = true;
|
||||
m_load_thread = std::thread(&DBLoadStream::Load, this);
|
||||
m_load_thread.detach();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_output_size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void GetOutput(const uint8_t** pBuffer, size_t* pSize)
|
||||
{
|
||||
assert(pBuffer != nullptr);
|
||||
assert(pSize != nullptr);
|
||||
|
||||
std::unique_lock<std::mutex> lock(m_load_mutex);
|
||||
if(m_is_loading)
|
||||
{
|
||||
m_loading_finished.wait(lock);
|
||||
}
|
||||
|
||||
*pBuffer = m_output_buffer;
|
||||
*pSize = m_output_size;
|
||||
}
|
||||
};
|
||||
|
||||
class ProcessorXChunks::ProcessorXChunksImpl
|
||||
{
|
||||
ProcessorXChunks* m_base;
|
||||
|
||||
std::vector<DBLoadStream*> m_streams;
|
||||
size_t m_chunk_size;
|
||||
std::vector<IXChunkProcessor*> m_chunk_processors;
|
||||
|
||||
bool m_initialized_streams;
|
||||
unsigned int m_current_stream;
|
||||
const uint8_t* m_current_chunk;
|
||||
size_t m_current_chunk_size;
|
||||
size_t m_current_chunk_offset;
|
||||
|
||||
bool m_eof_reached;
|
||||
unsigned int m_eof_stream;
|
||||
|
||||
void AdvanceStream(const unsigned int streamNum)
|
||||
{
|
||||
assert(streamNum >= 0 && streamNum < m_streams.size());
|
||||
|
||||
if(m_eof_reached)
|
||||
return;
|
||||
|
||||
xchunk_size_t chunkSize;
|
||||
const size_t readSize = m_base->m_base_stream->Load(&chunkSize, sizeof(chunkSize));
|
||||
|
||||
if(readSize == 0)
|
||||
{
|
||||
m_eof_reached = true;
|
||||
m_eof_stream = streamNum;
|
||||
return;
|
||||
}
|
||||
|
||||
if(chunkSize > m_chunk_size)
|
||||
{
|
||||
throw InvalidChunkSizeException(chunkSize, m_chunk_size);
|
||||
}
|
||||
|
||||
auto* stream = m_streams[streamNum];
|
||||
const size_t loadedChunkSize = m_base->m_base_stream->Load(stream->GetInputBuffer(), chunkSize);
|
||||
|
||||
if(loadedChunkSize != chunkSize)
|
||||
{
|
||||
throw InvalidChunkSizeException(chunkSize);
|
||||
}
|
||||
|
||||
stream->StartLoading(loadedChunkSize);
|
||||
}
|
||||
|
||||
void NextStream()
|
||||
{
|
||||
AdvanceStream(m_current_stream);
|
||||
|
||||
m_current_stream = (m_current_stream + 1) % m_streams.size();
|
||||
m_current_chunk_offset = 0;
|
||||
m_streams[m_current_stream]->GetOutput(&m_current_chunk, &m_current_chunk_size);
|
||||
}
|
||||
|
||||
void InitStreams()
|
||||
{
|
||||
m_initialized_streams = true;
|
||||
|
||||
const unsigned int streamCount = m_streams.size();
|
||||
for(unsigned int streamNum = 0; streamNum < streamCount; streamNum++)
|
||||
{
|
||||
AdvanceStream(streamNum);
|
||||
}
|
||||
|
||||
m_current_stream = 0;
|
||||
m_current_chunk_offset = 0;
|
||||
m_streams[0]->GetOutput(&m_current_chunk, &m_current_chunk_size);
|
||||
}
|
||||
|
||||
bool EndOfStream() const
|
||||
{
|
||||
return m_eof_reached && m_eof_stream == m_current_stream;
|
||||
}
|
||||
|
||||
public:
|
||||
ProcessorXChunksImpl(ProcessorXChunks* base, const int numStreams, const size_t xChunkSize)
|
||||
{
|
||||
assert(base != nullptr);
|
||||
assert(numStreams > 0);
|
||||
assert(xChunkSize > 0);
|
||||
|
||||
m_base = base;
|
||||
|
||||
for(int streamIndex = 0; streamIndex < numStreams; streamIndex++)
|
||||
{
|
||||
m_streams.push_back(new DBLoadStream(streamIndex, xChunkSize, m_chunk_processors));
|
||||
}
|
||||
|
||||
m_chunk_size = xChunkSize;
|
||||
|
||||
m_initialized_streams = false;
|
||||
m_current_stream = 0;
|
||||
m_current_chunk = nullptr;
|
||||
m_current_chunk_size = 0;
|
||||
m_current_chunk_offset = 0;
|
||||
|
||||
m_eof_reached = false;
|
||||
m_eof_stream = 0;
|
||||
}
|
||||
|
||||
~ProcessorXChunksImpl()
|
||||
{
|
||||
for(auto* stream : m_streams)
|
||||
{
|
||||
delete stream;
|
||||
}
|
||||
m_streams.clear();
|
||||
|
||||
for(auto* processor : m_chunk_processors)
|
||||
{
|
||||
delete processor;
|
||||
}
|
||||
m_chunk_processors.clear();
|
||||
}
|
||||
|
||||
void AddChunkProcessor(IXChunkProcessor* streamProcessor)
|
||||
{
|
||||
assert(streamProcessor != nullptr);
|
||||
|
||||
m_chunk_processors.push_back(streamProcessor);
|
||||
}
|
||||
|
||||
size_t Load(void* buffer, const size_t length)
|
||||
{
|
||||
assert(buffer != nullptr);
|
||||
|
||||
if(!m_initialized_streams)
|
||||
{
|
||||
InitStreams();
|
||||
}
|
||||
|
||||
size_t loadedSize = 0;
|
||||
while(!EndOfStream() && loadedSize < length)
|
||||
{
|
||||
auto* bufferPos = static_cast<uint8_t*>(buffer) + loadedSize;
|
||||
const size_t sizeToRead = length - loadedSize;
|
||||
const size_t bytesLeftInCurrentChunk = m_current_chunk_size - m_current_chunk_offset;
|
||||
|
||||
if(sizeToRead > bytesLeftInCurrentChunk)
|
||||
{
|
||||
memcpy_s(bufferPos, sizeToRead, &m_current_chunk[m_current_chunk_offset], bytesLeftInCurrentChunk);
|
||||
loadedSize += bytesLeftInCurrentChunk;
|
||||
|
||||
NextStream();
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy_s(bufferPos, sizeToRead, &m_current_chunk[m_current_chunk_offset], sizeToRead);
|
||||
loadedSize += sizeToRead;
|
||||
m_current_chunk_offset += sizeToRead;
|
||||
|
||||
if(m_current_chunk_offset == m_current_chunk_size)
|
||||
{
|
||||
NextStream();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return loadedSize;
|
||||
}
|
||||
};
|
||||
|
||||
ProcessorXChunks::ProcessorXChunks(const int numStreams, const size_t xChunkSize)
|
||||
{
|
||||
m_impl = new ProcessorXChunksImpl(this, numStreams, xChunkSize);
|
||||
}
|
||||
|
||||
ProcessorXChunks::~ProcessorXChunks()
|
||||
{
|
||||
delete m_impl;
|
||||
m_impl = nullptr;
|
||||
}
|
||||
|
||||
void ProcessorXChunks::AddChunkProcessor(IXChunkProcessor* chunkProcessor) const
|
||||
{
|
||||
m_impl->AddChunkProcessor(chunkProcessor);
|
||||
}
|
||||
|
||||
size_t ProcessorXChunks::Load(void* buffer, const size_t length)
|
||||
{
|
||||
return m_impl->Load(buffer, length);
|
||||
}
|
17
src/ZoneLoading/Loading/Processor/ProcessorXChunks.h
Normal file
17
src/ZoneLoading/Loading/Processor/ProcessorXChunks.h
Normal file
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
#include "Loading/StreamProcessor.h"
|
||||
#include "XChunks/IXChunkProcessor.h"
|
||||
|
||||
class ProcessorXChunks : public StreamProcessor
|
||||
{
|
||||
class ProcessorXChunksImpl;
|
||||
ProcessorXChunksImpl* m_impl;
|
||||
|
||||
public:
|
||||
ProcessorXChunks(int numStreams, size_t xChunkSize);
|
||||
~ProcessorXChunks() override;
|
||||
|
||||
size_t Load(void* buffer, size_t length) override;
|
||||
|
||||
void AddChunkProcessor(IXChunkProcessor* chunkProcessor) const;
|
||||
};
|
@ -0,0 +1,36 @@
|
||||
#include "ChunkProcessorInflate.h"
|
||||
#include "zlib.h"
|
||||
#include "zutil.h"
|
||||
#include <exception>
|
||||
#include "Loading/Exception/InvalidCompressionException.h"
|
||||
|
||||
size_t ChunkProcessorInflate::Process(int streamNumber, const uint8_t* input, const size_t inputLength, uint8_t* output, const size_t outputBufferSize)
|
||||
{
|
||||
z_stream stream{};
|
||||
stream.zalloc = Z_NULL;
|
||||
stream.zfree = Z_NULL;
|
||||
stream.opaque = Z_NULL;
|
||||
|
||||
int ret = inflateInit2(&stream, -DEF_WBITS);
|
||||
if(ret != Z_OK)
|
||||
{
|
||||
throw std::exception("Initializing inflate failed.");
|
||||
}
|
||||
|
||||
stream.avail_in = inputLength;
|
||||
stream.next_in = input;
|
||||
stream.avail_out = outputBufferSize;
|
||||
stream.next_out = output;
|
||||
|
||||
ret = inflate(&stream, Z_FULL_FLUSH);
|
||||
if(ret != Z_STREAM_END)
|
||||
{
|
||||
throw InvalidCompressionException();
|
||||
}
|
||||
|
||||
const size_t outputSize = stream.total_out;
|
||||
|
||||
inflateEnd(&stream);
|
||||
|
||||
return outputSize;
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
#include "IXChunkProcessor.h"
|
||||
|
||||
class ChunkProcessorInflate : public IXChunkProcessor
|
||||
{
|
||||
public:
|
||||
size_t Process(int streamNumber, const uint8_t* input, size_t inputLength, uint8_t* output, size_t outputBufferSize) override;
|
||||
};
|
@ -0,0 +1,156 @@
|
||||
#include "ChunkProcessorSalsa20.h"
|
||||
#include "Crypto.h"
|
||||
#include <cassert>
|
||||
|
||||
class StreamContextSalsa20
|
||||
{
|
||||
public:
|
||||
IStreamCipher* m_salsa20;
|
||||
IHashFunction* m_sha1;
|
||||
|
||||
StreamContextSalsa20()
|
||||
{
|
||||
m_salsa20 = nullptr;
|
||||
m_sha1 = nullptr;
|
||||
}
|
||||
|
||||
~StreamContextSalsa20()
|
||||
{
|
||||
delete m_salsa20;
|
||||
m_salsa20 = nullptr;
|
||||
|
||||
delete m_sha1;
|
||||
m_sha1 = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
class ChunkProcessorSalsa20::ChunkProcessorSalsa20Impl
|
||||
{
|
||||
static const int BLOCK_HASHES_COUNT = 200;
|
||||
static const int SHA1_HASH_SIZE = 20;
|
||||
static const int SALSA20_IV_SIZE = 8;
|
||||
|
||||
int m_stream_count;
|
||||
StreamContextSalsa20* m_stream_contexts;
|
||||
|
||||
// m_block_hashes[BLOCK_HASHES_COUNT][numStreams][HASH_SIZE]
|
||||
uint8_t* m_block_hashes;
|
||||
unsigned int* m_stream_block_indices;
|
||||
|
||||
uint8_t* GetHashBlock(const int streamNumber) const
|
||||
{
|
||||
const size_t blockIndexOffset = m_stream_block_indices[streamNumber] * m_stream_count * SHA1_HASH_SIZE;
|
||||
const size_t streamOffset = streamNumber * SHA1_HASH_SIZE;
|
||||
|
||||
return &m_block_hashes[blockIndexOffset + streamOffset];
|
||||
}
|
||||
|
||||
public:
|
||||
ChunkProcessorSalsa20Impl(const int streamCount, std::string& zoneName, const uint8_t* salsa20Key, size_t keySize)
|
||||
{
|
||||
m_stream_count = streamCount;
|
||||
m_stream_contexts = new StreamContextSalsa20[streamCount];
|
||||
m_block_hashes = new uint8_t[BLOCK_HASHES_COUNT * streamCount * SHA1_HASH_SIZE];
|
||||
m_stream_block_indices = new unsigned int[streamCount];
|
||||
|
||||
InitStreams(zoneName, salsa20Key, keySize);
|
||||
}
|
||||
|
||||
~ChunkProcessorSalsa20Impl()
|
||||
{
|
||||
delete[] m_stream_contexts;
|
||||
|
||||
delete[] m_block_hashes;
|
||||
m_block_hashes = nullptr;
|
||||
|
||||
delete[] m_stream_block_indices;
|
||||
m_stream_block_indices = nullptr;
|
||||
}
|
||||
|
||||
void InitStreams(std::string& zoneName, const uint8_t* salsa20Key, size_t keySize) const
|
||||
{
|
||||
const int zoneNameLength = zoneName.length();
|
||||
const size_t blockHashBufferSize = BLOCK_HASHES_COUNT * m_stream_count * SHA1_HASH_SIZE;
|
||||
|
||||
assert(blockHashBufferSize % 4 == 0);
|
||||
|
||||
size_t zoneNameOffset = 0;
|
||||
for(size_t i = 0; i < blockHashBufferSize; i += 4)
|
||||
{
|
||||
*reinterpret_cast<uint32_t*>(&m_block_hashes[i]) = 0x1010101 * zoneName[zoneNameOffset++];
|
||||
|
||||
zoneNameOffset %= zoneNameLength;
|
||||
}
|
||||
|
||||
for(int stream = 0; stream < m_stream_count; stream++)
|
||||
{
|
||||
m_stream_block_indices[stream] = 0;
|
||||
|
||||
m_stream_contexts[stream].m_salsa20 = Crypto::CreateSalsa20(salsa20Key, keySize);
|
||||
m_stream_contexts[stream].m_sha1 = Crypto::CreateSHA1();
|
||||
}
|
||||
}
|
||||
|
||||
size_t Process(const int streamNumber, const uint8_t* input, const size_t inputLength, uint8_t* output, const size_t outputBufferSize) const
|
||||
{
|
||||
assert(streamNumber >= 0 && streamNumber < m_stream_count);
|
||||
assert(input != nullptr);
|
||||
assert(output != nullptr);
|
||||
assert(inputLength <= outputBufferSize);
|
||||
|
||||
StreamContextSalsa20& streamContext = m_stream_contexts[streamNumber];
|
||||
|
||||
// Initialize Salsa20 with an IV of the first 8 bytes of the current hash block
|
||||
streamContext.m_salsa20->SetIV(GetHashBlock(streamNumber), SALSA20_IV_SIZE);
|
||||
streamContext.m_salsa20->Process(input, output, inputLength);
|
||||
|
||||
// Hash decrypted XChunk
|
||||
uint8_t blockSha1Hash[SHA1_HASH_SIZE];
|
||||
streamContext.m_sha1->Init();
|
||||
streamContext.m_sha1->Process(output, inputLength);
|
||||
streamContext.m_sha1->Finish(&blockSha1Hash);
|
||||
|
||||
// Advance index to next hash block
|
||||
m_stream_block_indices[streamNumber] = (m_stream_block_indices[streamNumber] + 1) % BLOCK_HASHES_COUNT;
|
||||
|
||||
uint8_t* nextHashBlock = GetHashBlock(streamNumber);
|
||||
|
||||
// XOR the upcoming hash block with the hash of the XChunk utilizing the previous hash block
|
||||
for(unsigned int hashOffset = 0; hashOffset < sizeof(blockSha1Hash); hashOffset++)
|
||||
{
|
||||
nextHashBlock[hashOffset] ^= blockSha1Hash[hashOffset];
|
||||
}
|
||||
|
||||
return inputLength;
|
||||
}
|
||||
|
||||
void GetSignatureData(const uint8_t** pSignatureData, size_t* pSize) const
|
||||
{
|
||||
assert(pSignatureData != nullptr);
|
||||
assert(pSize != nullptr);
|
||||
|
||||
*pSignatureData = m_block_hashes;
|
||||
*pSize = BLOCK_HASHES_COUNT * m_stream_count * SHA1_HASH_SIZE;
|
||||
}
|
||||
};
|
||||
|
||||
ChunkProcessorSalsa20::ChunkProcessorSalsa20(const int streamCount, std::string& zoneName, const uint8_t* salsa20Key, size_t keySize)
|
||||
{
|
||||
m_impl = new ChunkProcessorSalsa20Impl(streamCount, zoneName, salsa20Key, keySize);
|
||||
}
|
||||
|
||||
ChunkProcessorSalsa20::~ChunkProcessorSalsa20()
|
||||
{
|
||||
delete m_impl;
|
||||
m_impl = nullptr;
|
||||
}
|
||||
|
||||
size_t ChunkProcessorSalsa20::Process(const int streamNumber, const uint8_t* input, const size_t inputLength, uint8_t* output, const size_t outputBufferSize)
|
||||
{
|
||||
return m_impl->Process(streamNumber, input, inputLength, output, outputBufferSize);
|
||||
}
|
||||
|
||||
void ChunkProcessorSalsa20::GetSignatureData(const uint8_t** pSignatureData, size_t* pSize)
|
||||
{
|
||||
m_impl->GetSignatureData(pSignatureData, pSize);
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
#include "IXChunkProcessor.h"
|
||||
#include "Loading/ISignatureDataProvider.h"
|
||||
#include <string>
|
||||
|
||||
class ChunkProcessorSalsa20 : public IXChunkProcessor, public ISignatureDataProvider
|
||||
{
|
||||
class ChunkProcessorSalsa20Impl;
|
||||
ChunkProcessorSalsa20Impl* m_impl;
|
||||
|
||||
public:
|
||||
ChunkProcessorSalsa20(int streamCount, std::string& zoneName, const uint8_t* salsa20Key, size_t keySize);
|
||||
~ChunkProcessorSalsa20() override;
|
||||
|
||||
size_t Process(int streamNumber, const uint8_t* input, size_t inputLength, uint8_t* output, size_t outputBufferSize) override;
|
||||
void GetSignatureData(const uint8_t** pSignatureData, size_t* pSize) override;
|
||||
};
|
@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
|
||||
class IXChunkProcessor
|
||||
{
|
||||
public:
|
||||
virtual ~IXChunkProcessor() = default;
|
||||
virtual size_t Process(int streamNumber, const uint8_t* input, size_t inputLength, uint8_t* output, size_t outputBufferSize) = 0;
|
||||
};
|
22
src/ZoneLoading/Loading/Steps/StepAddProcessor.cpp
Normal file
22
src/ZoneLoading/Loading/Steps/StepAddProcessor.cpp
Normal file
@ -0,0 +1,22 @@
|
||||
#include "StepAddProcessor.h"
|
||||
#include <cassert>
|
||||
|
||||
StepAddProcessor::StepAddProcessor(StreamProcessor* streamProcessor)
|
||||
{
|
||||
m_stream_processor = streamProcessor;
|
||||
}
|
||||
|
||||
StepAddProcessor::~StepAddProcessor()
|
||||
{
|
||||
delete m_stream_processor;
|
||||
m_stream_processor = nullptr;
|
||||
}
|
||||
|
||||
void StepAddProcessor::PerformStep(ZoneLoader* zoneLoader, ILoadingStream* stream)
|
||||
{
|
||||
assert(zoneLoader != nullptr);
|
||||
assert(m_stream_processor != nullptr);
|
||||
|
||||
zoneLoader->AddStreamProcessor(m_stream_processor);
|
||||
m_stream_processor = nullptr;
|
||||
}
|
14
src/ZoneLoading/Loading/Steps/StepAddProcessor.h
Normal file
14
src/ZoneLoading/Loading/Steps/StepAddProcessor.h
Normal file
@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include "Loading/ILoadingStep.h"
|
||||
|
||||
class StepAddProcessor final : public ILoadingStep
|
||||
{
|
||||
StreamProcessor* m_stream_processor;
|
||||
|
||||
public:
|
||||
explicit StepAddProcessor(StreamProcessor* streamProcessor);
|
||||
~StepAddProcessor() override;
|
||||
|
||||
void PerformStep(ZoneLoader* zoneLoader, ILoadingStream* stream) override;
|
||||
};
|
30
src/ZoneLoading/Loading/Steps/StepAllocXBlocks.cpp
Normal file
30
src/ZoneLoading/Loading/Steps/StepAllocXBlocks.cpp
Normal file
@ -0,0 +1,30 @@
|
||||
#include "StepAllocXBlocks.h"
|
||||
#include "Loading/Exception/InvalidXBlockSizeException.h"
|
||||
|
||||
const uint64_t StepAllocXBlocks::MAX_XBLOCK_SIZE = 0x3C000000;
|
||||
|
||||
void StepAllocXBlocks::PerformStep(ZoneLoader* zoneLoader, ILoadingStream* stream)
|
||||
{
|
||||
const unsigned int blockCount = zoneLoader->m_blocks.size();
|
||||
|
||||
auto* blockSizes = new xblock_size_t[blockCount];
|
||||
stream->Load(blockSizes, sizeof(xblock_size_t) * blockCount);
|
||||
|
||||
uint64_t totalMemory = 0;
|
||||
for(unsigned int block = 0; block < blockCount; block++)
|
||||
{
|
||||
totalMemory += blockSizes[block];
|
||||
}
|
||||
|
||||
if(totalMemory > MAX_XBLOCK_SIZE)
|
||||
{
|
||||
throw InvalidXBlockSizeException(totalMemory, MAX_XBLOCK_SIZE);
|
||||
}
|
||||
|
||||
for(unsigned int block = 0; block < blockCount; block++)
|
||||
{
|
||||
zoneLoader->m_blocks[block]->Alloc(blockSizes[block]);
|
||||
}
|
||||
|
||||
delete[] blockSizes;
|
||||
}
|
11
src/ZoneLoading/Loading/Steps/StepAllocXBlocks.h
Normal file
11
src/ZoneLoading/Loading/Steps/StepAllocXBlocks.h
Normal file
@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include "Loading/ILoadingStep.h"
|
||||
|
||||
class StepAllocXBlocks final : public ILoadingStep
|
||||
{
|
||||
static const uint64_t MAX_XBLOCK_SIZE;
|
||||
|
||||
public:
|
||||
void PerformStep(ZoneLoader* zoneLoader, ILoadingStream* stream) override;
|
||||
};
|
34
src/ZoneLoading/Loading/Steps/StepLoadSignature.cpp
Normal file
34
src/ZoneLoading/Loading/Steps/StepLoadSignature.cpp
Normal file
@ -0,0 +1,34 @@
|
||||
#include "StepLoadSignature.h"
|
||||
#include "Loading/Exception/UnexpectedEndOfFileException.h"
|
||||
#include <cassert>
|
||||
|
||||
StepLoadSignature::StepLoadSignature(const size_t signatureSize)
|
||||
{
|
||||
m_signature_size = signatureSize;
|
||||
m_signature = new uint8_t[signatureSize];
|
||||
}
|
||||
|
||||
StepLoadSignature::~StepLoadSignature()
|
||||
{
|
||||
delete[] m_signature;
|
||||
m_signature = nullptr;
|
||||
}
|
||||
|
||||
void StepLoadSignature::PerformStep(ZoneLoader* zoneLoader, ILoadingStream* stream)
|
||||
{
|
||||
assert(stream != nullptr);
|
||||
|
||||
if(stream->Load(m_signature, m_signature_size) != m_signature_size)
|
||||
throw UnexpectedEndOfFileException();
|
||||
}
|
||||
|
||||
void StepLoadSignature::GetSignature(const uint8_t** pSignature, size_t* pSize)
|
||||
{
|
||||
assert(pSignature != nullptr);
|
||||
assert(pSize != nullptr);
|
||||
|
||||
assert(m_signature != nullptr);
|
||||
|
||||
*pSignature = m_signature;
|
||||
*pSize = m_signature_size;
|
||||
}
|
17
src/ZoneLoading/Loading/Steps/StepLoadSignature.h
Normal file
17
src/ZoneLoading/Loading/Steps/StepLoadSignature.h
Normal file
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include "Loading/ILoadingStep.h"
|
||||
#include "Loading/ISignatureProvider.h"
|
||||
|
||||
class StepLoadSignature final : public ILoadingStep, public ISignatureProvider
|
||||
{
|
||||
uint8_t* m_signature;
|
||||
size_t m_signature_size;
|
||||
|
||||
public:
|
||||
explicit StepLoadSignature(size_t signatureSize);
|
||||
~StepLoadSignature() override;
|
||||
|
||||
void PerformStep(ZoneLoader* zoneLoader, ILoadingStream* stream) override;
|
||||
void GetSignature(const uint8_t** pSignature, size_t* pSize) override;
|
||||
};
|
26
src/ZoneLoading/Loading/Steps/StepLoadZoneContent.cpp
Normal file
26
src/ZoneLoading/Loading/Steps/StepLoadZoneContent.cpp
Normal file
@ -0,0 +1,26 @@
|
||||
#include "StepLoadZoneContent.h"
|
||||
#include "Zone/Stream/Impl/XBlockInputStream.h"
|
||||
#include <cassert>
|
||||
|
||||
StepLoadZoneContent::StepLoadZoneContent(IContentLoadingEntryPoint* entryPoint, Zone* zone, const int offsetBlockBitCount, const block_t insertBlock)
|
||||
{
|
||||
m_content_loader = entryPoint;
|
||||
m_zone = zone;
|
||||
m_offset_block_bit_count = offsetBlockBitCount;
|
||||
m_insert_block = insertBlock;
|
||||
}
|
||||
|
||||
StepLoadZoneContent::~StepLoadZoneContent()
|
||||
{
|
||||
delete m_content_loader;
|
||||
m_content_loader = nullptr;
|
||||
}
|
||||
|
||||
void StepLoadZoneContent::PerformStep(ZoneLoader* zoneLoader, ILoadingStream* stream)
|
||||
{
|
||||
auto* inputStream = new XBlockInputStream(zoneLoader->m_blocks, stream, m_offset_block_bit_count, m_insert_block);
|
||||
|
||||
m_content_loader->Load(m_zone, inputStream);
|
||||
|
||||
delete inputStream;
|
||||
}
|
18
src/ZoneLoading/Loading/Steps/StepLoadZoneContent.h
Normal file
18
src/ZoneLoading/Loading/Steps/StepLoadZoneContent.h
Normal file
@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "Loading/ILoadingStep.h"
|
||||
#include "Loading/IContentLoadingEntryPoint.h"
|
||||
|
||||
class StepLoadZoneContent final : public ILoadingStep
|
||||
{
|
||||
IContentLoadingEntryPoint* m_content_loader;
|
||||
Zone* m_zone;
|
||||
int m_offset_block_bit_count;
|
||||
block_t m_insert_block;
|
||||
|
||||
public:
|
||||
StepLoadZoneContent(IContentLoadingEntryPoint* entryPoint, Zone* zone, int offsetBlockBitCount, block_t insertBlock);
|
||||
~StepLoadZoneContent();
|
||||
|
||||
void PerformStep(ZoneLoader* zoneLoader, ILoadingStream* stream) override;
|
||||
};
|
30
src/ZoneLoading/Loading/Steps/StepSkipBytes.cpp
Normal file
30
src/ZoneLoading/Loading/Steps/StepSkipBytes.cpp
Normal file
@ -0,0 +1,30 @@
|
||||
#include "StepSkipBytes.h"
|
||||
|
||||
StepSkipBytes::StepSkipBytes(const unsigned int skipCount)
|
||||
{
|
||||
m_skip_count = skipCount;
|
||||
}
|
||||
|
||||
void StepSkipBytes::PerformStep(ZoneLoader* zoneLoader, ILoadingStream* stream)
|
||||
{
|
||||
uint8_t tempBuffer[128];
|
||||
unsigned int skippedBytes = 0;
|
||||
|
||||
while(skippedBytes < m_skip_count)
|
||||
{
|
||||
unsigned int toSkip;
|
||||
|
||||
if(m_skip_count - skippedBytes < sizeof(tempBuffer))
|
||||
{
|
||||
toSkip = m_skip_count - skippedBytes;
|
||||
}
|
||||
else
|
||||
{
|
||||
toSkip = sizeof(tempBuffer);
|
||||
}
|
||||
|
||||
stream->Load(tempBuffer, toSkip);
|
||||
|
||||
skippedBytes += toSkip;
|
||||
}
|
||||
}
|
13
src/ZoneLoading/Loading/Steps/StepSkipBytes.h
Normal file
13
src/ZoneLoading/Loading/Steps/StepSkipBytes.h
Normal file
@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "Loading/ILoadingStep.h"
|
||||
|
||||
class StepSkipBytes final : public ILoadingStep
|
||||
{
|
||||
unsigned int m_skip_count;
|
||||
|
||||
public:
|
||||
explicit StepSkipBytes(unsigned int skipCount);
|
||||
|
||||
void PerformStep(ZoneLoader* zoneLoader, ILoadingStream* stream) override;
|
||||
};
|
42
src/ZoneLoading/Loading/Steps/StepVerifyFileName.cpp
Normal file
42
src/ZoneLoading/Loading/Steps/StepVerifyFileName.cpp
Normal file
@ -0,0 +1,42 @@
|
||||
#include "StepVerifyFileName.h"
|
||||
#include "Loading/Exception/InvalidFileNameException.h"
|
||||
|
||||
StepVerifyFileName::StepVerifyFileName(std::string fileName, const size_t fileNameBufferSize)
|
||||
{
|
||||
m_file_name = std::move(fileName);
|
||||
m_file_name_buffer_size = fileNameBufferSize;
|
||||
|
||||
if(m_file_name.length() > m_file_name_buffer_size)
|
||||
m_file_name.erase(m_file_name_buffer_size);
|
||||
}
|
||||
|
||||
void StepVerifyFileName::PerformStep(ZoneLoader* zoneLoader, ILoadingStream* stream)
|
||||
{
|
||||
std::string originalFileName;
|
||||
unsigned bufferOffset = 0;
|
||||
char c;
|
||||
|
||||
for(; bufferOffset < m_file_name_buffer_size; bufferOffset++)
|
||||
{
|
||||
|
||||
stream->Load(&c, sizeof(char));
|
||||
|
||||
if(c == '\00')
|
||||
{
|
||||
bufferOffset++;
|
||||
break;
|
||||
}
|
||||
|
||||
originalFileName += c;
|
||||
}
|
||||
|
||||
// Skip the rest of the buffer which should be null bytes
|
||||
while(bufferOffset < m_file_name_buffer_size)
|
||||
{
|
||||
stream->Load(&c, sizeof(char));
|
||||
bufferOffset++;
|
||||
}
|
||||
|
||||
if(originalFileName != m_file_name)
|
||||
throw InvalidFileNameException(m_file_name, originalFileName);
|
||||
}
|
14
src/ZoneLoading/Loading/Steps/StepVerifyFileName.h
Normal file
14
src/ZoneLoading/Loading/Steps/StepVerifyFileName.h
Normal file
@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include "Loading/ILoadingStep.h"
|
||||
|
||||
class StepVerifyFileName final : public ILoadingStep
|
||||
{
|
||||
std::string m_file_name;
|
||||
size_t m_file_name_buffer_size;
|
||||
|
||||
public:
|
||||
explicit StepVerifyFileName(std::string fileName, size_t fileNameBufferSize);
|
||||
|
||||
void PerformStep(ZoneLoader* zoneLoader, ILoadingStream* stream) override;
|
||||
};
|
21
src/ZoneLoading/Loading/Steps/StepVerifyMagic.cpp
Normal file
21
src/ZoneLoading/Loading/Steps/StepVerifyMagic.cpp
Normal file
@ -0,0 +1,21 @@
|
||||
#include "StepVerifyMagic.h"
|
||||
#include "Loading/Exception/InvalidMagicException.h"
|
||||
|
||||
StepVerifyMagic::StepVerifyMagic(const char* magic)
|
||||
{
|
||||
m_magic = magic;
|
||||
}
|
||||
|
||||
void StepVerifyMagic::PerformStep(ZoneLoader* zoneLoader, ILoadingStream* stream)
|
||||
{
|
||||
const size_t magicLength = strlen(m_magic);
|
||||
char currentCharacter;
|
||||
|
||||
for(unsigned i = 0; i < magicLength; i++)
|
||||
{
|
||||
stream->Load(¤tCharacter, sizeof(char));
|
||||
|
||||
if(currentCharacter != m_magic[i])
|
||||
throw InvalidMagicException(m_magic);
|
||||
}
|
||||
}
|
13
src/ZoneLoading/Loading/Steps/StepVerifyMagic.h
Normal file
13
src/ZoneLoading/Loading/Steps/StepVerifyMagic.h
Normal file
@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "Loading/ILoadingStep.h"
|
||||
|
||||
class StepVerifyMagic final : public ILoadingStep
|
||||
{
|
||||
const char* m_magic;
|
||||
|
||||
public:
|
||||
explicit StepVerifyMagic(const char* magic);
|
||||
|
||||
void PerformStep(ZoneLoader* zoneLoader, ILoadingStream* stream) override;
|
||||
};
|
36
src/ZoneLoading/Loading/Steps/StepVerifySignature.cpp
Normal file
36
src/ZoneLoading/Loading/Steps/StepVerifySignature.cpp
Normal file
@ -0,0 +1,36 @@
|
||||
#include "StepVerifySignature.h"
|
||||
#include "Loading/Exception/InvalidSignatureException.h"
|
||||
#include <cassert>
|
||||
|
||||
StepVerifySignature::StepVerifySignature(IPublicKeyAlgorithm* signatureAlgorithm, ISignatureProvider* signatureProvider, ISignatureDataProvider* signatureDataProvider)
|
||||
{
|
||||
m_algorithm = signatureAlgorithm;
|
||||
m_signature_provider = signatureProvider;
|
||||
m_signature_data_provider = signatureDataProvider;
|
||||
}
|
||||
|
||||
StepVerifySignature::~StepVerifySignature()
|
||||
{
|
||||
delete m_algorithm;
|
||||
m_algorithm = nullptr;
|
||||
}
|
||||
|
||||
void StepVerifySignature::PerformStep(ZoneLoader* zoneLoader, ILoadingStream* stream)
|
||||
{
|
||||
assert(m_algorithm != nullptr);
|
||||
assert(m_signature_provider != nullptr);
|
||||
assert(m_signature_data_provider != nullptr);
|
||||
|
||||
const uint8_t* signature;
|
||||
size_t signatureSize;
|
||||
m_signature_provider->GetSignature(&signature, &signatureSize);
|
||||
|
||||
const uint8_t* signatureData;
|
||||
size_t signatureDataSize;
|
||||
m_signature_data_provider->GetSignatureData(&signatureData, &signatureDataSize);
|
||||
|
||||
if(!m_algorithm->Verify(signatureData, signatureDataSize, signature, signatureSize))
|
||||
{
|
||||
throw InvalidSignatureException();
|
||||
}
|
||||
}
|
19
src/ZoneLoading/Loading/Steps/StepVerifySignature.h
Normal file
19
src/ZoneLoading/Loading/Steps/StepVerifySignature.h
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include "Loading/ILoadingStep.h"
|
||||
#include "Crypto.h"
|
||||
#include "Loading/ISignatureProvider.h"
|
||||
#include "Loading/ISignatureDataProvider.h"
|
||||
|
||||
class StepVerifySignature final : public ILoadingStep
|
||||
{
|
||||
IPublicKeyAlgorithm* m_algorithm;
|
||||
ISignatureProvider* m_signature_provider;
|
||||
ISignatureDataProvider* m_signature_data_provider;
|
||||
|
||||
public:
|
||||
StepVerifySignature(IPublicKeyAlgorithm* signatureAlgorithm, ISignatureProvider* signatureProvider, ISignatureDataProvider* signatureDataProvider);
|
||||
~StepVerifySignature();
|
||||
|
||||
void PerformStep(ZoneLoader* zoneLoader, ILoadingStream* stream) override;
|
||||
};
|
11
src/ZoneLoading/Loading/StreamProcessor.cpp
Normal file
11
src/ZoneLoading/Loading/StreamProcessor.cpp
Normal file
@ -0,0 +1,11 @@
|
||||
#include "StreamProcessor.h"
|
||||
|
||||
StreamProcessor::StreamProcessor()
|
||||
{
|
||||
m_base_stream = nullptr;
|
||||
}
|
||||
|
||||
void StreamProcessor::SetBaseStream(ILoadingStream* baseStream)
|
||||
{
|
||||
m_base_stream = baseStream;
|
||||
}
|
13
src/ZoneLoading/Loading/StreamProcessor.h
Normal file
13
src/ZoneLoading/Loading/StreamProcessor.h
Normal file
@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
#include "ILoadingStream.h"
|
||||
|
||||
class StreamProcessor : public ILoadingStream
|
||||
{
|
||||
protected:
|
||||
ILoadingStream* m_base_stream;
|
||||
|
||||
public:
|
||||
StreamProcessor();
|
||||
|
||||
void SetBaseStream(ILoadingStream* baseStream);
|
||||
};
|
94
src/ZoneLoading/Loading/ZoneLoader.cpp
Normal file
94
src/ZoneLoading/Loading/ZoneLoader.cpp
Normal file
@ -0,0 +1,94 @@
|
||||
#include "ZoneLoader.h"
|
||||
#include "Exception/LoadingException.h"
|
||||
#include "LoadingFileStream.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
ZoneLoader::ZoneLoader(Zone* zone)
|
||||
{
|
||||
m_zone = zone;
|
||||
m_processor_chain_dirty = false;
|
||||
}
|
||||
|
||||
ZoneLoader::~ZoneLoader()
|
||||
{
|
||||
for(auto step : m_steps)
|
||||
{
|
||||
delete step;
|
||||
}
|
||||
m_steps.clear();
|
||||
|
||||
for(auto processor : m_processors)
|
||||
{
|
||||
delete processor;
|
||||
}
|
||||
m_processors.clear();
|
||||
}
|
||||
|
||||
ILoadingStream* ZoneLoader::BuildLoadingChain(ILoadingStream* rootStream)
|
||||
{
|
||||
ILoadingStream* currentStream = rootStream;
|
||||
|
||||
for(auto processor : m_processors)
|
||||
{
|
||||
processor->SetBaseStream(currentStream);
|
||||
|
||||
currentStream = processor;
|
||||
}
|
||||
|
||||
m_processor_chain_dirty = false;
|
||||
return currentStream;
|
||||
}
|
||||
|
||||
void ZoneLoader::AddXBlock(XBlock* block)
|
||||
{
|
||||
m_blocks.push_back(block);
|
||||
|
||||
std::sort(m_blocks.begin(), m_blocks.end(), [](XBlock* b1, XBlock* b2) -> bool
|
||||
{
|
||||
return b1->m_index < b2->m_index;
|
||||
});
|
||||
}
|
||||
|
||||
void ZoneLoader::AddLoadingStep(ILoadingStep* step)
|
||||
{
|
||||
m_steps.push_back(step);
|
||||
}
|
||||
|
||||
void ZoneLoader::AddStreamProcessor(StreamProcessor* streamProcessor)
|
||||
{
|
||||
m_processors.push_back(streamProcessor);
|
||||
m_processor_chain_dirty = true;
|
||||
}
|
||||
|
||||
Zone* ZoneLoader::LoadZone(FileAPI::File* file)
|
||||
{
|
||||
LoadingFileStream fileStream(file);
|
||||
ILoadingStream* endStream = BuildLoadingChain(&fileStream);
|
||||
|
||||
try
|
||||
{
|
||||
for(auto step : m_steps)
|
||||
{
|
||||
step->PerformStep(this, endStream);
|
||||
|
||||
if(m_processor_chain_dirty)
|
||||
{
|
||||
endStream = BuildLoadingChain(&fileStream);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (LoadingException& e)
|
||||
{
|
||||
const std::string detailedMessage = e.DetailedMessage();
|
||||
printf("Loading fastfile failed: %s\n", detailedMessage.c_str());
|
||||
|
||||
delete m_zone;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
m_zone->m_game->AddZone(m_zone);
|
||||
|
||||
return m_zone;
|
||||
}
|
35
src/ZoneLoading/Loading/ZoneLoader.h
Normal file
35
src/ZoneLoading/Loading/ZoneLoader.h
Normal file
@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
#include "ILoadingStep.h"
|
||||
#include "Zone/Zone.h"
|
||||
#include "Zone/XBlock.h"
|
||||
#include "Utils/FileAPI.h"
|
||||
#include "StreamProcessor.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
class ILoadingStep;
|
||||
|
||||
class ZoneLoader
|
||||
{
|
||||
std::vector<ILoadingStep*> m_steps;
|
||||
std::vector<StreamProcessor*> m_processors;
|
||||
|
||||
bool m_processor_chain_dirty;
|
||||
|
||||
Zone* m_zone;
|
||||
|
||||
ILoadingStream* BuildLoadingChain(ILoadingStream* rootStream);
|
||||
|
||||
public:
|
||||
std::vector<XBlock*> m_blocks;
|
||||
|
||||
explicit ZoneLoader(Zone* zone);
|
||||
~ZoneLoader();
|
||||
|
||||
void AddXBlock(XBlock* block);
|
||||
void AddLoadingStep(ILoadingStep* step);
|
||||
void AddStreamProcessor(StreamProcessor* streamProcessor);
|
||||
|
||||
Zone* LoadZone(FileAPI::File* file);
|
||||
};
|
58
src/ZoneLoading/Zone/Stream/IZoneInputStream.h
Normal file
58
src/ZoneLoading/Zone/Stream/IZoneInputStream.h
Normal file
@ -0,0 +1,58 @@
|
||||
#pragma once
|
||||
|
||||
#include "Zone/Stream/IZoneStream.h"
|
||||
#include <cstdint>
|
||||
|
||||
class IZoneInputStream : public IZoneStream
|
||||
{
|
||||
public:
|
||||
virtual void* Alloc(int align) = 0;
|
||||
|
||||
template<typename T>
|
||||
T* Alloc(const int align)
|
||||
{
|
||||
return static_cast<T*>(Alloc(align));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T* Alloc()
|
||||
{
|
||||
return static_cast<T*>(Alloc(alignof(T)));
|
||||
}
|
||||
|
||||
virtual void LoadData(size_t size) = 0;
|
||||
virtual void LoadNullTerminated() = 0;
|
||||
|
||||
template<typename T>
|
||||
void Load()
|
||||
{
|
||||
LoadData(sizeof(T));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void Load(const uint32_t count)
|
||||
{
|
||||
LoadData(count * sizeof(T));
|
||||
}
|
||||
|
||||
virtual void** InsertPointer() = 0;
|
||||
template<typename T>
|
||||
T** InsertPointer()
|
||||
{
|
||||
return reinterpret_cast<T**>(InsertPointer());
|
||||
}
|
||||
|
||||
virtual void* ConvertOffsetToPointer(const void* offset) = 0;
|
||||
template<typename T>
|
||||
T* ConvertOffsetToPointer(T* offset)
|
||||
{
|
||||
return static_cast<T*>(ConvertOffsetToPointer(static_cast<const void*>(offset)));
|
||||
}
|
||||
|
||||
virtual void* ConvertOffsetToAlias(const void* offset) = 0;
|
||||
template<typename T>
|
||||
T* ConvertOffsetToAlias(T* offset)
|
||||
{
|
||||
return static_cast<T*>(ConvertOffsetToAlias(static_cast<const void*>(offset)));
|
||||
}
|
||||
};
|
197
src/ZoneLoading/Zone/Stream/Impl/XBlockInputStream.cpp
Normal file
197
src/ZoneLoading/Zone/Stream/Impl/XBlockInputStream.cpp
Normal file
@ -0,0 +1,197 @@
|
||||
#include "XBlockInputStream.h"
|
||||
#include "Loading/Exception/BlockOverflowException.h"
|
||||
#include "Loading/Exception/InvalidOffsetBlockException.h"
|
||||
#include "Loading/Exception/InvalidOffsetBlockOffsetException.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
XBlockInputStream::XBlockInputStream(std::vector<XBlock*>& blocks, ILoadingStream* stream, const int blockBitCount, const block_t insertBlock) : m_blocks(blocks)
|
||||
{
|
||||
m_stream = stream;
|
||||
|
||||
const unsigned int blockCount = blocks.size();
|
||||
m_block_offsets = new size_t[blockCount]{0};
|
||||
m_block_in_stack = new unsigned int[blockCount]{0};
|
||||
|
||||
m_block_bit_count = blockBitCount;
|
||||
|
||||
assert(insertBlock >= 0 && insertBlock < static_cast<block_t>(blocks.size()));
|
||||
m_insert_block = blocks[insertBlock];
|
||||
}
|
||||
|
||||
XBlockInputStream::~XBlockInputStream()
|
||||
{
|
||||
delete[] m_block_offsets;
|
||||
m_block_offsets = nullptr;
|
||||
|
||||
delete[] m_block_in_stack;
|
||||
m_block_in_stack = nullptr;
|
||||
|
||||
assert(m_block_stack.empty());
|
||||
}
|
||||
|
||||
void XBlockInputStream::Align(const int align)
|
||||
{
|
||||
assert(!m_block_stack.empty());
|
||||
|
||||
if(align > 0)
|
||||
{
|
||||
const block_t blockIndex = m_block_stack.top()->m_index;
|
||||
m_block_offsets[blockIndex] = (m_block_offsets[blockIndex] + align - 1) / align * align;
|
||||
}
|
||||
}
|
||||
|
||||
void XBlockInputStream::PushBlock(const block_t block)
|
||||
{
|
||||
assert(block >= 0 && block < static_cast<block_t>(m_blocks.size()));
|
||||
|
||||
XBlock* newBlock = m_blocks[block];
|
||||
|
||||
assert(newBlock->m_index == block);
|
||||
|
||||
m_block_stack.push(newBlock);
|
||||
m_block_in_stack[newBlock->m_index]++;
|
||||
}
|
||||
|
||||
block_t XBlockInputStream::PopBlock()
|
||||
{
|
||||
assert(!m_block_stack.empty());
|
||||
|
||||
if(m_block_stack.empty())
|
||||
return -1;
|
||||
|
||||
const XBlock* poppedBlock = m_block_stack.top();
|
||||
|
||||
m_block_stack.pop();
|
||||
m_block_in_stack[poppedBlock->m_index]--;
|
||||
|
||||
// If the temp block is not used anymore right now, reset it to the buffer start since as the name suggests, the data inside is temporary.
|
||||
if(poppedBlock->m_type == XBlock::BLOCK_TYPE_TEMP && m_block_in_stack[poppedBlock->m_index] == 0)
|
||||
{
|
||||
m_block_offsets[poppedBlock->m_index] = 0;
|
||||
}
|
||||
|
||||
return poppedBlock->m_index;
|
||||
}
|
||||
|
||||
void* XBlockInputStream::Alloc(const int align)
|
||||
{
|
||||
assert(!m_block_stack.empty());
|
||||
|
||||
if(m_block_stack.empty())
|
||||
return nullptr;
|
||||
|
||||
XBlock* block = m_block_stack.top();
|
||||
|
||||
Align(align);
|
||||
|
||||
if(m_block_offsets[block->m_index] >= block->m_buffer_size)
|
||||
{
|
||||
throw BlockOverflowException(block);
|
||||
}
|
||||
|
||||
return &block->m_buffer[m_block_offsets[block->m_index]];
|
||||
}
|
||||
|
||||
void XBlockInputStream::LoadData(const size_t size)
|
||||
{
|
||||
assert(!m_block_stack.empty());
|
||||
|
||||
if(m_block_stack.empty())
|
||||
return;
|
||||
|
||||
XBlock* block = m_block_stack.top();
|
||||
|
||||
if(m_block_offsets[block->m_index] + size >= block->m_buffer_size)
|
||||
{
|
||||
throw BlockOverflowException(block);
|
||||
}
|
||||
|
||||
m_stream->Load(&block->m_buffer[m_block_offsets[block->m_index]], size);
|
||||
|
||||
m_block_offsets[block->m_index] += size;
|
||||
}
|
||||
|
||||
void XBlockInputStream::LoadNullTerminated()
|
||||
{
|
||||
assert(!m_block_stack.empty());
|
||||
|
||||
if(m_block_stack.empty())
|
||||
return;
|
||||
|
||||
XBlock* block = m_block_stack.top();
|
||||
|
||||
uint8_t byte;
|
||||
size_t offset = m_block_offsets[block->m_index];
|
||||
do
|
||||
{
|
||||
m_stream->Load(&byte, 1);
|
||||
block->m_buffer[offset++] = byte;
|
||||
|
||||
if(offset >= block->m_buffer_size)
|
||||
{
|
||||
throw BlockOverflowException(block);
|
||||
}
|
||||
|
||||
} while(byte != 0);
|
||||
|
||||
m_block_offsets[block->m_index] = offset;
|
||||
}
|
||||
|
||||
void** XBlockInputStream::InsertPointer()
|
||||
{
|
||||
m_block_stack.push(m_insert_block);
|
||||
|
||||
Align(sizeof(void*));
|
||||
|
||||
if(m_block_offsets[m_insert_block->m_index] + sizeof(void*) >= m_insert_block->m_buffer_size)
|
||||
{
|
||||
throw BlockOverflowException(m_insert_block);
|
||||
}
|
||||
|
||||
void** ptr = reinterpret_cast<void**>(&m_insert_block->m_buffer[m_block_offsets[m_insert_block->m_index]]);
|
||||
|
||||
m_block_stack.pop();
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void* XBlockInputStream::ConvertOffsetToPointer(const void* offset)
|
||||
{
|
||||
const block_t blockNum = reinterpret_cast<uintptr_t>(offset) >> (sizeof(offset) * 8 - m_block_bit_count);
|
||||
const size_t blockOffset = reinterpret_cast<uintptr_t>(offset) & (UINTPTR_MAX >> m_block_bit_count);
|
||||
|
||||
if(blockNum < 0 || blockNum >= static_cast<block_t>(m_blocks.size()))
|
||||
{
|
||||
throw InvalidOffsetBlockException(blockNum);
|
||||
}
|
||||
|
||||
XBlock* block = m_blocks[blockNum];
|
||||
|
||||
if(block->m_buffer_size <= blockOffset)
|
||||
{
|
||||
throw InvalidOffsetBlockOffsetException(block, blockOffset);
|
||||
}
|
||||
|
||||
return &block->m_buffer[blockOffset];
|
||||
}
|
||||
|
||||
void* XBlockInputStream::ConvertOffsetToAlias(const void* offset)
|
||||
{
|
||||
const block_t blockNum = reinterpret_cast<uintptr_t>(offset) >> (sizeof(offset) * 8 - m_block_bit_count);
|
||||
const size_t blockOffset = reinterpret_cast<uintptr_t>(offset) & (UINTPTR_MAX >> m_block_bit_count);
|
||||
|
||||
if(blockNum < 0 || blockNum >= static_cast<block_t>(m_blocks.size()))
|
||||
{
|
||||
throw InvalidOffsetBlockException(blockNum);
|
||||
}
|
||||
|
||||
XBlock* block = m_blocks[blockNum];
|
||||
|
||||
if(block->m_buffer_size <= blockOffset + sizeof(void*))
|
||||
{
|
||||
throw InvalidOffsetBlockOffsetException(block, blockOffset);
|
||||
}
|
||||
|
||||
return *reinterpret_cast<void**>(&block->m_buffer[blockOffset]);
|
||||
}
|
40
src/ZoneLoading/Zone/Stream/Impl/XBlockInputStream.h
Normal file
40
src/ZoneLoading/Zone/Stream/Impl/XBlockInputStream.h
Normal file
@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#include "Zone/Stream/IZoneInputStream.h"
|
||||
#include "Zone/XBlock.h"
|
||||
#include "Loading/ILoadingStream.h"
|
||||
|
||||
#include <vector>
|
||||
#include <stack>
|
||||
|
||||
class XBlockInputStream final : public IZoneInputStream
|
||||
{
|
||||
std::vector<XBlock*>& m_blocks;
|
||||
size_t* m_block_offsets;
|
||||
unsigned int* m_block_in_stack;
|
||||
|
||||
std::stack<XBlock*> m_block_stack;
|
||||
ILoadingStream* m_stream;
|
||||
|
||||
int m_block_bit_count;
|
||||
XBlock* m_insert_block;
|
||||
|
||||
void Align(int align);
|
||||
|
||||
public:
|
||||
XBlockInputStream(std::vector<XBlock*>& blocks, ILoadingStream* stream, int blockBitCount, block_t insertBlock);
|
||||
~XBlockInputStream() override;
|
||||
|
||||
void PushBlock(block_t block) override;
|
||||
block_t PopBlock() override;
|
||||
|
||||
void* Alloc(int align) override;
|
||||
|
||||
void LoadData(size_t size) override;
|
||||
void LoadNullTerminated() override;
|
||||
|
||||
void** InsertPointer() override;
|
||||
|
||||
void* ConvertOffsetToPointer(const void* offset) override;
|
||||
void* ConvertOffsetToAlias(const void* offset) override;
|
||||
};
|
6
src/ZoneLoading/ZoneLoading.cpp
Normal file
6
src/ZoneLoading/ZoneLoading.cpp
Normal file
@ -0,0 +1,6 @@
|
||||
#include "ZoneLoading.h"
|
||||
|
||||
bool ZoneLoading::LoadZone(std::string& path)
|
||||
{
|
||||
return false;
|
||||
}
|
8
src/ZoneLoading/ZoneLoading.h
Normal file
8
src/ZoneLoading/ZoneLoading.h
Normal file
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
|
||||
class ZoneLoading
|
||||
{
|
||||
public:
|
||||
static bool LoadZone(std::string& path);
|
||||
};
|
269
src/ZoneLoading/ZoneLoading.vcxproj
Normal file
269
src/ZoneLoading/ZoneLoading.vcxproj
Normal file
@ -0,0 +1,269 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Game\T6\XAssets\rawfile\rawfile_load_db.h" />
|
||||
<ClInclude Include="Loading\AssetLoader.h" />
|
||||
<ClInclude Include="Loading\ContentLoader.h" />
|
||||
<ClInclude Include="Loading\Exception\BlockOverflowException.h" />
|
||||
<ClInclude Include="Loading\Exception\InvalidChunkSizeException.h" />
|
||||
<ClInclude Include="Loading\Exception\InvalidCompressionException.h" />
|
||||
<ClInclude Include="Loading\Exception\InvalidFileNameException.h" />
|
||||
<ClInclude Include="Loading\Exception\InvalidMagicException.h" />
|
||||
<ClInclude Include="Loading\Exception\InvalidOffsetBlockException.h" />
|
||||
<ClInclude Include="Loading\Exception\InvalidOffsetBlockOffsetException.h" />
|
||||
<ClInclude Include="Loading\Exception\InvalidSignatureException.h" />
|
||||
<ClInclude Include="Loading\Exception\InvalidVersionException.h" />
|
||||
<ClInclude Include="Loading\Exception\InvalidXBlockSizeException.h" />
|
||||
<ClInclude Include="Loading\Exception\LoadingException.h" />
|
||||
<ClInclude Include="Loading\Exception\UnexpectedEndOfFileException.h" />
|
||||
<ClInclude Include="Loading\Exception\UnsupportedAssetTypeException.h" />
|
||||
<ClInclude Include="Loading\IContentLoadingEntryPoint.h" />
|
||||
<ClInclude Include="Loading\ILoadingStep.h" />
|
||||
<ClInclude Include="Loading\ILoadingStream.h" />
|
||||
<ClInclude Include="Loading\ISignatureDataProvider.h" />
|
||||
<ClInclude Include="Loading\ISignatureProvider.h" />
|
||||
<ClInclude Include="Loading\IZoneLoaderFactory.h" />
|
||||
<ClInclude Include="Loading\IZoneScriptStringProvider.h" />
|
||||
<ClInclude Include="Loading\LoadingFileStream.h" />
|
||||
<ClInclude Include="Loading\Processor\ProcessorInflate.h" />
|
||||
<ClInclude Include="Loading\Processor\ProcessorStreamCipher.h" />
|
||||
<ClInclude Include="Loading\Processor\ProcessorXChunks.h" />
|
||||
<ClInclude Include="Loading\Processor\XChunks\ChunkProcessorInflate.h" />
|
||||
<ClInclude Include="Loading\Processor\XChunks\ChunkProcessorSalsa20.h" />
|
||||
<ClInclude Include="Loading\Processor\XChunks\IXChunkProcessor.h" />
|
||||
<ClInclude Include="Loading\Steps\StepAddProcessor.h" />
|
||||
<ClInclude Include="Loading\Steps\StepAllocXBlocks.h" />
|
||||
<ClInclude Include="Loading\Steps\StepLoadSignature.h" />
|
||||
<ClInclude Include="Loading\Steps\StepLoadZoneContent.h" />
|
||||
<ClInclude Include="Loading\Steps\StepSkipBytes.h" />
|
||||
<ClInclude Include="Loading\Steps\StepVerifyFileName.h" />
|
||||
<ClInclude Include="Loading\Steps\StepVerifyMagic.h" />
|
||||
<ClInclude Include="Loading\Steps\StepVerifySignature.h" />
|
||||
<ClInclude Include="Loading\StreamProcessor.h" />
|
||||
<ClInclude Include="Game\T6\ContentLoaderT6.h" />
|
||||
<ClInclude Include="Game\T6\ZoneLoaderFactoryT6.h" />
|
||||
<ClInclude Include="Loading\ZoneLoader.h" />
|
||||
<ClInclude Include="ZoneLoading.h" />
|
||||
<ClInclude Include="Zone\Stream\Impl\XBlockInputStream.h" />
|
||||
<ClInclude Include="Zone\Stream\IZoneInputStream.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Game\T6\XAssets\rawfile\rawfile_load_db.cpp" />
|
||||
<ClCompile Include="Loading\AssetLoader.cpp" />
|
||||
<ClCompile Include="Loading\ContentLoader.cpp" />
|
||||
<ClCompile Include="Loading\Exception\BlockOverflowException.cpp" />
|
||||
<ClCompile Include="Loading\Exception\InvalidChunkSizeException.cpp" />
|
||||
<ClCompile Include="Loading\Exception\InvalidCompressionException.cpp" />
|
||||
<ClCompile Include="Loading\Exception\InvalidFileNameException.cpp" />
|
||||
<ClCompile Include="Loading\Exception\InvalidMagicException.cpp" />
|
||||
<ClCompile Include="Loading\Exception\InvalidOffsetBlockException.cpp" />
|
||||
<ClCompile Include="Loading\Exception\InvalidOffsetBlockOffsetException.cpp" />
|
||||
<ClCompile Include="Loading\Exception\InvalidSignatureException.cpp" />
|
||||
<ClCompile Include="Loading\Exception\InvalidVersionException.cpp" />
|
||||
<ClCompile Include="Loading\Exception\InvalidXBlockSizeException.cpp" />
|
||||
<ClCompile Include="Loading\Exception\UnexpectedEndOfFileException.cpp" />
|
||||
<ClCompile Include="Loading\Exception\UnsupportedAssetTypeException.cpp" />
|
||||
<ClCompile Include="Loading\LoadingFileStream.cpp" />
|
||||
<ClCompile Include="Loading\Processor\ProcessorInflate.cpp" />
|
||||
<ClCompile Include="Loading\Processor\ProcessorStreamCipher.cpp" />
|
||||
<ClCompile Include="Loading\Processor\ProcessorXChunks.cpp" />
|
||||
<ClCompile Include="Loading\Processor\XChunks\ChunkProcessorInflate.cpp" />
|
||||
<ClCompile Include="Loading\Processor\XChunks\ChunkProcessorSalsa20.cpp" />
|
||||
<ClCompile Include="Loading\Steps\StepAddProcessor.cpp" />
|
||||
<ClCompile Include="Loading\Steps\StepAllocXBlocks.cpp" />
|
||||
<ClCompile Include="Loading\Steps\StepLoadSignature.cpp" />
|
||||
<ClCompile Include="Loading\Steps\StepLoadZoneContent.cpp" />
|
||||
<ClCompile Include="Loading\Steps\StepSkipBytes.cpp" />
|
||||
<ClCompile Include="Loading\Steps\StepVerifyFileName.cpp" />
|
||||
<ClCompile Include="Loading\Steps\StepVerifyMagic.cpp" />
|
||||
<ClCompile Include="Loading\Steps\StepVerifySignature.cpp" />
|
||||
<ClCompile Include="Loading\StreamProcessor.cpp" />
|
||||
<ClCompile Include="Game\T6\ContentLoaderT6.cpp" />
|
||||
<ClCompile Include="Game\T6\ZoneLoaderFactoryT6.cpp" />
|
||||
<ClCompile Include="Loading\ZoneLoader.cpp" />
|
||||
<ClCompile Include="ZoneLoading.cpp" />
|
||||
<ClCompile Include="Zone\Stream\Impl\XBlockInputStream.cpp" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>15.0</VCProjectVersion>
|
||||
<ProjectGuid>{C3308B0A-D7C7-4560-B5F7-3654DD4B668D}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>ZoneLoading</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
|
||||
<ProjectName>ZoneLoading</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IntDir>$(SolutionDir)obj\$(ProjectName)\$(Configuration)_$(Platform)\</IntDir>
|
||||
<OutDir>$(SolutionDir)lib\$(Configuration)_$(Platform)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IntDir>$(SolutionDir)obj\$(ProjectName)\$(Configuration)_$(Platform)\</IntDir>
|
||||
<OutDir>$(SolutionDir)lib\$(Configuration)_$(Platform)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IntDir>$(SolutionDir)obj\$(ProjectName)\$(Configuration)_$(Platform)\</IntDir>
|
||||
<OutDir>$(SolutionDir)lib\$(Configuration)_$(Platform)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IntDir>$(SolutionDir)obj\$(ProjectName)\$(Configuration)_$(Platform)\</IntDir>
|
||||
<OutDir>$(SolutionDir)lib\$(Configuration)_$(Platform)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir);$(SolutionDir)src\Crypto\;$(SolutionDir)src\Utils\;$(SolutionDir)src\ZoneCommon\;$(SolutionDir)thirdparty\zlib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<TreatSpecificWarningsAsErrors>4715;%(TreatSpecificWarningsAsErrors)</TreatSpecificWarningsAsErrors>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
<Lib>
|
||||
<AdditionalDependencies>Crypto.lib;Utils.lib;ZoneCommon.lib;zlib.lib</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(SolutionDir)lib\$(Configuration)_$(Platform)\</AdditionalLibraryDirectories>
|
||||
<AdditionalOptions>/ignore:4221</AdditionalOptions>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir);$(SolutionDir)src\Crypto\;$(SolutionDir)src\Utils\;$(SolutionDir)src\ZoneCommon\;$(SolutionDir)thirdparty\zlib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<TreatSpecificWarningsAsErrors>4715;%(TreatSpecificWarningsAsErrors)</TreatSpecificWarningsAsErrors>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
<Lib>
|
||||
<AdditionalDependencies>Crypto.lib;Utils.lib;ZoneCommon.lib;zlib.lib</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(SolutionDir)lib\$(Configuration)_$(Platform)\</AdditionalLibraryDirectories>
|
||||
<AdditionalOptions>/ignore:4221</AdditionalOptions>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir);$(SolutionDir)src\Crypto\;$(SolutionDir)src\Utils\;$(SolutionDir)src\ZoneCommon\;$(SolutionDir)thirdparty\zlib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<TreatSpecificWarningsAsErrors>4715;%(TreatSpecificWarningsAsErrors)</TreatSpecificWarningsAsErrors>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
<Lib>
|
||||
<AdditionalDependencies>Crypto.lib;Utils.lib;ZoneCommon.lib;zlib.lib</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(SolutionDir)lib\$(Configuration)_$(Platform)\</AdditionalLibraryDirectories>
|
||||
<AdditionalOptions>/ignore:4221</AdditionalOptions>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir);$(SolutionDir)src\Crypto\;$(SolutionDir)src\Utils\;$(SolutionDir)src\ZoneCommon\;$(SolutionDir)thirdparty\zlib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<TreatSpecificWarningsAsErrors>4715;%(TreatSpecificWarningsAsErrors)</TreatSpecificWarningsAsErrors>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
<Lib>
|
||||
<AdditionalDependencies>Crypto.lib;Utils.lib;ZoneCommon.lib;zlib.lib</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(SolutionDir)lib\$(Configuration)_$(Platform)\</AdditionalLibraryDirectories>
|
||||
<AdditionalOptions>/ignore:4221</AdditionalOptions>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
Reference in New Issue
Block a user