From 67e33e8866983e9a1854ff7bc771b2a5ea0c3438 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Tue, 20 Nov 2018 17:51:00 -0500 Subject: [PATCH] patch_manager: Apply LayeredExeFS patches This will scan the /exefs dir for all files and then layer those on top of the game's exefs and use this as the new exefs. This allows for overriding of the compressed NSOs or adding new files. This does use the same dir as IPS/IPSwitch patch, but since the loader will not look for those they are ignored. --- src/core/file_sys/patch_manager.cpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp index f56b1c773e..ccc4f3061b 100644 --- a/src/core/file_sys/patch_manager.cpp +++ b/src/core/file_sys/patch_manager.cpp @@ -79,6 +79,31 @@ VirtualDir PatchManager::PatchExeFS(VirtualDir exefs) const { exefs = update->GetExeFS(); } + // LayeredExeFS + const auto load_dir = Service::FileSystem::GetModificationLoadRoot(title_id); + if (load_dir != nullptr && load_dir->GetSize() > 0) { + + 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) { + auto exefs_dir = subdir->GetSubdirectory("exefs"); + if (exefs_dir != nullptr) + layers.push_back(std::move(exefs_dir)); + } + layers.push_back(exefs); + + auto layered = LayeredVfsDirectory::MakeLayeredDirectory(std::move(layers)); + if (layered != nullptr) { + LOG_INFO(Loader, " ExeFS: LayeredExeFS patches applied successfully"); + exefs = std::move(layered); + } + } + return exefs; }