diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/core.cpp | 8 | ||||
-rw-r--r-- | src/core/core.h | 4 | ||||
-rw-r--r-- | src/core/file_sys/patch_manager.cpp | 56 | ||||
-rw-r--r-- | src/core/file_sys/patch_manager.h | 5 | ||||
-rw-r--r-- | src/core/hle/service/aoc/aoc_u.cpp | 12 | ||||
-rw-r--r-- | src/core/loader/loader.h | 10 | ||||
-rw-r--r-- | src/core/loader/nsp.cpp | 7 | ||||
-rw-r--r-- | src/core/loader/nsp.h | 1 | ||||
-rw-r--r-- | src/core/loader/xci.cpp | 7 | ||||
-rw-r--r-- | src/core/loader/xci.h | 1 | ||||
-rw-r--r-- | src/core/settings.h | 5 |
11 files changed, 102 insertions, 14 deletions
diff --git a/src/core/core.cpp b/src/core/core.cpp index 795fabc65..ce7851538 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -8,6 +8,7 @@ #include <thread> #include <utility> +#include "common/file_util.h" #include "common/logging/log.h" #include "common/string_util.h" #include "core/arm/exclusive_monitor.h" @@ -40,7 +41,6 @@ namespace Core { /*static*/ System System::s_instance; -namespace { FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs, const std::string& path) { // To account for split 00+01+etc files. @@ -69,11 +69,13 @@ FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs, return FileSys::ConcatenatedVfsFile::MakeConcatenatedFile(concat, dir->GetName()); } + if (FileUtil::IsDirectory(path)) + return vfs->OpenFile(path + "/" + "main", FileSys::Mode::Read); + return vfs->OpenFile(path, FileSys::Mode::Read); } -} // Anonymous namespace - struct System::Impl { + Cpu& CurrentCpuCore() { return cpu_core_manager.GetCurrentCore(); } diff --git a/src/core/core.h b/src/core/core.h index be71bd437..71031dfcf 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -9,6 +9,7 @@ #include <string> #include "common/common_types.h" +#include "core/file_sys/vfs_types.h" #include "core/hle/kernel/object.h" namespace Core::Frontend { @@ -55,6 +56,9 @@ class TelemetrySession; struct PerfStatsResults; +FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs, + const std::string& path); + class System { public: System(const System&) = delete; diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp index 6b14e08be..ecdc21c87 100644 --- a/src/core/file_sys/patch_manager.cpp +++ b/src/core/file_sys/patch_manager.cpp @@ -56,6 +56,10 @@ PatchManager::PatchManager(u64 title_id) : title_id(title_id) {} PatchManager::~PatchManager() = default; +u64 PatchManager::GetTitleID() const { + return title_id; +} + VirtualDir PatchManager::PatchExeFS(VirtualDir exefs) const { LOG_INFO(Loader, "Patching ExeFS for title_id={:016X}", title_id); @@ -73,11 +77,15 @@ VirtualDir PatchManager::PatchExeFS(VirtualDir exefs) const { const auto installed = Service::FileSystem::GetUnionContents(); + const auto& disabled = Settings::values.disabled_addons[title_id]; + const auto update_disabled = + std::find(disabled.begin(), disabled.end(), "Update") != disabled.end(); + // Game Updates const auto update_tid = GetUpdateTitleID(title_id); const auto update = installed.GetEntry(update_tid, ContentRecordType::Program); - if (update != nullptr && update->GetExeFS() != nullptr && + if (!update_disabled && update != nullptr && update->GetExeFS() != nullptr && update->GetStatus() == Loader::ResultStatus::ErrorMissingBKTRBaseRomFS) { LOG_INFO(Loader, " ExeFS: Update ({}) applied successfully", FormatTitleVersion(installed.GetEntryVersion(update_tid).value_or(0))); @@ -95,6 +103,9 @@ VirtualDir PatchManager::PatchExeFS(VirtualDir exefs) const { std::vector<VirtualDir> layers; layers.reserve(patch_dirs.size() + 1); for (const auto& subdir : patch_dirs) { + if (std::find(disabled.begin(), disabled.end(), subdir->GetName()) != disabled.end()) + continue; + auto exefs_dir = subdir->GetSubdirectory("exefs"); if (exefs_dir != nullptr) layers.push_back(std::move(exefs_dir)); @@ -111,11 +122,16 @@ VirtualDir PatchManager::PatchExeFS(VirtualDir exefs) const { return exefs; } -static std::vector<VirtualFile> CollectPatches(const std::vector<VirtualDir>& patch_dirs, - const std::string& build_id) { +std::vector<VirtualFile> PatchManager::CollectPatches(const std::vector<VirtualDir>& patch_dirs, + const std::string& build_id) const { + const auto& disabled = Settings::values.disabled_addons[title_id]; + std::vector<VirtualFile> out; out.reserve(patch_dirs.size()); for (const auto& subdir : patch_dirs) { + if (std::find(disabled.begin(), disabled.end(), subdir->GetName()) != disabled.end()) + continue; + auto exefs_dir = subdir->GetSubdirectory("exefs"); if (exefs_dir != nullptr) { for (const auto& file : exefs_dir->GetFiles()) { @@ -228,6 +244,7 @@ static void ApplyLayeredFS(VirtualFile& romfs, u64 title_id, ContentRecordType t return; } + const auto& disabled = Settings::values.disabled_addons[title_id]; 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(); }); @@ -237,6 +254,9 @@ static void ApplyLayeredFS(VirtualFile& romfs, u64 title_id, ContentRecordType t layers.reserve(patch_dirs.size() + 1); layers_ext.reserve(patch_dirs.size() + 1); for (const auto& subdir : patch_dirs) { + if (std::find(disabled.begin(), disabled.end(), subdir->GetName()) != disabled.end()) + continue; + auto romfs_dir = subdir->GetSubdirectory("romfs"); if (romfs_dir != nullptr) layers.push_back(std::move(romfs_dir)); @@ -282,7 +302,12 @@ VirtualFile PatchManager::PatchRomFS(VirtualFile romfs, u64 ivfc_offset, Content // Game Updates const auto update_tid = GetUpdateTitleID(title_id); const auto update = installed.GetEntryRaw(update_tid, type); - if (update != nullptr) { + + const auto& disabled = Settings::values.disabled_addons[title_id]; + const auto update_disabled = + std::find(disabled.begin(), disabled.end(), "Update") != disabled.end(); + + if (!update_disabled && update != nullptr) { const auto new_nca = std::make_shared<NCA>(update, romfs, ivfc_offset); if (new_nca->GetStatus() == Loader::ResultStatus::Success && new_nca->GetRomFS() != nullptr) { @@ -290,7 +315,7 @@ VirtualFile PatchManager::PatchRomFS(VirtualFile romfs, u64 ivfc_offset, Content FormatTitleVersion(installed.GetEntryVersion(update_tid).value_or(0))); romfs = new_nca->GetRomFS(); } - } else if (update_raw != nullptr) { + } else if (!update_disabled && update_raw != nullptr) { const auto new_nca = std::make_shared<NCA>(update_raw, romfs, ivfc_offset); if (new_nca->GetStatus() == Loader::ResultStatus::Success && new_nca->GetRomFS() != nullptr) { @@ -320,25 +345,30 @@ std::map<std::string, std::string, std::less<>> PatchManager::GetPatchVersionNam VirtualFile update_raw) const { std::map<std::string, std::string, std::less<>> out; const auto installed = Service::FileSystem::GetUnionContents(); + const auto& disabled = Settings::values.disabled_addons[title_id]; // Game Updates const auto update_tid = GetUpdateTitleID(title_id); PatchManager update{update_tid}; auto [nacp, discard_icon_file] = update.GetControlMetadata(); + const auto update_disabled = + std::find(disabled.begin(), disabled.end(), "Update") != disabled.end(); + const auto update_label = update_disabled ? "[D] Update" : "Update"; + if (nacp != nullptr) { - out.insert_or_assign("Update", nacp->GetVersionString()); + out.insert_or_assign(update_label, nacp->GetVersionString()); } else { if (installed.HasEntry(update_tid, ContentRecordType::Program)) { const auto meta_ver = installed.GetEntryVersion(update_tid); if (meta_ver.value_or(0) == 0) { - out.insert_or_assign("Update", ""); + out.insert_or_assign(update_label, ""); } else { out.insert_or_assign( - "Update", FormatTitleVersion(*meta_ver, TitleVersionFormat::ThreeElements)); + update_label, FormatTitleVersion(*meta_ver, TitleVersionFormat::ThreeElements)); } } else if (update_raw != nullptr) { - out.insert_or_assign("Update", "PACKED"); + out.insert_or_assign(update_label, "PACKED"); } } @@ -378,7 +408,9 @@ std::map<std::string, std::string, std::less<>> PatchManager::GetPatchVersionNam if (types.empty()) continue; - out.insert_or_assign(mod->GetName(), types); + const auto mod_disabled = + std::find(disabled.begin(), disabled.end(), mod->GetName()) != disabled.end(); + out.insert_or_assign(mod_disabled ? "[D] " + mod->GetName() : mod->GetName(), types); } } @@ -401,7 +433,9 @@ std::map<std::string, std::string, std::less<>> PatchManager::GetPatchVersionNam list += fmt::format("{}", dlc_match.back().title_id & 0x7FF); - out.insert_or_assign("DLC", std::move(list)); + const auto dlc_disabled = + std::find(disabled.begin(), disabled.end(), "DLC") != disabled.end(); + out.insert_or_assign(dlc_disabled ? "[D] DLC" : "DLC", std::move(list)); } return out; diff --git a/src/core/file_sys/patch_manager.h b/src/core/file_sys/patch_manager.h index 7d168837f..b8a1652fd 100644 --- a/src/core/file_sys/patch_manager.h +++ b/src/core/file_sys/patch_manager.h @@ -30,6 +30,8 @@ public: explicit PatchManager(u64 title_id); ~PatchManager(); + u64 GetTitleID() const; + // Currently tracked ExeFS patches: // - Game Updates VirtualDir PatchExeFS(VirtualDir exefs) const; @@ -63,6 +65,9 @@ public: std::pair<std::unique_ptr<NACP>, VirtualFile> ParseControlNCA(const NCA& nca) const; private: + std::vector<VirtualFile> CollectPatches(const std::vector<VirtualDir>& patch_dirs, + const std::string& build_id) const; + u64 title_id; }; diff --git a/src/core/hle/service/aoc/aoc_u.cpp b/src/core/hle/service/aoc/aoc_u.cpp index 0417fdb92..b506bc3dd 100644 --- a/src/core/hle/service/aoc/aoc_u.cpp +++ b/src/core/hle/service/aoc/aoc_u.cpp @@ -20,6 +20,7 @@ #include "core/hle/service/aoc/aoc_u.h" #include "core/hle/service/filesystem/filesystem.h" #include "core/loader/loader.h" +#include "core/settings.h" namespace Service::AOC { @@ -76,6 +77,13 @@ void AOC_U::CountAddOnContent(Kernel::HLERequestContext& ctx) { rb.Push(RESULT_SUCCESS); const auto current = Core::System::GetInstance().CurrentProcess()->GetTitleID(); + + const auto& disabled = Settings::values.disabled_addons[current]; + if (std::find(disabled.begin(), disabled.end(), "DLC") != disabled.end()) { + rb.Push<u32>(0); + return; + } + rb.Push<u32>(static_cast<u32>( std::count_if(add_on_content.begin(), add_on_content.end(), [current](u64 tid) { return CheckAOCTitleIDMatchesBase(tid, current); }))); @@ -96,6 +104,10 @@ void AOC_U::ListAddOnContent(Kernel::HLERequestContext& ctx) { out.push_back(static_cast<u32>(add_on_content[i] & 0x7FF)); } + const auto& disabled = Settings::values.disabled_addons[current]; + if (std::find(disabled.begin(), disabled.end(), "DLC") != disabled.end()) + out = {}; + if (out.size() < offset) { IPC::ResponseBuilder rb{ctx, 2}; // TODO(DarkLordZach): Find the correct error code. diff --git a/src/core/loader/loader.h b/src/core/loader/loader.h index 5390ab9ee..0838e303b 100644 --- a/src/core/loader/loader.h +++ b/src/core/loader/loader.h @@ -12,6 +12,7 @@ #include <vector> #include "common/common_types.h" +#include "core/file_sys/control_metadata.h" #include "core/file_sys/vfs.h" namespace Kernel { @@ -243,6 +244,15 @@ public: return ResultStatus::ErrorNotImplemented; } + /** + * Get the developer of the application + * @param developer Reference to store the application developer into + * @return ResultStatus result of function + */ + virtual ResultStatus ReadDeveloper(std::string& developer) { + return ResultStatus::ErrorNotImplemented; + } + protected: FileSys::VirtualFile file; bool is_loaded = false; diff --git a/src/core/loader/nsp.cpp b/src/core/loader/nsp.cpp index 080d89904..b4ab88ae8 100644 --- a/src/core/loader/nsp.cpp +++ b/src/core/loader/nsp.cpp @@ -151,4 +151,11 @@ ResultStatus AppLoader_NSP::ReadTitle(std::string& title) { title = nacp_file->GetApplicationName(); return ResultStatus::Success; } + +ResultStatus AppLoader_NSP::ReadDeveloper(std::string& developer) { + if (nacp_file == nullptr) + return ResultStatus::ErrorNoControl; + developer = nacp_file->GetDeveloperName(); + return ResultStatus::Success; +} } // namespace Loader diff --git a/src/core/loader/nsp.h b/src/core/loader/nsp.h index 9ed8a59cf..2b1e0719b 100644 --- a/src/core/loader/nsp.h +++ b/src/core/loader/nsp.h @@ -43,6 +43,7 @@ public: ResultStatus ReadProgramId(u64& out_program_id) override; ResultStatus ReadIcon(std::vector<u8>& buffer) override; ResultStatus ReadTitle(std::string& title) override; + ResultStatus ReadDeveloper(std::string& developer) override; private: std::unique_ptr<FileSys::NSP> nsp; diff --git a/src/core/loader/xci.cpp b/src/core/loader/xci.cpp index 461607c95..bd5a83b49 100644 --- a/src/core/loader/xci.cpp +++ b/src/core/loader/xci.cpp @@ -120,4 +120,11 @@ ResultStatus AppLoader_XCI::ReadTitle(std::string& title) { title = nacp_file->GetApplicationName(); return ResultStatus::Success; } + +ResultStatus AppLoader_XCI::ReadDeveloper(std::string& developer) { + if (nacp_file == nullptr) + return ResultStatus::ErrorNoControl; + developer = nacp_file->GetDeveloperName(); + return ResultStatus::Success; +} } // namespace Loader diff --git a/src/core/loader/xci.h b/src/core/loader/xci.h index ded5bb88a..15d1b1a23 100644 --- a/src/core/loader/xci.h +++ b/src/core/loader/xci.h @@ -43,6 +43,7 @@ public: ResultStatus ReadProgramId(u64& out_program_id) override; ResultStatus ReadIcon(std::vector<u8>& buffer) override; ResultStatus ReadTitle(std::string& title) override; + ResultStatus ReadDeveloper(std::string& developer) override; private: std::unique_ptr<FileSys::XCI> xci; diff --git a/src/core/settings.h b/src/core/settings.h index a0c5fd447..de01b05c0 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -6,8 +6,10 @@ #include <array> #include <atomic> +#include <map> #include <optional> #include <string> +#include <vector> #include "common/common_types.h" namespace Settings { @@ -411,6 +413,9 @@ struct Values { std::string web_api_url; std::string yuzu_username; std::string yuzu_token; + + // Add-Ons + std::map<u64, std::vector<std::string>> disabled_addons; } extern values; void Apply(); |