From fee5c2aefd02f86e8d0f5cffb0bbe5f8a1894fdc Mon Sep 17 00:00:00 2001 From: William JCM Date: Fri, 30 Jul 2021 15:39:11 +0200 Subject: [PATCH] Profile: add support for reading arch unlocks. --- src/Profile/Profile.cpp | 52 +++++++++++++++++++++++++++++++++++++++++ src/Profile/Profile.h | 4 ++++ 2 files changed, 56 insertions(+) diff --git a/src/Profile/Profile.cpp b/src/Profile/Profile.cpp index b1e562b..9c11c8b 100644 --- a/src/Profile/Profile.cpp +++ b/src/Profile/Profile.cpp @@ -112,6 +112,7 @@ void Profile::refreshValues() { getEngineUnlocks(); getOsUnlocks(); + getArchUnlocks(); } auto Profile::companyName() const -> std::string const& { @@ -1106,3 +1107,54 @@ void Profile::getOsUnlocks() { _lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file."; } } + +auto Profile::archInventory() -> Containers::ArrayView { + return _archInventory; +} + +auto Profile::techInventory() -> Containers::ArrayView { + return _techInventory; +} + +void Profile::getArchUnlocks() { + auto mmap = Utility::Directory::map(Utility::Directory::join(_profileDirectory, _filename)); + + auto iter = std::search(mmap.begin(), mmap.end(), &arch_inventory_locator[0], &arch_inventory_locator[36]); + + if(iter != mmap.end()) { + Int* int_iter = reinterpret_cast(iter + 0x3E); + Int size = *(int_iter++); + + if(size > 0) { + _archInventory = Containers::Array{DefaultInit, std::size_t(size)}; + std::copy_n(int_iter, size, _archInventory.data()); + + Utility::Debug{} << "_archInventory:" << _archInventory; + + iter = std::search(mmap.begin(), mmap.end(), &tech_inventory_locator[0], &tech_inventory_locator[31]); + + if(iter == mmap.end()) { + return; + } + + int_iter = reinterpret_cast(iter + 0x39); + size = *(int_iter++); + + if(size <= 0) { + return; + } + + _techInventory = Containers::Array{DefaultInit, std::size_t(size)}; + std::copy_n(int_iter, size, _techInventory.data()); + + Utility::Debug{} << "_techInventory:" << _techInventory; + } + else { + _lastError = "An array can't have a null or negative size."; + Utility::Fatal{EXIT_FAILURE} << _lastError.c_str(); + } + } + else { + _lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file."; + } +} diff --git a/src/Profile/Profile.h b/src/Profile/Profile.h index 6f16116..947aab7 100644 --- a/src/Profile/Profile.h +++ b/src/Profile/Profile.h @@ -151,6 +151,10 @@ class Profile { auto moduleInventory() -> Containers::ArrayView; void getOsUnlocks(); + auto archInventory() -> Containers::ArrayView; + auto techInventory() -> Containers::ArrayView; + void getArchUnlocks(); + private: std::string _profileDirectory; std::string _filename;