From 7f5de6bcd651f8145e4746c76d0531b6560fd5e4 Mon Sep 17 00:00:00 2001 From: xbzk Date: Wed, 4 Mar 2026 22:51:35 +0100 Subject: [android/fs] external content loader + nca/xci patches (#3596) Foreword: WHY DON'T EVERYBODY USE ONE FOLDER FOR EACH GAME+CONTENTS? AIN'T THIS THE FORMAT GAMES COME WHEN YOU BUE THEM? DO YOU LIVE WITH ALL YOUR FRIENDS AND HAVE A 2ND HOUSE FOR ALL THE CHILDREN? Nice, i feel better now. This feat extends Maufeat's work on external content loading. It harmonically additions: "...also, if in each game folder X, you find a folder Y, and in this folder Y you detect ONLY a single game, then mount all external content for that game found in that folder Y and its subfolders." Permanent (not toggleable). External Content folders are supported equally. Also: -Reworked several routines for preserving single source of truth between android and other systems; -Fixed the annoying unknown format error for content files, by providing proper format detection. Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3596 Reviewed-by: MaranBr Reviewed-by: Lizzie Co-authored-by: xbzk Co-committed-by: xbzk --- src/core/file_sys/patch_manager.cpp | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) (limited to 'src/core/file_sys/patch_manager.cpp') diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp index 82944ceceb..e9c3bb75c2 100644 --- a/src/core/file_sys/patch_manager.cpp +++ b/src/core/file_sys/patch_manager.cpp @@ -117,6 +117,12 @@ void AppendCommaIfNotEmpty(std::string& to, std::string_view with) { bool IsDirValidAndNonEmpty(const VirtualDir& dir) { return dir != nullptr && (!dir->GetFiles().empty() || !dir->GetSubdirectories().empty()); } + +bool IsVersionedExternalUpdateDisabled(const std::vector& disabled, u32 version) { + const std::string disabled_key = fmt::format("Update@{}", version); + return std::find(disabled.cbegin(), disabled.cend(), disabled_key) != disabled.cend() || + std::find(disabled.cbegin(), disabled.cend(), "Update") != disabled.cend(); +} } // Anonymous namespace PatchManager::PatchManager(u64 title_id_, @@ -155,8 +161,7 @@ VirtualDir PatchManager::PatchExeFS(VirtualDir exefs) const { if (!update_versions.empty()) { checked_external = true; for (const auto& update_entry : update_versions) { - std::string disabled_key = fmt::format("Update@{}", update_entry.version); - if (std::find(disabled.cbegin(), disabled.cend(), disabled_key) == disabled.cend()) { + if (!IsVersionedExternalUpdateDisabled(disabled, update_entry.version)) { update_disabled = false; enabled_version = update_entry.version; break; @@ -175,8 +180,7 @@ VirtualDir PatchManager::PatchExeFS(VirtualDir exefs) const { if (!manual_update_versions.empty()) { checked_manual = true; for (const auto& update_entry : manual_update_versions) { - std::string disabled_key = fmt::format("Update@{}", update_entry.version); - if (std::find(disabled.cbegin(), disabled.cend(), disabled_key) == disabled.cend()) { + if (!IsVersionedExternalUpdateDisabled(disabled, update_entry.version)) { update_disabled = false; enabled_version = update_entry.version; break; @@ -580,8 +584,7 @@ VirtualFile PatchManager::PatchRomFS(const NCA* base_nca, VirtualFile base_romfs if (!update_versions.empty()) { checked_external = true; for (const auto& update_entry : update_versions) { - std::string disabled_key = fmt::format("Update@{}", update_entry.version); - if (std::find(disabled.cbegin(), disabled.cend(), disabled_key) == disabled.cend()) { + if (!IsVersionedExternalUpdateDisabled(disabled, update_entry.version)) { update_disabled = false; enabled_version = update_entry.version; update_raw = external_provider->GetEntryForVersion(update_tid, type, update_entry.version); @@ -600,8 +603,7 @@ VirtualFile PatchManager::PatchRomFS(const NCA* base_nca, VirtualFile base_romfs if (!manual_update_versions.empty()) { checked_manual = true; for (const auto& update_entry : manual_update_versions) { - std::string disabled_key = fmt::format("Update@{}", update_entry.version); - if (std::find(disabled.cbegin(), disabled.cend(), disabled_key) == disabled.cend()) { + if (!IsVersionedExternalUpdateDisabled(disabled, update_entry.version)) { update_disabled = false; enabled_version = update_entry.version; update_raw = manual_provider->GetEntryForVersion(update_tid, type, update_entry.version); @@ -704,9 +706,8 @@ std::vector PatchManager::GetPatches(VirtualFile update_raw) const { version_str = FormatTitleVersion(update_entry.version); } - std::string disabled_key = fmt::format("Update@{}", update_entry.version); const auto update_disabled = - std::find(disabled.cbegin(), disabled.cend(), disabled_key) != disabled.cend(); + IsVersionedExternalUpdateDisabled(disabled, update_entry.version); Patch update_patch = {.enabled = !update_disabled, .name = "Update", @@ -732,9 +733,8 @@ std::vector PatchManager::GetPatches(VirtualFile update_raw) const { version_str = FormatTitleVersion(update_entry.version); } - std::string disabled_key = fmt::format("Update@{}", update_entry.version); const auto update_disabled = - std::find(disabled.cbegin(), disabled.cend(), disabled_key) != disabled.cend(); + IsVersionedExternalUpdateDisabled(disabled, update_entry.version); Patch update_patch = {.enabled = !update_disabled, @@ -771,7 +771,8 @@ std::vector PatchManager::GetPatches(VirtualFile update_raw) const { std::nullopt, std::nullopt, ContentRecordType::Program, update_tid); for (const auto& [slot, entry] : all_updates) { - if (slot == ContentProviderUnionSlot::External) { + if (slot == ContentProviderUnionSlot::External || + slot == ContentProviderUnionSlot::FrontendManual) { continue; } -- cgit v1.2.3