diff options
Diffstat (limited to 'src/core/file_sys/patch_manager.cpp')
-rw-r--r-- | src/core/file_sys/patch_manager.cpp | 47 |
1 files changed, 46 insertions, 1 deletions
diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp index aebc69d52..af3f9a78f 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<const char*, 1> PATCH_TYPE_NAMES{ +constexpr std::array<const char*, 2> PATCH_TYPE_NAMES{ "Update", + "LayeredFS", }; std::string FormatPatchTypeName(PatchType type) { @@ -66,6 +68,42 @@ VirtualDir PatchManager::PatchExeFS(VirtualDir exefs) const { return exefs; } +static void ApplyLayeredFS(VirtualFile& romfs, u64 title_id, ContentRecordType type) { + const auto load_dir = Service::FileSystem::GetModificationLoadRoot(title_id); + if (type == ContentRecordType::Program && load_dir != nullptr && load_dir->GetSize() > 0) { + 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<VirtualDir> layers; + layers.reserve(patch_dirs.size() + 1); + for (const auto& subdir : patch_dirs) { + auto romfs_dir = subdir->GetSubdirectory("romfs"); + if (romfs_dir != nullptr) + layers.push_back(std::move(romfs_dir)); + } + + layers.push_back(std::move(extracted)); + + const auto layered = LayerDirectories(layers); + + if (layered != nullptr) { + auto packed = CreateRomFS(layered); + + if (packed != nullptr) { + LOG_INFO(Loader, " RomFS: LayeredFS patches applied successfully"); + romfs = std::move(packed); + } + } + } + } +} + VirtualFile PatchManager::PatchRomFS(VirtualFile romfs, u64 ivfc_offset, ContentRecordType type) const { LOG_INFO(Loader, "Patching RomFS for title_id={:016X}, type={:02X}", title_id, @@ -89,6 +127,9 @@ VirtualFile PatchManager::PatchRomFS(VirtualFile romfs, u64 ivfc_offset, } } + // LayeredFS + ApplyLayeredFS(romfs, title_id, type); + return romfs; } @@ -114,6 +155,10 @@ std::map<PatchType, std::string> PatchManager::GetPatchVersionNames() const { } } + const auto lfs_dir = Service::FileSystem::GetModificationLoadRoot(title_id); + if (lfs_dir != nullptr && lfs_dir->GetSize() > 0) + out.insert_or_assign(PatchType::LayeredFS, ""); + return out; } |