diff --git a/CHANGELIST.md b/CHANGELIST.md index 2a7ede9b..f735a2a9 100644 --- a/CHANGELIST.md +++ b/CHANGELIST.md @@ -3,6 +3,7 @@ - Handle layers for PS3CFW - Further clarify configuration requirements for CLI - Ignore volume labels with path separators +- Reduce media-specific checks where unnecessary ### 3.3.2 (2025-06-12) diff --git a/MPF.Processors.Test/BaseProcessorTests.cs b/MPF.Processors.Test/BaseProcessorTests.cs index 3be1bc1d..596b4443 100644 --- a/MPF.Processors.Test/BaseProcessorTests.cs +++ b/MPF.Processors.Test/BaseProcessorTests.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using SabreTools.Models.Logiqx; using Xunit; namespace MPF.Processors.Test @@ -85,6 +86,43 @@ namespace MPF.Processors.Test #endregion + #region GenerateDatafile + + [Fact] + public void GenerateDatafile_Empty_Null() + { + string iso = string.Empty; + Datafile? actual = BaseProcessor.GenerateDatafile(iso); + Assert.Null(actual); + } + + [Fact] + public void GenerateDatafile_Invalid_Null() + { + string iso = "INVALID"; + Datafile? actual = BaseProcessor.GenerateDatafile(iso); + Assert.Null(actual); + } + + [Fact] + public void GenerateDatafile_Valid_Filled() + { + string iso = Path.Combine(Environment.CurrentDirectory, "TestData", "PS3CFW", "BluRay", "test.iso"); + var actual = BaseProcessor.GenerateDatafile(iso); + + Assert.NotNull(actual); + Assert.NotNull(actual.Game); + var game = Assert.Single(actual.Game); + Assert.NotNull(game.Rom); + var rom = Assert.Single(game.Rom); + Assert.Equal("9", rom.Size); + Assert.Equal("560b9f59", rom.CRC); + Assert.Equal("edbb6676247e65c2245dd4883ed9fc24", rom.MD5); + Assert.Equal("1b33ad54d78085be5ecb1cf1b3e9da821e708075", rom.SHA1); + } + + #endregion + #region GetPIC [Fact] diff --git a/MPF.Processors.Test/PS3CFWTests.cs b/MPF.Processors.Test/PS3CFWTests.cs index e37f58c9..6026b65b 100644 --- a/MPF.Processors.Test/PS3CFWTests.cs +++ b/MPF.Processors.Test/PS3CFWTests.cs @@ -174,42 +174,5 @@ namespace MPF.Processors.Test } #endregion - - #region GeneratePS3CFWDatafile - - [Fact] - public void GeneratePS3CFWDatafile_Empty_Null() - { - string iso = string.Empty; - Datafile? actual = PS3CFW.GeneratePS3CFWDatafile(iso); - Assert.Null(actual); - } - - [Fact] - public void GeneratePS3CFWDatafile_Invalid_Null() - { - string iso = "INVALID"; - Datafile? actual = PS3CFW.GeneratePS3CFWDatafile(iso); - Assert.Null(actual); - } - - [Fact] - public void GeneratePS3CFWDatafile_Valid_Filled() - { - string iso = Path.Combine(Environment.CurrentDirectory, "TestData", "PS3CFW", "BluRay", "test.iso"); - var actual = PS3CFW.GeneratePS3CFWDatafile(iso); - - Assert.NotNull(actual); - Assert.NotNull(actual.Game); - var game = Assert.Single(actual.Game); - Assert.NotNull(game.Rom); - var rom = Assert.Single(game.Rom); - Assert.Equal("9", rom.Size); - Assert.Equal("560b9f59", rom.CRC); - Assert.Equal("edbb6676247e65c2245dd4883ed9fc24", rom.MD5); - Assert.Equal("1b33ad54d78085be5ecb1cf1b3e9da821e708075", rom.SHA1); - } - - #endregion } } \ No newline at end of file diff --git a/MPF.Processors/Aaru.cs b/MPF.Processors/Aaru.cs index 5e5a107c..a275889d 100644 --- a/MPF.Processors/Aaru.cs +++ b/MPF.Processors/Aaru.cs @@ -36,10 +36,10 @@ namespace MPF.Processors info = Builder.EnsureAllSections(info); // TODO: Determine if there's an Aaru version anywhere - info.DumpingInfo!.DumpingDate = ProcessingTool.GetFileModifiedDate(basePath + ".cicm.xml")?.ToString("yyyy-MM-dd HH:mm:ss"); + info.DumpingInfo!.DumpingDate = ProcessingTool.GetFileModifiedDate($"{basePath}.cicm.xml")?.ToString("yyyy-MM-dd HH:mm:ss"); // Deserialize the sidecar, if possible - var sidecar = GenerateSidecar(basePath + ".cicm.xml"); + var sidecar = GenerateSidecar($"{basePath}.cicm.xml"); // Fill in the hardware data if (GetHardwareInfo(sidecar, out var manufacturer, out var model, out var firmware)) @@ -63,31 +63,29 @@ namespace MPF.Processors info.DumpingInfo.ReportedDiscType = fullDiscType; } + // TODO: Re-enable once PVD generation / finding is fixed + // Generate / obtain the PVD + //info.Extras.PVD = GeneratePVD(sidecar) ?? "Disc has no PVD"; + // Get the Datafile information var datafile = GenerateDatafile(sidecar, basePath); - - // Fill in the hash data info.TracksAndWriteOffsets!.ClrMameProData = ProcessingTool.GenerateDatfile(datafile); + // Get the error count + long errorCount = GetErrorCount($"{basePath}.resume.xml"); + info.CommonDiscInfo!.ErrorsCount = (errorCount == -1 ? "Error retrieving error count" : errorCount.ToString()); + + // Get the write offset, if it exists + string? writeOffset = GetWriteOffset(sidecar); + info.CommonDiscInfo.RingWriteOffset = writeOffset; + info.TracksAndWriteOffsets.OtherWriteOffsets = writeOffset; + + // Extract info based generically on MediaType switch (Type) { // TODO: Can this do GD-ROM? case MediaType.CDROM: - // TODO: Re-enable once PVD generation / finding is fixed - // Generate / obtain the PVD - //info.Extras.PVD = GeneratePVD(sidecar) ?? "Disc has no PVD"; - - long errorCount = -1; - if (File.Exists(basePath + ".resume.xml")) - errorCount = GetErrorCount(basePath + ".resume.xml"); - - info.CommonDiscInfo!.ErrorsCount = (errorCount == -1 ? "Error retrieving error count" : errorCount.ToString()); - info.TracksAndWriteOffsets.Cuesheet = GenerateCuesheet(sidecar, basePath) ?? string.Empty; - - string cdWriteOffset = GetWriteOffset(sidecar) ?? string.Empty; - info.CommonDiscInfo.RingWriteOffset = cdWriteOffset; - info.TracksAndWriteOffsets.OtherWriteOffsets = cdWriteOffset; break; case MediaType.DVD: @@ -103,10 +101,7 @@ namespace MPF.Processors info.SizeAndChecksums.SHA1 = sha1; } - // TODO: Re-enable once PVD generation / finding is fixed - // Generate / obtain the PVD - //info.Extras.PVD = GeneratePVD(sidecar) ?? "Disc has no PVD"; - + // TODO: Sync layerbreak finding with other processors // Deal with the layerbreak string? layerbreak = null; if (Type == MediaType.DVD) diff --git a/MPF.Processors/BaseProcessor.cs b/MPF.Processors/BaseProcessor.cs index 18efcf14..e1eb2831 100644 --- a/MPF.Processors/BaseProcessor.cs +++ b/MPF.Processors/BaseProcessor.cs @@ -5,6 +5,8 @@ using System.IO; using System.IO.Compression; #endif using System.Text; +using SabreTools.Hashing; +using SabreTools.Models.Logiqx; using SabreTools.RedumpLib.Data; namespace MPF.Processors @@ -520,6 +522,38 @@ namespace MPF.Processors #region Shared Methods + /// + /// Generate a CMP XML datfile string based on a single input file + /// + /// File to generate a datfile for + /// Datafile containing the hash information, null on error + internal static Datafile? GenerateDatafile(string file) + { + // If the file is invalid + if (string.IsNullOrEmpty(file)) + return null; + if (!File.Exists(file)) + return null; + + // Attempt to get the hashes + if (!HashTool.GetStandardHashes(file, out long size, out var crc32, out var md5, out var sha1)) + return null; + + // Generate and return the Datafile + var rom = new Rom + { + Name = string.Empty, + Size = size.ToString(), + CRC = crc32, + MD5 = md5, + SHA1 = sha1, + }; + var game = new Game { Rom = [rom] }; + var datafile = new Datafile { Game = [game] }; + + return datafile; + } + /// /// Get the hex contents of the PIC file /// diff --git a/MPF.Processors/CleanRip.cs b/MPF.Processors/CleanRip.cs index 2011db06..ea5e84b5 100644 --- a/MPF.Processors/CleanRip.cs +++ b/MPF.Processors/CleanRip.cs @@ -25,10 +25,10 @@ namespace MPF.Processors info = Builder.EnsureAllSections(info); // TODO: Determine if there's a CleanRip version anywhere - info.DumpingInfo!.DumpingDate = ProcessingTool.GetFileModifiedDate(basePath + "-dumpinfo.txt")?.ToString("yyyy-MM-dd HH:mm:ss"); + info.DumpingInfo!.DumpingDate = ProcessingTool.GetFileModifiedDate($"{basePath}-dumpinfo.txt")?.ToString("yyyy-MM-dd HH:mm:ss"); // Get the Datafile information - var datafile = GenerateCleanripDatafile(basePath + ".iso", basePath + "-dumpinfo.txt"); + var datafile = GenerateCleanripDatafile($"{basePath}.iso", $"{basePath}-dumpinfo.txt"); info.TracksAndWriteOffsets!.ClrMameProData = ProcessingTool.GenerateDatfile(datafile); // Get the individual hash data, as per internal @@ -44,27 +44,19 @@ namespace MPF.Processors info.SizeAndChecksums.Layerbreak = 2084960; } - // Extract info based generically on MediaType - switch (Type) + // Get BCA information, if available + info.Extras!.BCA = GetBCA(basePath + $"{basePath}.bca"); + + // Get internal information + if (GetGameCubeWiiInformation(basePath + $"{basePath}-dumpinfo.txt", out Region? region, out var version, out var internalName, out var serial)) { - case MediaType.DVD: // Only added here to help users; not strictly correct - case MediaType.NintendoGameCubeGameDisc: - case MediaType.NintendoWiiOpticalDisc: - if (File.Exists(basePath + ".bca")) - info.Extras!.BCA = GetBCA(basePath + ".bca"); - - if (GetGameCubeWiiInformation(basePath + "-dumpinfo.txt", out Region? gcRegion, out var gcVersion, out var gcName, out var gcSerial)) - { - info.CommonDiscInfo!.CommentsSpecialFields![SiteCode.InternalName] = gcName ?? string.Empty; - info.CommonDiscInfo.CommentsSpecialFields![SiteCode.InternalSerialName] = gcSerial ?? string.Empty; - if (!redumpCompat) - { - info.VersionAndEditions!.Version = gcVersion ?? info.VersionAndEditions.Version; - info.CommonDiscInfo.Region = gcRegion ?? info.CommonDiscInfo.Region; - } - } - - break; + info.CommonDiscInfo!.CommentsSpecialFields![SiteCode.InternalName] = internalName ?? string.Empty; + info.CommonDiscInfo.CommentsSpecialFields![SiteCode.InternalSerialName] = serial ?? string.Empty; + if (!redumpCompat) + { + info.VersionAndEditions!.Version = version ?? info.VersionAndEditions.Version; + info.CommonDiscInfo.Region = region ?? info.CommonDiscInfo.Region; + } } } diff --git a/MPF.Processors/DiscImageCreator.cs b/MPF.Processors/DiscImageCreator.cs index 23d69a88..671ac2d5 100644 --- a/MPF.Processors/DiscImageCreator.cs +++ b/MPF.Processors/DiscImageCreator.cs @@ -94,12 +94,23 @@ namespace MPF.Processors if (GetDiscType($"{basePath}_disc.txt", out var discTypeOrBookType)) info.DumpingInfo.ReportedDiscType = discTypeOrBookType; + // Get the PVD, if it exists + info.Extras!.PVD = GetPVD($"{basePath}_mainInfo.txt") ?? "Disc has no PVD"; + // Get the Datafile information var datafile = ProcessingTool.GetDatafile($"{basePath}.dat"); - - // Fill in the hash data info.TracksAndWriteOffsets!.ClrMameProData = ProcessingTool.GenerateDatfile(datafile); + // Get the write offset, if it exists + string? writeOffset = GetWriteOffset($"{basePath}_disc.txt"); + info.CommonDiscInfo!.RingWriteOffset = writeOffset; + info.TracksAndWriteOffsets.OtherWriteOffsets = writeOffset; + + // Attempt to get multisession data + string? multiSessionInfo = GetMultisessionInformation($"{basePath}_disc.txt"); + if (!string.IsNullOrEmpty(multiSessionInfo)) + info.CommonDiscInfo.CommentsSpecialFields![SiteCode.Multisession] = multiSessionInfo!; + // Fill in the volume labels if (GetVolumeLabels($"{basePath}_volDesc.txt", out var volLabels)) VolumeLabels = volLabels; @@ -109,8 +120,6 @@ namespace MPF.Processors { case MediaType.CDROM: case MediaType.GDROM: // TODO: Verify GD-ROM outputs this - info.Extras!.PVD = GetPVD($"{basePath}_mainInfo.txt") ?? "Disc has no PVD"; - // Audio-only discs will fail if there are any C2 errors, so they would never get here if (System.IsAudio()) { @@ -128,18 +137,6 @@ namespace MPF.Processors } info.TracksAndWriteOffsets.Cuesheet = ProcessingTool.GetFullFile($"{basePath}.cue") ?? string.Empty; - //var cueSheet = new CueSheet($"{basePath}.cue"); // TODO: Do something with this - - // Attempt to get the write offset - string cdWriteOffset = GetWriteOffset($"{basePath}_disc.txt") ?? string.Empty; - info.CommonDiscInfo.RingWriteOffset = cdWriteOffset; - info.TracksAndWriteOffsets.OtherWriteOffsets = cdWriteOffset; - - // Attempt to get multisession data - string cdMultiSessionInfo = GetMultisessionInformation($"{basePath}_disc.txt") ?? string.Empty; - if (!string.IsNullOrEmpty(cdMultiSessionInfo)) - info.CommonDiscInfo.CommentsSpecialFields![SiteCode.Multisession] = cdMultiSessionInfo; - break; case MediaType.DVD: @@ -178,9 +175,6 @@ namespace MPF.Processors } } - // Read the PVD - info.Extras!.PVD = GetPVD($"{basePath}_mainInfo.txt") ?? string.Empty; - // Bluray-specific options if (Type == MediaType.BluRay) { diff --git a/MPF.Processors/PS3CFW.cs b/MPF.Processors/PS3CFW.cs index 5b228b7f..d2bdc99b 100644 --- a/MPF.Processors/PS3CFW.cs +++ b/MPF.Processors/PS3CFW.cs @@ -1,6 +1,5 @@ using System.Collections.Generic; using System.IO; -using SabreTools.Hashing; using SabreTools.Models.Logiqx; using SabreTools.RedumpLib; using SabreTools.RedumpLib.Data; @@ -34,9 +33,7 @@ namespace MPF.Processors info.DumpingInfo!.DumpingDate = ProcessingTool.GetFileModifiedDate(isoPath)?.ToString("yyyy-MM-dd HH:mm:ss"); // Get the Datafile information - Datafile? datafile = GeneratePS3CFWDatafile(isoPath); - - // Fill in the hash data + Datafile? datafile = GenerateDatafile(isoPath); info.TracksAndWriteOffsets!.ClrMameProData = ProcessingTool.GenerateDatfile(datafile); // Get the individual hash data, as per internal @@ -159,40 +156,5 @@ namespace MPF.Processors } #endregion - - #region Information Extraction Methods - - /// - /// Get a formatted datfile from the PS3 CFW output, if possible - /// - /// Path to ISO file - /// - internal static Datafile? GeneratePS3CFWDatafile(string iso) - { - // If the ISO file doesn't exist - if (string.IsNullOrEmpty(iso)) - return null; - if (!File.Exists(iso)) - return null; - - try - { - if (HashTool.GetStandardHashes(iso, out long size, out string? crc, out string? md5, out string? sha1)) - { - return new Datafile - { - Game = [new Game { Rom = [new Rom { Name = Path.GetFileName(iso), Size = size.ToString(), CRC = crc, MD5 = md5, SHA1 = sha1 }] }] - }; - } - return null; - } - catch - { - // We don't care what the exception is right now - return null; - } - } - - #endregion } } diff --git a/MPF.Processors/Redumper.cs b/MPF.Processors/Redumper.cs index 046bd54e..68ecaaf2 100644 --- a/MPF.Processors/Redumper.cs +++ b/MPF.Processors/Redumper.cs @@ -46,22 +46,32 @@ namespace MPF.Processors if (GetDiscType($"{basePath}.log", out var discTypeOrBookType)) info.DumpingInfo.ReportedDiscType = discTypeOrBookType; + // Get the PVD, if it exists + info.Extras!.PVD = GetPVD($"{basePath}.log") ?? "Disc has no PVD"; + + // Get the Datafile information + info.TracksAndWriteOffsets!.ClrMameProData = GetDatfile($"{basePath}.log"); + + // Get the write offset, if it exists + string? writeOffset = GetWriteOffset($"{basePath}.log"); + info.CommonDiscInfo!.RingWriteOffset = writeOffset; + info.TracksAndWriteOffsets.OtherWriteOffsets = writeOffset; + + // Attempt to get multisession data + string? multiSessionInfo = GetMultisessionInformation($"{basePath}.log"); + if (!string.IsNullOrEmpty(multiSessionInfo)) + info.CommonDiscInfo.CommentsSpecialFields![SiteCode.Multisession] = multiSessionInfo!; + // Fill in the volume labels if (GetVolumeLabels($"{basePath}.log", out var volLabels)) VolumeLabels = volLabels; + // Extract info based generically on MediaType switch (Type) { case MediaType.CDROM: - info.Extras!.PVD = GetPVD($"{basePath}.log") ?? "Disc has no PVD"; - info.TracksAndWriteOffsets!.ClrMameProData = GetDatfile($"{basePath}.log"); info.TracksAndWriteOffsets.Cuesheet = ProcessingTool.GetFullFile($"{basePath}.cue") ?? string.Empty; - // Attempt to get the write offset - string cdWriteOffset = GetWriteOffset($"{basePath}.log") ?? string.Empty; - info.CommonDiscInfo!.RingWriteOffset = cdWriteOffset; - info.TracksAndWriteOffsets.OtherWriteOffsets = cdWriteOffset; - // Attempt to get the error count if (GetErrorCount($"{basePath}.log", out long redumpErrors, out long c2Errors)) { @@ -69,11 +79,6 @@ namespace MPF.Processors info.DumpingInfo.C2ErrorsCount = (c2Errors == -1 ? "Error retrieving error count" : c2Errors.ToString()); } - // Attempt to get multisession data - string? cdMultiSessionInfo = GetMultisessionInformation($"{basePath}.log"); - if (!string.IsNullOrEmpty(cdMultiSessionInfo)) - info.CommonDiscInfo.CommentsSpecialFields![SiteCode.Multisession] = cdMultiSessionInfo!; - // Attempt to get extra metadata if it's an audio disc if (IsAudio(info.TracksAndWriteOffsets.Cuesheet)) { @@ -95,9 +100,6 @@ namespace MPF.Processors case MediaType.NintendoGameCubeGameDisc: case MediaType.NintendoWiiOpticalDisc: case MediaType.NintendoWiiUOpticalDisc: - info.Extras!.PVD = GetPVD($"{basePath}.log") ?? "Disc has no PVD"; - info.TracksAndWriteOffsets!.ClrMameProData = GetDatfile($"{basePath}.log"); - // Get the individual hash data, as per internal if (ProcessingTool.GetISOHashValues(info.TracksAndWriteOffsets.ClrMameProData, out long size, out var crc32, out var md5, out var sha1)) { diff --git a/MPF.Processors/UmdImageCreator.cs b/MPF.Processors/UmdImageCreator.cs index f716fa7a..cbe71a8d 100644 --- a/MPF.Processors/UmdImageCreator.cs +++ b/MPF.Processors/UmdImageCreator.cs @@ -25,55 +25,51 @@ namespace MPF.Processors info = Builder.EnsureAllSections(info); // TODO: Determine if there's a UMDImageCreator version anywhere - info.DumpingInfo!.DumpingDate = ProcessingTool.GetFileModifiedDate(basePath + "_disc.txt")?.ToString("yyyy-MM-dd HH:mm:ss"); + info.DumpingInfo!.DumpingDate = ProcessingTool.GetFileModifiedDate($"{basePath}_disc.txt")?.ToString("yyyy-MM-dd HH:mm:ss"); + + // Get the PVD, if it exists + info.Extras!.PVD = GetPVD($"{basePath}_mainInfo.txt") ?? string.Empty; + + // Get the Datafile information + if (HashTool.GetStandardHashes($"{basePath}.iso", out long filesize, out var crc32, out var md5, out var sha1)) + { + // Create a Datafile from the hashes + var datafile = new Datafile + { + Game = [new Game { Rom = [new Rom { Name = string.Empty, Size = filesize.ToString(), CRC = crc32, MD5 = md5, SHA1 = sha1 }] }] + }; + + // Fill in the hash data + info.TracksAndWriteOffsets!.ClrMameProData = ProcessingTool.GenerateDatfile(datafile); + + info.SizeAndChecksums!.Size = filesize; + info.SizeAndChecksums.CRC32 = crc32; + info.SizeAndChecksums.MD5 = md5; + info.SizeAndChecksums.SHA1 = sha1; + } + + // Get internal information + if (GetUMDAuxInfo($"{basePath}_disc.txt", + out var title, + out DiscCategory? category, + out string? serial, + out var version, + out var layer, + out long size)) + { + info.CommonDiscInfo!.Title = title ?? string.Empty; + info.CommonDiscInfo.Category = category ?? DiscCategory.Games; + info.CommonDiscInfo.CommentsSpecialFields![SiteCode.InternalSerialName] = serial ?? string.Empty; + info.VersionAndEditions!.Version = version ?? string.Empty; + info.SizeAndChecksums!.Size = size; + + if (!string.IsNullOrEmpty(layer)) + info.SizeAndChecksums.Layerbreak = long.Parse(layer ?? "-1"); + } // Fill in the volume labels if (GetVolumeLabels($"{basePath}_volDesc.txt", out var volLabels)) VolumeLabels = volLabels; - - // Extract info based generically on MediaType - switch (Type) - { - case MediaType.UMD: - info.Extras!.PVD = GetPVD(basePath + "_mainInfo.txt") ?? string.Empty; - - if (HashTool.GetStandardHashes(basePath + ".iso", out long filesize, out var crc32, out var md5, out var sha1)) - { - // Get the Datafile information - var datafile = new Datafile - { - Game = [new Game { Rom = [new Rom { Name = string.Empty, Size = filesize.ToString(), CRC = crc32, MD5 = md5, SHA1 = sha1 }] }] - }; - - // Fill in the hash data - info.TracksAndWriteOffsets!.ClrMameProData = ProcessingTool.GenerateDatfile(datafile); - - info.SizeAndChecksums!.Size = filesize; - info.SizeAndChecksums.CRC32 = crc32; - info.SizeAndChecksums.MD5 = md5; - info.SizeAndChecksums.SHA1 = sha1; - } - - if (GetUMDAuxInfo(basePath + "_disc.txt", - out var title, - out DiscCategory? category, - out string? serial, - out var version, - out var layer, - out long size)) - { - info.CommonDiscInfo!.Title = title ?? string.Empty; - info.CommonDiscInfo.Category = category ?? DiscCategory.Games; - info.CommonDiscInfo.CommentsSpecialFields![SiteCode.InternalSerialName] = serial ?? string.Empty; - info.VersionAndEditions!.Version = version ?? string.Empty; - info.SizeAndChecksums!.Size = size; - - if (!string.IsNullOrEmpty(layer)) - info.SizeAndChecksums.Layerbreak = long.Parse(layer ?? "-1"); - } - - break; - } } /// diff --git a/MPF.Processors/XboxBackupCreator.cs b/MPF.Processors/XboxBackupCreator.cs index 7ce965a2..056e5f02 100644 --- a/MPF.Processors/XboxBackupCreator.cs +++ b/MPF.Processors/XboxBackupCreator.cs @@ -38,112 +38,97 @@ namespace MPF.Processors info.DumpingInfo.DumpingDate = ProcessingTool.GetFileModifiedDate(logPath)?.ToString("yyyy-MM-dd HH:mm:ss"); info.DumpingInfo.Model = GetDrive(logPath) ?? "Unknown Drive"; + // Get the Datafile information + Datafile? datafile = GenerateDatafile($"{basePath}.iso"); + info.TracksAndWriteOffsets!.ClrMameProData = ProcessingTool.GenerateDatfile(datafile); + + // Get the individual hash data, as per internal + if (ProcessingTool.GetISOHashValues(datafile, out long size, out var crc32, out var md5, out var sha1)) + { + info.SizeAndChecksums!.Size = size; + info.SizeAndChecksums.CRC32 = crc32; + info.SizeAndChecksums.MD5 = md5; + info.SizeAndChecksums.SHA1 = sha1; + } + + // Get Layerbreak from .dvd file if possible + if (GetLayerbreak($"{basePath}.dvd", out long layerbreak)) + info.SizeAndChecksums!.Layerbreak = layerbreak; + // Look for read errors if (GetReadErrors(logPath, out long readErrors)) info.CommonDiscInfo!.ErrorsCount = readErrors == -1 ? "Error retrieving error count" : readErrors.ToString(); - // Extract info based generically on MediaType - switch (Type) + switch (System) { - case MediaType.DVD: - - // Get Layerbreak from .dvd file if possible - if (GetLayerbreak($"{basePath}.dvd", out long layerbreak)) - info.SizeAndChecksums!.Layerbreak = layerbreak; - - // Hash data - if (HashTool.GetStandardHashes(basePath + ".iso", out long filesize, out var crc32, out var md5, out var sha1)) + case RedumpSystem.MicrosoftXbox: + string xmidString = ProcessingTool.GetXMID(Path.Combine(outputDirectory, "DMI.bin")); + var xmid = SabreTools.Serialization.Wrappers.XMID.Create(xmidString); + if (xmid != null) { - // Get the Datafile information - var datafile = new Datafile + info.CommonDiscInfo!.CommentsSpecialFields![SiteCode.XMID] = xmidString?.TrimEnd('\0') ?? string.Empty; + info.CommonDiscInfo.Serial = xmid.Serial ?? string.Empty; + if (!redumpCompat) { - Game = [new Game { Rom = [new Rom { Name = string.Empty, Size = filesize.ToString(), CRC = crc32, MD5 = md5, SHA1 = sha1 }] }] - }; - - // Fill in the hash data - info.TracksAndWriteOffsets!.ClrMameProData = ProcessingTool.GenerateDatfile(datafile); - - info.SizeAndChecksums!.Size = filesize; - info.SizeAndChecksums.CRC32 = crc32; - info.SizeAndChecksums.MD5 = md5; - info.SizeAndChecksums.SHA1 = sha1; + info.VersionAndEditions!.Version = xmid.Version ?? string.Empty; + info.CommonDiscInfo.Region = ProcessingTool.GetXGDRegion(xmid.Model.RegionIdentifier); + } } - switch (System) + break; + + case RedumpSystem.MicrosoftXbox360: + + // Get PVD from ISO + if (GetPVD($"{basePath}.iso", out string? pvd)) + info.Extras!.PVD = pvd; + + // Parse Media ID + //string? mediaID = GetMediaID(logPath); + + // Parse DMI.bin + string xemidString = ProcessingTool.GetXeMID(Path.Combine(outputDirectory, "DMI.bin")); + var xemid = SabreTools.Serialization.Wrappers.XeMID.Create(xemidString); + if (xemid != null) { - case RedumpSystem.MicrosoftXbox: + info.CommonDiscInfo!.CommentsSpecialFields![SiteCode.XeMID] = xemidString?.TrimEnd('\0') ?? string.Empty; + info.CommonDiscInfo.Serial = xemid.Serial ?? string.Empty; + if (!redumpCompat) + info.VersionAndEditions!.Version = xemid.Version ?? string.Empty; - // Parse DMI.bin - string xmidString = ProcessingTool.GetXMID(Path.Combine(outputDirectory, "DMI.bin")); - var xmid = SabreTools.Serialization.Wrappers.XMID.Create(xmidString); - if (xmid != null) - { - info.CommonDiscInfo!.CommentsSpecialFields![SiteCode.XMID] = xmidString?.TrimEnd('\0') ?? string.Empty; - info.CommonDiscInfo.Serial = xmid.Serial ?? string.Empty; - if (!redumpCompat) - { - info.VersionAndEditions!.Version = xmid.Version ?? string.Empty; - info.CommonDiscInfo.Region = ProcessingTool.GetXGDRegion(xmid.Model.RegionIdentifier); - } - } - - break; - - case RedumpSystem.MicrosoftXbox360: - - // Get PVD from ISO - if (GetPVD(basePath + ".iso", out string? pvd)) - info.Extras!.PVD = pvd; - - // Parse Media ID - //string? mediaID = GetMediaID(logPath); - - // Parse DMI.bin - string xemidString = ProcessingTool.GetXeMID(Path.Combine(outputDirectory, "DMI.bin")); - var xemid = SabreTools.Serialization.Wrappers.XeMID.Create(xemidString); - if (xemid != null) - { - info.CommonDiscInfo!.CommentsSpecialFields![SiteCode.XeMID] = xemidString?.TrimEnd('\0') ?? string.Empty; - info.CommonDiscInfo.Serial = xemid.Serial ?? string.Empty; - if (!redumpCompat) - info.VersionAndEditions!.Version = xemid.Version ?? string.Empty; - - info.CommonDiscInfo.Region = ProcessingTool.GetXGDRegion(xemid.Model.RegionIdentifier); - } - - break; + info.CommonDiscInfo.Region = ProcessingTool.GetXGDRegion(xemid.Model.RegionIdentifier); } - // Get the output file paths - string dmiPath = Path.Combine(outputDirectory, "DMI.bin"); - string pfiPath = Path.Combine(outputDirectory, "PFI.bin"); - string ssPath = Path.Combine(outputDirectory, "SS.bin"); - - // Deal with SS.bin - if (File.Exists(ssPath)) - { - // Save security sector ranges - string? ranges = ProcessingTool.GetSSRanges(ssPath); - if (!string.IsNullOrEmpty(ranges)) - info.Extras!.SecuritySectorRanges = ranges; - - // Recreate RawSS.bin - RecreateSS(logPath!, ssPath, Path.Combine(outputDirectory, "RawSS.bin")); - - // Run ss_sector_range to get repeatable SS hash - ProcessingTool.CleanSS(ssPath, ssPath); - } - - // DMI/PFI/SS CRC32 hashes - if (File.Exists(dmiPath)) - info.CommonDiscInfo!.CommentsSpecialFields![SiteCode.DMIHash] = HashTool.GetFileHash(dmiPath, HashType.CRC32)?.ToUpperInvariant() ?? string.Empty; - if (File.Exists(pfiPath)) - info.CommonDiscInfo!.CommentsSpecialFields![SiteCode.PFIHash] = HashTool.GetFileHash(pfiPath, HashType.CRC32)?.ToUpperInvariant() ?? string.Empty; - if (File.Exists(ssPath)) - info.CommonDiscInfo!.CommentsSpecialFields![SiteCode.SSHash] = HashTool.GetFileHash(ssPath, HashType.CRC32)?.ToUpperInvariant() ?? string.Empty; - break; } + + // Get the output file paths + string dmiPath = Path.Combine(outputDirectory, "DMI.bin"); + string pfiPath = Path.Combine(outputDirectory, "PFI.bin"); + string ssPath = Path.Combine(outputDirectory, "SS.bin"); + + // Deal with SS.bin + if (File.Exists(ssPath)) + { + // Save security sector ranges + string? ranges = ProcessingTool.GetSSRanges(ssPath); + if (!string.IsNullOrEmpty(ranges)) + info.Extras!.SecuritySectorRanges = ranges; + + // Recreate RawSS.bin + RecreateSS(logPath!, ssPath, Path.Combine(outputDirectory, "RawSS.bin")); + + // Run ss_sector_range to get repeatable SS hash + ProcessingTool.CleanSS(ssPath, ssPath); + } + + // DMI/PFI/SS CRC32 hashes + if (File.Exists(dmiPath)) + info.CommonDiscInfo!.CommentsSpecialFields![SiteCode.DMIHash] = HashTool.GetFileHash(dmiPath, HashType.CRC32)?.ToUpperInvariant() ?? string.Empty; + if (File.Exists(pfiPath)) + info.CommonDiscInfo!.CommentsSpecialFields![SiteCode.PFIHash] = HashTool.GetFileHash(pfiPath, HashType.CRC32)?.ToUpperInvariant() ?? string.Empty; + if (File.Exists(ssPath)) + info.CommonDiscInfo!.CommentsSpecialFields![SiteCode.SSHash] = HashTool.GetFileHash(ssPath, HashType.CRC32)?.ToUpperInvariant() ?? string.Empty; } /// @@ -160,7 +145,7 @@ namespace MPF.Processors | OutputFileFlags.Zippable, "dvd"), new($"{outputFilename}.iso", OutputFileFlags.Required), - + new("DMI.bin", OutputFileFlags.Required | OutputFileFlags.Binary | OutputFileFlags.Zippable,