diff options
| author | 2018-12-22 21:28:56 -0500 | |
|---|---|---|
| committer | 2019-03-04 18:39:57 -0500 | |
| commit | c5091bfe00c241b6432367aeaea020d4e3d40d28 (patch) | |
| tree | 652232b1ab5ba14d49c5fc70d54bd0e0d2edf55f /src | |
| parent | controllers/npad: Add accessor for current press state (diff) | |
| download | yuzu-c5091bfe00c241b6432367aeaea020d4e3d40d28.tar.gz yuzu-c5091bfe00c241b6432367aeaea020d4e3d40d28.tar.xz yuzu-c5091bfe00c241b6432367aeaea020d4e3d40d28.zip | |
patch_manager: Add support for loading cheats lists
Uses load/<title_id>/<mod_name>/cheats as root dir, file name is all upper or lower hex first 8 bytes build ID.
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/file_sys/patch_manager.cpp | 52 | ||||
| -rw-r--r-- | src/core/file_sys/patch_manager.h | 4 |
2 files changed, 56 insertions, 0 deletions
diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp index 61706966e..f0fb28e2f 100644 --- a/src/core/file_sys/patch_manager.cpp +++ b/src/core/file_sys/patch_manager.cpp | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | #include <cstddef> | 7 | #include <cstddef> |
| 8 | #include <cstring> | 8 | #include <cstring> |
| 9 | 9 | ||
| 10 | #include "common/file_util.h" | ||
| 10 | #include "common/hex_util.h" | 11 | #include "common/hex_util.h" |
| 11 | #include "common/logging/log.h" | 12 | #include "common/logging/log.h" |
| 12 | #include "core/file_sys/content_archive.h" | 13 | #include "core/file_sys/content_archive.h" |
| @@ -232,6 +233,57 @@ bool PatchManager::HasNSOPatch(const std::array<u8, 32>& build_id_) const { | |||
| 232 | return !CollectPatches(patch_dirs, build_id).empty(); | 233 | return !CollectPatches(patch_dirs, build_id).empty(); |
| 233 | } | 234 | } |
| 234 | 235 | ||
| 236 | static std::optional<CheatList> ReadCheatFileFromFolder(u64 title_id, | ||
| 237 | const std::array<u8, 0x20>& build_id_, | ||
| 238 | const VirtualDir& base_path, bool upper) { | ||
| 239 | const auto build_id_raw = Common::HexArrayToString(build_id_, upper); | ||
| 240 | const auto build_id = build_id_raw.substr(0, sizeof(u64) * 2); | ||
| 241 | const auto file = base_path->GetFile(fmt::format("{}.txt", build_id)); | ||
| 242 | |||
| 243 | if (file == nullptr) { | ||
| 244 | LOG_INFO(Common_Filesystem, "No cheats file found for title_id={:016X}, build_id={}", | ||
| 245 | title_id, build_id); | ||
| 246 | return std::nullopt; | ||
| 247 | } | ||
| 248 | |||
| 249 | std::vector<u8> data(file->GetSize()); | ||
| 250 | if (file->Read(data.data(), data.size()) != data.size()) { | ||
| 251 | LOG_INFO(Common_Filesystem, "Failed to read cheats file for title_id={:016X}, build_id={}", | ||
| 252 | title_id, build_id); | ||
| 253 | return std::nullopt; | ||
| 254 | } | ||
| 255 | |||
| 256 | TextCheatParser parser; | ||
| 257 | return parser.Parse(data); | ||
| 258 | } | ||
| 259 | |||
| 260 | std::vector<CheatList> PatchManager::CreateCheatList(const std::array<u8, 32>& build_id_) const { | ||
| 261 | std::vector<CheatList> out; | ||
| 262 | |||
| 263 | const auto load_dir = Service::FileSystem::GetModificationLoadRoot(title_id); | ||
| 264 | auto patch_dirs = load_dir->GetSubdirectories(); | ||
| 265 | std::sort(patch_dirs.begin(), patch_dirs.end(), | ||
| 266 | [](const VirtualDir& l, const VirtualDir& r) { return l->GetName() < r->GetName(); }); | ||
| 267 | |||
| 268 | out.reserve(patch_dirs.size()); | ||
| 269 | for (const auto& subdir : patch_dirs) { | ||
| 270 | auto cheats_dir = subdir->GetSubdirectory("cheats"); | ||
| 271 | if (cheats_dir != nullptr) { | ||
| 272 | auto res = ReadCheatFileFromFolder(title_id, build_id_, cheats_dir, true); | ||
| 273 | if (res.has_value()) { | ||
| 274 | out.push_back(std::move(*res)); | ||
| 275 | continue; | ||
| 276 | } | ||
| 277 | |||
| 278 | res = ReadCheatFileFromFolder(title_id, build_id_, cheats_dir, false); | ||
| 279 | if (res.has_value()) | ||
| 280 | out.push_back(std::move(*res)); | ||
| 281 | } | ||
| 282 | } | ||
| 283 | |||
| 284 | return out; | ||
| 285 | } | ||
| 286 | |||
| 235 | static void ApplyLayeredFS(VirtualFile& romfs, u64 title_id, ContentRecordType type) { | 287 | static void ApplyLayeredFS(VirtualFile& romfs, u64 title_id, ContentRecordType type) { |
| 236 | const auto load_dir = Service::FileSystem::GetModificationLoadRoot(title_id); | 288 | const auto load_dir = Service::FileSystem::GetModificationLoadRoot(title_id); |
| 237 | if ((type != ContentRecordType::Program && type != ContentRecordType::Data) || | 289 | if ((type != ContentRecordType::Program && type != ContentRecordType::Data) || |
diff --git a/src/core/file_sys/patch_manager.h b/src/core/file_sys/patch_manager.h index b8a1652fd..3e3ac6aca 100644 --- a/src/core/file_sys/patch_manager.h +++ b/src/core/file_sys/patch_manager.h | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | #include <memory> | 8 | #include <memory> |
| 9 | #include <string> | 9 | #include <string> |
| 10 | #include "common/common_types.h" | 10 | #include "common/common_types.h" |
| 11 | #include "core/file_sys/cheat_engine.h" | ||
| 11 | #include "core/file_sys/nca_metadata.h" | 12 | #include "core/file_sys/nca_metadata.h" |
| 12 | #include "core/file_sys/vfs.h" | 13 | #include "core/file_sys/vfs.h" |
| 13 | 14 | ||
| @@ -45,6 +46,9 @@ public: | |||
| 45 | // Used to prevent expensive copies in NSO loader. | 46 | // Used to prevent expensive copies in NSO loader. |
| 46 | bool HasNSOPatch(const std::array<u8, 0x20>& build_id) const; | 47 | bool HasNSOPatch(const std::array<u8, 0x20>& build_id) const; |
| 47 | 48 | ||
| 49 | // Creates a CheatList object with all | ||
| 50 | std::vector<CheatList> CreateCheatList(const std::array<u8, 0x20>& build_id) const; | ||
| 51 | |||
| 48 | // Currently tracked RomFS patches: | 52 | // Currently tracked RomFS patches: |
| 49 | // - Game Updates | 53 | // - Game Updates |
| 50 | // - LayeredFS | 54 | // - LayeredFS |