diff --git a/CHANGELIST.md b/CHANGELIST.md index 67807607..09a48458 100644 --- a/CHANGELIST.md +++ b/CHANGELIST.md @@ -31,6 +31,7 @@ - Add datafile models - Add datafile helper method - Start migrating to datafile serialization +- Prepare for future DIC changes ### 2.5 (2023-03-12) diff --git a/MPF.Modules/BaseParameters.cs b/MPF.Modules/BaseParameters.cs index f5b35684..12955b3b 100644 --- a/MPF.Modules/BaseParameters.cs +++ b/MPF.Modules/BaseParameters.cs @@ -1279,6 +1279,8 @@ namespace MPF.Modules if (string.IsNullOrWhiteSpace(hashData)) return false; + // TODO: Use deserialization to Rom instead of Regex + Regex hashreg = new Regex(@" + /// Get the XGD auxiliary hash info from the outputted files, if possible + /// + /// Datafile representing the supplementary hashes + /// Extracted DMI.bin CRC32 hash (upper-cased) + /// Extracted PFI.bin CRC32 hash (upper-cased) + /// Extracted SS.bin CRC32 hash (upper-cased) + /// True on successful extraction of info, false otherwise + /// Currently only the CRC32 values are returned for each, this may change in the future + private static bool GetXGDAuxHashInfo(Datafile suppl, out string dmihash, out string pfihash, out string sshash) + { + // Assign values to all outputs first + dmihash = null; pfihash = null; sshash = null; + + // If we don't have a valid datafile, we can't do anything + if (suppl == null || suppl.Games.Length == 0 || suppl.Games[0].Roms.Length == 0) + return false; + + // Try to extract the hash information + var roms = suppl.Games[0].Roms; + dmihash = roms.FirstOrDefault(r => r.Name == "DMI.bin")?.Crc?.ToUpperInvariant(); + pfihash = roms.FirstOrDefault(r => r.Name == "PFI.bin")?.Crc?.ToUpperInvariant(); + sshash = roms.FirstOrDefault(r => r.Name == "SS.bin")?.Crc?.ToUpperInvariant(); + + return true; + } + /// /// Get the XGD auxiliary info from the outputted files, if possible /// @@ -3618,6 +3655,72 @@ namespace MPF.Modules.DiscImageCreator } } + /// + /// Get the XGD auxiliary security sector info from the outputted files, if possible + /// + /// _disc.txt file location + /// Extracted security sector data + /// Extracted security sector version + /// True on successful extraction of info, false otherwise + private static bool GetXGDAuxSSInfo(string disc, out string ss, out string ssver) + { + ss = null; ssver = null; + + // If the file doesn't exist, we can't get info from it + if (!File.Exists(disc)) + return false; + + // This flag is needed because recent versions of DIC include security data twice + bool foundSecuritySectors = false; + + using (StreamReader sr = File.OpenText(disc)) + { + try + { + while (!sr.EndOfStream) + { + string line = sr.ReadLine().Trim(); + + // Security Sector version + if (line.StartsWith("Version of challenge table")) + { + ssver = line.Split(' ')[4]; // "Version of challenge table: " + } + + // Security Sector ranges + else if (line.StartsWith("Number of security sector ranges:") && !foundSecuritySectors) + { + // Set the flag so we don't read duplicate data + foundSecuritySectors = true; + + Regex layerRegex = new Regex(@"Layer [01].*, startLBA-endLBA:\s*(\d+)-\s*(\d+)"); + + line = sr.ReadLine().Trim(); + while (!line.StartsWith("========== TotalLength ==========") + && !line.StartsWith("========== Unlock 2 state(wxripper) ==========")) + { + // If we have a recognized line format, parse it + if (line.StartsWith("Layer ")) + { + var match = layerRegex.Match(line); + ss += $"{match.Groups[1]}-{match.Groups[2]}\n"; + } + + line = sr.ReadLine().Trim(); + } + } + } + + return true; + } + catch + { + // We don't care what the exception is right now + return false; + } + } + } + /// /// Get the XGD1 Master ID (XMID) information ///