Skip to content
Permalink
Browse files

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.
  • Loading branch information...
JosJuice committed Nov 2, 2019
1 parent a7d4be7 commit 56d37d773bee782d64e9eaa32e881d9c6941e72b
Showing with 21 additions and 3 deletions.
  1. +20 −2 Source/Core/DiscIO/VolumeVerifier.cpp
  2. +1 −1 Source/Core/DiscIO/VolumeVerifier.h
@@ -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;
}

@@ -88,7 +88,7 @@ class RedumpVerifier final

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;

0 comments on commit 56d37d7

Please sign in to comment.
You can’t perform that action at this time.