RedumpVerifier: Show an error when datfile lacks serials or versions

This happens if someone manually downloads a regular datfile from
redump.org and puts it where Dolphin stores datfiles. Dolphin needs
"special" datfiles that contain fields for serials and versions.

Before this change, all discs (except Datel discs) would show up as
"Unknown disc" when using a regular datfile.
This commit is contained in:
JosJuice 2019-11-02 16:47:08 +01:00
parent a7d4be79ae
commit 56d37d773b
2 changed files with 21 additions and 3 deletions

View File

@ -99,7 +99,7 @@ void RedumpVerifier::Start(const Volume& volume)
ERROR_LOG(DISCIO, "Failed to fetch data from Redump.org, using old cached data instead");
[[fallthrough]];
case DownloadStatus::Success:
return ScanDatfile(ReadDatfile(system));
return ScanDatfile(ReadDatfile(system), system);
case DownloadStatus::SystemNotAvailable:
m_result = {Status::Error, Common::GetStringT("Wii data is not public yet")};
@ -213,7 +213,8 @@ static std::vector<u8> ParseHash(const char* str)
return hash;
}
std::vector<RedumpVerifier::PotentialMatch> RedumpVerifier::ScanDatfile(const std::vector<u8>& data)
std::vector<RedumpVerifier::PotentialMatch> RedumpVerifier::ScanDatfile(const std::vector<u8>& data,
const std::string& system)
{
pugi::xml_document doc;
if (!doc.load_buffer(data.data(), data.size()))
@ -223,10 +224,14 @@ std::vector<RedumpVerifier::PotentialMatch> RedumpVerifier::ScanDatfile(const st
}
std::vector<PotentialMatch> potential_matches;
bool serials_exist = false;
bool versions_exist = false;
const pugi::xml_node datafile = doc.child("datafile");
for (const pugi::xml_node game : datafile.children("game"))
{
std::string version_string = game.child("version").text().as_string();
if (!version_string.empty())
versions_exist = true;
// Strip out prefix (e.g. "v1.02" -> "02", "Rev 2" -> "2")
const size_t last_non_numeric = version_string.find_last_not_of("0123456789");
@ -241,6 +246,8 @@ std::vector<RedumpVerifier::PotentialMatch> RedumpVerifier::ScanDatfile(const st
continue;
const std::string serials = game.child("serial").text().as_string();
if (!serials.empty())
serials_exist = true;
if (serials.empty() || StringBeginsWith(serials, "DS"))
{
// GC Datel discs have no serials in Redump, Wii Datel discs have serials like "DS000101"
@ -299,6 +306,17 @@ std::vector<RedumpVerifier::PotentialMatch> RedumpVerifier::ScanDatfile(const st
potential_match.hashes.sha1 = ParseHash(rom.attribute("sha1").value());
}
if (!serials_exist || !versions_exist)
{
// If we reach this, the user has most likely downloaded a datfile manually,
// so show a panic alert rather than just using ERROR_LOG
// i18n: "Serial" refers to serial numbers, e.g. RVL-RSBE-USA
PanicAlertT("Serial and/or version data is missing from %s", GetPathForSystem(system).c_str());
m_result = {Status::Error, Common::GetStringT("Failed to parse Redump.org data")};
return {};
}
return potential_matches;
}

View File

@ -88,7 +88,7 @@ private:
static DownloadStatus DownloadDatfile(const std::string& system, DownloadStatus old_status);
static std::vector<u8> ReadDatfile(const std::string& system);
std::vector<PotentialMatch> ScanDatfile(const std::vector<u8>& data);
std::vector<PotentialMatch> ScanDatfile(const std::vector<u8>& data, const std::string& system);
std::string m_game_id;
u16 m_revision;