Core: Attempt to parse Gecko cheat codes with disregarded creator name.

This is a follow-up to the previous commit, where the cheat code name
and the creator name have been combined into a single field.

For backwards compatibility, if an *enabled* cheat code is not found
among the available cheat codes, there will be a second attempt to
find a match by disregarding the creator name from the available Gecko
codes.
This commit is contained in:
cristian64 2024-12-10 15:37:48 +00:00
parent 6bdda09b71
commit 5902e891cb
2 changed files with 38 additions and 7 deletions

View File

@ -3,12 +3,14 @@
#pragma once #pragma once
#include <regex>
#include <string> #include <string>
#include <vector> #include <vector>
#include "Common/IniFile.h" #include "Common/IniFile.h"
#include "Common/StringUtil.h"
template <typename T> template <typename T, bool disregard_creator_in_name = false>
void ReadEnabledOrDisabled(const Common::IniFile& ini, const std::string& section, bool enabled, void ReadEnabledOrDisabled(const Common::IniFile& ini, const std::string& section, bool enabled,
std::vector<T>* codes) std::vector<T>* codes)
{ {
@ -20,19 +22,48 @@ void ReadEnabledOrDisabled(const Common::IniFile& ini, const std::string& sectio
if (line.empty() || line[0] != '$') if (line.empty() || line[0] != '$')
continue; continue;
// Exclude the initial '$' from the comparison.
const auto name = StripWhitespace(std::string_view{line}.substr(1));
bool matched{false};
for (T& code : *codes) for (T& code : *codes)
{ {
// Exclude the initial '$' from the comparison. if (name == code.name)
if (line.compare(1, std::string::npos, code.name) == 0) {
code.enabled = enabled; code.enabled = enabled;
matched = true;
break;
}
}
if (!matched && disregard_creator_in_name)
{
// For backwards compatibility, where certain cheat code types (namedly Gecko cheat codes)
// would be stored in the _Enabled/_Disabled sections without including the creator name,
// there will be a second attempt to match the parsed line with any of the cheat codes in the
// list after disregarding the potential creator name.
static const std::regex s_regex("(.*)(\\[.+\\])");
for (T& code : *codes)
{
const std::string codeNameWithoutCreator{
StripWhitespace(std::regex_replace(code.name, s_regex, "$1"))};
if (name == codeNameWithoutCreator)
{
code.enabled = enabled;
matched = true;
break;
}
}
} }
} }
} }
template <typename T> template <typename T, bool disregard_creator_in_name = false>
void ReadEnabledAndDisabled(const Common::IniFile& ini, const std::string& section, void ReadEnabledAndDisabled(const Common::IniFile& ini, const std::string& section,
std::vector<T>* codes) std::vector<T>* codes)
{ {
ReadEnabledOrDisabled(ini, section + "_Enabled", true, codes); ReadEnabledOrDisabled<T, disregard_creator_in_name>(ini, section + "_Enabled", true, codes);
ReadEnabledOrDisabled(ini, section + "_Disabled", false, codes); ReadEnabledOrDisabled<T, disregard_creator_in_name>(ini, section + "_Disabled", false, codes);
} }

View File

@ -189,7 +189,7 @@ std::vector<GeckoCode> LoadCodes(const Common::IniFile& globalIni, const Common:
gcodes.push_back(gcode); gcodes.push_back(gcode);
} }
ReadEnabledAndDisabled(*ini, "Gecko", &gcodes); ReadEnabledAndDisabled<GeckoCode, true>(*ini, "Gecko", &gcodes);
if (ini == &globalIni) if (ini == &globalIni)
{ {