summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZach Hilman <zachhilman@gmail.com>2018-11-20 17:51:00 -0500
committerZach Hilman <zachhilman@gmail.com>2018-11-20 17:51:00 -0500
commitda6d4cde567695d22fefc152d2d913f54e5ece68 (patch)
treee57ea6b05aeac098a2fc63d35ceedec4d77b521a
parent17d8e25cbfd0c8937c8791bc1941af85f9541666 (diff)
patch_manager: Apply LayeredExeFS patches
This will scan the <mod>/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.
-rw-r--r--src/core/file_sys/patch_manager.cpp25
1 files changed, 25 insertions, 0 deletions
diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp
index f56b1c773..ccc4f3061 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<VirtualDir> 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;
}