diff options
Diffstat (limited to '')
| -rw-r--r-- | src/core/file_sys/patch_manager.cpp | 14 | ||||
| -rw-r--r-- | src/core/memory/cheat_engine.cpp | 41 | ||||
| -rw-r--r-- | src/core/memory/cheat_engine.h | 5 |
3 files changed, 26 insertions, 34 deletions
diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp index 87c354a43..b9c09b456 100644 --- a/src/core/file_sys/patch_manager.cpp +++ b/src/core/file_sys/patch_manager.cpp | |||
| @@ -76,8 +76,7 @@ VirtualDir FindSubdirectoryCaseless(const VirtualDir dir, std::string_view name) | |||
| 76 | } | 76 | } |
| 77 | 77 | ||
| 78 | std::optional<std::vector<Core::Memory::CheatEntry>> ReadCheatFileFromFolder( | 78 | std::optional<std::vector<Core::Memory::CheatEntry>> ReadCheatFileFromFolder( |
| 79 | const Core::System& system, u64 title_id, const PatchManager::BuildID& build_id_, | 79 | u64 title_id, const PatchManager::BuildID& build_id_, const VirtualDir& base_path, bool upper) { |
| 80 | const VirtualDir& base_path, bool upper) { | ||
| 81 | const auto build_id_raw = Common::HexToString(build_id_, upper); | 80 | const auto build_id_raw = Common::HexToString(build_id_, upper); |
| 82 | const auto build_id = build_id_raw.substr(0, sizeof(u64) * 2); | 81 | const auto build_id = build_id_raw.substr(0, sizeof(u64) * 2); |
| 83 | const auto file = base_path->GetFile(fmt::format("{}.txt", build_id)); | 82 | const auto file = base_path->GetFile(fmt::format("{}.txt", build_id)); |
| @@ -95,9 +94,8 @@ std::optional<std::vector<Core::Memory::CheatEntry>> ReadCheatFileFromFolder( | |||
| 95 | return std::nullopt; | 94 | return std::nullopt; |
| 96 | } | 95 | } |
| 97 | 96 | ||
| 98 | Core::Memory::TextCheatParser parser; | 97 | const Core::Memory::TextCheatParser parser; |
| 99 | return parser.Parse(system, | 98 | return parser.Parse(std::string_view(reinterpret_cast<const char*>(data.data()), data.size())); |
| 100 | std::string_view(reinterpret_cast<const char*>(data.data()), data.size())); | ||
| 101 | } | 99 | } |
| 102 | 100 | ||
| 103 | void AppendCommaIfNotEmpty(std::string& to, std::string_view with) { | 101 | void AppendCommaIfNotEmpty(std::string& to, std::string_view with) { |
| @@ -335,14 +333,12 @@ std::vector<Core::Memory::CheatEntry> PatchManager::CreateCheatList( | |||
| 335 | 333 | ||
| 336 | auto cheats_dir = FindSubdirectoryCaseless(subdir, "cheats"); | 334 | auto cheats_dir = FindSubdirectoryCaseless(subdir, "cheats"); |
| 337 | if (cheats_dir != nullptr) { | 335 | if (cheats_dir != nullptr) { |
| 338 | auto res = ReadCheatFileFromFolder(system, title_id, build_id_, cheats_dir, true); | 336 | if (const auto res = ReadCheatFileFromFolder(title_id, build_id_, cheats_dir, true)) { |
| 339 | if (res.has_value()) { | ||
| 340 | std::copy(res->begin(), res->end(), std::back_inserter(out)); | 337 | std::copy(res->begin(), res->end(), std::back_inserter(out)); |
| 341 | continue; | 338 | continue; |
| 342 | } | 339 | } |
| 343 | 340 | ||
| 344 | res = ReadCheatFileFromFolder(system, title_id, build_id_, cheats_dir, false); | 341 | if (const auto res = ReadCheatFileFromFolder(title_id, build_id_, cheats_dir, false)) { |
| 345 | if (res.has_value()) { | ||
| 346 | std::copy(res->begin(), res->end(), std::back_inserter(out)); | 342 | std::copy(res->begin(), res->end(), std::back_inserter(out)); |
| 347 | } | 343 | } |
| 348 | } | 344 | } |
diff --git a/src/core/memory/cheat_engine.cpp b/src/core/memory/cheat_engine.cpp index e503118dd..29284a42d 100644 --- a/src/core/memory/cheat_engine.cpp +++ b/src/core/memory/cheat_engine.cpp | |||
| @@ -19,10 +19,24 @@ | |||
| 19 | #include "core/memory/cheat_engine.h" | 19 | #include "core/memory/cheat_engine.h" |
| 20 | 20 | ||
| 21 | namespace Core::Memory { | 21 | namespace Core::Memory { |
| 22 | 22 | namespace { | |
| 23 | constexpr auto CHEAT_ENGINE_NS = std::chrono::nanoseconds{1000000000 / 12}; | 23 | constexpr auto CHEAT_ENGINE_NS = std::chrono::nanoseconds{1000000000 / 12}; |
| 24 | constexpr u32 KEYPAD_BITMASK = 0x3FFFFFF; | 24 | constexpr u32 KEYPAD_BITMASK = 0x3FFFFFF; |
| 25 | 25 | ||
| 26 | std::string_view ExtractName(std::string_view data, std::size_t start_index, char match) { | ||
| 27 | auto end_index = start_index; | ||
| 28 | while (data[end_index] != match) { | ||
| 29 | ++end_index; | ||
| 30 | if (end_index > data.size() || | ||
| 31 | (end_index - start_index - 1) > sizeof(CheatDefinition::readable_name)) { | ||
| 32 | return {}; | ||
| 33 | } | ||
| 34 | } | ||
| 35 | |||
| 36 | return data.substr(start_index, end_index - start_index); | ||
| 37 | } | ||
| 38 | } // Anonymous namespace | ||
| 39 | |||
| 26 | StandardVmCallbacks::StandardVmCallbacks(Core::System& system, const CheatProcessMetadata& metadata) | 40 | StandardVmCallbacks::StandardVmCallbacks(Core::System& system, const CheatProcessMetadata& metadata) |
| 27 | : metadata(metadata), system(system) {} | 41 | : metadata(metadata), system(system) {} |
| 28 | 42 | ||
| @@ -82,26 +96,9 @@ CheatParser::~CheatParser() = default; | |||
| 82 | 96 | ||
| 83 | TextCheatParser::~TextCheatParser() = default; | 97 | TextCheatParser::~TextCheatParser() = default; |
| 84 | 98 | ||
| 85 | namespace { | 99 | std::vector<CheatEntry> TextCheatParser::Parse(std::string_view data) const { |
| 86 | template <char match> | ||
| 87 | std::string_view ExtractName(std::string_view data, std::size_t start_index) { | ||
| 88 | auto end_index = start_index; | ||
| 89 | while (data[end_index] != match) { | ||
| 90 | ++end_index; | ||
| 91 | if (end_index > data.size() || | ||
| 92 | (end_index - start_index - 1) > sizeof(CheatDefinition::readable_name)) { | ||
| 93 | return {}; | ||
| 94 | } | ||
| 95 | } | ||
| 96 | |||
| 97 | return data.substr(start_index, end_index - start_index); | ||
| 98 | } | ||
| 99 | } // Anonymous namespace | ||
| 100 | |||
| 101 | std::vector<CheatEntry> TextCheatParser::Parse(const Core::System& system, | ||
| 102 | std::string_view data) const { | ||
| 103 | std::vector<CheatEntry> out(1); | 100 | std::vector<CheatEntry> out(1); |
| 104 | std::optional<u64> current_entry = std::nullopt; | 101 | std::optional<u64> current_entry; |
| 105 | 102 | ||
| 106 | for (std::size_t i = 0; i < data.size(); ++i) { | 103 | for (std::size_t i = 0; i < data.size(); ++i) { |
| 107 | if (::isspace(data[i])) { | 104 | if (::isspace(data[i])) { |
| @@ -115,7 +112,7 @@ std::vector<CheatEntry> TextCheatParser::Parse(const Core::System& system, | |||
| 115 | return {}; | 112 | return {}; |
| 116 | } | 113 | } |
| 117 | 114 | ||
| 118 | const auto name = ExtractName<'}'>(data, i + 1); | 115 | const auto name = ExtractName(data, i + 1, '}'); |
| 119 | if (name.empty()) { | 116 | if (name.empty()) { |
| 120 | return {}; | 117 | return {}; |
| 121 | } | 118 | } |
| @@ -132,7 +129,7 @@ std::vector<CheatEntry> TextCheatParser::Parse(const Core::System& system, | |||
| 132 | current_entry = out.size(); | 129 | current_entry = out.size(); |
| 133 | out.emplace_back(); | 130 | out.emplace_back(); |
| 134 | 131 | ||
| 135 | const auto name = ExtractName<']'>(data, i + 1); | 132 | const auto name = ExtractName(data, i + 1, ']'); |
| 136 | if (name.empty()) { | 133 | if (name.empty()) { |
| 137 | return {}; | 134 | return {}; |
| 138 | } | 135 | } |
diff --git a/src/core/memory/cheat_engine.h b/src/core/memory/cheat_engine.h index fa039a831..a31002346 100644 --- a/src/core/memory/cheat_engine.h +++ b/src/core/memory/cheat_engine.h | |||
| @@ -47,8 +47,7 @@ class CheatParser { | |||
| 47 | public: | 47 | public: |
| 48 | virtual ~CheatParser(); | 48 | virtual ~CheatParser(); |
| 49 | 49 | ||
| 50 | virtual std::vector<CheatEntry> Parse(const Core::System& system, | 50 | [[nodiscard]] virtual std::vector<CheatEntry> Parse(std::string_view data) const = 0; |
| 51 | std::string_view data) const = 0; | ||
| 52 | }; | 51 | }; |
| 53 | 52 | ||
| 54 | // CheatParser implementation that parses text files | 53 | // CheatParser implementation that parses text files |
| @@ -56,7 +55,7 @@ class TextCheatParser final : public CheatParser { | |||
| 56 | public: | 55 | public: |
| 57 | ~TextCheatParser() override; | 56 | ~TextCheatParser() override; |
| 58 | 57 | ||
| 59 | std::vector<CheatEntry> Parse(const Core::System& system, std::string_view data) const override; | 58 | [[nodiscard]] std::vector<CheatEntry> Parse(std::string_view data) const override; |
| 60 | }; | 59 | }; |
| 61 | 60 | ||
| 62 | // Class that encapsulates a CheatList and manages its interaction with memory and CoreTiming | 61 | // Class that encapsulates a CheatList and manages its interaction with memory and CoreTiming |