GameDB: Fixed invalid GameFix instances using new validation process

GameDB: Delete the .dbf file
This commit is contained in:
Tyler Wilding 2020-11-13 22:46:35 -05:00 committed by refractionpcsx2
parent df1a8e8667
commit b800ed0a10
7 changed files with 1237 additions and 48643 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -17,6 +17,7 @@
#include "GameDatabase.h" #include "GameDatabase.h"
#include "fmt/core.h"
#include "yaml-cpp/yaml.h" #include "yaml-cpp/yaml.h"
std::string GameDatabaseSchema::GameEntry::memcardFiltersAsString() std::string GameDatabaseSchema::GameEntry::memcardFiltersAsString()
@ -49,6 +50,23 @@ int YamlGameDatabaseImpl::safeGetInt(const YAML::Node& n, std::string key, int d
return n[key].as<int>(); return n[key].as<int>();
} }
std::vector<std::string> YamlGameDatabaseImpl::safeGetMultilineString(const YAML::Node& n, std::string key, std::vector<std::string> def)
{
if (!n[key])
return def;
std::vector<std::string> lines;
std::istringstream stream(safeGetString(n, key));
std::string line;
while(std::getline(stream, line)) {
lines.push_back(line);
}
return lines;
}
std::vector<std::string> YamlGameDatabaseImpl::safeGetStringList(const YAML::Node& n, std::string key, std::vector<std::string> def) std::vector<std::string> YamlGameDatabaseImpl::safeGetStringList(const YAML::Node& n, std::string key, std::vector<std::string> def)
{ {
if (!n[key]) if (!n[key])
@ -58,21 +76,22 @@ std::vector<std::string> YamlGameDatabaseImpl::safeGetStringList(const YAML::Nod
GameDatabaseSchema::GameEntry YamlGameDatabaseImpl::entryFromYaml(const std::string serial, const YAML::Node& node) GameDatabaseSchema::GameEntry YamlGameDatabaseImpl::entryFromYaml(const std::string serial, const YAML::Node& node)
{ {
if (serial == "SCUS-97265")
int x = 0;
GameDatabaseSchema::GameEntry gameEntry; GameDatabaseSchema::GameEntry gameEntry;
try try
{ {
gameEntry.name = safeGetString(node, "name"); gameEntry.name = safeGetString(node, "name");
gameEntry.region = safeGetString(node, "region"); gameEntry.region = safeGetString(node, "region");
gameEntry.compat = static_cast<GameDatabaseSchema::Compatibility>(safeGetInt(node, "compat")); gameEntry.compat = static_cast<GameDatabaseSchema::Compatibility>(safeGetInt(node, "compat", enum_cast(gameEntry.compat)));
gameEntry.eeRoundMode = static_cast<GameDatabaseSchema::RoundMode>(safeGetInt(node, "eeRoundMode")); gameEntry.eeRoundMode = static_cast<GameDatabaseSchema::RoundMode>(safeGetInt(node, "eeRoundMode", enum_cast(gameEntry.eeRoundMode)));
gameEntry.vuRoundMode = static_cast<GameDatabaseSchema::RoundMode>(safeGetInt(node, "vuRoundMode")); gameEntry.vuRoundMode = static_cast<GameDatabaseSchema::RoundMode>(safeGetInt(node, "vuRoundMode", enum_cast(gameEntry.vuRoundMode)));
gameEntry.eeClampMode = static_cast<GameDatabaseSchema::ClampMode>(safeGetInt(node, "eeClampMode")); gameEntry.eeClampMode = static_cast<GameDatabaseSchema::ClampMode>(safeGetInt(node, "eeClampMode", enum_cast(gameEntry.eeClampMode)));
gameEntry.vuClampMode = static_cast<GameDatabaseSchema::ClampMode>(safeGetInt(node, "vuClampMode")); gameEntry.vuClampMode = static_cast<GameDatabaseSchema::ClampMode>(safeGetInt(node, "vuClampMode", enum_cast(gameEntry.vuClampMode)));
// Validate game fixes, invalid ones will be dropped! // Validate game fixes, invalid ones will be dropped!
for (std::string fix : gameEntry.gameFixes) for (std::string fix : safeGetStringList(node, "gameFixes"))
{ {
std::vector<std::string> rawFixes = safeGetStringList(node, "gameFixes");
bool fixValidated = false; bool fixValidated = false;
for (GamefixId id = GamefixId_FIRST; id < pxEnumEnd; ++id) for (GamefixId id = GamefixId_FIRST; id < pxEnumEnd; ++id)
{ {
@ -89,7 +108,7 @@ GameDatabaseSchema::GameEntry YamlGameDatabaseImpl::entryFromYaml(const std::str
} }
else else
{ {
Console.Error("[GameDB] Invalid gamefix: '%s', specified for serial: '%s'. Dropping!", fix, serial); Console.Error(fmt::format("[GameDB] Invalid gamefix: '{}', specified for serial: '{}'. Dropping!", fix, serial));
} }
} }
@ -103,7 +122,7 @@ GameDatabaseSchema::GameEntry YamlGameDatabaseImpl::entryFromYaml(const std::str
// NOTE - currently only 1 speedhack! // NOTE - currently only 1 speedhack!
if (speedHack != "mvuFlagSpeedHack") if (speedHack != "mvuFlagSpeedHack")
{ {
Console.Error("[GameDB] Invalid speedhack: '%s', specified for serial: '%s'. Dropping!", speedHack, serial); Console.Error(fmt::format("[GameDB] Invalid speedhack: '{}', specified for serial: '{}'. Dropping!", speedHack, serial));
continue; continue;
} }
@ -117,18 +136,17 @@ GameDatabaseSchema::GameEntry YamlGameDatabaseImpl::entryFromYaml(const std::str
{ {
for (YAML::const_iterator it = patches.begin(); it != patches.end(); ++it) for (YAML::const_iterator it = patches.begin(); it != patches.end(); ++it)
{ {
YAML::Node key = it->first; const YAML::Node& node = *it;
YAML::Node val = it->second;
GameDatabaseSchema::Patch patchCol; GameDatabaseSchema::Patch patchCol;
patchCol.author = safeGetString(val, "author"); patchCol.author = safeGetString(node, "author");
patchCol.patchLines = safeGetStringList(val, "patchLines"); patchCol.patchLines = safeGetMultilineString(node, "content");
gameEntry.patches[key.as<std::string>()] = patchCol; gameEntry.patches[safeGetString(node, "crc", "default")] = patchCol;
} }
} }
} }
catch (YAML::RepresentationException e) catch (YAML::RepresentationException e)
{ {
Console.Error("[GameDB] Invalid GameDB syntax detected on serial: '%s'. Error Details - %s", serial, e.what()); Console.Error(fmt::format("[GameDB] Invalid GameDB syntax detected on serial: '{}'. Error Details - {}", serial, e.msg));
gameEntry.isValid = false; gameEntry.isValid = false;
} }
return gameEntry; return gameEntry;
@ -167,13 +185,13 @@ bool YamlGameDatabaseImpl::initDatabase(const std::string filePath)
} }
catch (YAML::RepresentationException e) catch (YAML::RepresentationException e)
{ {
Console.Error("[GameDB] Invalid GameDB syntax detected. Error Details - %s", e.what()); Console.Error(fmt::format("[GameDB] Invalid GameDB syntax detected. Error Details - {}", e.msg));
} }
} }
} }
catch (const std::exception& e) catch (const std::exception& e)
{ {
Console.Error("Error occured when initializing GameDB: %s", e.what()); Console.Error(fmt::format("Error occured when initializing GameDB: {}", e.what()));
return false; return false;
} }

View File

@ -103,6 +103,7 @@ private:
// TODO - config - move these into a generic library // TODO - config - move these into a generic library
std::string safeGetString(const YAML::Node& n, std::string key, std::string def = ""); std::string safeGetString(const YAML::Node& n, std::string key, std::string def = "");
int safeGetInt(const YAML::Node& n, std::string key, int def = 0); int safeGetInt(const YAML::Node& n, std::string key, int def = 0);
std::vector<std::string> safeGetMultilineString(const YAML::Node& n, std::string key, std::vector<std::string> def = {});
std::vector<std::string> safeGetStringList(const YAML::Node& n, std::string key, std::vector<std::string> def = {}); std::vector<std::string> safeGetStringList(const YAML::Node& n, std::string key, std::vector<std::string> def = {});
}; };

