diff options
| author | 2018-08-25 19:03:45 -0400 | |
|---|---|---|
| committer | 2018-09-04 16:22:25 -0400 | |
| commit | 8e900a301a1094d74f68f173c7dec67b12baec25 (patch) | |
| tree | 1f9491769fc1f59b207e0442d1b903018a868ed9 /src | |
| parent | file_sys: Add BKTR patching mechanism (diff) | |
| download | yuzu-8e900a301a1094d74f68f173c7dec67b12baec25.tar.gz yuzu-8e900a301a1094d74f68f173c7dec67b12baec25.tar.xz yuzu-8e900a301a1094d74f68f173c7dec67b12baec25.zip | |
file_sys: Add class to manage game patches
Right now only includes Updates, but should eventually contain all of the other patches we need.
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/file_sys/patch_manager.cpp | 90 | ||||
| -rw-r--r-- | src/core/file_sys/patch_manager.h | 42 |
2 files changed, 132 insertions, 0 deletions
diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp new file mode 100644 index 000000000..697b8a4c9 --- /dev/null +++ b/src/core/file_sys/patch_manager.cpp | |||
| @@ -0,0 +1,90 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "core/file_sys/patch_manager.h" | ||
| 6 | #include "core/file_sys/registered_cache.h" | ||
| 7 | #include "core/hle/service/filesystem/filesystem.h" | ||
| 8 | |||
| 9 | namespace FileSys { | ||
| 10 | |||
| 11 | union TitleVersion { | ||
| 12 | u32 version; | ||
| 13 | |||
| 14 | struct { | ||
| 15 | u8 v_revision; | ||
| 16 | u8 v_micro; | ||
| 17 | u8 v_minor; | ||
| 18 | u8 v_major; | ||
| 19 | }; | ||
| 20 | }; | ||
| 21 | |||
| 22 | std::string FormatTitleVersion(u32 version_, bool full) { | ||
| 23 | TitleVersion ver{}; | ||
| 24 | ver.version = version_; | ||
| 25 | |||
| 26 | if (full) | ||
| 27 | return fmt::format("v{}.{}.{}.{}", ver.v_major, ver.v_minor, ver.v_minor, ver.v_revision); | ||
| 28 | return fmt::format("v{}.{}.{}", ver.v_major, ver.v_minor, ver.v_micro); | ||
| 29 | } | ||
| 30 | |||
| 31 | constexpr std::array<const char*, 1> PATCH_TYPE_NAMES{ | ||
| 32 | "Update", | ||
| 33 | }; | ||
| 34 | |||
| 35 | std::string FormatPatchTypeName(PatchType type) { | ||
| 36 | return PATCH_TYPE_NAMES.at(static_cast<size_t>(type)); | ||
| 37 | } | ||
| 38 | |||
| 39 | PatchManager::PatchManager(u64 title_id) : title_id(title_id) {} | ||
| 40 | |||
| 41 | VirtualDir PatchManager::PatchExeFS(VirtualDir exefs) const { | ||
| 42 | if (exefs == nullptr) | ||
| 43 | return exefs; | ||
| 44 | |||
| 45 | const auto installed = Service::FileSystem::GetUnionContents(); | ||
| 46 | |||
| 47 | // Game Updates | ||
| 48 | const auto update_tid = GetUpdateTitleID(title_id); | ||
| 49 | const auto update = installed->GetEntry(update_tid, ContentRecordType::Program); | ||
| 50 | if (update != nullptr) { | ||
| 51 | if (update->GetStatus() == Loader::ResultStatus::ErrorMissingBKTRBaseRomFS && | ||
| 52 | update->GetExeFS() != nullptr) | ||
| 53 | exefs = update->GetExeFS(); | ||
| 54 | } | ||
| 55 | |||
| 56 | return exefs; | ||
| 57 | } | ||
| 58 | |||
| 59 | VirtualFile PatchManager::PatchRomFS(VirtualFile romfs) const { | ||
| 60 | if (romfs == nullptr) | ||
| 61 | return romfs; | ||
| 62 | |||
| 63 | const auto installed = Service::FileSystem::GetUnionContents(); | ||
| 64 | |||
| 65 | // Game Updates | ||
| 66 | const auto update_tid = GetUpdateTitleID(title_id); | ||
| 67 | const auto update = installed->GetEntryRaw(update_tid, ContentRecordType::Program); | ||
| 68 | if (update != nullptr) { | ||
| 69 | const auto nca = std::make_shared<NCA>(update, romfs); | ||
| 70 | if (nca->GetStatus() == Loader::ResultStatus::Success && nca->GetRomFS() != nullptr) | ||
| 71 | romfs = nca->GetRomFS(); | ||
| 72 | } | ||
| 73 | |||
| 74 | return romfs; | ||
| 75 | } | ||
| 76 | |||
| 77 | std::map<PatchType, u32> PatchManager::GetPatchVersionNames() const { | ||
| 78 | std::map<PatchType, u32> out; | ||
| 79 | const auto installed = Service::FileSystem::GetUnionContents(); | ||
| 80 | |||
| 81 | const auto update_tid = GetUpdateTitleID(title_id); | ||
| 82 | const auto update_version = installed->GetEntryVersion(update_tid); | ||
| 83 | if (update_version != boost::none && | ||
| 84 | installed->HasEntry(update_tid, ContentRecordType::Program)) | ||
| 85 | out[PatchType::Update] = update_version.get(); | ||
| 86 | |||
| 87 | return out; | ||
| 88 | } | ||
| 89 | |||
| 90 | } // namespace FileSys | ||
diff --git a/src/core/file_sys/patch_manager.h b/src/core/file_sys/patch_manager.h new file mode 100644 index 000000000..2a39c473a --- /dev/null +++ b/src/core/file_sys/patch_manager.h | |||
| @@ -0,0 +1,42 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <map> | ||
| 8 | #include "common/common_types.h" | ||
| 9 | #include "core/file_sys/vfs.h" | ||
| 10 | |||
| 11 | namespace FileSys { | ||
| 12 | |||
| 13 | std::string FormatTitleVersion(u32 version, bool full = false); | ||
| 14 | |||
| 15 | enum class PatchType { | ||
| 16 | Update, | ||
| 17 | }; | ||
| 18 | |||
| 19 | std::string FormatPatchTypeName(PatchType type); | ||
| 20 | |||
| 21 | // A centralized class to manage patches to games. | ||
| 22 | class PatchManager { | ||
| 23 | public: | ||
| 24 | explicit PatchManager(u64 title_id); | ||
| 25 | |||
| 26 | // Currently tracked ExeFS patches: | ||
| 27 | // - Game Updates | ||
| 28 | VirtualDir PatchExeFS(VirtualDir exefs) const; | ||
| 29 | |||
| 30 | // Currently tracked RomFS patches: | ||
| 31 | // - Game Updates | ||
| 32 | VirtualFile PatchRomFS(VirtualFile romfs) const; | ||
| 33 | |||
| 34 | // Returns a vector of pairs between patch names and patch versions. | ||
| 35 | // i.e. Update v80 will return {Update, 80} | ||
| 36 | std::map<PatchType, u32> GetPatchVersionNames() const; | ||
| 37 | |||
| 38 | private: | ||
| 39 | u64 title_id; | ||
| 40 | }; | ||
| 41 | |||
| 42 | } // namespace FileSys | ||