From 897a571a41282aba2366ef422f035acf00852f36 Mon Sep 17 00:00:00 2001 From: Jan Date: Sat, 19 Oct 2024 20:14:26 +0200 Subject: [PATCH 1/5] chore: make GetLanguagePrefixes return a reference instead of a vector copy --- src/Common/Game/IGame.h | 4 +++- src/Common/Game/IW3/GameIW3.cpp | 4 ++-- src/Common/Game/IW3/GameIW3.h | 2 +- src/Common/Game/IW4/GameIW4.cpp | 4 ++-- src/Common/Game/IW4/GameIW4.h | 2 +- src/Common/Game/IW5/GameIW5.cpp | 4 ++-- src/Common/Game/IW5/GameIW5.h | 2 +- src/Common/Game/T5/GameT5.cpp | 32 +++++++++++++-------------- src/Common/Game/T5/GameT5.h | 2 +- src/Common/Game/T6/GameT6.cpp | 38 ++++++++++++++++----------------- src/Common/Game/T6/GameT6.h | 2 +- 11 files changed, 49 insertions(+), 47 deletions(-) diff --git a/src/Common/Game/IGame.h b/src/Common/Game/IGame.h index 065e2ff0..2fb4b5c6 100644 --- a/src/Common/Game/IGame.h +++ b/src/Common/Game/IGame.h @@ -42,5 +42,7 @@ class IGame virtual void AddZone(Zone* zone) = 0; virtual void RemoveZone(Zone* zone) = 0; virtual std::vector GetZones() = 0; - virtual std::vector GetLanguagePrefixes() = 0; + virtual const std::vector& GetLanguagePrefixes() = 0; + + static IGame* GetGameById(GameId gameId); }; diff --git a/src/Common/Game/IW3/GameIW3.cpp b/src/Common/Game/IW3/GameIW3.cpp index 788c9017..ea8b3840 100644 --- a/src/Common/Game/IW3/GameIW3.cpp +++ b/src/Common/Game/IW3/GameIW3.cpp @@ -41,8 +41,8 @@ std::vector GameIW3::GetZones() return m_zones; } -std::vector GameIW3::GetLanguagePrefixes() +const std::vector& GameIW3::GetLanguagePrefixes() { - std::vector prefixes; + static std::vector prefixes; return prefixes; } diff --git a/src/Common/Game/IW3/GameIW3.h b/src/Common/Game/IW3/GameIW3.h index a4f10716..b212834c 100644 --- a/src/Common/Game/IW3/GameIW3.h +++ b/src/Common/Game/IW3/GameIW3.h @@ -10,7 +10,7 @@ class GameIW3 final : public IGame void AddZone(Zone* zone) override; void RemoveZone(Zone* zone) override; std::vector GetZones() override; - std::vector GetLanguagePrefixes() override; + const std::vector& GetLanguagePrefixes() override; private: std::vector m_zones; diff --git a/src/Common/Game/IW4/GameIW4.cpp b/src/Common/Game/IW4/GameIW4.cpp index beb22d84..7d825b2c 100644 --- a/src/Common/Game/IW4/GameIW4.cpp +++ b/src/Common/Game/IW4/GameIW4.cpp @@ -41,8 +41,8 @@ std::vector GameIW4::GetZones() return m_zones; } -std::vector GameIW4::GetLanguagePrefixes() +const std::vector& GameIW4::GetLanguagePrefixes() { - std::vector prefixes; + static std::vector prefixes; return prefixes; } diff --git a/src/Common/Game/IW4/GameIW4.h b/src/Common/Game/IW4/GameIW4.h index de9cb0b7..fb335bfa 100644 --- a/src/Common/Game/IW4/GameIW4.h +++ b/src/Common/Game/IW4/GameIW4.h @@ -10,7 +10,7 @@ class GameIW4 final : public IGame void AddZone(Zone* zone) override; void RemoveZone(Zone* zone) override; std::vector GetZones() override; - std::vector GetLanguagePrefixes() override; + const std::vector& GetLanguagePrefixes() override; private: std::vector m_zones; diff --git a/src/Common/Game/IW5/GameIW5.cpp b/src/Common/Game/IW5/GameIW5.cpp index d5c6141c..a82108b5 100644 --- a/src/Common/Game/IW5/GameIW5.cpp +++ b/src/Common/Game/IW5/GameIW5.cpp @@ -41,8 +41,8 @@ std::vector GameIW5::GetZones() return m_zones; } -std::vector GameIW5::GetLanguagePrefixes() +const std::vector& GameIW5::GetLanguagePrefixes() { - std::vector prefixes; + static std::vector prefixes; return prefixes; } diff --git a/src/Common/Game/IW5/GameIW5.h b/src/Common/Game/IW5/GameIW5.h index 9632c657..06c87139 100644 --- a/src/Common/Game/IW5/GameIW5.h +++ b/src/Common/Game/IW5/GameIW5.h @@ -10,7 +10,7 @@ class GameIW5 final : public IGame void AddZone(Zone* zone) override; void RemoveZone(Zone* zone) override; std::vector GetZones() override; - std::vector GetLanguagePrefixes() override; + const std::vector& GetLanguagePrefixes() override; private: std::vector m_zones; diff --git a/src/Common/Game/T5/GameT5.cpp b/src/Common/Game/T5/GameT5.cpp index 28cd06e2..705f8028 100644 --- a/src/Common/Game/T5/GameT5.cpp +++ b/src/Common/Game/T5/GameT5.cpp @@ -41,23 +41,23 @@ std::vector GameT5::GetZones() return m_zones; } -std::vector GameT5::GetLanguagePrefixes() +const std::vector& GameT5::GetLanguagePrefixes() { - std::vector prefixes; - - prefixes.emplace_back(GameLanguage::LANGUAGE_ENGLISH, "en_"); - prefixes.emplace_back(GameLanguage::LANGUAGE_FRENCH, "fr_"); - prefixes.emplace_back(GameLanguage::LANGUAGE_FRENCH_CAN, "fc_"); - prefixes.emplace_back(GameLanguage::LANGUAGE_GERMAN, "ge_"); - prefixes.emplace_back(GameLanguage::LANGUAGE_AUSTRIAN, "ge_"); - prefixes.emplace_back(GameLanguage::LANGUAGE_ITALIAN, "it_"); - prefixes.emplace_back(GameLanguage::LANGUAGE_SPANISH, "sp_"); - prefixes.emplace_back(GameLanguage::LANGUAGE_BRITISH, "br_"); - prefixes.emplace_back(GameLanguage::LANGUAGE_RUSSIAN, "ru_"); - prefixes.emplace_back(GameLanguage::LANGUAGE_POLISH, "po_"); - prefixes.emplace_back(GameLanguage::LANGUAGE_KOREAN, "ko_"); - prefixes.emplace_back(GameLanguage::LANGUAGE_JAPANESE, "ja_"); - prefixes.emplace_back(GameLanguage::LANGUAGE_CZECH, "cz_"); + static std::vector prefixes{ + {GameLanguage::LANGUAGE_ENGLISH, "en_"}, + {GameLanguage::LANGUAGE_FRENCH, "fr_"}, + {GameLanguage::LANGUAGE_FRENCH_CAN, "fc_"}, + {GameLanguage::LANGUAGE_GERMAN, "ge_"}, + {GameLanguage::LANGUAGE_AUSTRIAN, "ge_"}, + {GameLanguage::LANGUAGE_ITALIAN, "it_"}, + {GameLanguage::LANGUAGE_SPANISH, "sp_"}, + {GameLanguage::LANGUAGE_BRITISH, "br_"}, + {GameLanguage::LANGUAGE_RUSSIAN, "ru_"}, + {GameLanguage::LANGUAGE_POLISH, "po_"}, + {GameLanguage::LANGUAGE_KOREAN, "ko_"}, + {GameLanguage::LANGUAGE_JAPANESE, "ja_"}, + {GameLanguage::LANGUAGE_CZECH, "cz_"}, + }; return prefixes; } diff --git a/src/Common/Game/T5/GameT5.h b/src/Common/Game/T5/GameT5.h index df413e5c..bf392a7e 100644 --- a/src/Common/Game/T5/GameT5.h +++ b/src/Common/Game/T5/GameT5.h @@ -10,7 +10,7 @@ class GameT5 final : public IGame void AddZone(Zone* zone) override; void RemoveZone(Zone* zone) override; std::vector GetZones() override; - std::vector GetLanguagePrefixes() override; + const std::vector& GetLanguagePrefixes() override; private: std::vector m_zones; diff --git a/src/Common/Game/T6/GameT6.cpp b/src/Common/Game/T6/GameT6.cpp index 15a9c590..10553342 100644 --- a/src/Common/Game/T6/GameT6.cpp +++ b/src/Common/Game/T6/GameT6.cpp @@ -41,26 +41,26 @@ std::vector GameT6::GetZones() return m_zones; } -std::vector GameT6::GetLanguagePrefixes() +const std::vector& GameT6::GetLanguagePrefixes() { - std::vector prefixes; - - prefixes.emplace_back(GameLanguage::LANGUAGE_ENGLISH, "en_"); - prefixes.emplace_back(GameLanguage::LANGUAGE_FRENCH, "fr_"); - prefixes.emplace_back(GameLanguage::LANGUAGE_FRENCH_CAN, "fc_"); - prefixes.emplace_back(GameLanguage::LANGUAGE_GERMAN, "ge_"); - prefixes.emplace_back(GameLanguage::LANGUAGE_AUSTRIAN, "as_"); - prefixes.emplace_back(GameLanguage::LANGUAGE_ITALIAN, "it_"); - prefixes.emplace_back(GameLanguage::LANGUAGE_SPANISH, "sp_"); - prefixes.emplace_back(GameLanguage::LANGUAGE_BRITISH, "br_"); - prefixes.emplace_back(GameLanguage::LANGUAGE_RUSSIAN, "ru_"); - prefixes.emplace_back(GameLanguage::LANGUAGE_POLISH, "po_"); - prefixes.emplace_back(GameLanguage::LANGUAGE_KOREAN, "ko_"); - prefixes.emplace_back(GameLanguage::LANGUAGE_JAPANESE, "ja_"); - prefixes.emplace_back(GameLanguage::LANGUAGE_CZECH, "cz_"); - prefixes.emplace_back(GameLanguage::LANGUAGE_FULL_JAPANESE, "fj_"); - prefixes.emplace_back(GameLanguage::LANGUAGE_PORTUGUESE, "bp_"); - prefixes.emplace_back(GameLanguage::LANGUAGE_MEXICAN_SPANISH, "ms_"); + static std::vector prefixes{ + {GameLanguage::LANGUAGE_ENGLISH, "en_"}, + {GameLanguage::LANGUAGE_FRENCH, "fr_"}, + {GameLanguage::LANGUAGE_FRENCH_CAN, "fc_"}, + {GameLanguage::LANGUAGE_GERMAN, "ge_"}, + {GameLanguage::LANGUAGE_AUSTRIAN, "as_"}, + {GameLanguage::LANGUAGE_ITALIAN, "it_"}, + {GameLanguage::LANGUAGE_SPANISH, "sp_"}, + {GameLanguage::LANGUAGE_BRITISH, "br_"}, + {GameLanguage::LANGUAGE_RUSSIAN, "ru_"}, + {GameLanguage::LANGUAGE_POLISH, "po_"}, + {GameLanguage::LANGUAGE_KOREAN, "ko_"}, + {GameLanguage::LANGUAGE_JAPANESE, "ja_"}, + {GameLanguage::LANGUAGE_CZECH, "cz_"}, + {GameLanguage::LANGUAGE_FULL_JAPANESE, "fj_"}, + {GameLanguage::LANGUAGE_PORTUGUESE, "bp_"}, + {GameLanguage::LANGUAGE_MEXICAN_SPANISH, "ms_"}, + }; return prefixes; } diff --git a/src/Common/Game/T6/GameT6.h b/src/Common/Game/T6/GameT6.h index ad55f99d..f5bb5441 100644 --- a/src/Common/Game/T6/GameT6.h +++ b/src/Common/Game/T6/GameT6.h @@ -10,7 +10,7 @@ class GameT6 final : public IGame void AddZone(Zone* zone) override; void RemoveZone(Zone* zone) override; std::vector GetZones() override; - std::vector GetLanguagePrefixes() override; + const std::vector& GetLanguagePrefixes() override; private: std::vector m_zones; From 778361728c66efbf02347ad8c45db828e42677da Mon Sep 17 00:00:00 2001 From: Jan Date: Sat, 19 Oct 2024 20:17:06 +0200 Subject: [PATCH 2/5] chore: make some zone classes use const references --- src/ZoneCommon/Zone/XChunk/AbstractSalsa20Processor.cpp | 6 +++--- src/ZoneCommon/Zone/XChunk/AbstractSalsa20Processor.h | 4 ++-- .../Zone/XChunk/XChunkProcessorSalsa20Encryption.cpp | 2 +- .../Zone/XChunk/XChunkProcessorSalsa20Encryption.h | 2 +- src/ZoneWriting/Writing/ZoneWriter.cpp | 7 ++++--- src/ZoneWriting/Writing/ZoneWriter.h | 2 +- 6 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/ZoneCommon/Zone/XChunk/AbstractSalsa20Processor.cpp b/src/ZoneCommon/Zone/XChunk/AbstractSalsa20Processor.cpp index b1bd7d1e..1805c2a8 100644 --- a/src/ZoneCommon/Zone/XChunk/AbstractSalsa20Processor.cpp +++ b/src/ZoneCommon/Zone/XChunk/AbstractSalsa20Processor.cpp @@ -2,7 +2,7 @@ #include -AbstractSalsa20Processor::AbstractSalsa20Processor(const int streamCount, std::string& zoneName, const uint8_t* salsa20Key, size_t keySize) +AbstractSalsa20Processor::AbstractSalsa20Processor(const int streamCount, const std::string& zoneName, const uint8_t* salsa20Key, const size_t keySize) : m_stream_count(streamCount), m_stream_contexts(std::make_unique(streamCount)), m_stream_block_indices(std::make_unique(streamCount)) @@ -19,9 +19,9 @@ uint8_t* AbstractSalsa20Processor::GetHashBlock(const int streamNumber) const return &m_block_hashes[blockIndexOffset + streamOffset]; } -void AbstractSalsa20Processor::InitStreams(std::string& zoneName, const uint8_t* salsa20Key, size_t keySize) const +void AbstractSalsa20Processor::InitStreams(const std::string& zoneName, const uint8_t* salsa20Key, const size_t keySize) const { - const int zoneNameLength = zoneName.length(); + const auto zoneNameLength = zoneName.length(); const size_t blockHashBufferSize = BLOCK_HASHES_COUNT * m_stream_count * SHA1_HASH_SIZE; assert(blockHashBufferSize % 4 == 0); diff --git a/src/ZoneCommon/Zone/XChunk/AbstractSalsa20Processor.h b/src/ZoneCommon/Zone/XChunk/AbstractSalsa20Processor.h index c769eb19..38ed4aad 100644 --- a/src/ZoneCommon/Zone/XChunk/AbstractSalsa20Processor.h +++ b/src/ZoneCommon/Zone/XChunk/AbstractSalsa20Processor.h @@ -28,11 +28,11 @@ class AbstractSalsa20Processor : public ICapturedDataProvider std::unique_ptr m_block_hashes; std::unique_ptr m_stream_block_indices; - AbstractSalsa20Processor(int streamCount, std::string& zoneName, const uint8_t* salsa20Key, size_t keySize); + AbstractSalsa20Processor(int streamCount, const std::string& zoneName, const uint8_t* salsa20Key, size_t keySize); _NODISCARD uint8_t* GetHashBlock(int streamNumber) const; - void InitStreams(std::string& zoneName, const uint8_t* salsa20Key, size_t keySize) const; + void InitStreams(const std::string& zoneName, const uint8_t* salsa20Key, size_t keySize) const; public: virtual ~AbstractSalsa20Processor() = default; diff --git a/src/ZoneCommon/Zone/XChunk/XChunkProcessorSalsa20Encryption.cpp b/src/ZoneCommon/Zone/XChunk/XChunkProcessorSalsa20Encryption.cpp index 4bca33f8..3f36b12d 100644 --- a/src/ZoneCommon/Zone/XChunk/XChunkProcessorSalsa20Encryption.cpp +++ b/src/ZoneCommon/Zone/XChunk/XChunkProcessorSalsa20Encryption.cpp @@ -3,7 +3,7 @@ #include XChunkProcessorSalsa20Encryption::XChunkProcessorSalsa20Encryption(const int streamCount, - std::string& zoneName, + const std::string& zoneName, const uint8_t* salsa20Key, const size_t keySize) : AbstractSalsa20Processor(streamCount, zoneName, salsa20Key, keySize) diff --git a/src/ZoneCommon/Zone/XChunk/XChunkProcessorSalsa20Encryption.h b/src/ZoneCommon/Zone/XChunk/XChunkProcessorSalsa20Encryption.h index b1fa7206..89272df3 100644 --- a/src/ZoneCommon/Zone/XChunk/XChunkProcessorSalsa20Encryption.h +++ b/src/ZoneCommon/Zone/XChunk/XChunkProcessorSalsa20Encryption.h @@ -8,7 +8,7 @@ class XChunkProcessorSalsa20Encryption final : public IXChunkProcessor, public AbstractSalsa20Processor { public: - XChunkProcessorSalsa20Encryption(int streamCount, std::string& zoneName, const uint8_t* salsa20Key, size_t keySize); + XChunkProcessorSalsa20Encryption(int streamCount, const std::string& zoneName, const uint8_t* salsa20Key, size_t keySize); size_t Process(int streamNumber, const uint8_t* input, size_t inputLength, uint8_t* output, size_t outputBufferSize) override; }; diff --git a/src/ZoneWriting/Writing/ZoneWriter.cpp b/src/ZoneWriting/Writing/ZoneWriter.cpp index 0a7e7a83..82e4287b 100644 --- a/src/ZoneWriting/Writing/ZoneWriter.cpp +++ b/src/ZoneWriting/Writing/ZoneWriter.cpp @@ -3,6 +3,7 @@ #include "WritingException.h" #include "WritingFileStream.h" +#include #include #include @@ -42,7 +43,7 @@ void ZoneWriter::AddStreamProcessor(std::unique_ptr strea m_processor_chain_dirty = true; } -void ZoneWriter::RemoveStreamProcessor(OutputStreamProcessor* streamProcessor) +void ZoneWriter::RemoveStreamProcessor(const OutputStreamProcessor* streamProcessor) { for (auto i = m_processors.begin(); i < m_processors.end(); ++i) { @@ -72,12 +73,12 @@ bool ZoneWriter::WriteZone(std::ostream& stream) } catch (WritingException& e) { - std::cout << "Writing fastfile failed: " << e.Message() << "\n"; + std::cout << std::format("Writing fastfile failed: {}\n", e.Message()); return false; } catch (std::runtime_error& e) { - std::cout << "Writing fastfile failed: " << e.what() << "\n"; + std::cout << std::format("Writing fastfile failed: {}\n", e.what()); return false; } diff --git a/src/ZoneWriting/Writing/ZoneWriter.h b/src/ZoneWriting/Writing/ZoneWriter.h index 231bc5ee..739d8565 100644 --- a/src/ZoneWriting/Writing/ZoneWriter.h +++ b/src/ZoneWriting/Writing/ZoneWriter.h @@ -27,7 +27,7 @@ class ZoneWriter void AddWritingStep(std::unique_ptr step); void AddStreamProcessor(std::unique_ptr streamProcessor); - void RemoveStreamProcessor(OutputStreamProcessor* streamProcessor); + void RemoveStreamProcessor(const OutputStreamProcessor* streamProcessor); bool WriteZone(std::ostream& stream); }; From a1851b0ea090f50a4c2990f275b566503b7c85d6 Mon Sep 17 00:00:00 2001 From: Jan Date: Sat, 19 Oct 2024 20:21:58 +0200 Subject: [PATCH 3/5] chore: use method static array for zoneloaderfactory --- .../Game/IW3/ZoneLoaderFactoryIW3.cpp | 88 +++++------ .../Game/IW3/ZoneLoaderFactoryIW3.h | 4 +- .../Game/IW4/ZoneLoaderFactoryIW4.cpp | 143 ++++++++---------- .../Game/IW4/ZoneLoaderFactoryIW4.h | 4 +- .../Game/IW5/ZoneLoaderFactoryIW5.cpp | 133 ++++++++-------- .../Game/IW5/ZoneLoaderFactoryIW5.h | 4 +- .../Game/T5/ZoneLoaderFactoryT5.cpp | 82 +++++----- src/ZoneLoading/Game/T5/ZoneLoaderFactoryT5.h | 4 +- .../Game/T6/ZoneLoaderFactoryT6.cpp | 118 +++++++-------- src/ZoneLoading/Game/T6/ZoneLoaderFactoryT6.h | 4 +- .../Loading/IZoneLoaderFactory.cpp | 27 ++++ src/ZoneLoading/Loading/IZoneLoaderFactory.h | 6 +- src/ZoneLoading/ZoneLoading.cpp | 34 ++--- 13 files changed, 304 insertions(+), 347 deletions(-) create mode 100644 src/ZoneLoading/Loading/IZoneLoaderFactory.cpp diff --git a/src/ZoneLoading/Game/IW3/ZoneLoaderFactoryIW3.cpp b/src/ZoneLoading/Game/IW3/ZoneLoaderFactoryIW3.cpp index 1c5d6ff1..1bfedf58 100644 --- a/src/ZoneLoading/Game/IW3/ZoneLoaderFactoryIW3.cpp +++ b/src/ZoneLoading/Game/IW3/ZoneLoaderFactoryIW3.cpp @@ -19,22 +19,15 @@ using namespace IW3; -class ZoneLoaderFactory::Impl +namespace { - static GameLanguage GetZoneLanguage(std::string& zoneName) - { - return GameLanguage::LANGUAGE_NONE; - } - - static bool CanLoad(ZoneHeader& header, bool* isSecure, bool* isOfficial) + bool CanLoad(const ZoneHeader& header, bool* isSecure, bool* isOfficial) { assert(isSecure != nullptr); assert(isOfficial != nullptr); if (header.m_version != ZoneConstants::ZONE_VERSION) - { return false; - } if (!memcmp(header.m_magic, ZoneConstants::MAGIC_UNSIGNED, std::char_traits::length(ZoneConstants::MAGIC_UNSIGNED))) { @@ -46,61 +39,54 @@ class ZoneLoaderFactory::Impl return false; } - static void SetupBlock(ZoneLoader* zoneLoader) + void SetupBlock(ZoneLoader& zoneLoader) { #define XBLOCK_DEF(name, type) std::make_unique(STR(name), name, type) - zoneLoader->AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_TEMP, XBlock::Type::BLOCK_TYPE_TEMP)); - zoneLoader->AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME)); - zoneLoader->AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_LARGE_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME)); - zoneLoader->AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_PHYSICAL_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME)); - zoneLoader->AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_VIRTUAL, XBlock::Type::BLOCK_TYPE_NORMAL)); - zoneLoader->AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_LARGE, XBlock::Type::BLOCK_TYPE_NORMAL)); - zoneLoader->AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_PHYSICAL, XBlock::Type::BLOCK_TYPE_NORMAL)); - zoneLoader->AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_VERTEX, XBlock::Type::BLOCK_TYPE_NORMAL)); - zoneLoader->AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_INDEX, XBlock::Type::BLOCK_TYPE_NORMAL)); + zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_TEMP, XBlock::Type::BLOCK_TYPE_TEMP)); + zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME)); + zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_LARGE_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME)); + zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_PHYSICAL_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME)); + zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_VIRTUAL, XBlock::Type::BLOCK_TYPE_NORMAL)); + zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_LARGE, XBlock::Type::BLOCK_TYPE_NORMAL)); + zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_PHYSICAL, XBlock::Type::BLOCK_TYPE_NORMAL)); + zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_VERTEX, XBlock::Type::BLOCK_TYPE_NORMAL)); + zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_INDEX, XBlock::Type::BLOCK_TYPE_NORMAL)); #undef XBLOCK_DEF } +} // namespace -public: - static ZoneLoader* CreateLoaderForHeader(ZoneHeader& header, std::string& fileName) - { - bool isSecure; - bool isOfficial; +std::unique_ptr ZoneLoaderFactory::CreateLoaderForHeader(ZoneHeader& header, std::string& fileName) const +{ + bool isSecure; + bool isOfficial; - // Check if this file is a supported IW4 zone. - if (!CanLoad(header, &isSecure, &isOfficial)) - return nullptr; + // Check if this file is a supported IW4 zone. + if (!CanLoad(header, &isSecure, &isOfficial)) + return nullptr; - // Create new zone - auto zone = std::make_unique(fileName, 0, &g_GameIW3); - auto* zonePtr = zone.get(); - zone->m_pools = std::make_unique(zonePtr, 0); - zone->m_language = GetZoneLanguage(fileName); + // Create new zone + auto zone = std::make_unique(fileName, 0, IGame::GetGameById(GameId::IW3)); + auto* zonePtr = zone.get(); + zone->m_pools = std::make_unique(zonePtr, 0); + zone->m_language = GameLanguage::LANGUAGE_NONE; - // File is supported. Now setup all required steps for loading this file. - auto* zoneLoader = new ZoneLoader(std::move(zone)); + // File is supported. Now setup all required steps for loading this file. + auto zoneLoader = std::make_unique(std::move(zone)); - SetupBlock(zoneLoader); + SetupBlock(*zoneLoader); - zoneLoader->AddLoadingStep(std::make_unique(std::make_unique(ZoneConstants::AUTHED_CHUNK_SIZE))); + zoneLoader->AddLoadingStep(std::make_unique(std::make_unique(ZoneConstants::AUTHED_CHUNK_SIZE))); - // Start of the XFile struct - zoneLoader->AddLoadingStep(std::make_unique(8)); - // Skip size and externalSize fields since they are not interesting for us - zoneLoader->AddLoadingStep(std::make_unique()); + // Start of the XFile struct + zoneLoader->AddLoadingStep(std::make_unique(8)); + // Skip size and externalSize fields since they are not interesting for us + zoneLoader->AddLoadingStep(std::make_unique()); - // Start of the zone content - zoneLoader->AddLoadingStep(std::make_unique( - std::make_unique(), zonePtr, ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK)); + // Start of the zone content + zoneLoader->AddLoadingStep( + std::make_unique(std::make_unique(), zonePtr, ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK)); - // Return the fully setup zoneloader - return zoneLoader; - } -}; - -ZoneLoader* ZoneLoaderFactory::CreateLoaderForHeader(ZoneHeader& header, std::string& fileName) -{ - return Impl::CreateLoaderForHeader(header, fileName); + return zoneLoader; } diff --git a/src/ZoneLoading/Game/IW3/ZoneLoaderFactoryIW3.h b/src/ZoneLoading/Game/IW3/ZoneLoaderFactoryIW3.h index cbe67a65..2e6ba8e6 100644 --- a/src/ZoneLoading/Game/IW3/ZoneLoaderFactoryIW3.h +++ b/src/ZoneLoading/Game/IW3/ZoneLoaderFactoryIW3.h @@ -8,9 +8,7 @@ namespace IW3 { class ZoneLoaderFactory final : public IZoneLoaderFactory { - class Impl; - public: - ZoneLoader* CreateLoaderForHeader(ZoneHeader& header, std::string& fileName) override; + std::unique_ptr CreateLoaderForHeader(ZoneHeader& header, std::string& fileName) const override; }; } // namespace IW3 diff --git a/src/ZoneLoading/Game/IW4/ZoneLoaderFactoryIW4.cpp b/src/ZoneLoading/Game/IW4/ZoneLoaderFactoryIW4.cpp index 7b0163c3..a90f8993 100644 --- a/src/ZoneLoading/Game/IW4/ZoneLoaderFactoryIW4.cpp +++ b/src/ZoneLoading/Game/IW4/ZoneLoaderFactoryIW4.cpp @@ -25,18 +25,14 @@ #include #include +#include #include using namespace IW4; -class ZoneLoaderFactory::Impl +namespace { - static GameLanguage GetZoneLanguage(std::string& zoneName) - { - return GameLanguage::LANGUAGE_NONE; - } - - static bool CanLoad(ZoneHeader& header, bool* isSecure, bool* isOfficial, bool* isIw4x) + bool CanLoad(ZoneHeader& header, bool* isSecure, bool* isOfficial, bool* isIw4x) { assert(isSecure != nullptr); assert(isOfficial != nullptr); @@ -79,23 +75,23 @@ class ZoneLoaderFactory::Impl return false; } - static void SetupBlock(ZoneLoader* zoneLoader) + void SetupBlock(ZoneLoader& zoneLoader) { #define XBLOCK_DEF(name, type) std::make_unique(STR(name), name, type) - zoneLoader->AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_TEMP, XBlock::Type::BLOCK_TYPE_TEMP)); - zoneLoader->AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_PHYSICAL, XBlock::Type::BLOCK_TYPE_NORMAL)); - zoneLoader->AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME)); - zoneLoader->AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_VIRTUAL, XBlock::Type::BLOCK_TYPE_NORMAL)); - zoneLoader->AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_LARGE, XBlock::Type::BLOCK_TYPE_NORMAL)); - zoneLoader->AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_CALLBACK, XBlock::Type::BLOCK_TYPE_NORMAL)); - zoneLoader->AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_VERTEX, XBlock::Type::BLOCK_TYPE_NORMAL)); - zoneLoader->AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_INDEX, XBlock::Type::BLOCK_TYPE_NORMAL)); + zoneLoader.AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_TEMP, XBlock::Type::BLOCK_TYPE_TEMP)); + zoneLoader.AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_PHYSICAL, XBlock::Type::BLOCK_TYPE_NORMAL)); + zoneLoader.AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME)); + zoneLoader.AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_VIRTUAL, XBlock::Type::BLOCK_TYPE_NORMAL)); + zoneLoader.AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_LARGE, XBlock::Type::BLOCK_TYPE_NORMAL)); + zoneLoader.AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_CALLBACK, XBlock::Type::BLOCK_TYPE_NORMAL)); + zoneLoader.AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_VERTEX, XBlock::Type::BLOCK_TYPE_NORMAL)); + zoneLoader.AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_INDEX, XBlock::Type::BLOCK_TYPE_NORMAL)); #undef XBLOCK_DEF } - static std::unique_ptr SetupRSA(const bool isOfficial) + std::unique_ptr SetupRSA(const bool isOfficial) { if (isOfficial) { @@ -103,7 +99,7 @@ class ZoneLoaderFactory::Impl if (!rsa->SetKey(ZoneConstants::RSA_PUBLIC_KEY_INFINITY_WARD, sizeof(ZoneConstants::RSA_PUBLIC_KEY_INFINITY_WARD))) { - printf("Invalid public key for signature checking\n"); + std::cerr << "Invalid public key for signature checking\n"; return nullptr; } @@ -118,7 +114,7 @@ class ZoneLoaderFactory::Impl } } - static void AddAuthHeaderSteps(const bool isSecure, const bool isOfficial, ZoneLoader* zoneLoader, std::string& fileName) + void AddAuthHeaderSteps(const bool isSecure, const bool isOfficial, ZoneLoader& zoneLoader, std::string& fileName) { // Unsigned zones do not have an auth header if (!isSecure) @@ -127,99 +123,92 @@ class ZoneLoaderFactory::Impl // If file is signed setup a RSA instance. auto rsa = SetupRSA(isOfficial); - zoneLoader->AddLoadingStep(std::make_unique(ZoneConstants::MAGIC_AUTH_HEADER)); - zoneLoader->AddLoadingStep(std::make_unique(4)); // Skip reserved + zoneLoader.AddLoadingStep(std::make_unique(ZoneConstants::MAGIC_AUTH_HEADER)); + zoneLoader.AddLoadingStep(std::make_unique(4)); // Skip reserved auto subHeaderHash = std::make_unique(sizeof(DB_AuthHash::bytes), 1); auto* subHeaderHashPtr = subHeaderHash.get(); - zoneLoader->AddLoadingStep(std::move(subHeaderHash)); + zoneLoader.AddLoadingStep(std::move(subHeaderHash)); auto subHeaderHashSignature = std::make_unique(sizeof(DB_AuthSignature::bytes)); auto* subHeaderHashSignaturePtr = subHeaderHashSignature.get(); - zoneLoader->AddLoadingStep(std::move(subHeaderHashSignature)); + zoneLoader.AddLoadingStep(std::move(subHeaderHashSignature)); - zoneLoader->AddLoadingStep(std::make_unique(std::move(rsa), subHeaderHashSignaturePtr, subHeaderHashPtr)); + zoneLoader.AddLoadingStep(std::make_unique(std::move(rsa), subHeaderHashSignaturePtr, subHeaderHashPtr)); auto subHeaderCapture = std::make_unique(sizeof(DB_AuthSubHeader)); auto* subHeaderCapturePtr = subHeaderCapture.get(); - zoneLoader->AddLoadingStep(std::make_unique(std::move(subHeaderCapture))); + zoneLoader.AddLoadingStep(std::make_unique(std::move(subHeaderCapture))); - zoneLoader->AddLoadingStep(std::make_unique(fileName, sizeof(DB_AuthSubHeader::fastfileName))); - zoneLoader->AddLoadingStep(std::make_unique(4)); // Skip reserved + zoneLoader.AddLoadingStep(std::make_unique(fileName, sizeof(DB_AuthSubHeader::fastfileName))); + zoneLoader.AddLoadingStep(std::make_unique(4)); // Skip reserved auto masterBlockHashes = std::make_unique(sizeof(DB_AuthHash::bytes), std::extent_v); auto* masterBlockHashesPtr = masterBlockHashes.get(); - zoneLoader->AddLoadingStep(std::move(masterBlockHashes)); + zoneLoader.AddLoadingStep(std::move(masterBlockHashes)); - zoneLoader->AddLoadingStep( + zoneLoader.AddLoadingStep( std::make_unique(std::unique_ptr(Crypto::CreateSHA256()), 0, subHeaderHashPtr, subHeaderCapturePtr)); - zoneLoader->AddLoadingStep(std::make_unique(subHeaderCapturePtr)); + zoneLoader.AddLoadingStep(std::make_unique(subHeaderCapturePtr)); // Skip the rest of the first chunk - zoneLoader->AddLoadingStep(std::make_unique(ZoneConstants::AUTHED_CHUNK_SIZE - sizeof(DB_AuthHeader))); + zoneLoader.AddLoadingStep(std::make_unique(ZoneConstants::AUTHED_CHUNK_SIZE - sizeof(DB_AuthHeader))); - zoneLoader->AddLoadingStep( + zoneLoader.AddLoadingStep( std::make_unique(std::make_unique(ZoneConstants::AUTHED_CHUNK_COUNT_PER_GROUP, ZoneConstants::AUTHED_CHUNK_SIZE, std::extent_v, - std::unique_ptr(Crypto::CreateSHA256()), + Crypto::CreateSHA256(), masterBlockHashesPtr))); } +} // namespace -public: - static ZoneLoader* CreateLoaderForHeader(ZoneHeader& header, std::string& fileName) - { - bool isSecure; - bool isOfficial; - bool isIw4x; +std::unique_ptr ZoneLoaderFactory::CreateLoaderForHeader(ZoneHeader& header, std::string& fileName) const +{ + bool isSecure; + bool isOfficial; + bool isIw4x; - // Check if this file is a supported IW4 zone. - if (!CanLoad(header, &isSecure, &isOfficial, &isIw4x)) - return nullptr; + // Check if this file is a supported IW4 zone. + if (!CanLoad(header, &isSecure, &isOfficial, &isIw4x)) + return nullptr; - // Create new zone - auto zone = std::make_unique(fileName, 0, &g_GameIW4); - auto* zonePtr = zone.get(); - zone->m_pools = std::make_unique(zonePtr, 0); - zone->m_language = GetZoneLanguage(fileName); + // Create new zone + auto zone = std::make_unique(fileName, 0, IGame::GetGameById(GameId::IW4)); + auto* zonePtr = zone.get(); + zone->m_pools = std::make_unique(zonePtr, 0); + zone->m_language = GameLanguage::LANGUAGE_NONE; - // File is supported. Now setup all required steps for loading this file. - auto* zoneLoader = new ZoneLoader(std::move(zone)); + // File is supported. Now setup all required steps for loading this file. + auto zoneLoader = std::make_unique(std::move(zone)); - SetupBlock(zoneLoader); + SetupBlock(*zoneLoader); - // Skip unknown 1 byte field that the game ignores as well - zoneLoader->AddLoadingStep(std::make_unique(1)); + // Skip unknown 1 byte field that the game ignores as well + zoneLoader->AddLoadingStep(std::make_unique(1)); - // Skip timestamp - zoneLoader->AddLoadingStep(std::make_unique(8)); + // Skip timestamp + zoneLoader->AddLoadingStep(std::make_unique(8)); - // Add steps for loading the auth header which also contain the signature of the zone if it is signed. - AddAuthHeaderSteps(isSecure, isOfficial, zoneLoader, fileName); + // Add steps for loading the auth header which also contain the signature of the zone if it is signed. + AddAuthHeaderSteps(isSecure, isOfficial, *zoneLoader, fileName); - zoneLoader->AddLoadingStep(std::make_unique(std::make_unique(ZoneConstants::AUTHED_CHUNK_SIZE))); + zoneLoader->AddLoadingStep(std::make_unique(std::make_unique(ZoneConstants::AUTHED_CHUNK_SIZE))); - if (isIw4x) // IW4x has one extra byte of padding here for protection purposes - { - zoneLoader->AddLoadingStep(std::make_unique(std::make_unique())); - zoneLoader->AddLoadingStep(std::make_unique(1)); - } - - // Start of the XFile struct - zoneLoader->AddLoadingStep(std::make_unique(8)); - // Skip size and externalSize fields since they are not interesting for us - zoneLoader->AddLoadingStep(std::make_unique()); + if (isIw4x) // IW4x has one extra byte of padding here for protection purposes + { + zoneLoader->AddLoadingStep(std::make_unique(std::make_unique())); + zoneLoader->AddLoadingStep(std::make_unique(1)); + } - // Start of the zone content - zoneLoader->AddLoadingStep(std::make_unique( - std::make_unique(), zonePtr, ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK)); + // Start of the XFile struct + zoneLoader->AddLoadingStep(std::make_unique(8)); + // Skip size and externalSize fields since they are not interesting for us + zoneLoader->AddLoadingStep(std::make_unique()); - // Return the fully setup zoneloader - return zoneLoader; - } -}; + // Start of the zone content + zoneLoader->AddLoadingStep( + std::make_unique(std::make_unique(), zonePtr, ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK)); -ZoneLoader* ZoneLoaderFactory::CreateLoaderForHeader(ZoneHeader& header, std::string& fileName) -{ - return Impl::CreateLoaderForHeader(header, fileName); + return zoneLoader; } diff --git a/src/ZoneLoading/Game/IW4/ZoneLoaderFactoryIW4.h b/src/ZoneLoading/Game/IW4/ZoneLoaderFactoryIW4.h index ce31128c..a840e686 100644 --- a/src/ZoneLoading/Game/IW4/ZoneLoaderFactoryIW4.h +++ b/src/ZoneLoading/Game/IW4/ZoneLoaderFactoryIW4.h @@ -8,9 +8,7 @@ namespace IW4 { class ZoneLoaderFactory final : public IZoneLoaderFactory { - class Impl; - public: - ZoneLoader* CreateLoaderForHeader(ZoneHeader& header, std::string& fileName) override; + std::unique_ptr CreateLoaderForHeader(ZoneHeader& header, std::string& fileName) const override; }; } // namespace IW4 diff --git a/src/ZoneLoading/Game/IW5/ZoneLoaderFactoryIW5.cpp b/src/ZoneLoading/Game/IW5/ZoneLoaderFactoryIW5.cpp index f2202fd5..a5dc37bc 100644 --- a/src/ZoneLoading/Game/IW5/ZoneLoaderFactoryIW5.cpp +++ b/src/ZoneLoading/Game/IW5/ZoneLoaderFactoryIW5.cpp @@ -24,18 +24,14 @@ #include #include +#include #include using namespace IW5; -class ZoneLoaderFactory::Impl +namespace { - static GameLanguage GetZoneLanguage(std::string& zoneName) - { - return GameLanguage::LANGUAGE_NONE; - } - - static bool CanLoad(ZoneHeader& header, bool* isSecure, bool* isOfficial) + bool CanLoad(const ZoneHeader& header, bool* isSecure, bool* isOfficial) { assert(isSecure != nullptr); assert(isOfficial != nullptr); @@ -62,24 +58,24 @@ class ZoneLoaderFactory::Impl return false; } - static void SetupBlock(ZoneLoader* zoneLoader) + void SetupBlock(ZoneLoader& zoneLoader) { #define XBLOCK_DEF(name, type) std::make_unique(STR(name), name, type) - zoneLoader->AddXBlock(XBLOCK_DEF(XFILE_BLOCK_TEMP, XBlock::Type::BLOCK_TYPE_TEMP)); - zoneLoader->AddXBlock(XBLOCK_DEF(XFILE_BLOCK_PHYSICAL, XBlock::Type::BLOCK_TYPE_NORMAL)); - zoneLoader->AddXBlock(XBLOCK_DEF(XFILE_BLOCK_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME)); - zoneLoader->AddXBlock(XBLOCK_DEF(XFILE_BLOCK_VIRTUAL, XBlock::Type::BLOCK_TYPE_NORMAL)); - zoneLoader->AddXBlock(XBLOCK_DEF(XFILE_BLOCK_LARGE, XBlock::Type::BLOCK_TYPE_NORMAL)); - zoneLoader->AddXBlock(XBLOCK_DEF(XFILE_BLOCK_CALLBACK, XBlock::Type::BLOCK_TYPE_NORMAL)); - zoneLoader->AddXBlock(XBLOCK_DEF(XFILE_BLOCK_VERTEX, XBlock::Type::BLOCK_TYPE_NORMAL)); - zoneLoader->AddXBlock(XBLOCK_DEF(XFILE_BLOCK_INDEX, XBlock::Type::BLOCK_TYPE_NORMAL)); - zoneLoader->AddXBlock(XBLOCK_DEF(XFILE_BLOCK_SCRIPT, XBlock::Type::BLOCK_TYPE_NORMAL)); + zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_TEMP, XBlock::Type::BLOCK_TYPE_TEMP)); + zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_PHYSICAL, XBlock::Type::BLOCK_TYPE_NORMAL)); + zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME)); + zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_VIRTUAL, XBlock::Type::BLOCK_TYPE_NORMAL)); + zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_LARGE, XBlock::Type::BLOCK_TYPE_NORMAL)); + zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_CALLBACK, XBlock::Type::BLOCK_TYPE_NORMAL)); + zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_VERTEX, XBlock::Type::BLOCK_TYPE_NORMAL)); + zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_INDEX, XBlock::Type::BLOCK_TYPE_NORMAL)); + zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_SCRIPT, XBlock::Type::BLOCK_TYPE_NORMAL)); #undef XBLOCK_DEF } - static std::unique_ptr SetupRSA(const bool isOfficial) + std::unique_ptr SetupRSA(const bool isOfficial) { if (isOfficial) { @@ -87,7 +83,7 @@ class ZoneLoaderFactory::Impl if (!rsa->SetKey(ZoneConstants::RSA_PUBLIC_KEY_INFINITY_WARD, sizeof(ZoneConstants::RSA_PUBLIC_KEY_INFINITY_WARD))) { - printf("Invalid public key for signature checking\n"); + std::cerr << "Invalid public key for signature checking\n"; return nullptr; } @@ -102,7 +98,7 @@ class ZoneLoaderFactory::Impl } } - static void AddAuthHeaderSteps(const bool isSecure, const bool isOfficial, ZoneLoader* zoneLoader, std::string& fileName) + void AddAuthHeaderSteps(const bool isSecure, const bool isOfficial, ZoneLoader& zoneLoader, std::string& fileName) { // Unsigned zones do not have an auth header if (!isSecure) @@ -111,92 +107,85 @@ class ZoneLoaderFactory::Impl // If file is signed setup a RSA instance. auto rsa = SetupRSA(isOfficial); - zoneLoader->AddLoadingStep(std::make_unique(ZoneConstants::MAGIC_AUTH_HEADER)); - zoneLoader->AddLoadingStep(std::make_unique(4)); // Skip reserved + zoneLoader.AddLoadingStep(std::make_unique(ZoneConstants::MAGIC_AUTH_HEADER)); + zoneLoader.AddLoadingStep(std::make_unique(4)); // Skip reserved auto subHeaderHash = std::make_unique(sizeof(DB_AuthHash::bytes), 1); auto* subHeaderHashPtr = subHeaderHash.get(); - zoneLoader->AddLoadingStep(std::move(subHeaderHash)); + zoneLoader.AddLoadingStep(std::move(subHeaderHash)); auto subHeaderHashSignature = std::make_unique(sizeof(DB_AuthSignature::bytes)); auto* subHeaderHashSignaturePtr = subHeaderHashSignature.get(); - zoneLoader->AddLoadingStep(std::move(subHeaderHashSignature)); + zoneLoader.AddLoadingStep(std::move(subHeaderHashSignature)); - zoneLoader->AddLoadingStep(std::make_unique(std::move(rsa), subHeaderHashSignaturePtr, subHeaderHashPtr)); + zoneLoader.AddLoadingStep(std::make_unique(std::move(rsa), subHeaderHashSignaturePtr, subHeaderHashPtr)); auto subHeaderCapture = std::make_unique(sizeof(DB_AuthSubHeader)); auto* subHeaderCapturePtr = subHeaderCapture.get(); - zoneLoader->AddLoadingStep(std::make_unique(std::move(subHeaderCapture))); + zoneLoader.AddLoadingStep(std::make_unique(std::move(subHeaderCapture))); - zoneLoader->AddLoadingStep(std::make_unique(fileName, sizeof(DB_AuthSubHeader::fastfileName))); - zoneLoader->AddLoadingStep(std::make_unique(4)); // Skip reserved + zoneLoader.AddLoadingStep(std::make_unique(fileName, sizeof(DB_AuthSubHeader::fastfileName))); + zoneLoader.AddLoadingStep(std::make_unique(4)); // Skip reserved auto masterBlockHashes = std::make_unique(sizeof(DB_AuthHash::bytes), std::extent_v); auto* masterBlockHashesPtr = masterBlockHashes.get(); - zoneLoader->AddLoadingStep(std::move(masterBlockHashes)); + zoneLoader.AddLoadingStep(std::move(masterBlockHashes)); - zoneLoader->AddLoadingStep( + zoneLoader.AddLoadingStep( std::make_unique(std::unique_ptr(Crypto::CreateSHA256()), 0, subHeaderHashPtr, subHeaderCapturePtr)); - zoneLoader->AddLoadingStep(std::make_unique(subHeaderCapturePtr)); + zoneLoader.AddLoadingStep(std::make_unique(subHeaderCapturePtr)); // Skip the rest of the first chunk - zoneLoader->AddLoadingStep(std::make_unique(ZoneConstants::AUTHED_CHUNK_SIZE - sizeof(DB_AuthHeader))); + zoneLoader.AddLoadingStep(std::make_unique(ZoneConstants::AUTHED_CHUNK_SIZE - sizeof(DB_AuthHeader))); - zoneLoader->AddLoadingStep( + zoneLoader.AddLoadingStep( std::make_unique(std::make_unique(ZoneConstants::AUTHED_CHUNK_COUNT_PER_GROUP, ZoneConstants::AUTHED_CHUNK_SIZE, std::extent_v, - std::unique_ptr(Crypto::CreateSHA256()), + Crypto::CreateSHA256(), masterBlockHashesPtr))); } +} // namespace -public: - static ZoneLoader* CreateLoaderForHeader(ZoneHeader& header, std::string& fileName) - { - bool isSecure; - bool isOfficial; - - // Check if this file is a supported IW4 zone. - if (!CanLoad(header, &isSecure, &isOfficial)) - return nullptr; +std::unique_ptr ZoneLoaderFactory::CreateLoaderForHeader(ZoneHeader& header, std::string& fileName) const +{ + bool isSecure; + bool isOfficial; - // Create new zone - auto zone = std::make_unique(fileName, 0, &g_GameIW5); - auto* zonePtr = zone.get(); - zone->m_pools = std::make_unique(zonePtr, 0); - zone->m_language = GetZoneLanguage(fileName); + // Check if this file is a supported IW4 zone. + if (!CanLoad(header, &isSecure, &isOfficial)) + return nullptr; - // File is supported. Now setup all required steps for loading this file. - auto* zoneLoader = new ZoneLoader(std::move(zone)); + // Create new zone + auto zone = std::make_unique(fileName, 0, IGame::GetGameById(GameId::IW5)); + auto* zonePtr = zone.get(); + zone->m_pools = std::make_unique(zonePtr, 0); + zone->m_language = GameLanguage::LANGUAGE_NONE; - SetupBlock(zoneLoader); + // File is supported. Now setup all required steps for loading this file. + auto zoneLoader = std::make_unique(std::move(zone)); - // Skip unknown 1 byte field that the game ignores as well - zoneLoader->AddLoadingStep(std::make_unique(1)); + SetupBlock(*zoneLoader); - // Skip timestamp - zoneLoader->AddLoadingStep(std::make_unique(8)); + // Skip unknown 1 byte field that the game ignores as well + zoneLoader->AddLoadingStep(std::make_unique(1)); - // Add steps for loading the auth header which also contain the signature of the zone if it is signed. - AddAuthHeaderSteps(isSecure, isOfficial, zoneLoader, fileName); + // Skip timestamp + zoneLoader->AddLoadingStep(std::make_unique(8)); - zoneLoader->AddLoadingStep(std::make_unique(std::make_unique(ZoneConstants::AUTHED_CHUNK_SIZE))); + // Add steps for loading the auth header which also contain the signature of the zone if it is signed. + AddAuthHeaderSteps(isSecure, isOfficial, *zoneLoader, fileName); - // Start of the XFile struct - zoneLoader->AddLoadingStep(std::make_unique(8)); - // Skip size and externalSize fields since they are not interesting for us - zoneLoader->AddLoadingStep(std::make_unique()); + zoneLoader->AddLoadingStep(std::make_unique(std::make_unique(ZoneConstants::AUTHED_CHUNK_SIZE))); - // Start of the zone content - zoneLoader->AddLoadingStep(std::make_unique( - std::make_unique(), zonePtr, ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK)); + // Start of the XFile struct + zoneLoader->AddLoadingStep(std::make_unique(8)); + // Skip size and externalSize fields since they are not interesting for us + zoneLoader->AddLoadingStep(std::make_unique()); - // Return the fully setup zoneloader - return zoneLoader; - } -}; + // Start of the zone content + zoneLoader->AddLoadingStep( + std::make_unique(std::make_unique(), zonePtr, ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK)); -ZoneLoader* ZoneLoaderFactory::CreateLoaderForHeader(ZoneHeader& header, std::string& fileName) -{ - return Impl::CreateLoaderForHeader(header, fileName); + return zoneLoader; } diff --git a/src/ZoneLoading/Game/IW5/ZoneLoaderFactoryIW5.h b/src/ZoneLoading/Game/IW5/ZoneLoaderFactoryIW5.h index 435c89f2..a3a522a1 100644 --- a/src/ZoneLoading/Game/IW5/ZoneLoaderFactoryIW5.h +++ b/src/ZoneLoading/Game/IW5/ZoneLoaderFactoryIW5.h @@ -8,9 +8,7 @@ namespace IW5 { class ZoneLoaderFactory final : public IZoneLoaderFactory { - class Impl; - public: - ZoneLoader* CreateLoaderForHeader(ZoneHeader& header, std::string& fileName) override; + std::unique_ptr CreateLoaderForHeader(ZoneHeader& header, std::string& fileName) const override; }; } // namespace IW5 diff --git a/src/ZoneLoading/Game/T5/ZoneLoaderFactoryT5.cpp b/src/ZoneLoading/Game/T5/ZoneLoaderFactoryT5.cpp index fd49746e..d1fa61fd 100644 --- a/src/ZoneLoading/Game/T5/ZoneLoaderFactoryT5.cpp +++ b/src/ZoneLoading/Game/T5/ZoneLoaderFactoryT5.cpp @@ -19,14 +19,9 @@ using namespace T5; -class ZoneLoaderFactory::Impl +namespace { - static GameLanguage GetZoneLanguage(std::string& zoneName) - { - return GameLanguage::LANGUAGE_NONE; - } - - static bool CanLoad(ZoneHeader& header, bool* isSecure, bool* isOfficial) + bool CanLoad(const ZoneHeader& header, bool* isSecure, bool* isOfficial) { assert(isSecure != nullptr); assert(isOfficial != nullptr); @@ -46,59 +41,52 @@ class ZoneLoaderFactory::Impl return false; } - static void SetupBlock(ZoneLoader* zoneLoader) + void SetupBlock(ZoneLoader& zoneLoader) { #define XBLOCK_DEF(name, type) std::make_unique(STR(name), name, type) - zoneLoader->AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_TEMP, XBlock::Type::BLOCK_TYPE_TEMP)); - zoneLoader->AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME)); - zoneLoader->AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_LARGE_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME)); - zoneLoader->AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_PHYSICAL_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME)); - zoneLoader->AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_VIRTUAL, XBlock::Type::BLOCK_TYPE_NORMAL)); - zoneLoader->AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_LARGE, XBlock::Type::BLOCK_TYPE_NORMAL)); - zoneLoader->AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_PHYSICAL, XBlock::Type::BLOCK_TYPE_NORMAL)); + zoneLoader.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_TEMP, XBlock::Type::BLOCK_TYPE_TEMP)); + zoneLoader.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME)); + zoneLoader.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_LARGE_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME)); + zoneLoader.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_PHYSICAL_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME)); + zoneLoader.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_VIRTUAL, XBlock::Type::BLOCK_TYPE_NORMAL)); + zoneLoader.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_LARGE, XBlock::Type::BLOCK_TYPE_NORMAL)); + zoneLoader.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_PHYSICAL, XBlock::Type::BLOCK_TYPE_NORMAL)); #undef XBLOCK_DEF } +} // namespace -public: - static ZoneLoader* CreateLoaderForHeader(ZoneHeader& header, std::string& fileName) - { - bool isSecure; - bool isOfficial; - - // Check if this file is a supported IW4 zone. - if (!CanLoad(header, &isSecure, &isOfficial)) - return nullptr; +std::unique_ptr ZoneLoaderFactory::CreateLoaderForHeader(ZoneHeader& header, std::string& fileName) const +{ + bool isSecure; + bool isOfficial; - // Create new zone - auto zone = std::make_unique(fileName, 0, &g_GameT5); - auto* zonePtr = zone.get(); - zone->m_pools = std::make_unique(zonePtr, 0); - zone->m_language = GetZoneLanguage(fileName); + // Check if this file is a supported IW4 zone. + if (!CanLoad(header, &isSecure, &isOfficial)) + return nullptr; - // File is supported. Now setup all required steps for loading this file. - auto* zoneLoader = new ZoneLoader(std::move(zone)); + // Create new zone + auto zone = std::make_unique(fileName, 0, IGame::GetGameById(GameId::T5)); + auto* zonePtr = zone.get(); + zone->m_pools = std::make_unique(zonePtr, 0); + zone->m_language = GameLanguage::LANGUAGE_NONE; - SetupBlock(zoneLoader); + // File is supported. Now setup all required steps for loading this file. + auto zoneLoader = std::make_unique(std::move(zone)); - zoneLoader->AddLoadingStep(std::make_unique(std::make_unique(ZoneConstants::AUTHED_CHUNK_SIZE))); + SetupBlock(*zoneLoader); - // Start of the XFile struct - zoneLoader->AddLoadingStep(std::make_unique(8)); - // Skip size and externalSize fields since they are not interesting for us - zoneLoader->AddLoadingStep(std::make_unique()); + zoneLoader->AddLoadingStep(std::make_unique(std::make_unique(ZoneConstants::AUTHED_CHUNK_SIZE))); - // Start of the zone content - zoneLoader->AddLoadingStep(std::make_unique( - std::make_unique(), zonePtr, ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK)); + // Start of the XFile struct + zoneLoader->AddLoadingStep(std::make_unique(8)); + // Skip size and externalSize fields since they are not interesting for us + zoneLoader->AddLoadingStep(std::make_unique()); - // Return the fully setup zoneloader - return zoneLoader; - } -}; + // Start of the zone content + zoneLoader->AddLoadingStep( + std::make_unique(std::make_unique(), zonePtr, ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK)); -ZoneLoader* ZoneLoaderFactory::CreateLoaderForHeader(ZoneHeader& header, std::string& fileName) -{ - return Impl::CreateLoaderForHeader(header, fileName); + return zoneLoader; } diff --git a/src/ZoneLoading/Game/T5/ZoneLoaderFactoryT5.h b/src/ZoneLoading/Game/T5/ZoneLoaderFactoryT5.h index 98f3182a..12c21ffb 100644 --- a/src/ZoneLoading/Game/T5/ZoneLoaderFactoryT5.h +++ b/src/ZoneLoading/Game/T5/ZoneLoaderFactoryT5.h @@ -8,9 +8,7 @@ namespace T5 { class ZoneLoaderFactory final : public IZoneLoaderFactory { - class Impl; - public: - ZoneLoader* CreateLoaderForHeader(ZoneHeader& header, std::string& fileName) override; + std::unique_ptr CreateLoaderForHeader(ZoneHeader& header, std::string& fileName) const override; }; } // namespace T5 diff --git a/src/ZoneLoading/Game/T6/ZoneLoaderFactoryT6.cpp b/src/ZoneLoading/Game/T6/ZoneLoaderFactoryT6.cpp index b10b9b25..6ebb70f6 100644 --- a/src/ZoneLoading/Game/T6/ZoneLoaderFactoryT6.cpp +++ b/src/ZoneLoading/Game/T6/ZoneLoaderFactoryT6.cpp @@ -22,15 +22,16 @@ #include #include +#include #include using namespace T6; -class ZoneLoaderFactory::Impl +namespace { - static GameLanguage GetZoneLanguage(std::string& zoneName) + GameLanguage GetZoneLanguage(const std::string& zoneName) { - auto languagePrefixes = g_GameT6.GetLanguagePrefixes(); + const auto& languagePrefixes = IGame::GetGameById(GameId::T6)->GetLanguagePrefixes(); for (const auto& languagePrefix : languagePrefixes) { @@ -43,7 +44,7 @@ class ZoneLoaderFactory::Impl return GameLanguage::LANGUAGE_NONE; } - static bool CanLoad(ZoneHeader& header, bool* isSecure, bool* isOfficial, bool* isEncrypted) + bool CanLoad(const ZoneHeader& header, bool* isSecure, bool* isOfficial, bool* isEncrypted) { assert(isSecure != nullptr); assert(isOfficial != nullptr); @@ -88,23 +89,23 @@ class ZoneLoaderFactory::Impl return false; } - static void SetupBlock(ZoneLoader* zoneLoader) + void SetupBlock(ZoneLoader& zoneLoader) { #define XBLOCK_DEF(name, type) std::make_unique(STR(name), name, type) - zoneLoader->AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_TEMP, XBlock::Type::BLOCK_TYPE_TEMP)); - zoneLoader->AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_RUNTIME_VIRTUAL, XBlock::Type::BLOCK_TYPE_RUNTIME)); - zoneLoader->AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_RUNTIME_PHYSICAL, XBlock::Type::BLOCK_TYPE_RUNTIME)); - zoneLoader->AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_DELAY_VIRTUAL, XBlock::Type::BLOCK_TYPE_DELAY)); - zoneLoader->AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_DELAY_PHYSICAL, XBlock::Type::BLOCK_TYPE_DELAY)); - zoneLoader->AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_VIRTUAL, XBlock::Type::BLOCK_TYPE_NORMAL)); - zoneLoader->AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_PHYSICAL, XBlock::Type::BLOCK_TYPE_NORMAL)); - zoneLoader->AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_STREAMER_RESERVE, XBlock::Type::BLOCK_TYPE_NORMAL)); + zoneLoader.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_TEMP, XBlock::Type::BLOCK_TYPE_TEMP)); + zoneLoader.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_RUNTIME_VIRTUAL, XBlock::Type::BLOCK_TYPE_RUNTIME)); + zoneLoader.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_RUNTIME_PHYSICAL, XBlock::Type::BLOCK_TYPE_RUNTIME)); + zoneLoader.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_DELAY_VIRTUAL, XBlock::Type::BLOCK_TYPE_DELAY)); + zoneLoader.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_DELAY_PHYSICAL, XBlock::Type::BLOCK_TYPE_DELAY)); + zoneLoader.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_VIRTUAL, XBlock::Type::BLOCK_TYPE_NORMAL)); + zoneLoader.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_PHYSICAL, XBlock::Type::BLOCK_TYPE_NORMAL)); + zoneLoader.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_STREAMER_RESERVE, XBlock::Type::BLOCK_TYPE_NORMAL)); #undef XBLOCK_DEF } - static std::unique_ptr SetupRSA(const bool isOfficial) + std::unique_ptr SetupRSA(const bool isOfficial) { if (isOfficial) { @@ -112,7 +113,7 @@ class ZoneLoaderFactory::Impl if (!rsa->SetKey(ZoneConstants::RSA_PUBLIC_KEY_TREYARCH, sizeof(ZoneConstants::RSA_PUBLIC_KEY_TREYARCH))) { - printf("Invalid public key for signature checking\n"); + std::cerr << "Invalid public key for signature checking\n"; return nullptr; } @@ -127,24 +128,24 @@ class ZoneLoaderFactory::Impl } } - static ISignatureProvider* AddAuthHeaderSteps(const bool isSecure, ZoneLoader* zoneLoader, std::string& fileName) + ISignatureProvider* AddAuthHeaderSteps(const bool isSecure, ZoneLoader& zoneLoader, std::string& fileName) { // Unsigned zones do not have an auth header if (!isSecure) return nullptr; - zoneLoader->AddLoadingStep(std::make_unique(ZoneConstants::MAGIC_AUTH_HEADER)); - zoneLoader->AddLoadingStep(std::make_unique(4)); // Loading Flags which are always zero - zoneLoader->AddLoadingStep(std::make_unique(fileName, 32)); + zoneLoader.AddLoadingStep(std::make_unique(ZoneConstants::MAGIC_AUTH_HEADER)); + zoneLoader.AddLoadingStep(std::make_unique(4)); // Loading Flags which are always zero + zoneLoader.AddLoadingStep(std::make_unique(fileName, 32)); auto signatureLoadStep = std::make_unique(256); auto* signatureLoadStepPtr = signatureLoadStep.get(); - zoneLoader->AddLoadingStep(std::move(signatureLoadStep)); + zoneLoader.AddLoadingStep(std::move(signatureLoadStep)); return signatureLoadStepPtr; } - static ICapturedDataProvider* AddXChunkProcessor(bool isEncrypted, ZoneLoader* zoneLoader, std::string& fileName) + ICapturedDataProvider* AddXChunkProcessor(const bool isEncrypted, ZoneLoader& zoneLoader, std::string& fileName) { ICapturedDataProvider* result = nullptr; auto xChunkProcessor = std::make_unique(ZoneConstants::STREAM_COUNT, ZoneConstants::XCHUNK_SIZE, ZoneConstants::VANILLA_BUFFER_SIZE); @@ -160,62 +161,55 @@ class ZoneLoaderFactory::Impl // Decompress the chunks using zlib xChunkProcessor->AddChunkProcessor(std::make_unique()); - zoneLoader->AddLoadingStep(std::make_unique(std::move(xChunkProcessor))); + zoneLoader.AddLoadingStep(std::make_unique(std::move(xChunkProcessor))); // If there is encryption, the signed data of the zone is the final hash blocks provided by the Salsa20 IV adaption algorithm return result; } +} // namespace -public: - static ZoneLoader* CreateLoaderForHeader(ZoneHeader& header, std::string& fileName) - { - bool isSecure; - bool isOfficial; - bool isEncrypted; - - // Check if this file is a supported T6 zone. - if (!CanLoad(header, &isSecure, &isOfficial, &isEncrypted)) - return nullptr; +std::unique_ptr ZoneLoaderFactory::CreateLoaderForHeader(ZoneHeader& header, std::string& fileName) const +{ + bool isSecure; + bool isOfficial; + bool isEncrypted; - // Create new zone - auto zone = std::make_unique(fileName, 0, &g_GameT6); - auto* zonePtr = zone.get(); - zone->m_pools = std::make_unique(zonePtr, 0); - zone->m_language = GetZoneLanguage(fileName); + // Check if this file is a supported T6 zone. + if (!CanLoad(header, &isSecure, &isOfficial, &isEncrypted)) + return nullptr; - // File is supported. Now setup all required steps for loading this file. - auto* zoneLoader = new ZoneLoader(std::move(zone)); + // Create new zone + auto zone = std::make_unique(fileName, 0, IGame::GetGameById(GameId::T6)); + auto* zonePtr = zone.get(); + zone->m_pools = std::make_unique(zonePtr, 0); + zone->m_language = GetZoneLanguage(fileName); - SetupBlock(zoneLoader); + // File is supported. Now setup all required steps for loading this file. + auto zoneLoader = std::make_unique(std::move(zone)); - // If file is signed setup a RSA instance. - auto rsa = isSecure ? SetupRSA(isOfficial) : nullptr; + SetupBlock(*zoneLoader); - // 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); + // If file is signed setup a RSA instance. + auto rsa = isSecure ? SetupRSA(isOfficial) : nullptr; - // Setup loading XChunks from the zone from this point on. - ICapturedDataProvider* signatureDataProvider = AddXChunkProcessor(isEncrypted, zoneLoader, fileName); + // 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); - // Start of the XFile struct - zoneLoader->AddLoadingStep(std::make_unique()); - zoneLoader->AddLoadingStep(std::make_unique()); + // Setup loading XChunks from the zone from this point on. + ICapturedDataProvider* signatureDataProvider = AddXChunkProcessor(isEncrypted, *zoneLoader, fileName); - // Start of the zone content - zoneLoader->AddLoadingStep(std::make_unique( - std::make_unique(), zonePtr, ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK)); + // Start of the XFile struct + zoneLoader->AddLoadingStep(std::make_unique()); + zoneLoader->AddLoadingStep(std::make_unique()); - if (isSecure) - { - zoneLoader->AddLoadingStep(std::make_unique(std::move(rsa), signatureProvider, signatureDataProvider)); - } + // Start of the zone content + zoneLoader->AddLoadingStep( + std::make_unique(std::make_unique(), zonePtr, ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK)); - // Return the fully setup zoneloader - return zoneLoader; + if (isSecure) + { + zoneLoader->AddLoadingStep(std::make_unique(std::move(rsa), signatureProvider, signatureDataProvider)); } -}; -ZoneLoader* ZoneLoaderFactory::CreateLoaderForHeader(ZoneHeader& header, std::string& fileName) -{ - return Impl::CreateLoaderForHeader(header, fileName); + return zoneLoader; } diff --git a/src/ZoneLoading/Game/T6/ZoneLoaderFactoryT6.h b/src/ZoneLoading/Game/T6/ZoneLoaderFactoryT6.h index 4f55d94c..0890f555 100644 --- a/src/ZoneLoading/Game/T6/ZoneLoaderFactoryT6.h +++ b/src/ZoneLoading/Game/T6/ZoneLoaderFactoryT6.h @@ -8,9 +8,7 @@ namespace T6 { class ZoneLoaderFactory final : public IZoneLoaderFactory { - class Impl; - public: - ZoneLoader* CreateLoaderForHeader(ZoneHeader& header, std::string& fileName) override; + std::unique_ptr CreateLoaderForHeader(ZoneHeader& header, std::string& fileName) const override; }; } // namespace T6 diff --git a/src/ZoneLoading/Loading/IZoneLoaderFactory.cpp b/src/ZoneLoading/Loading/IZoneLoaderFactory.cpp new file mode 100644 index 00000000..a02f025a --- /dev/null +++ b/src/ZoneLoading/Loading/IZoneLoaderFactory.cpp @@ -0,0 +1,27 @@ +#include "IZoneLoaderFactory.h" + +#include "Game/IW3/ZoneLoaderFactoryIW3.h" +#include "Game/IW4/ZoneLoaderFactoryIW4.h" +#include "Game/IW5/ZoneLoaderFactoryIW5.h" +#include "Game/T5/ZoneLoaderFactoryT5.h" +#include "Game/T6/ZoneLoaderFactoryT6.h" + +#include + +const IZoneLoaderFactory* IZoneLoaderFactory::GetZoneLoaderFactoryForGame(GameId game) +{ + static const IZoneLoaderFactory* zoneCreators[static_cast(GameId::COUNT)]{ + new IW3::ZoneLoaderFactory(), + new IW4::ZoneLoaderFactory(), + new IW5::ZoneLoaderFactory(), + new T5::ZoneLoaderFactory(), + new T6::ZoneLoaderFactory(), + }; + static_assert(std::extent_v == static_cast(GameId::COUNT)); + + assert(static_cast(game) < static_cast(GameId::COUNT)); + const auto* result = zoneCreators[static_cast(game)]; + assert(result); + + return result; +} diff --git a/src/ZoneLoading/Loading/IZoneLoaderFactory.h b/src/ZoneLoading/Loading/IZoneLoaderFactory.h index 988c763c..46ab7393 100644 --- a/src/ZoneLoading/Loading/IZoneLoaderFactory.h +++ b/src/ZoneLoading/Loading/IZoneLoaderFactory.h @@ -3,6 +3,8 @@ #include "Zone/ZoneTypes.h" #include "ZoneLoader.h" +#include + class IZoneLoaderFactory { public: @@ -13,5 +15,7 @@ class IZoneLoaderFactory IZoneLoaderFactory& operator=(const IZoneLoaderFactory& other) = default; IZoneLoaderFactory& operator=(IZoneLoaderFactory&& other) noexcept = default; - virtual ZoneLoader* CreateLoaderForHeader(ZoneHeader& header, std::string& fileName) = 0; + virtual std::unique_ptr CreateLoaderForHeader(ZoneHeader& header, std::string& fileName) const = 0; + + static const IZoneLoaderFactory* GetZoneLoaderFactoryForGame(GameId game); }; diff --git a/src/ZoneLoading/ZoneLoading.cpp b/src/ZoneLoading/ZoneLoading.cpp index 8aed7c3b..ad934839 100644 --- a/src/ZoneLoading/ZoneLoading.cpp +++ b/src/ZoneLoading/ZoneLoading.cpp @@ -1,34 +1,24 @@ #include "ZoneLoading.h" -#include "Game/IW3/ZoneLoaderFactoryIW3.h" -#include "Game/IW4/ZoneLoaderFactoryIW4.h" -#include "Game/IW5/ZoneLoaderFactoryIW5.h" -#include "Game/T5/ZoneLoaderFactoryT5.h" -#include "Game/T6/ZoneLoaderFactoryT6.h" +#include "Loading/IZoneLoaderFactory.h" +#include "Loading/ZoneLoader.h" #include "Utils/ObjFileStream.h" #include +#include #include #include namespace fs = std::filesystem; -IZoneLoaderFactory* ZoneLoaderFactories[]{ - new IW3::ZoneLoaderFactory(), - new IW4::ZoneLoaderFactory(), - new IW5::ZoneLoaderFactory(), - new T5::ZoneLoaderFactory(), - new T6::ZoneLoaderFactory(), -}; - std::unique_ptr ZoneLoading::LoadZone(const std::string& path) { - auto zoneName = fs::path(path).filename().replace_extension("").string(); + auto zoneName = fs::path(path).filename().replace_extension().string(); std::ifstream file(path, std::fstream::in | std::fstream::binary); if (!file.is_open()) { - printf("Could not open file '%s'.\n", path.c_str()); + std::cerr << std::format("Could not open file '{}'.\n", path); return nullptr; } @@ -36,27 +26,27 @@ std::unique_ptr ZoneLoading::LoadZone(const std::string& path) file.read(reinterpret_cast(&header), sizeof(header)); if (file.gcount() != sizeof(header)) { - std::cout << "Failed to read zone header from file '" << path << "'.\n"; + std::cerr << std::format("Failed to read zone header from file '{}'.\n", path); return nullptr; } - ZoneLoader* zoneLoader = nullptr; - for (auto* factory : ZoneLoaderFactories) + std::unique_ptr zoneLoader; + for (auto game = 0u; game < static_cast(GameId::COUNT); game++) { + const auto* factory = IZoneLoaderFactory::GetZoneLoaderFactoryForGame(static_cast(game)); zoneLoader = factory->CreateLoaderForHeader(header, zoneName); - if (zoneLoader != nullptr) + if (zoneLoader) break; } - if (zoneLoader == nullptr) + if (!zoneLoader) { - printf("Could not create factory for zone '%s'.\n", zoneName.c_str()); + std::cerr << std::format("Could not create factory for zone '{}'.\n", zoneName); return nullptr; } auto loadedZone = zoneLoader->LoadZone(file); - delete zoneLoader; file.close(); return std::move(loadedZone); From ce16d8e6c86b685e15015d2c5751a46133251329 Mon Sep 17 00:00:00 2001 From: Jan Date: Sat, 19 Oct 2024 20:22:11 +0200 Subject: [PATCH 4/5] chore: use method static array for zonewriterfactory --- .../Game/IW3/ZoneWriterFactoryIW3.cpp | 80 +++++------- .../Game/IW3/ZoneWriterFactoryIW3.h | 3 - .../Game/IW4/ZoneWriterFactoryIW4.cpp | 90 ++++++-------- .../Game/IW4/ZoneWriterFactoryIW4.h | 3 - .../Game/IW5/ZoneWriterFactoryIW5.cpp | 92 ++++++-------- .../Game/IW5/ZoneWriterFactoryIW5.h | 3 - .../Game/T5/ZoneWriterFactoryT5.cpp | 76 +++++------- src/ZoneWriting/Game/T5/ZoneWriterFactoryT5.h | 1 - .../Game/T6/ZoneWriterFactoryT6.cpp | 114 ++++++++---------- src/ZoneWriting/Game/T6/ZoneWriterFactoryT6.h | 1 - .../Writing/IZoneWriterFactory.cpp | 27 +++++ src/ZoneWriting/Writing/IZoneWriterFactory.h | 3 +- src/ZoneWriting/ZoneWriting.cpp | 24 +--- 13 files changed, 209 insertions(+), 308 deletions(-) create mode 100644 src/ZoneWriting/Writing/IZoneWriterFactory.cpp diff --git a/src/ZoneWriting/Game/IW3/ZoneWriterFactoryIW3.cpp b/src/ZoneWriting/Game/IW3/ZoneWriterFactoryIW3.cpp index 4fdeead9..ce9a0824 100644 --- a/src/ZoneWriting/Game/IW3/ZoneWriterFactoryIW3.cpp +++ b/src/ZoneWriting/Game/IW3/ZoneWriterFactoryIW3.cpp @@ -16,36 +16,26 @@ using namespace IW3; -class ZoneWriterFactory::Impl +namespace { - Zone* m_zone; - std::unique_ptr m_writer; - -public: - explicit Impl(Zone* zone) - : m_zone(zone), - m_writer(std::make_unique()) - { - } - - void SetupBlocks() const + void SetupBlocks(ZoneWriter& writer) { #define XBLOCK_DEF(name, type) std::make_unique(STR(name), name, type) - m_writer->AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_TEMP, XBlock::Type::BLOCK_TYPE_TEMP)); - m_writer->AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME)); - m_writer->AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_LARGE_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME)); - m_writer->AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_PHYSICAL_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME)); - m_writer->AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_VIRTUAL, XBlock::Type::BLOCK_TYPE_NORMAL)); - m_writer->AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_LARGE, XBlock::Type::BLOCK_TYPE_NORMAL)); - m_writer->AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_PHYSICAL, XBlock::Type::BLOCK_TYPE_NORMAL)); - m_writer->AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_VERTEX, XBlock::Type::BLOCK_TYPE_NORMAL)); - m_writer->AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_INDEX, XBlock::Type::BLOCK_TYPE_NORMAL)); + writer.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_TEMP, XBlock::Type::BLOCK_TYPE_TEMP)); + writer.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME)); + writer.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_LARGE_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME)); + writer.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_PHYSICAL_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME)); + writer.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_VIRTUAL, XBlock::Type::BLOCK_TYPE_NORMAL)); + writer.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_LARGE, XBlock::Type::BLOCK_TYPE_NORMAL)); + writer.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_PHYSICAL, XBlock::Type::BLOCK_TYPE_NORMAL)); + writer.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_VERTEX, XBlock::Type::BLOCK_TYPE_NORMAL)); + writer.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_INDEX, XBlock::Type::BLOCK_TYPE_NORMAL)); #undef XBLOCK_DEF } - static ZoneHeader CreateHeaderForParams() + ZoneHeader CreateHeaderForParams() { ZoneHeader header{}; header.m_version = ZoneConstants::ZONE_VERSION; @@ -53,40 +43,30 @@ class ZoneWriterFactory::Impl return header; } +} // namespace - std::unique_ptr CreateWriter() - { - SetupBlocks(); - - auto contentInMemory = std::make_unique( - std::make_unique(), m_zone, ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK); - auto* contentInMemoryPtr = contentInMemory.get(); - m_writer->AddWritingStep(std::move(contentInMemory)); +std::unique_ptr ZoneWriterFactory::CreateWriter(Zone* zone) const +{ + std::unique_ptr writer; - // Write zone header - m_writer->AddWritingStep(std::make_unique(CreateHeaderForParams())); + SetupBlocks(*writer); - m_writer->AddWritingStep(std::make_unique(std::make_unique())); + auto contentInMemory = std::make_unique( + std::make_unique(), zone, ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK); + auto* contentInMemoryPtr = contentInMemory.get(); + writer->AddWritingStep(std::move(contentInMemory)); - // Start of the XFile struct - m_writer->AddWritingStep(std::make_unique(contentInMemoryPtr)); - m_writer->AddWritingStep(std::make_unique(m_zone)); + // Write zone header + writer->AddWritingStep(std::make_unique(CreateHeaderForParams())); - // Start of the zone content - m_writer->AddWritingStep(std::make_unique(contentInMemoryPtr)); + writer->AddWritingStep(std::make_unique(std::make_unique())); - // Return the fully setup zoneloader - return std::move(m_writer); - } -}; + // Start of the XFile struct + writer->AddWritingStep(std::make_unique(contentInMemoryPtr)); + writer->AddWritingStep(std::make_unique(zone)); -bool ZoneWriterFactory::SupportsZone(Zone* zone) const -{ - return zone->m_game == &g_GameIW3; -} + // Start of the zone content + writer->AddWritingStep(std::make_unique(contentInMemoryPtr)); -std::unique_ptr ZoneWriterFactory::CreateWriter(Zone* zone) const -{ - Impl impl(zone); - return impl.CreateWriter(); + return std::move(writer); } diff --git a/src/ZoneWriting/Game/IW3/ZoneWriterFactoryIW3.h b/src/ZoneWriting/Game/IW3/ZoneWriterFactoryIW3.h index e0f26e1f..1296ad46 100644 --- a/src/ZoneWriting/Game/IW3/ZoneWriterFactoryIW3.h +++ b/src/ZoneWriting/Game/IW3/ZoneWriterFactoryIW3.h @@ -8,10 +8,7 @@ namespace IW3 { class ZoneWriterFactory final : public IZoneWriterFactory { - class Impl; - public: - _NODISCARD bool SupportsZone(Zone* zone) const override; _NODISCARD std::unique_ptr CreateWriter(Zone* zone) const override; }; } // namespace IW3 diff --git a/src/ZoneWriting/Game/IW4/ZoneWriterFactoryIW4.cpp b/src/ZoneWriting/Game/IW4/ZoneWriterFactoryIW4.cpp index 8dbd6754..e9371ba9 100644 --- a/src/ZoneWriting/Game/IW4/ZoneWriterFactoryIW4.cpp +++ b/src/ZoneWriting/Game/IW4/ZoneWriterFactoryIW4.cpp @@ -18,35 +18,25 @@ using namespace IW4; -class ZoneWriterFactory::Impl +namespace { - Zone* m_zone; - std::unique_ptr m_writer; - -public: - explicit Impl(Zone* zone) - : m_zone(zone), - m_writer(std::make_unique()) - { - } - - void SetupBlocks() const + void SetupBlocks(ZoneWriter& writer) { #define XBLOCK_DEF(name, type) std::make_unique(STR(name), name, type) - m_writer->AddXBlock(XBLOCK_DEF(XFILE_BLOCK_TEMP, XBlock::Type::BLOCK_TYPE_TEMP)); - m_writer->AddXBlock(XBLOCK_DEF(XFILE_BLOCK_PHYSICAL, XBlock::Type::BLOCK_TYPE_NORMAL)); - m_writer->AddXBlock(XBLOCK_DEF(XFILE_BLOCK_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME)); - m_writer->AddXBlock(XBLOCK_DEF(XFILE_BLOCK_VIRTUAL, XBlock::Type::BLOCK_TYPE_NORMAL)); - m_writer->AddXBlock(XBLOCK_DEF(XFILE_BLOCK_LARGE, XBlock::Type::BLOCK_TYPE_NORMAL)); - m_writer->AddXBlock(XBLOCK_DEF(XFILE_BLOCK_CALLBACK, XBlock::Type::BLOCK_TYPE_NORMAL)); - m_writer->AddXBlock(XBLOCK_DEF(XFILE_BLOCK_VERTEX, XBlock::Type::BLOCK_TYPE_NORMAL)); - m_writer->AddXBlock(XBLOCK_DEF(XFILE_BLOCK_INDEX, XBlock::Type::BLOCK_TYPE_NORMAL)); + writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_TEMP, XBlock::Type::BLOCK_TYPE_TEMP)); + writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_PHYSICAL, XBlock::Type::BLOCK_TYPE_NORMAL)); + writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME)); + writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_VIRTUAL, XBlock::Type::BLOCK_TYPE_NORMAL)); + writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_LARGE, XBlock::Type::BLOCK_TYPE_NORMAL)); + writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_CALLBACK, XBlock::Type::BLOCK_TYPE_NORMAL)); + writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_VERTEX, XBlock::Type::BLOCK_TYPE_NORMAL)); + writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_INDEX, XBlock::Type::BLOCK_TYPE_NORMAL)); #undef XBLOCK_DEF } - static ZoneHeader CreateHeaderForParams(const bool isSecure, const bool isOfficial) + ZoneHeader CreateHeaderForParams(const bool isSecure, const bool isOfficial) { ZoneHeader header{}; header.m_version = ZoneConstants::ZONE_VERSION; @@ -65,49 +55,39 @@ class ZoneWriterFactory::Impl return header; } +}; // namespace - std::unique_ptr CreateWriter() - { - // TODO Support signed fastfiles - bool isSecure = false; - - SetupBlocks(); +std::unique_ptr ZoneWriterFactory::CreateWriter(Zone* zone) const +{ + auto writer = std::make_unique(); - auto contentInMemory = std::make_unique( - std::make_unique(), m_zone, ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK); - auto* contentInMemoryPtr = contentInMemory.get(); - m_writer->AddWritingStep(std::move(contentInMemory)); + // TODO Support signed fastfiles + bool isSecure = false; - // Write zone header - m_writer->AddWritingStep(std::make_unique(CreateHeaderForParams(isSecure, false))); + SetupBlocks(*writer); - // Write dummy byte that the game ignores as well. No clue what it means. - m_writer->AddWritingStep(std::make_unique(1)); + auto contentInMemory = std::make_unique( + std::make_unique(), zone, ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK); + auto* contentInMemoryPtr = contentInMemory.get(); + writer->AddWritingStep(std::move(contentInMemory)); - // Write timestamp - m_writer->AddWritingStep(std::make_unique()); + // Write zone header + writer->AddWritingStep(std::make_unique(CreateHeaderForParams(isSecure, false))); - m_writer->AddWritingStep(std::make_unique(std::make_unique())); + // Write dummy byte that the game ignores as well. No clue what it means. + writer->AddWritingStep(std::make_unique(1)); - // Start of the XFile struct - m_writer->AddWritingStep(std::make_unique(contentInMemoryPtr)); - m_writer->AddWritingStep(std::make_unique(m_zone)); + // Write timestamp + writer->AddWritingStep(std::make_unique()); - // Start of the zone content - m_writer->AddWritingStep(std::make_unique(contentInMemoryPtr)); + writer->AddWritingStep(std::make_unique(std::make_unique())); - // Return the fully setup zoneloader - return std::move(m_writer); - } -}; + // Start of the XFile struct + writer->AddWritingStep(std::make_unique(contentInMemoryPtr)); + writer->AddWritingStep(std::make_unique(zone)); -bool ZoneWriterFactory::SupportsZone(Zone* zone) const -{ - return zone->m_game == &g_GameIW4; -} + // Start of the zone content + writer->AddWritingStep(std::make_unique(contentInMemoryPtr)); -std::unique_ptr ZoneWriterFactory::CreateWriter(Zone* zone) const -{ - Impl impl(zone); - return impl.CreateWriter(); + return std::move(writer); } diff --git a/src/ZoneWriting/Game/IW4/ZoneWriterFactoryIW4.h b/src/ZoneWriting/Game/IW4/ZoneWriterFactoryIW4.h index 7625668e..0b5240b3 100644 --- a/src/ZoneWriting/Game/IW4/ZoneWriterFactoryIW4.h +++ b/src/ZoneWriting/Game/IW4/ZoneWriterFactoryIW4.h @@ -8,10 +8,7 @@ namespace IW4 { class ZoneWriterFactory final : public IZoneWriterFactory { - class Impl; - public: - _NODISCARD bool SupportsZone(Zone* zone) const override; _NODISCARD std::unique_ptr CreateWriter(Zone* zone) const override; }; } // namespace IW4 diff --git a/src/ZoneWriting/Game/IW5/ZoneWriterFactoryIW5.cpp b/src/ZoneWriting/Game/IW5/ZoneWriterFactoryIW5.cpp index 1b91a4c5..402e46bf 100644 --- a/src/ZoneWriting/Game/IW5/ZoneWriterFactoryIW5.cpp +++ b/src/ZoneWriting/Game/IW5/ZoneWriterFactoryIW5.cpp @@ -18,36 +18,26 @@ using namespace IW5; -class ZoneWriterFactory::Impl +namespace { - Zone* m_zone; - std::unique_ptr m_writer; - -public: - explicit Impl(Zone* zone) - : m_zone(zone), - m_writer(std::make_unique()) - { - } - - void SetupBlocks() const + void SetupBlocks(ZoneWriter& writer) { #define XBLOCK_DEF(name, type) std::make_unique(STR(name), name, type) - m_writer->AddXBlock(XBLOCK_DEF(XFILE_BLOCK_TEMP, XBlock::Type::BLOCK_TYPE_TEMP)); - m_writer->AddXBlock(XBLOCK_DEF(XFILE_BLOCK_PHYSICAL, XBlock::Type::BLOCK_TYPE_NORMAL)); - m_writer->AddXBlock(XBLOCK_DEF(XFILE_BLOCK_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME)); - m_writer->AddXBlock(XBLOCK_DEF(XFILE_BLOCK_VIRTUAL, XBlock::Type::BLOCK_TYPE_NORMAL)); - m_writer->AddXBlock(XBLOCK_DEF(XFILE_BLOCK_LARGE, XBlock::Type::BLOCK_TYPE_NORMAL)); - m_writer->AddXBlock(XBLOCK_DEF(XFILE_BLOCK_CALLBACK, XBlock::Type::BLOCK_TYPE_NORMAL)); - m_writer->AddXBlock(XBLOCK_DEF(XFILE_BLOCK_VERTEX, XBlock::Type::BLOCK_TYPE_NORMAL)); - m_writer->AddXBlock(XBLOCK_DEF(XFILE_BLOCK_INDEX, XBlock::Type::BLOCK_TYPE_NORMAL)); - m_writer->AddXBlock(XBLOCK_DEF(XFILE_BLOCK_SCRIPT, XBlock::Type::BLOCK_TYPE_NORMAL)); + writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_TEMP, XBlock::Type::BLOCK_TYPE_TEMP)); + writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_PHYSICAL, XBlock::Type::BLOCK_TYPE_NORMAL)); + writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME)); + writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_VIRTUAL, XBlock::Type::BLOCK_TYPE_NORMAL)); + writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_LARGE, XBlock::Type::BLOCK_TYPE_NORMAL)); + writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_CALLBACK, XBlock::Type::BLOCK_TYPE_NORMAL)); + writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_VERTEX, XBlock::Type::BLOCK_TYPE_NORMAL)); + writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_INDEX, XBlock::Type::BLOCK_TYPE_NORMAL)); + writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_SCRIPT, XBlock::Type::BLOCK_TYPE_NORMAL)); #undef XBLOCK_DEF } - static ZoneHeader CreateHeaderForParams(const bool isSecure, const bool isOfficial) + ZoneHeader CreateHeaderForParams(const bool isSecure, const bool isOfficial) { ZoneHeader header{}; header.m_version = ZoneConstants::ZONE_VERSION; @@ -66,49 +56,39 @@ class ZoneWriterFactory::Impl return header; } +}; // namespace - std::unique_ptr CreateWriter() - { - // TODO Support signed fastfiles - bool isSecure = false; - - SetupBlocks(); +std::unique_ptr ZoneWriterFactory::CreateWriter(Zone* zone) const +{ + auto writer = std::make_unique(); - auto contentInMemory = std::make_unique( - std::make_unique(), m_zone, ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK); - auto* contentInMemoryPtr = contentInMemory.get(); - m_writer->AddWritingStep(std::move(contentInMemory)); + // TODO Support signed fastfiles + bool isSecure = false; - // Write zone header - m_writer->AddWritingStep(std::make_unique(CreateHeaderForParams(isSecure, false))); + SetupBlocks(*writer); - // Write dummy byte that the game ignores as well. No clue what it means. - m_writer->AddWritingStep(std::make_unique(1)); + auto contentInMemory = std::make_unique( + std::make_unique(), zone, ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK); + auto* contentInMemoryPtr = contentInMemory.get(); + writer->AddWritingStep(std::move(contentInMemory)); - // Write timestamp - m_writer->AddWritingStep(std::make_unique()); + // Write zone header + writer->AddWritingStep(std::make_unique(CreateHeaderForParams(isSecure, false))); - m_writer->AddWritingStep(std::make_unique(std::make_unique())); + // Write dummy byte that the game ignores as well. No clue what it means. + writer->AddWritingStep(std::make_unique(1)); - // Start of the XFile struct - m_writer->AddWritingStep(std::make_unique(contentInMemoryPtr)); - m_writer->AddWritingStep(std::make_unique(m_zone)); + // Write timestamp + writer->AddWritingStep(std::make_unique()); - // Start of the zone content - m_writer->AddWritingStep(std::make_unique(contentInMemoryPtr)); + writer->AddWritingStep(std::make_unique(std::make_unique())); - // Return the fully setup zoneloader - return std::move(m_writer); - } -}; + // Start of the XFile struct + writer->AddWritingStep(std::make_unique(contentInMemoryPtr)); + writer->AddWritingStep(std::make_unique(zone)); -bool ZoneWriterFactory::SupportsZone(Zone* zone) const -{ - return zone->m_game == &g_GameIW5; -} + // Start of the zone content + writer->AddWritingStep(std::make_unique(contentInMemoryPtr)); -std::unique_ptr ZoneWriterFactory::CreateWriter(Zone* zone) const -{ - Impl impl(zone); - return impl.CreateWriter(); + return std::move(writer); } diff --git a/src/ZoneWriting/Game/IW5/ZoneWriterFactoryIW5.h b/src/ZoneWriting/Game/IW5/ZoneWriterFactoryIW5.h index 847dd114..db956778 100644 --- a/src/ZoneWriting/Game/IW5/ZoneWriterFactoryIW5.h +++ b/src/ZoneWriting/Game/IW5/ZoneWriterFactoryIW5.h @@ -8,10 +8,7 @@ namespace IW5 { class ZoneWriterFactory final : public IZoneWriterFactory { - class Impl; - public: - _NODISCARD bool SupportsZone(Zone* zone) const override; _NODISCARD std::unique_ptr CreateWriter(Zone* zone) const override; }; } // namespace IW5 diff --git a/src/ZoneWriting/Game/T5/ZoneWriterFactoryT5.cpp b/src/ZoneWriting/Game/T5/ZoneWriterFactoryT5.cpp index 7fe34144..d3a03a33 100644 --- a/src/ZoneWriting/Game/T5/ZoneWriterFactoryT5.cpp +++ b/src/ZoneWriting/Game/T5/ZoneWriterFactoryT5.cpp @@ -16,34 +16,24 @@ using namespace T5; -class ZoneWriterFactory::Impl +namespace { - Zone* m_zone; - std::unique_ptr m_writer; - -public: - explicit Impl(Zone* zone) - : m_zone(zone), - m_writer(std::make_unique()) - { - } - - void SetupBlocks() const + void SetupBlocks(ZoneWriter& writer) { #define XBLOCK_DEF(name, type) std::make_unique(STR(name), name, type) - m_writer->AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_TEMP, XBlock::Type::BLOCK_TYPE_TEMP)); - m_writer->AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME)); - m_writer->AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_LARGE_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME)); - m_writer->AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_PHYSICAL_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME)); - m_writer->AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_VIRTUAL, XBlock::Type::BLOCK_TYPE_NORMAL)); - m_writer->AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_LARGE, XBlock::Type::BLOCK_TYPE_NORMAL)); - m_writer->AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_PHYSICAL, XBlock::Type::BLOCK_TYPE_NORMAL)); + writer.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_TEMP, XBlock::Type::BLOCK_TYPE_TEMP)); + writer.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME)); + writer.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_LARGE_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME)); + writer.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_PHYSICAL_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME)); + writer.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_VIRTUAL, XBlock::Type::BLOCK_TYPE_NORMAL)); + writer.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_LARGE, XBlock::Type::BLOCK_TYPE_NORMAL)); + writer.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_PHYSICAL, XBlock::Type::BLOCK_TYPE_NORMAL)); #undef XBLOCK_DEF } - static ZoneHeader CreateHeaderForParams() + ZoneHeader CreateHeaderForParams() { ZoneHeader header{}; header.m_version = ZoneConstants::ZONE_VERSION; @@ -51,40 +41,30 @@ class ZoneWriterFactory::Impl return header; } +} // namespace - std::unique_ptr CreateWriter() - { - SetupBlocks(); - - auto contentInMemory = std::make_unique( - std::make_unique(), m_zone, ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK); - auto* contentInMemoryPtr = contentInMemory.get(); - m_writer->AddWritingStep(std::move(contentInMemory)); +std::unique_ptr ZoneWriterFactory::CreateWriter(Zone* zone) const +{ + auto writer = std::make_unique(); - // Write zone header - m_writer->AddWritingStep(std::make_unique(CreateHeaderForParams())); + SetupBlocks(*writer); - m_writer->AddWritingStep(std::make_unique(std::make_unique())); + auto contentInMemory = std::make_unique( + std::make_unique(), zone, ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK); + auto* contentInMemoryPtr = contentInMemory.get(); + writer->AddWritingStep(std::move(contentInMemory)); - // Start of the XFile struct - m_writer->AddWritingStep(std::make_unique(contentInMemoryPtr)); - m_writer->AddWritingStep(std::make_unique(m_zone)); + // Write zone header + writer->AddWritingStep(std::make_unique(CreateHeaderForParams())); - // Start of the zone content - m_writer->AddWritingStep(std::make_unique(contentInMemoryPtr)); + writer->AddWritingStep(std::make_unique(std::make_unique())); - // Return the fully setup zoneloader - return std::move(m_writer); - } -}; + // Start of the XFile struct + writer->AddWritingStep(std::make_unique(contentInMemoryPtr)); + writer->AddWritingStep(std::make_unique(zone)); -bool ZoneWriterFactory::SupportsZone(Zone* zone) const -{ - return zone->m_game == &g_GameT5; -} + // Start of the zone content + writer->AddWritingStep(std::make_unique(contentInMemoryPtr)); -std::unique_ptr ZoneWriterFactory::CreateWriter(Zone* zone) const -{ - Impl impl(zone); - return impl.CreateWriter(); + return std::move(writer); } diff --git a/src/ZoneWriting/Game/T5/ZoneWriterFactoryT5.h b/src/ZoneWriting/Game/T5/ZoneWriterFactoryT5.h index 6a6fa5a7..f993903b 100644 --- a/src/ZoneWriting/Game/T5/ZoneWriterFactoryT5.h +++ b/src/ZoneWriting/Game/T5/ZoneWriterFactoryT5.h @@ -11,7 +11,6 @@ namespace T5 class Impl; public: - _NODISCARD bool SupportsZone(Zone* zone) const override; _NODISCARD std::unique_ptr CreateWriter(Zone* zone) const override; }; } // namespace T5 diff --git a/src/ZoneWriting/Game/T6/ZoneWriterFactoryT6.cpp b/src/ZoneWriting/Game/T6/ZoneWriterFactoryT6.cpp index 20f24c0c..4baede1f 100644 --- a/src/ZoneWriting/Game/T6/ZoneWriterFactoryT6.cpp +++ b/src/ZoneWriting/Game/T6/ZoneWriterFactoryT6.cpp @@ -23,35 +23,25 @@ using namespace T6; -class ZoneWriterFactory::Impl +namespace { - Zone* m_zone; - std::unique_ptr m_writer; - -public: - explicit Impl(Zone* zone) - : m_zone(zone), - m_writer(std::make_unique()) - { - } - - void SetupBlocks() const + void SetupBlocks(ZoneWriter& writer) { #define XBLOCK_DEF(name, type) std::make_unique(STR(name), name, type) - m_writer->AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_TEMP, XBlock::Type::BLOCK_TYPE_TEMP)); - m_writer->AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_RUNTIME_VIRTUAL, XBlock::Type::BLOCK_TYPE_RUNTIME)); - m_writer->AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_RUNTIME_PHYSICAL, XBlock::Type::BLOCK_TYPE_RUNTIME)); - m_writer->AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_DELAY_VIRTUAL, XBlock::Type::BLOCK_TYPE_DELAY)); - m_writer->AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_DELAY_PHYSICAL, XBlock::Type::BLOCK_TYPE_DELAY)); - m_writer->AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_VIRTUAL, XBlock::Type::BLOCK_TYPE_NORMAL)); - m_writer->AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_PHYSICAL, XBlock::Type::BLOCK_TYPE_NORMAL)); - m_writer->AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_STREAMER_RESERVE, XBlock::Type::BLOCK_TYPE_NORMAL)); + writer.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_TEMP, XBlock::Type::BLOCK_TYPE_TEMP)); + writer.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_RUNTIME_VIRTUAL, XBlock::Type::BLOCK_TYPE_RUNTIME)); + writer.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_RUNTIME_PHYSICAL, XBlock::Type::BLOCK_TYPE_RUNTIME)); + writer.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_DELAY_VIRTUAL, XBlock::Type::BLOCK_TYPE_DELAY)); + writer.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_DELAY_PHYSICAL, XBlock::Type::BLOCK_TYPE_DELAY)); + writer.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_VIRTUAL, XBlock::Type::BLOCK_TYPE_NORMAL)); + writer.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_PHYSICAL, XBlock::Type::BLOCK_TYPE_NORMAL)); + writer.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_STREAMER_RESERVE, XBlock::Type::BLOCK_TYPE_NORMAL)); #undef XBLOCK_DEF } - static ZoneHeader CreateHeaderForParams(const bool isSecure, const bool isOfficial, const bool isEncrypted) + ZoneHeader CreateHeaderForParams(const bool isSecure, const bool isOfficial, const bool isEncrypted) { ZoneHeader header{}; header.m_version = ZoneConstants::ZONE_VERSION; @@ -74,7 +64,11 @@ class ZoneWriterFactory::Impl return header; } - void AddXChunkProcessor(const bool isEncrypted, ICapturedDataProvider** dataToSignProviderPtr, OutputProcessorXChunks** xChunkProcessorPtr) const + void AddXChunkProcessor(ZoneWriter& writer, + const Zone& zone, + const bool isEncrypted, + ICapturedDataProvider** dataToSignProviderPtr, + OutputProcessorXChunks** xChunkProcessorPtr) { auto xChunkProcessor = std::make_unique( ZoneConstants::STREAM_COUNT, ZoneConstants::XCHUNK_SIZE, ZoneConstants::XCHUNK_MAX_WRITE_SIZE, ZoneConstants::VANILLA_BUFFER_SIZE); @@ -88,7 +82,7 @@ class ZoneWriterFactory::Impl { // If zone is encrypted, the decryption is applied before the decompression. T6 Zones always use Salsa20. auto chunkProcessorSalsa20 = std::make_unique( - ZoneConstants::STREAM_COUNT, m_zone->m_name, ZoneConstants::SALSA20_KEY_TREYARCH, sizeof(ZoneConstants::SALSA20_KEY_TREYARCH)); + ZoneConstants::STREAM_COUNT, zone.m_name, ZoneConstants::SALSA20_KEY_TREYARCH, sizeof(ZoneConstants::SALSA20_KEY_TREYARCH)); // If there is encryption, the signed data of the zone is the final hash blocks provided by the Salsa20 IV adaption algorithm if (dataToSignProviderPtr) @@ -97,58 +91,48 @@ class ZoneWriterFactory::Impl xChunkProcessor->AddChunkProcessor(std::move(chunkProcessorSalsa20)); } - m_writer->AddWritingStep(std::make_unique(std::move(xChunkProcessor))); + writer.AddWritingStep(std::make_unique(std::move(xChunkProcessor))); } +}; // namespace - std::unique_ptr CreateWriter() - { - // TODO Support signed fastfiles - bool isSecure = false; - bool isEncrypted = true; - - SetupBlocks(); +std::unique_ptr ZoneWriterFactory::CreateWriter(Zone* zone) const +{ + auto writer = std::make_unique(); - auto contentInMemory = std::make_unique( - std::make_unique(), m_zone, ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK); - auto* contentInMemoryPtr = contentInMemory.get(); - m_writer->AddWritingStep(std::move(contentInMemory)); + // TODO Support signed fastfiles + bool isSecure = false; + bool isEncrypted = true; - // Write zone header - m_writer->AddWritingStep(std::make_unique(CreateHeaderForParams(isSecure, false, isEncrypted))); + SetupBlocks(*writer); - // Setup loading XChunks from the zone from this point on. - ICapturedDataProvider* dataToSignProvider; - OutputProcessorXChunks* xChunksProcessor; - AddXChunkProcessor(isEncrypted, &dataToSignProvider, &xChunksProcessor); + auto contentInMemory = std::make_unique( + std::make_unique(), zone, ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK); + auto* contentInMemoryPtr = contentInMemory.get(); + writer->AddWritingStep(std::move(contentInMemory)); - // Start of the XFile struct - // m_writer->AddWritingStep(std::make_unique(8)); // Skip size and externalSize fields since they are not interesting for us - m_writer->AddWritingStep(std::make_unique(contentInMemoryPtr)); - m_writer->AddWritingStep(std::make_unique(m_zone)); + // Write zone header + writer->AddWritingStep(std::make_unique(CreateHeaderForParams(isSecure, false, isEncrypted))); - // Start of the zone content - m_writer->AddWritingStep(std::make_unique(contentInMemoryPtr)); + // Setup loading XChunks from the zone from this point on. + ICapturedDataProvider* dataToSignProvider; + OutputProcessorXChunks* xChunksProcessor; + AddXChunkProcessor(*writer, *zone, isEncrypted, &dataToSignProvider, &xChunksProcessor); - // Stop writing in XChunks - m_writer->AddWritingStep(std::make_unique(xChunksProcessor)); + // Start of the XFile struct + // m_writer->AddWritingStep(std::make_unique(8)); // Skip size and externalSize fields since they are not interesting for us + writer->AddWritingStep(std::make_unique(contentInMemoryPtr)); + writer->AddWritingStep(std::make_unique(zone)); - // Pad ending with zeros like the original linker does it. The game's reader needs it for some reason. - // From my observations this is most likely the logic behind the amount of bytes: At least 0x40 bytes and aligned to the next 0x40 - m_writer->AddWritingStep(std::make_unique(ZoneConstants::FILE_SUFFIX_ZERO_MIN_SIZE)); - m_writer->AddWritingStep(std::make_unique(ZoneConstants::FILE_SUFFIX_ZERO_ALIGN, '\0')); + // Start of the zone content + writer->AddWritingStep(std::make_unique(contentInMemoryPtr)); - // Return the fully setup zoneloader - return std::move(m_writer); - } -}; + // Stop writing in XChunks + writer->AddWritingStep(std::make_unique(xChunksProcessor)); -bool ZoneWriterFactory::SupportsZone(Zone* zone) const -{ - return zone->m_game == &g_GameT6; -} + // Pad ending with zeros like the original linker does it. The game's reader needs it for some reason. + // From my observations this is most likely the logic behind the amount of bytes: At least 0x40 bytes and aligned to the next 0x40 + writer->AddWritingStep(std::make_unique(ZoneConstants::FILE_SUFFIX_ZERO_MIN_SIZE)); + writer->AddWritingStep(std::make_unique(ZoneConstants::FILE_SUFFIX_ZERO_ALIGN, '\0')); -std::unique_ptr ZoneWriterFactory::CreateWriter(Zone* zone) const -{ - Impl impl(zone); - return impl.CreateWriter(); + return std::move(writer); } diff --git a/src/ZoneWriting/Game/T6/ZoneWriterFactoryT6.h b/src/ZoneWriting/Game/T6/ZoneWriterFactoryT6.h index 7f9c6cd5..895bf82e 100644 --- a/src/ZoneWriting/Game/T6/ZoneWriterFactoryT6.h +++ b/src/ZoneWriting/Game/T6/ZoneWriterFactoryT6.h @@ -11,7 +11,6 @@ namespace T6 class Impl; public: - _NODISCARD bool SupportsZone(Zone* zone) const override; _NODISCARD std::unique_ptr CreateWriter(Zone* zone) const override; }; } // namespace T6 diff --git a/src/ZoneWriting/Writing/IZoneWriterFactory.cpp b/src/ZoneWriting/Writing/IZoneWriterFactory.cpp new file mode 100644 index 00000000..193c4c84 --- /dev/null +++ b/src/ZoneWriting/Writing/IZoneWriterFactory.cpp @@ -0,0 +1,27 @@ +#include "IZoneWriterFactory.h" + +#include "Game/IW3/ZoneWriterFactoryIW3.h" +#include "Game/IW4/ZoneWriterFactoryIW4.h" +#include "Game/IW5/ZoneWriterFactoryIW5.h" +#include "Game/T5/ZoneWriterFactoryT5.h" +#include "Game/T6/ZoneWriterFactoryT6.h" + +#include + +const IZoneWriterFactory* IZoneWriterFactory::GetZoneWriterFactoryForGame(GameId game) +{ + static const IZoneWriterFactory* zoneCreators[static_cast(GameId::COUNT)]{ + new IW3::ZoneWriterFactory(), + new IW4::ZoneWriterFactory(), + new IW5::ZoneWriterFactory(), + new T5::ZoneWriterFactory(), + new T6::ZoneWriterFactory(), + }; + static_assert(std::extent_v == static_cast(GameId::COUNT)); + + assert(static_cast(game) < static_cast(GameId::COUNT)); + const auto* result = zoneCreators[static_cast(game)]; + assert(result); + + return result; +} diff --git a/src/ZoneWriting/Writing/IZoneWriterFactory.h b/src/ZoneWriting/Writing/IZoneWriterFactory.h index 84a1d484..12f97b34 100644 --- a/src/ZoneWriting/Writing/IZoneWriterFactory.h +++ b/src/ZoneWriting/Writing/IZoneWriterFactory.h @@ -14,6 +14,7 @@ class IZoneWriterFactory IZoneWriterFactory& operator=(const IZoneWriterFactory& other) = default; IZoneWriterFactory& operator=(IZoneWriterFactory&& other) noexcept = default; - _NODISCARD virtual bool SupportsZone(Zone* zone) const = 0; _NODISCARD virtual std::unique_ptr CreateWriter(Zone* zone) const = 0; + + static const IZoneWriterFactory* GetZoneWriterFactoryForGame(GameId game); }; diff --git a/src/ZoneWriting/ZoneWriting.cpp b/src/ZoneWriting/ZoneWriting.cpp index 48c53407..7b04f431 100644 --- a/src/ZoneWriting/ZoneWriting.cpp +++ b/src/ZoneWriting/ZoneWriting.cpp @@ -1,38 +1,18 @@ #include "ZoneWriting.h" -#include "Game/IW3/ZoneWriterFactoryIW3.h" -#include "Game/IW4/ZoneWriterFactoryIW4.h" -#include "Game/IW5/ZoneWriterFactoryIW5.h" -#include "Game/T5/ZoneWriterFactoryT5.h" -#include "Game/T6/ZoneWriterFactoryT6.h" #include "Writing/IZoneWriterFactory.h" #include #include #include -IZoneWriterFactory* ZoneWriterFactories[]{ - new IW3::ZoneWriterFactory(), - new IW4::ZoneWriterFactory(), - new IW5::ZoneWriterFactory(), - new T5::ZoneWriterFactory(), - new T6::ZoneWriterFactory(), -}; - bool ZoneWriting::WriteZone(std::ostream& stream, Zone* zone) { const auto start = std::chrono::high_resolution_clock::now(); - std::unique_ptr zoneWriter; - for (auto* factory : ZoneWriterFactories) - { - if (factory->SupportsZone(zone)) - { - zoneWriter = factory->CreateWriter(zone); - break; - } - } + const auto factory = IZoneWriterFactory::GetZoneWriterFactoryForGame(zone->m_game->GetId()); + const auto zoneWriter = factory->CreateWriter(zone); if (zoneWriter == nullptr) { std::cerr << std::format("Could not create ZoneWriter for zone \"{}\".\n", zone->m_name); From b00c65c8c067f01ccdbc2383dffc987ff5ace556 Mon Sep 17 00:00:00 2001 From: Jan Date: Sat, 19 Oct 2024 21:03:36 +0200 Subject: [PATCH 5/5] refactor: get rid of global game variables --- src/Common/Game/IGame.cpp | 26 +++++++++++++++++ src/Common/Game/IGame.h | 10 +++---- src/Common/Game/IW3/GameIW3.cpp | 24 +++++++-------- src/Common/Game/IW3/GameIW3.h | 29 ++++++++++--------- src/Common/Game/IW4/GameIW4.cpp | 24 +++++++-------- src/Common/Game/IW4/GameIW4.h | 29 ++++++++++--------- src/Common/Game/IW5/GameIW5.cpp | 24 +++++++-------- src/Common/Game/IW5/GameIW5.h | 29 ++++++++++--------- src/Common/Game/T5/GameT5.cpp | 24 +++++++-------- src/Common/Game/T5/GameT5.h | 29 ++++++++++--------- src/Common/Game/T6/GameT6.cpp | 24 +++++++-------- src/Common/Game/T6/GameT6.h | 29 ++++++++++--------- src/Linker/Game/IW3/ZoneCreatorIW3.cpp | 2 +- src/Linker/Game/IW4/ZoneCreatorIW4.cpp | 2 +- src/Linker/Game/IW5/ZoneCreatorIW5.cpp | 2 +- src/Linker/Game/T5/ZoneCreatorT5.cpp | 2 +- src/Linker/Game/T6/ZoneCreatorT6.cpp | 2 +- src/ObjLoading/Game/T6/ObjLoaderT6.cpp | 2 +- .../Material/MaterialConstantZoneState.cpp | 2 +- .../T6/AssetDumpers/AssetDumperSndBank.cpp | 2 +- .../T6/Material/MaterialConstantZoneState.cpp | 2 +- .../Game/IW3/ZoneWriterFactoryIW3.cpp | 2 +- .../AssetLoaderStringTableTest.cpp | 2 +- .../AssetLoaderStringTableTest.cpp | 2 +- .../Game/IW4/Menu/MenuParsingIW4IT.cpp | 2 +- .../AssetLoaderStringTableTest.cpp | 2 +- .../AssetLoaderStringTableTest.cpp | 2 +- .../AssetLoaderStringTableTest.cpp | 2 +- 28 files changed, 177 insertions(+), 156 deletions(-) create mode 100644 src/Common/Game/IGame.cpp diff --git a/src/Common/Game/IGame.cpp b/src/Common/Game/IGame.cpp new file mode 100644 index 00000000..ad8827db --- /dev/null +++ b/src/Common/Game/IGame.cpp @@ -0,0 +1,26 @@ +#include "IGame.h" + +#include "IW3/GameIW3.h" +#include "IW4/GameIW4.h" +#include "IW5/GameIW5.h" +#include "T5/GameT5.h" +#include "T6/GameT6.h" + +#include + +IGame* IGame::GetGameById(GameId gameId) +{ + static IGame* games[static_cast(GameId::COUNT)]{ + new IW3::Game(), + new IW4::Game(), + new IW5::Game(), + new T5::Game(), + new T6::Game(), + }; + + assert(static_cast(gameId) < static_cast(GameId::COUNT)); + auto* result = games[static_cast(gameId)]; + assert(result); + + return result; +} diff --git a/src/Common/Game/IGame.h b/src/Common/Game/IGame.h index 2fb4b5c6..02419205 100644 --- a/src/Common/Game/IGame.h +++ b/src/Common/Game/IGame.h @@ -36,13 +36,13 @@ class IGame IGame& operator=(const IGame& other) = default; IGame& operator=(IGame&& other) noexcept = default; - virtual GameId GetId() = 0; - virtual std::string GetFullName() = 0; - virtual std::string GetShortName() = 0; + [[nodiscard]] virtual GameId GetId() const = 0; + [[nodiscard]] virtual const std::string& GetFullName() const = 0; + [[nodiscard]] virtual const std::string& GetShortName() const = 0; virtual void AddZone(Zone* zone) = 0; virtual void RemoveZone(Zone* zone) = 0; - virtual std::vector GetZones() = 0; - virtual const std::vector& GetLanguagePrefixes() = 0; + [[nodiscard]] virtual const std::vector& GetZones() const = 0; + [[nodiscard]] virtual const std::vector& GetLanguagePrefixes() const = 0; static IGame* GetGameById(GameId gameId); }; diff --git a/src/Common/Game/IW3/GameIW3.cpp b/src/Common/Game/IW3/GameIW3.cpp index ea8b3840..2c080343 100644 --- a/src/Common/Game/IW3/GameIW3.cpp +++ b/src/Common/Game/IW3/GameIW3.cpp @@ -1,34 +1,32 @@ #include "GameIW3.h" -#include "IW3.h" - #include using namespace IW3; -GameIW3 g_GameIW3; - -GameId GameIW3::GetId() +GameId Game::GetId() const { return GameId::IW3; } -std::string GameIW3::GetFullName() +const std::string& Game::GetFullName() const { - return "Call Of Duty 4: Modern Warfare"; + static std::string fullName = "Call Of Duty 4: Modern Warfare"; + return fullName; } -std::string GameIW3::GetShortName() +const std::string& Game::GetShortName() const { - return "IW3"; + static std::string shortName = "IW3"; + return shortName; } -void GameIW3::AddZone(Zone* zone) +void Game::AddZone(Zone* zone) { m_zones.push_back(zone); } -void GameIW3::RemoveZone(Zone* zone) +void Game::RemoveZone(Zone* zone) { const auto foundEntry = std::ranges::find(m_zones, zone); @@ -36,12 +34,12 @@ void GameIW3::RemoveZone(Zone* zone) m_zones.erase(foundEntry); } -std::vector GameIW3::GetZones() +const std::vector& Game::GetZones() const { return m_zones; } -const std::vector& GameIW3::GetLanguagePrefixes() +const std::vector& Game::GetLanguagePrefixes() const { static std::vector prefixes; return prefixes; diff --git a/src/Common/Game/IW3/GameIW3.h b/src/Common/Game/IW3/GameIW3.h index b212834c..bfd896e6 100644 --- a/src/Common/Game/IW3/GameIW3.h +++ b/src/Common/Game/IW3/GameIW3.h @@ -1,19 +1,20 @@ #pragma once #include "Game/IGame.h" -class GameIW3 final : public IGame +namespace IW3 { -public: - GameId GetId() override; - std::string GetFullName() override; - std::string GetShortName() override; - void AddZone(Zone* zone) override; - void RemoveZone(Zone* zone) override; - std::vector GetZones() override; - const std::vector& GetLanguagePrefixes() override; + class Game final : public IGame + { + public: + [[nodiscard]] GameId GetId() const override; + [[nodiscard]] const std::string& GetFullName() const override; + [[nodiscard]] const std::string& GetShortName() const override; + void AddZone(Zone* zone) override; + void RemoveZone(Zone* zone) override; + [[nodiscard]] const std::vector& GetZones() const override; + [[nodiscard]] const std::vector& GetLanguagePrefixes() const override; -private: - std::vector m_zones; -}; - -extern GameIW3 g_GameIW3; + private: + std::vector m_zones; + }; +} // namespace IW3 diff --git a/src/Common/Game/IW4/GameIW4.cpp b/src/Common/Game/IW4/GameIW4.cpp index 7d825b2c..bb5de03b 100644 --- a/src/Common/Game/IW4/GameIW4.cpp +++ b/src/Common/Game/IW4/GameIW4.cpp @@ -1,34 +1,32 @@ #include "GameIW4.h" -#include "IW4.h" - #include using namespace IW4; -GameIW4 g_GameIW4; - -GameId GameIW4::GetId() +GameId Game::GetId() const { return GameId::IW4; } -std::string GameIW4::GetFullName() +const std::string& Game::GetFullName() const { - return "Call Of Duty: Modern Warfare 2"; + static std::string fullName = "Call Of Duty: Modern Warfare 2"; + return fullName; } -std::string GameIW4::GetShortName() +const std::string& Game::GetShortName() const { - return "IW4"; + static std::string shortName = "IW4"; + return shortName; } -void GameIW4::AddZone(Zone* zone) +void Game::AddZone(Zone* zone) { m_zones.push_back(zone); } -void GameIW4::RemoveZone(Zone* zone) +void Game::RemoveZone(Zone* zone) { const auto foundEntry = std::ranges::find(m_zones, zone); @@ -36,12 +34,12 @@ void GameIW4::RemoveZone(Zone* zone) m_zones.erase(foundEntry); } -std::vector GameIW4::GetZones() +const std::vector& Game::GetZones() const { return m_zones; } -const std::vector& GameIW4::GetLanguagePrefixes() +const std::vector& Game::GetLanguagePrefixes() const { static std::vector prefixes; return prefixes; diff --git a/src/Common/Game/IW4/GameIW4.h b/src/Common/Game/IW4/GameIW4.h index fb335bfa..2f8e6d66 100644 --- a/src/Common/Game/IW4/GameIW4.h +++ b/src/Common/Game/IW4/GameIW4.h @@ -1,19 +1,20 @@ #pragma once #include "Game/IGame.h" -class GameIW4 final : public IGame +namespace IW4 { -public: - GameId GetId() override; - std::string GetFullName() override; - std::string GetShortName() override; - void AddZone(Zone* zone) override; - void RemoveZone(Zone* zone) override; - std::vector GetZones() override; - const std::vector& GetLanguagePrefixes() override; + class Game final : public IGame + { + public: + [[nodiscard]] GameId GetId() const override; + [[nodiscard]] const std::string& GetFullName() const override; + [[nodiscard]] const std::string& GetShortName() const override; + void AddZone(Zone* zone) override; + void RemoveZone(Zone* zone) override; + [[nodiscard]] const std::vector& GetZones() const override; + [[nodiscard]] const std::vector& GetLanguagePrefixes() const override; -private: - std::vector m_zones; -}; - -extern GameIW4 g_GameIW4; + private: + std::vector m_zones; + }; +} // namespace IW4 diff --git a/src/Common/Game/IW5/GameIW5.cpp b/src/Common/Game/IW5/GameIW5.cpp index a82108b5..17581d9b 100644 --- a/src/Common/Game/IW5/GameIW5.cpp +++ b/src/Common/Game/IW5/GameIW5.cpp @@ -1,34 +1,32 @@ #include "GameIW5.h" -#include "IW5.h" - #include using namespace IW5; -GameIW5 g_GameIW5; - -GameId GameIW5::GetId() +GameId Game::GetId() const { return GameId::IW5; } -std::string GameIW5::GetFullName() +const std::string& Game::GetFullName() const { - return "Call Of Duty: Modern Warfare 3"; + static std::string fullName = "Call Of Duty: Modern Warfare 3"; + return fullName; } -std::string GameIW5::GetShortName() +const std::string& Game::GetShortName() const { - return "IW5"; + static std::string shortName = "IW5"; + return shortName; } -void GameIW5::AddZone(Zone* zone) +void Game::AddZone(Zone* zone) { m_zones.push_back(zone); } -void GameIW5::RemoveZone(Zone* zone) +void Game::RemoveZone(Zone* zone) { const auto foundEntry = std::ranges::find(m_zones, zone); @@ -36,12 +34,12 @@ void GameIW5::RemoveZone(Zone* zone) m_zones.erase(foundEntry); } -std::vector GameIW5::GetZones() +const std::vector& Game::GetZones() const { return m_zones; } -const std::vector& GameIW5::GetLanguagePrefixes() +const std::vector& Game::GetLanguagePrefixes() const { static std::vector prefixes; return prefixes; diff --git a/src/Common/Game/IW5/GameIW5.h b/src/Common/Game/IW5/GameIW5.h index 06c87139..2ba464d6 100644 --- a/src/Common/Game/IW5/GameIW5.h +++ b/src/Common/Game/IW5/GameIW5.h @@ -1,19 +1,20 @@ #pragma once #include "Game/IGame.h" -class GameIW5 final : public IGame +namespace IW5 { -public: - GameId GetId() override; - std::string GetFullName() override; - std::string GetShortName() override; - void AddZone(Zone* zone) override; - void RemoveZone(Zone* zone) override; - std::vector GetZones() override; - const std::vector& GetLanguagePrefixes() override; + class Game final : public IGame + { + public: + [[nodiscard]] GameId GetId() const override; + [[nodiscard]] const std::string& GetFullName() const override; + [[nodiscard]] const std::string& GetShortName() const override; + void AddZone(Zone* zone) override; + void RemoveZone(Zone* zone) override; + [[nodiscard]] const std::vector& GetZones() const override; + [[nodiscard]] const std::vector& GetLanguagePrefixes() const override; -private: - std::vector m_zones; -}; - -extern GameIW5 g_GameIW5; + private: + std::vector m_zones; + }; +} // namespace IW5 diff --git a/src/Common/Game/T5/GameT5.cpp b/src/Common/Game/T5/GameT5.cpp index 705f8028..7448b026 100644 --- a/src/Common/Game/T5/GameT5.cpp +++ b/src/Common/Game/T5/GameT5.cpp @@ -1,34 +1,32 @@ #include "GameT5.h" -#include "T5.h" - #include using namespace T5; -GameT5 g_GameT5; - -GameId GameT5::GetId() +GameId Game::GetId() const { return GameId::T5; } -std::string GameT5::GetFullName() +const std::string& Game::GetFullName() const { - return "Call Of Duty: Black Ops"; + static std::string fullName = "Call Of Duty: Black Ops"; + return fullName; } -std::string GameT5::GetShortName() +const std::string& Game::GetShortName() const { - return "T5"; + static std::string shortName = "T5"; + return shortName; } -void GameT5::AddZone(Zone* zone) +void Game::AddZone(Zone* zone) { m_zones.push_back(zone); } -void GameT5::RemoveZone(Zone* zone) +void Game::RemoveZone(Zone* zone) { const auto foundEntry = std::ranges::find(m_zones, zone); @@ -36,12 +34,12 @@ void GameT5::RemoveZone(Zone* zone) m_zones.erase(foundEntry); } -std::vector GameT5::GetZones() +const std::vector& Game::GetZones() const { return m_zones; } -const std::vector& GameT5::GetLanguagePrefixes() +const std::vector& Game::GetLanguagePrefixes() const { static std::vector prefixes{ {GameLanguage::LANGUAGE_ENGLISH, "en_"}, diff --git a/src/Common/Game/T5/GameT5.h b/src/Common/Game/T5/GameT5.h index bf392a7e..43ee7f6f 100644 --- a/src/Common/Game/T5/GameT5.h +++ b/src/Common/Game/T5/GameT5.h @@ -1,19 +1,20 @@ #pragma once #include "Game/IGame.h" -class GameT5 final : public IGame +namespace T5 { -public: - GameId GetId() override; - std::string GetFullName() override; - std::string GetShortName() override; - void AddZone(Zone* zone) override; - void RemoveZone(Zone* zone) override; - std::vector GetZones() override; - const std::vector& GetLanguagePrefixes() override; + class Game final : public IGame + { + public: + [[nodiscard]] GameId GetId() const override; + [[nodiscard]] const std::string& GetFullName() const override; + [[nodiscard]] const std::string& GetShortName() const override; + void AddZone(Zone* zone) override; + void RemoveZone(Zone* zone) override; + [[nodiscard]] const std::vector& GetZones() const override; + [[nodiscard]] const std::vector& GetLanguagePrefixes() const override; -private: - std::vector m_zones; -}; - -extern GameT5 g_GameT5; + private: + std::vector m_zones; + }; +} // namespace T5 diff --git a/src/Common/Game/T6/GameT6.cpp b/src/Common/Game/T6/GameT6.cpp index 10553342..26edc8ce 100644 --- a/src/Common/Game/T6/GameT6.cpp +++ b/src/Common/Game/T6/GameT6.cpp @@ -1,34 +1,32 @@ #include "GameT6.h" -#include "T6.h" - #include using namespace T6; -GameT6 g_GameT6; - -GameId GameT6::GetId() +GameId Game::GetId() const { return GameId::T6; } -std::string GameT6::GetFullName() +const std::string& Game::GetFullName() const { - return "Call Of Duty: Black Ops II"; + static std::string fullName = "Call Of Duty: Black Ops II"; + return fullName; } -std::string GameT6::GetShortName() +const std::string& Game::GetShortName() const { - return "T6"; + static std::string shortName = "T6"; + return shortName; } -void GameT6::AddZone(Zone* zone) +void Game::AddZone(Zone* zone) { m_zones.push_back(zone); } -void GameT6::RemoveZone(Zone* zone) +void Game::RemoveZone(Zone* zone) { const auto foundEntry = std::ranges::find(m_zones, zone); @@ -36,12 +34,12 @@ void GameT6::RemoveZone(Zone* zone) m_zones.erase(foundEntry); } -std::vector GameT6::GetZones() +const std::vector& Game::GetZones() const { return m_zones; } -const std::vector& GameT6::GetLanguagePrefixes() +const std::vector& Game::GetLanguagePrefixes() const { static std::vector prefixes{ {GameLanguage::LANGUAGE_ENGLISH, "en_"}, diff --git a/src/Common/Game/T6/GameT6.h b/src/Common/Game/T6/GameT6.h index f5bb5441..248f2aeb 100644 --- a/src/Common/Game/T6/GameT6.h +++ b/src/Common/Game/T6/GameT6.h @@ -1,19 +1,20 @@ #pragma once #include "Game/IGame.h" -class GameT6 final : public IGame +namespace T6 { -public: - GameId GetId() override; - std::string GetFullName() override; - std::string GetShortName() override; - void AddZone(Zone* zone) override; - void RemoveZone(Zone* zone) override; - std::vector GetZones() override; - const std::vector& GetLanguagePrefixes() override; + class Game final : public IGame + { + public: + [[nodiscard]] GameId GetId() const override; + [[nodiscard]] const std::string& GetFullName() const override; + [[nodiscard]] const std::string& GetShortName() const override; + void AddZone(Zone* zone) override; + void RemoveZone(Zone* zone) override; + [[nodiscard]] const std::vector& GetZones() const override; + [[nodiscard]] const std::vector& GetLanguagePrefixes() const override; -private: - std::vector m_zones; -}; - -extern GameT6 g_GameT6; + private: + std::vector m_zones; + }; +} // namespace T6 diff --git a/src/Linker/Game/IW3/ZoneCreatorIW3.cpp b/src/Linker/Game/IW3/ZoneCreatorIW3.cpp index a512f1eb..7266fc52 100644 --- a/src/Linker/Game/IW3/ZoneCreatorIW3.cpp +++ b/src/Linker/Game/IW3/ZoneCreatorIW3.cpp @@ -40,7 +40,7 @@ GameId ZoneCreator::GetGameId() const std::unique_ptr ZoneCreator::CreateZoneForDefinition(ZoneCreationContext& context) const { - auto zone = std::make_unique(context.m_definition->m_name, 0, &g_GameIW3); + auto zone = std::make_unique(context.m_definition->m_name, 0, IGame::GetGameById(GameId::IW3)); CreateZoneAssetPools(zone.get()); for (const auto& assetEntry : context.m_definition->m_assets) diff --git a/src/Linker/Game/IW4/ZoneCreatorIW4.cpp b/src/Linker/Game/IW4/ZoneCreatorIW4.cpp index 34c01b14..5a1165bb 100644 --- a/src/Linker/Game/IW4/ZoneCreatorIW4.cpp +++ b/src/Linker/Game/IW4/ZoneCreatorIW4.cpp @@ -39,7 +39,7 @@ GameId ZoneCreator::GetGameId() const std::unique_ptr ZoneCreator::CreateZoneForDefinition(ZoneCreationContext& context) const { - auto zone = std::make_unique(context.m_definition->m_name, 0, &g_GameIW4); + auto zone = std::make_unique(context.m_definition->m_name, 0, IGame::GetGameById(GameId::IW4)); CreateZoneAssetPools(zone.get()); for (const auto& assetEntry : context.m_definition->m_assets) diff --git a/src/Linker/Game/IW5/ZoneCreatorIW5.cpp b/src/Linker/Game/IW5/ZoneCreatorIW5.cpp index 83023066..a31841a6 100644 --- a/src/Linker/Game/IW5/ZoneCreatorIW5.cpp +++ b/src/Linker/Game/IW5/ZoneCreatorIW5.cpp @@ -39,7 +39,7 @@ GameId ZoneCreator::GetGameId() const std::unique_ptr ZoneCreator::CreateZoneForDefinition(ZoneCreationContext& context) const { - auto zone = std::make_unique(context.m_definition->m_name, 0, &g_GameIW5); + auto zone = std::make_unique(context.m_definition->m_name, 0, IGame::GetGameById(GameId::IW5)); CreateZoneAssetPools(zone.get()); for (const auto& assetEntry : context.m_definition->m_assets) diff --git a/src/Linker/Game/T5/ZoneCreatorT5.cpp b/src/Linker/Game/T5/ZoneCreatorT5.cpp index 58330267..ee72e9df 100644 --- a/src/Linker/Game/T5/ZoneCreatorT5.cpp +++ b/src/Linker/Game/T5/ZoneCreatorT5.cpp @@ -40,7 +40,7 @@ GameId ZoneCreator::GetGameId() const std::unique_ptr ZoneCreator::CreateZoneForDefinition(ZoneCreationContext& context) const { - auto zone = std::make_unique(context.m_definition->m_name, 0, &g_GameT5); + auto zone = std::make_unique(context.m_definition->m_name, 0, IGame::GetGameById(GameId::T5)); CreateZoneAssetPools(zone.get()); for (const auto& assetEntry : context.m_definition->m_assets) diff --git a/src/Linker/Game/T6/ZoneCreatorT6.cpp b/src/Linker/Game/T6/ZoneCreatorT6.cpp index 388ab962..960e258d 100644 --- a/src/Linker/Game/T6/ZoneCreatorT6.cpp +++ b/src/Linker/Game/T6/ZoneCreatorT6.cpp @@ -91,7 +91,7 @@ GameId ZoneCreator::GetGameId() const std::unique_ptr ZoneCreator::CreateZoneForDefinition(ZoneCreationContext& context) const { - auto zone = std::make_unique(context.m_definition->m_name, 0, &g_GameT6); + auto zone = std::make_unique(context.m_definition->m_name, 0, IGame::GetGameById(GameId::T6)); CreateZoneAssetPools(zone.get()); for (const auto& assetEntry : context.m_definition->m_assets) diff --git a/src/ObjLoading/Game/T6/ObjLoaderT6.cpp b/src/ObjLoading/Game/T6/ObjLoaderT6.cpp index e272d454..99d48000 100644 --- a/src/ObjLoading/Game/T6/ObjLoaderT6.cpp +++ b/src/ObjLoading/Game/T6/ObjLoaderT6.cpp @@ -288,7 +288,7 @@ namespace T6 std::cout << std::format("Loading common ipaks for zone \"{}\"\n", zone.m_name); LoadIPakForZone(searchPath, "base", zone); - const auto languagePrefixes = g_GameT6.GetLanguagePrefixes(); + const auto& languagePrefixes = IGame::GetGameById(GameId::T6)->GetLanguagePrefixes(); for (const auto& languagePrefix : languagePrefixes) LoadIPakForZone(searchPath, std::format("{}base", languagePrefix.m_prefix), zone); diff --git a/src/ObjWriting/Game/IW5/Material/MaterialConstantZoneState.cpp b/src/ObjWriting/Game/IW5/Material/MaterialConstantZoneState.cpp index 033421f8..fe6d870d 100644 --- a/src/ObjWriting/Game/IW5/Material/MaterialConstantZoneState.cpp +++ b/src/ObjWriting/Game/IW5/Material/MaterialConstantZoneState.cpp @@ -199,7 +199,7 @@ namespace IW5 void MaterialConstantZoneState::ExtractNamesFromZoneInternal() { - for (const auto* zone : g_GameIW5.GetZones()) + for (const auto* zone : IGame::GetGameById(GameId::IW5)->GetZones()) { const auto* iw5AssetPools = dynamic_cast(zone->m_pools.get()); if (!iw5AssetPools) diff --git a/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperSndBank.cpp b/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperSndBank.cpp index 10805b9c..a1d47041 100644 --- a/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperSndBank.cpp +++ b/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperSndBank.cpp @@ -201,7 +201,7 @@ namespace public: void Initialize() { - for (const auto& zone : g_GameT6.GetZones()) + for (const auto& zone : IGame::GetGameById(GameId::T6)->GetZones()) { auto& sndBankPool = *dynamic_cast(zone->m_pools.get())->m_sound_bank; for (auto* entry : sndBankPool) diff --git a/src/ObjWriting/Game/T6/Material/MaterialConstantZoneState.cpp b/src/ObjWriting/Game/T6/Material/MaterialConstantZoneState.cpp index 0219063e..5492c775 100644 --- a/src/ObjWriting/Game/T6/Material/MaterialConstantZoneState.cpp +++ b/src/ObjWriting/Game/T6/Material/MaterialConstantZoneState.cpp @@ -473,7 +473,7 @@ namespace T6 void MaterialConstantZoneState::ExtractNamesFromZoneInternal() { - for (const auto* zone : g_GameT6.GetZones()) + for (const auto* zone : IGame::GetGameById(GameId::T6)->GetZones()) { const auto* t6AssetPools = dynamic_cast(zone->m_pools.get()); if (!t6AssetPools) diff --git a/src/ZoneWriting/Game/IW3/ZoneWriterFactoryIW3.cpp b/src/ZoneWriting/Game/IW3/ZoneWriterFactoryIW3.cpp index ce9a0824..325e039d 100644 --- a/src/ZoneWriting/Game/IW3/ZoneWriterFactoryIW3.cpp +++ b/src/ZoneWriting/Game/IW3/ZoneWriterFactoryIW3.cpp @@ -47,7 +47,7 @@ namespace std::unique_ptr ZoneWriterFactory::CreateWriter(Zone* zone) const { - std::unique_ptr writer; + auto writer = std::make_unique(); SetupBlocks(*writer); diff --git a/test/ObjLoadingTests/Game/IW3/AssetLoaders/AssetLoaderStringTableTest.cpp b/test/ObjLoadingTests/Game/IW3/AssetLoaders/AssetLoaderStringTableTest.cpp index 339d2871..e3320300 100644 --- a/test/ObjLoadingTests/Game/IW3/AssetLoaders/AssetLoaderStringTableTest.cpp +++ b/test/ObjLoadingTests/Game/IW3/AssetLoaders/AssetLoaderStringTableTest.cpp @@ -20,7 +20,7 @@ namespace "test,data,lol\n" "lorem,ipsum"); - Zone zone("MockZone", 0, &g_GameIW3); + Zone zone("MockZone", 0, IGame::GetGameById(GameId::IW3)); MockAssetLoadingManager assetLoadingManager(zone, searchPath); AssetLoaderStringTable assetLoader; diff --git a/test/ObjLoadingTests/Game/IW4/AssetLoaders/AssetLoaderStringTableTest.cpp b/test/ObjLoadingTests/Game/IW4/AssetLoaders/AssetLoaderStringTableTest.cpp index 5feb8ae0..5dc5769c 100644 --- a/test/ObjLoadingTests/Game/IW4/AssetLoaders/AssetLoaderStringTableTest.cpp +++ b/test/ObjLoadingTests/Game/IW4/AssetLoaders/AssetLoaderStringTableTest.cpp @@ -21,7 +21,7 @@ namespace "test,data,lol\n" "lorem,ipsum"); - Zone zone("MockZone", 0, &g_GameIW4); + Zone zone("MockZone", 0, IGame::GetGameById(GameId::IW4)); MockAssetLoadingManager assetLoadingManager(zone, searchPath); AssetLoaderStringTable assetLoader; diff --git a/test/ObjLoadingTests/Game/IW4/Menu/MenuParsingIW4IT.cpp b/test/ObjLoadingTests/Game/IW4/Menu/MenuParsingIW4IT.cpp index da44d544..195d5621 100644 --- a/test/ObjLoadingTests/Game/IW4/Menu/MenuParsingIW4IT.cpp +++ b/test/ObjLoadingTests/Game/IW4/Menu/MenuParsingIW4IT.cpp @@ -28,7 +28,7 @@ namespace test::game::iw4::menu::parsing::it public: MenuParsingItHelper() - : m_zone("MockZone", 0, &g_GameIW4), + : m_zone("MockZone", 0, IGame::GetGameById(GameId::IW4)), m_manager(m_zone, m_search_path) { } diff --git a/test/ObjLoadingTests/Game/IW5/AssetLoaders/AssetLoaderStringTableTest.cpp b/test/ObjLoadingTests/Game/IW5/AssetLoaders/AssetLoaderStringTableTest.cpp index d921b6fe..27f434c8 100644 --- a/test/ObjLoadingTests/Game/IW5/AssetLoaders/AssetLoaderStringTableTest.cpp +++ b/test/ObjLoadingTests/Game/IW5/AssetLoaders/AssetLoaderStringTableTest.cpp @@ -20,7 +20,7 @@ namespace "test,data,lol\n" "lorem,ipsum"); - Zone zone("MockZone", 0, &g_GameIW5); + Zone zone("MockZone", 0, IGame::GetGameById(GameId::IW5)); MockAssetLoadingManager assetLoadingManager(zone, searchPath); AssetLoaderStringTable assetLoader; diff --git a/test/ObjLoadingTests/Game/T5/AssetLoaders/AssetLoaderStringTableTest.cpp b/test/ObjLoadingTests/Game/T5/AssetLoaders/AssetLoaderStringTableTest.cpp index 0b8b83fe..6d0c1a40 100644 --- a/test/ObjLoadingTests/Game/T5/AssetLoaders/AssetLoaderStringTableTest.cpp +++ b/test/ObjLoadingTests/Game/T5/AssetLoaders/AssetLoaderStringTableTest.cpp @@ -20,7 +20,7 @@ namespace "test,data,lol\n" "lorem,ipsum"); - Zone zone("MockZone", 0, &g_GameT5); + Zone zone("MockZone", 0, IGame::GetGameById(GameId::T5)); MockAssetLoadingManager assetLoadingManager(zone, searchPath); AssetLoaderStringTable assetLoader; diff --git a/test/ObjLoadingTests/Game/T6/AssetLoaders/AssetLoaderStringTableTest.cpp b/test/ObjLoadingTests/Game/T6/AssetLoaders/AssetLoaderStringTableTest.cpp index 7c4a3461..a853c878 100644 --- a/test/ObjLoadingTests/Game/T6/AssetLoaders/AssetLoaderStringTableTest.cpp +++ b/test/ObjLoadingTests/Game/T6/AssetLoaders/AssetLoaderStringTableTest.cpp @@ -20,7 +20,7 @@ namespace "test,data,lol\n" "lorem,ipsum"); - Zone zone("MockZone", 0, &g_GameT6); + Zone zone("MockZone", 0, IGame::GetGameById(GameId::T6)); MockAssetLoadingManager assetLoadingManager(zone, searchPath); AssetLoaderStringTable assetLoader;