View File

@ -127,19 +127,19 @@ int LoadPatchesFromGamesDB(const wxString& crc, const GameDatabaseSchema::GameEn
{ {
if (game.isValid) if (game.isValid)
{ {
GameDatabaseSchema::PatchCollection patchCollection; GameDatabaseSchema::Patch patch;
if (game.patches.count(std::string(crc)) == 1) if (game.patches.count(std::string(crc)) == 1)
{ {
patchCollection = game.patches.at(std::string(crc)); patch = game.patches.at(std::string(crc));
} }
else if (game.patches.count("default") == 1) else if (game.patches.count("default") == 1)
{ {
patchCollection = game.patches.at("default"); patch = game.patches.at("default");
} }
if (patchCollection.patchLines.size() > 0) if (patch.patchLines.size() > 0)
{ {
for (auto line : patchCollection.patchLines) for (auto line : patch.patchLines)
{ {
inifile_command(line); inifile_command(line);
} }

View File

@ -258,9 +258,9 @@ const wxChar *const tbl_GamefixNames[] =
L"FpuMul", L"FpuMul",
L"FpuNegDiv", L"FpuNegDiv",
L"XGKick", L"XGKick",
L"IpuWait", L"IPUWait",
L"EETiming", L"EETiming",
L"SkipMpeg", L"SkipMPEG",
L"OPHFlag", L"OPHFlag",
L"DMABusy", L"DMABusy",
L"VIFFIFO", L"VIFFIFO",

View File

@ -50,9 +50,8 @@ AppGameDatabase& AppGameDatabase::LoadFromFile(const wxString& _file)
} }
u64 qpc_Start = GetCPUTicks(); u64 qpc_Start = GetCPUTicks();
YamlGameDatabaseImpl gameDb = YamlGameDatabaseImpl();
if (!gameDb.initDatabase(std::string(file))) if (!this->initDatabase(std::string(file)))
{ {
Console.Error(L"(GameDB) Database could not be loaded successfully"); Console.Error(L"(GameDB) Database could not be loaded successfully");
return *this; return *this;
@ -60,7 +59,7 @@ AppGameDatabase& AppGameDatabase::LoadFromFile(const wxString& _file)
u64 qpc_end = GetCPUTicks(); u64 qpc_end = GetCPUTicks();
Console.WriteLn(fmt::format("(GameDB) {} games on record (loaded in {}ms)", gameDb.numGames(), Console.WriteLn(fmt::format("(GameDB) {} games on record (loaded in {}ms)", this->numGames(),
(u32)(((qpc_end - qpc_Start) * 1000) / GetTickFrequency()))); (u32)(((qpc_end - qpc_Start) * 1000) / GetTickFrequency())));
return *this; return *this;