// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once #include #include #include #include #include "common/common_types.h" #include "core/file_sys/nca_metadata.h" #include "core/file_sys/vfs_types.h" #include "core/memory/dmnt_cheat_types.h" namespace Core { class System; } namespace Service::FileSystem { class FileSystemController; } namespace FileSys { class ContentProvider; class NCA; class NACP; enum class PatchType { Update, DLC, Mod }; struct Patch { bool enabled; std::string name; std::string version; PatchType type; u64 program_id; u64 title_id; }; // A centralized class to manage patches to games. class PatchManager { public: using BuildID = std::array; using Metadata = std::pair, VirtualFile>; explicit PatchManager(u64 title_id_, const Service::FileSystem::FileSystemController& fs_controller_, const ContentProvider& content_provider_); ~PatchManager(); [[nodiscard]] u64 GetTitleID() const; // Currently tracked ExeFS patches: // - Game Updates [[nodiscard]] VirtualDir PatchExeFS(VirtualDir exefs) const; // Currently tracked NSO patches: // - IPS // - IPSwitch [[nodiscard]] std::vector PatchNSO(const std::vector& nso, const std::string& name) const; // Checks to see if PatchNSO() will have any effect given the NSO's build ID. // Used to prevent expensive copies in NSO loader. [[nodiscard]] bool HasNSOPatch(const BuildID& build_id, std::string_view name) const; // Creates a CheatList object with all [[nodiscard]] std::vector CreateCheatList( const BuildID& build_id) const; // Currently tracked RomFS patches: // - Game Updates // - LayeredFS [[nodiscard]] VirtualFile PatchRomFS(const NCA* base_nca, VirtualFile base_romfs, ContentRecordType type = ContentRecordType::Program, VirtualFile packed_update_raw = nullptr, bool apply_layeredfs = true) const; // Returns a vector of patches [[nodiscard]] std::vector GetPatches(VirtualFile update_raw = nullptr) const; // If the game update exists, returns the u32 version field in its Meta-type NCA. If that fails, // it will fallback to the Meta-type NCA of the base game. If that fails, the result will be // std::nullopt [[nodiscard]] std::optional GetGameVersion() const; // Given title_id of the program, attempts to get the control data of the update and parse // it, falling back to the base control data. [[nodiscard]] Metadata GetControlMetadata() const; // Version of GetControlMetadata that takes an arbitrary NCA [[nodiscard]] Metadata ParseControlNCA(const NCA& nca) const; private: [[nodiscard]] std::vector CollectPatches(const std::vector& patch_dirs, const std::string& build_id) const; u64 title_id; const Service::FileSystem::FileSystemController& fs_controller; const ContentProvider& content_provider; }; } // namespace FileSys