From 16188acb500cb238281dff28d944008ea56eb81b Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Wed, 19 Sep 2018 22:02:44 -0400 Subject: [PATCH] patch_manager: Add LayeredFS mods support --- src/core/file_sys/patch_manager.cpp | 43 ++++++++++++++++++++++++++++- src/core/file_sys/patch_manager.h | 2 ++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp index aebc69d52..74a0acf1a 100644 --- a/src/core/file_sys/patch_manager.cpp +++ b/src/core/file_sys/patch_manager.cpp @@ -11,6 +11,7 @@ #include "core/file_sys/patch_manager.h" #include "core/file_sys/registered_cache.h" #include "core/file_sys/romfs.h" +#include "core/file_sys/vfs_layered.h" #include "core/hle/service/filesystem/filesystem.h" #include "core/loader/loader.h" @@ -31,8 +32,9 @@ std::string FormatTitleVersion(u32 version, TitleVersionFormat format) { return fmt::format("v{}.{}.{}", bytes[3], bytes[2], bytes[1]); } -constexpr std::array PATCH_TYPE_NAMES{ +constexpr std::array PATCH_TYPE_NAMES{ "Update", + "LayeredFS", }; std::string FormatPatchTypeName(PatchType type) { @@ -89,6 +91,41 @@ VirtualFile PatchManager::PatchRomFS(VirtualFile romfs, u64 ivfc_offset, } } + // LayeredFS + const auto load_dir = Service::FileSystem::GetModificationLoadRoot(title_id); + if (type == ContentRecordType::Program && load_dir != nullptr && load_dir->GetSize() > 0) { + const auto extracted = ExtractRomFS(romfs); + + if (extracted != nullptr) { + auto patch_dirs = load_dir->GetSubdirectories(); + std::sort(patch_dirs.begin(), patch_dirs.end(), + [](const VirtualDir& l, const VirtualDir& r) { + return l->GetName() < r->GetName(); + }); + + std::vector layers; + layers.reserve(patch_dirs.size() + 1); + for (const auto& subdir : patch_dirs) { + const auto romfs_dir = subdir->GetSubdirectory("romfs"); + if (romfs_dir != nullptr) + layers.push_back(romfs_dir); + } + + layers.push_back(extracted); + + const auto layered = LayerDirectories(layers); + + if (layered != nullptr) { + const auto packed = CreateRomFS(layered); + + if (packed != nullptr) { + LOG_INFO(Loader, " RomFS: LayeredFS patches applied successfully"); + romfs = packed; + } + } + } + } + return romfs; } @@ -114,6 +151,10 @@ std::map PatchManager::GetPatchVersionNames() const { } } + const auto lfs_dir = Service::FileSystem::GetModificationLoadRoot(title_id); + if (lfs_dir != nullptr && lfs_dir->GetSize() > 0) + out[PatchType::LayeredFS] = ""; + return out; } diff --git a/src/core/file_sys/patch_manager.h b/src/core/file_sys/patch_manager.h index 209cab1dc..464f17515 100644 --- a/src/core/file_sys/patch_manager.h +++ b/src/core/file_sys/patch_manager.h @@ -26,6 +26,7 @@ std::string FormatTitleVersion(u32 version, enum class PatchType { Update, + LayeredFS, }; std::string FormatPatchTypeName(PatchType type); @@ -42,6 +43,7 @@ public: // Currently tracked RomFS patches: // - Game Updates + // - LayeredFS VirtualFile PatchRomFS(VirtualFile base, u64 ivfc_offset, ContentRecordType type = ContentRecordType::Program) const;