diff --git a/MPF.Frontend/Tools/PhysicalTool.cs b/MPF.Frontend/Tools/PhysicalTool.cs index bb39b5efd..f3db6df72 100644 --- a/MPF.Frontend/Tools/PhysicalTool.cs +++ b/MPF.Frontend/Tools/PhysicalTool.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Text; using System.Text.RegularExpressions; using Newtonsoft.Json; @@ -157,6 +158,266 @@ public static bool GetBusEncryptionEnabled(Drive? drive) #endregion + #region Computer + + /// + /// Get info for discs containing Steam2 (sis/sim/sid) depots + /// + /// Drive to extract information from + /// Steam2 information on success, null otherwise + public static string? GetSteamSimSidInfo(Drive? drive) + { + // If there's no drive path, we can't get any sis files + if (string.IsNullOrEmpty(drive?.Name)) + return null; + + // If the folder no longer exists, we can't get any information + if (!Directory.Exists(drive!.Name)) + return null; + + try + { + string? steamInfo = ""; + var steamDepotIdList = new List(); + + // ? needed due to note in https://learn.microsoft.com/en-us/dotnet/api/system.io.directory.getfiles +#if NETFRAMEWORK + string[] sisPaths = Directory.GetFiles(drive.Name, "?*.sis", SearchOption.AllDirectories); +#else + var options = new EnumerationOptions + { + MatchCasing = MatchCasing.CaseInsensitive, RecurseSubdirectories = true + }; + string[] sisPaths = Directory.GetFiles(drive.Name, "?*.sis", options); +#endif + + foreach (string sis in sisPaths) + { + if (!File.Exists(sis)) + continue; + + long sisSize = new FileInfo(sis).Length; + + // Arbitrary filesize cap, a disc would need over 100x the normal amount of depots to go over this. + if (sisSize > 10000) + continue; + + // Read the sku sis file + using var fileStream = new FileStream(sis, FileMode.Open, FileAccess.Read); + var skuSisDeserializer = new SabreTools.Serialization.Readers.SkuSis(); + var skuSis = skuSisDeserializer.Deserialize(fileStream); + + if (skuSis != null && skuSis.Sku != null) + { + var sku = skuSis.Sku; + + // Skips csm/csd sku sis files + if (sku.Manifests != null) + continue; + + // There should always be depots. + if (sku.Depots == null) + continue; + + steamDepotIdList.AddRange(sku.Depots.Values.ToList()); + } + } + + var sortedArray = steamDepotIdList.ToArray(); + Array.Sort(sortedArray); + +#if NET20 || NET35 + var compatibilitySortedArray = sortedArray.Select(x => x.ToString()).ToArray(); + steamInfo = string.Join("\n", compatibilitySortedArray); +#else + steamInfo = string.Join("\n", sortedArray); +#endif + + if (steamInfo == "") + return null; + else + return steamInfo; + } + catch + { + // Absorb the exception + return null; + } + } + + /// + /// Get info for discs containing Steam3 (sis/csm/csd) depots + /// + /// Drive to extract information from + /// Steam Csm/Csd information on success, null otherwise + public static string? GetSteamCsmCsdInfo(Drive? drive) + { + // If there's no drive path, we can't get exe name + if (string.IsNullOrEmpty(drive?.Name)) + return null; + + // If the folder no longer exists, we can't get any information + if (!Directory.Exists(drive!.Name)) + return null; + + try + { + string? steamInfo = ""; + var steamDepotIdDict = new SortedDictionary(); + + // ? needed due to note in https://learn.microsoft.com/en-us/dotnet/api/system.io.directory.getfiles +#if NETFRAMEWORK + string[] sisPaths = Directory.GetFiles(drive.Name, "?*.sis", SearchOption.AllDirectories); +#else + var options = new EnumerationOptions + { + MatchCasing = MatchCasing.CaseInsensitive, RecurseSubdirectories = true + }; + string[] sisPaths = Directory.GetFiles(drive.Name, "?*.sis", options); +#endif + + foreach (string sis in sisPaths) + { + if (!File.Exists(sis)) + continue; + + long sisSize = new FileInfo(sis).Length; + + // Arbitrary filesize cap, a disc would need over 100x the normal amount of depots to go over this. + if (sisSize > 10000) + continue; + + // Read the sku sis file + using var fileStream = new FileStream(sis, FileMode.Open, FileAccess.Read); + var skuSisDeserializer = new SabreTools.Serialization.Readers.SkuSis(); + var skuSis = skuSisDeserializer.Deserialize(fileStream); + + if (skuSis != null && skuSis.Sku != null) + { + var sku = skuSis.Sku; + + if (sku == null) + continue; + + // Skips steam2 sku sis files. Steam3 csm/csd sis files always have manifests. + if (sku.Manifests != null) + { + foreach (var depot in sku.Manifests) + { +#if NETFRAMEWORK + steamDepotIdDict.Add(depot.Key, depot.Value); // Always fine in practice. +#else + steamDepotIdDict.TryAdd(depot.Key, + depot.Value); // Mainly here to allow easier bulk testing. +#endif + } + } + } + } + + foreach (var depot in steamDepotIdDict) + { + steamInfo += $"{depot.Key} ({depot.Value})\n"; + } + + if (steamInfo == "") + return null; + else + return steamInfo; + } + catch + { + // Absorb the exception + return null; + } + } + + /// + /// Get info for discs containing Steam2 (sis/sim/sid) depots + /// + /// Drive to extract information from + /// Steam2 information on success, null otherwise + public static string? GetSteamAppInfo(Drive? drive) + { + // If there's no drive path, we can't get exe name + if (string.IsNullOrEmpty(drive?.Name)) + return null; + + // If the folder no longer exists, we can't get any information + if (!Directory.Exists(drive!.Name)) + return null; + + try + { + string? steamInfo = ""; + var steamAppIdList = new List(); + + // ? needed due to note in note in https://learn.microsoft.com/en-us/dotnet/api/system.io.directory.getfiles +#if NETFRAMEWORK + string[] sisPaths = Directory.GetFiles(drive.Name, "?*.sis", SearchOption.AllDirectories); +#else + var options = new EnumerationOptions + { + MatchCasing = MatchCasing.CaseInsensitive, RecurseSubdirectories = true + }; + string[] sisPaths = Directory.GetFiles(drive.Name, "?*.sis", options); +#endif + + // Looping needed in case i.e. this is a coverdisc with multiple steam game installers on it. + foreach (string sis in sisPaths) + { + if (!File.Exists(sis)) + continue; + + string filename = Path.GetFileName(sis); + + long sisSize = new FileInfo(sis).Length; + + // Arbitrary filesize cap, a disc would need over 100x the normal amount of depots to go over this. + if (sisSize > 10000) + continue; + + // Read the sku sis file + using var fileStream = new FileStream(sis, FileMode.Open, FileAccess.Read); + var skuSisDeserializer = new SabreTools.Serialization.Readers.SkuSis(); + var skuSis = skuSisDeserializer.Deserialize(fileStream); + + if (skuSis != null && skuSis.Sku != null) + { + var sku = skuSis.Sku; + + // There should always be apps + if (sku.Apps == null) + continue; + + steamAppIdList.AddRange(sku.Apps.Values.ToList()); + } + } + + var sortedArray = steamAppIdList.ToArray(); + Array.Sort(sortedArray); + +#if NET20 || NET35 + var compatibilitySortedArray = sortedArray.Select(x => x.ToString()).ToArray(); + steamInfo = string.Join(", ", compatibilitySortedArray); +#else + steamInfo = string.Join(", ", sortedArray); +#endif + + if (steamInfo == "") + return null; + else + return steamInfo; + } + catch + { + // Absorb the exception + return null; + } + } + + #endregion + #region PlayStation /// @@ -532,7 +793,8 @@ public static bool GetBusEncryptionEnabled(Drive? drive) { string? pkgInfo = ""; - string[] appDirs = Directory.GetDirectories(Path.Combine(drive.Name, "app"), "?????????", SearchOption.TopDirectoryOnly); + string[] appDirs = Directory.GetDirectories(Path.Combine(drive.Name, "app"), "?????????", + SearchOption.TopDirectoryOnly); foreach (string dir in appDirs) { @@ -683,7 +945,8 @@ public static bool GetBusEncryptionEnabled(Drive? drive) { string? pkgInfo = ""; - string[] appDirs = Directory.GetDirectories(Path.Combine(drive.Name, "app"), "?????????", SearchOption.TopDirectoryOnly); + string[] appDirs = Directory.GetDirectories(Path.Combine(drive.Name, "app"), "?????????", + SearchOption.TopDirectoryOnly); foreach (string dir in appDirs) { @@ -866,6 +1129,5 @@ public static bool GetBusEncryptionEnabled(Drive? drive) } #endregion - } } diff --git a/MPF.Frontend/Tools/SubmissionGenerator.cs b/MPF.Frontend/Tools/SubmissionGenerator.cs index 3fe8232e5..5d6f39344 100644 --- a/MPF.Frontend/Tools/SubmissionGenerator.cs +++ b/MPF.Frontend/Tools/SubmissionGenerator.cs @@ -71,7 +71,8 @@ internal static class SubmissionGenerator List missingFiles = processor.FoundAllFiles(mediaType, outputDirectory, outputFilename); if (missingFiles.Count > 0) { - resultProgress?.Report(ResultEventArgs.Failure($"There were files missing from the output:\n{string.Join("\n", [.. missingFiles])}\nThis may indicate an issue with the hardware or media, including unsupported devices.\nPlease see dumping program documentation for more details.")); + resultProgress?.Report(ResultEventArgs.Failure( + $"There were files missing from the output:\n{string.Join("\n", [.. missingFiles])}\nThis may indicate an issue with the hardware or media, including unsupported devices.\nPlease see dumping program documentation for more details.")); return null; } @@ -100,7 +101,8 @@ internal static class SubmissionGenerator // Add a placeholder for the logs link if not a verification if (!filledInfo) - info.CommonDiscInfo.CommentsSpecialFields[SiteCode.LogsLink] = "[Please provide a link to your logs here]"; + info.CommonDiscInfo.CommentsSpecialFields[SiteCode.LogsLink] = + "[Please provide a link to your logs here]"; } // If we have both ClrMamePro and Size and Checksums data, remove the ClrMamePro @@ -121,15 +123,19 @@ internal static class SubmissionGenerator // Run anti-modchip check, if necessary if (drive is not null && system.SupportsAntiModchipScans() && info.CopyProtection.AntiModchip == YesNo.NULL) { - resultProgress?.Report(ResultEventArgs.Success("Checking for anti-modchip strings... this might take a while!")); - info.CopyProtection.AntiModchip = await ProtectionTool.GetPlayStationAntiModchipDetected(drive?.Name) ? YesNo.Yes : YesNo.No; + resultProgress?.Report( + ResultEventArgs.Success("Checking for anti-modchip strings... this might take a while!")); + info.CopyProtection.AntiModchip = await ProtectionTool.GetPlayStationAntiModchipDetected(drive?.Name) + ? YesNo.Yes + : YesNo.No; resultProgress?.Report(ResultEventArgs.Success("Anti-modchip string scan complete!")); } // Run copy protection, if possible or necessary if (system.SupportsCopyProtectionScans()) { - resultProgress?.Report(ResultEventArgs.Success("Running copy protection scan... this might take a while!")); + resultProgress?.Report( + ResultEventArgs.Success("Running copy protection scan... this might take a while!")); try { @@ -138,9 +144,13 @@ internal static class SubmissionGenerator { // Explicitly note missing/invalid device paths if (drive?.Name is null) - resultProgress?.Report(ResultEventArgs.Success("No mounted device path found, protection outputs may be incomplete!")); + resultProgress?.Report( + ResultEventArgs.Success( + "No mounted device path found, protection outputs may be incomplete!")); - protections = await ProtectionTool.RunCombinedProtectionScans(basePath, drive, options, protectionProgress); + protections = + await ProtectionTool.RunCombinedProtectionScans(basePath, drive, options, + protectionProgress); } var protectionString = ProtectionTool.FormatProtections(protections, drive); @@ -196,12 +206,14 @@ public static async Task FillFromRedump(Options options, bool? loggedIn = await wc.Login(options.RedumpUsername!, options.RedumpPassword!); if (loggedIn is null) { - resultProgress?.Report(ResultEventArgs.Failure("There was an unknown error connecting to Redump, skipping...")); + resultProgress?.Report( + ResultEventArgs.Failure("There was an unknown error connecting to Redump, skipping...")); return false; } else if (loggedIn == false) { - resultProgress?.Report(ResultEventArgs.Failure("Provided Redump credentials were invalid, not using...")); + resultProgress?.Report( + ResultEventArgs.Failure("Provided Redump credentials were invalid, not using...")); } } @@ -302,14 +314,16 @@ public static async Task FillFromRedump(Options options, } // If we don't have any matches but we have a universal hash - if (info.PartiallyMatchedIDs.Count == 0 && info.CommonDiscInfo?.CommentsSpecialFields?.ContainsKey(SiteCode.UniversalHash) == true) + if (info.PartiallyMatchedIDs.Count == 0 && + info.CommonDiscInfo?.CommentsSpecialFields?.ContainsKey(SiteCode.UniversalHash) == true) { string sha1 = info.CommonDiscInfo.CommentsSpecialFields[SiteCode.UniversalHash]; var foundIds = await Validator.ValidateUniversalHash(wc, info); if (foundIds is not null && foundIds.Count == 1) resultProgress?.Report(ResultEventArgs.Success($"Single match found for universal hash {sha1}")); else if (foundIds is not null && foundIds.Count != 1) - resultProgress?.Report(ResultEventArgs.Success($"Multiple matches found for universal hash {sha1}")); + resultProgress?.Report( + ResultEventArgs.Success($"Multiple matches found for universal hash {sha1}")); else resultProgress?.Report(ResultEventArgs.Failure($"No matches found for universal hash {sha1}")); @@ -332,9 +346,14 @@ public static async Task FillFromRedump(Options options, info.PartiallyMatchedIDs = [.. partiallyMatchedIds]; info.PartiallyMatchedIDs.Sort(); - resultProgress?.Report(ResultEventArgs.Success("Match finding complete! " + (fullyMatchedIdsList is not null && fullyMatchedIdsList.Count > 0 - ? "Fully Matched IDs: " + string.Join(",", [.. fullyMatchedIdsList.ConvertAll(i => i.ToString())]) - : "No matches found"))); + resultProgress?.Report(ResultEventArgs.Success("Match finding complete! " + + (fullyMatchedIdsList is not null && + fullyMatchedIdsList.Count > 0 + ? "Fully Matched IDs: " + string.Join(",", + [ + .. fullyMatchedIdsList.ConvertAll(i => i.ToString()) + ]) + : "No matches found"))); // Exit early if one failed or there are no matched IDs if (!allFound || fullyMatchedIdsList is null || fullyMatchedIdsList.Count == 0) @@ -349,7 +368,8 @@ public static async Task FillFromRedump(Options options, continue; // Fill in the fields from the existing ID - resultProgress?.Report(ResultEventArgs.Success($"Filling fields from existing ID {fullyMatchedIdsList[i]}...")); + resultProgress?.Report( + ResultEventArgs.Success($"Filling fields from existing ID {fullyMatchedIdsList[i]}...")); _ = await Builder.FillFromId(wc, info, fullyMatchedIdsList[i], options.PullAllInformation); resultProgress?.Report(ResultEventArgs.Success("Information filling complete!")); @@ -377,7 +397,8 @@ public static async Task FillFromRedump(Options options, /// /// Creates a default SubmissionInfo object based on the current system and media type /// - private static SubmissionInfo CreateDefaultSubmissionInfo(BaseProcessor processor, RedumpSystem? system, MediaType? mediaType, bool addPlaceholders) + private static SubmissionInfo CreateDefaultSubmissionInfo(BaseProcessor processor, RedumpSystem? system, + MediaType? mediaType, bool addPlaceholders) { // Create the template object var info = new SubmissionInfo() @@ -397,10 +418,11 @@ private static SubmissionInfo CreateDefaultSubmissionInfo(BaseProcessor processo Barcode = addPlaceholders ? OptionalValue : string.Empty, Contents = string.Empty, }, - VersionAndEditions = new VersionAndEditionsSection() - { - OtherEditions = addPlaceholders ? "(VERIFY THIS) Original" : string.Empty, - }, + VersionAndEditions = + new VersionAndEditionsSection() + { + OtherEditions = addPlaceholders ? "(VERIFY THIS) Original" : string.Empty, + }, DumpingInfo = new DumpingInfoSection() { FrontendVersion = FrontendTool.GetCurrentVersion(), @@ -568,7 +590,8 @@ private static SubmissionInfo CreateDefaultSubmissionInfo(BaseProcessor processo List volLabels = []; // Begin formatted output with the label from Windows, if it is unique and not a common volume label - if (driveLabel is not null && !labels.TryGetValue(driveLabel, out List? value) && FrontendTool.GetRedumpSystemFromVolumeLabel(driveLabel) is null) + if (driveLabel is not null && !labels.TryGetValue(driveLabel, out List? value) && + FrontendTool.GetRedumpSystemFromVolumeLabel(driveLabel) is null) volLabels.Add(driveLabel); // Add remaining labels with their corresponding filesystems @@ -601,7 +624,8 @@ private static bool ProcessMediaType(SubmissionInfo info, MediaType? mediaType, case MediaType.GDROM: info.CommonDiscInfo.Layer0MasteringRing = addPlaceholders ? RequiredIfExistsValue : string.Empty; info.CommonDiscInfo.Layer0MasteringSID = addPlaceholders ? RequiredIfExistsValue : string.Empty; - info.CommonDiscInfo.Layer0ToolstampMasteringCode = addPlaceholders ? RequiredIfExistsValue : string.Empty; + info.CommonDiscInfo.Layer0ToolstampMasteringCode = + addPlaceholders ? RequiredIfExistsValue : string.Empty; info.CommonDiscInfo.Layer0MouldSID = addPlaceholders ? RequiredIfExistsValue : string.Empty; info.CommonDiscInfo.Layer1MouldSID = addPlaceholders ? RequiredIfExistsValue : string.Empty; info.CommonDiscInfo.Layer0AdditionalMould = addPlaceholders ? RequiredIfExistsValue : string.Empty; @@ -614,66 +638,90 @@ private static bool ProcessMediaType(SubmissionInfo info, MediaType? mediaType, // If we have a single-layer disc if (info.SizeAndChecksums.Layerbreak == default) { - info.CommonDiscInfo.Layer0MasteringRing = addPlaceholders ? RequiredIfExistsValue : string.Empty; + info.CommonDiscInfo.Layer0MasteringRing = + addPlaceholders ? RequiredIfExistsValue : string.Empty; info.CommonDiscInfo.Layer0MasteringSID = addPlaceholders ? RequiredIfExistsValue : string.Empty; - info.CommonDiscInfo.Layer0ToolstampMasteringCode = addPlaceholders ? RequiredIfExistsValue : string.Empty; + info.CommonDiscInfo.Layer0ToolstampMasteringCode = + addPlaceholders ? RequiredIfExistsValue : string.Empty; info.CommonDiscInfo.Layer0MouldSID = addPlaceholders ? RequiredIfExistsValue : string.Empty; info.CommonDiscInfo.Layer1MouldSID = addPlaceholders ? RequiredIfExistsValue : string.Empty; - info.CommonDiscInfo.Layer0AdditionalMould = addPlaceholders ? RequiredIfExistsValue : string.Empty; + info.CommonDiscInfo.Layer0AdditionalMould = + addPlaceholders ? RequiredIfExistsValue : string.Empty; } // If we have a dual-layer disc else if (info.SizeAndChecksums.Layerbreak2 == default) { - info.CommonDiscInfo.Layer0MasteringRing = addPlaceholders ? RequiredIfExistsValue : string.Empty; + info.CommonDiscInfo.Layer0MasteringRing = + addPlaceholders ? RequiredIfExistsValue : string.Empty; info.CommonDiscInfo.Layer0MasteringSID = addPlaceholders ? RequiredIfExistsValue : string.Empty; - info.CommonDiscInfo.Layer0ToolstampMasteringCode = addPlaceholders ? RequiredIfExistsValue : string.Empty; + info.CommonDiscInfo.Layer0ToolstampMasteringCode = + addPlaceholders ? RequiredIfExistsValue : string.Empty; info.CommonDiscInfo.Layer0MouldSID = addPlaceholders ? RequiredIfExistsValue : string.Empty; - info.CommonDiscInfo.Layer0AdditionalMould = addPlaceholders ? RequiredIfExistsValue : string.Empty; + info.CommonDiscInfo.Layer0AdditionalMould = + addPlaceholders ? RequiredIfExistsValue : string.Empty; - info.CommonDiscInfo.Layer1MasteringRing = addPlaceholders ? RequiredIfExistsValue : string.Empty; + info.CommonDiscInfo.Layer1MasteringRing = + addPlaceholders ? RequiredIfExistsValue : string.Empty; info.CommonDiscInfo.Layer1MasteringSID = addPlaceholders ? RequiredIfExistsValue : string.Empty; - info.CommonDiscInfo.Layer1ToolstampMasteringCode = addPlaceholders ? RequiredIfExistsValue : string.Empty; + info.CommonDiscInfo.Layer1ToolstampMasteringCode = + addPlaceholders ? RequiredIfExistsValue : string.Empty; info.CommonDiscInfo.Layer1MouldSID = addPlaceholders ? RequiredIfExistsValue : string.Empty; } // If we have a triple-layer disc else if (info.SizeAndChecksums.Layerbreak3 == default) { - info.CommonDiscInfo.Layer0MasteringRing = addPlaceholders ? RequiredIfExistsValue : string.Empty; + info.CommonDiscInfo.Layer0MasteringRing = + addPlaceholders ? RequiredIfExistsValue : string.Empty; info.CommonDiscInfo.Layer0MasteringSID = addPlaceholders ? RequiredIfExistsValue : string.Empty; - info.CommonDiscInfo.Layer0ToolstampMasteringCode = addPlaceholders ? RequiredIfExistsValue : string.Empty; + info.CommonDiscInfo.Layer0ToolstampMasteringCode = + addPlaceholders ? RequiredIfExistsValue : string.Empty; info.CommonDiscInfo.Layer0MouldSID = addPlaceholders ? RequiredIfExistsValue : string.Empty; - info.CommonDiscInfo.Layer0AdditionalMould = addPlaceholders ? RequiredIfExistsValue : string.Empty; + info.CommonDiscInfo.Layer0AdditionalMould = + addPlaceholders ? RequiredIfExistsValue : string.Empty; - info.CommonDiscInfo.Layer1MasteringRing = addPlaceholders ? RequiredIfExistsValue : string.Empty; + info.CommonDiscInfo.Layer1MasteringRing = + addPlaceholders ? RequiredIfExistsValue : string.Empty; info.CommonDiscInfo.Layer1MasteringSID = addPlaceholders ? RequiredIfExistsValue : string.Empty; - info.CommonDiscInfo.Layer1ToolstampMasteringCode = addPlaceholders ? RequiredIfExistsValue : string.Empty; + info.CommonDiscInfo.Layer1ToolstampMasteringCode = + addPlaceholders ? RequiredIfExistsValue : string.Empty; info.CommonDiscInfo.Layer1MouldSID = addPlaceholders ? RequiredIfExistsValue : string.Empty; - info.CommonDiscInfo.Layer2MasteringRing = addPlaceholders ? RequiredIfExistsValue : string.Empty; + info.CommonDiscInfo.Layer2MasteringRing = + addPlaceholders ? RequiredIfExistsValue : string.Empty; info.CommonDiscInfo.Layer2MasteringSID = addPlaceholders ? RequiredIfExistsValue : string.Empty; - info.CommonDiscInfo.Layer2ToolstampMasteringCode = addPlaceholders ? RequiredIfExistsValue : string.Empty; + info.CommonDiscInfo.Layer2ToolstampMasteringCode = + addPlaceholders ? RequiredIfExistsValue : string.Empty; } // If we have a quad-layer disc else { - info.CommonDiscInfo.Layer0MasteringRing = addPlaceholders ? RequiredIfExistsValue : string.Empty; + info.CommonDiscInfo.Layer0MasteringRing = + addPlaceholders ? RequiredIfExistsValue : string.Empty; info.CommonDiscInfo.Layer0MasteringSID = addPlaceholders ? RequiredIfExistsValue : string.Empty; - info.CommonDiscInfo.Layer0ToolstampMasteringCode = addPlaceholders ? RequiredIfExistsValue : string.Empty; + info.CommonDiscInfo.Layer0ToolstampMasteringCode = + addPlaceholders ? RequiredIfExistsValue : string.Empty; info.CommonDiscInfo.Layer0MouldSID = addPlaceholders ? RequiredIfExistsValue : string.Empty; - info.CommonDiscInfo.Layer0AdditionalMould = addPlaceholders ? RequiredIfExistsValue : string.Empty; + info.CommonDiscInfo.Layer0AdditionalMould = + addPlaceholders ? RequiredIfExistsValue : string.Empty; - info.CommonDiscInfo.Layer1MasteringRing = addPlaceholders ? RequiredIfExistsValue : string.Empty; + info.CommonDiscInfo.Layer1MasteringRing = + addPlaceholders ? RequiredIfExistsValue : string.Empty; info.CommonDiscInfo.Layer1MasteringSID = addPlaceholders ? RequiredIfExistsValue : string.Empty; - info.CommonDiscInfo.Layer1ToolstampMasteringCode = addPlaceholders ? RequiredIfExistsValue : string.Empty; + info.CommonDiscInfo.Layer1ToolstampMasteringCode = + addPlaceholders ? RequiredIfExistsValue : string.Empty; info.CommonDiscInfo.Layer1MouldSID = addPlaceholders ? RequiredIfExistsValue : string.Empty; - info.CommonDiscInfo.Layer2MasteringRing = addPlaceholders ? RequiredIfExistsValue : string.Empty; + info.CommonDiscInfo.Layer2MasteringRing = + addPlaceholders ? RequiredIfExistsValue : string.Empty; info.CommonDiscInfo.Layer2MasteringSID = addPlaceholders ? RequiredIfExistsValue : string.Empty; - info.CommonDiscInfo.Layer2ToolstampMasteringCode = addPlaceholders ? RequiredIfExistsValue : string.Empty; + info.CommonDiscInfo.Layer2ToolstampMasteringCode = + addPlaceholders ? RequiredIfExistsValue : string.Empty; - info.CommonDiscInfo.Layer3MasteringRing = addPlaceholders ? RequiredIfExistsValue : string.Empty; + info.CommonDiscInfo.Layer3MasteringRing = + addPlaceholders ? RequiredIfExistsValue : string.Empty; info.CommonDiscInfo.Layer3MasteringSID = addPlaceholders ? RequiredIfExistsValue : string.Empty; - info.CommonDiscInfo.Layer3ToolstampMasteringCode = addPlaceholders ? RequiredIfExistsValue : string.Empty; + info.CommonDiscInfo.Layer3ToolstampMasteringCode = + addPlaceholders ? RequiredIfExistsValue : string.Empty; } break; @@ -681,7 +729,8 @@ private static bool ProcessMediaType(SubmissionInfo info, MediaType? mediaType, case MediaType.NintendoGameCubeGameDisc: info.CommonDiscInfo.Layer0MasteringRing = addPlaceholders ? RequiredIfExistsValue : string.Empty; info.CommonDiscInfo.Layer0MasteringSID = addPlaceholders ? RequiredIfExistsValue : string.Empty; - info.CommonDiscInfo.Layer0ToolstampMasteringCode = addPlaceholders ? RequiredIfExistsValue : string.Empty; + info.CommonDiscInfo.Layer0ToolstampMasteringCode = + addPlaceholders ? RequiredIfExistsValue : string.Empty; info.CommonDiscInfo.Layer0MouldSID = addPlaceholders ? RequiredIfExistsValue : string.Empty; info.CommonDiscInfo.Layer1MouldSID = addPlaceholders ? RequiredIfExistsValue : string.Empty; info.CommonDiscInfo.Layer0AdditionalMould = addPlaceholders ? RequiredIfExistsValue : string.Empty; @@ -694,25 +743,33 @@ private static bool ProcessMediaType(SubmissionInfo info, MediaType? mediaType, // If we have a single-layer disc if (info.SizeAndChecksums.Layerbreak == default) { - info.CommonDiscInfo.Layer0MasteringRing = addPlaceholders ? RequiredIfExistsValue : string.Empty; + info.CommonDiscInfo.Layer0MasteringRing = + addPlaceholders ? RequiredIfExistsValue : string.Empty; info.CommonDiscInfo.Layer0MasteringSID = addPlaceholders ? RequiredIfExistsValue : string.Empty; - info.CommonDiscInfo.Layer0ToolstampMasteringCode = addPlaceholders ? RequiredIfExistsValue : string.Empty; + info.CommonDiscInfo.Layer0ToolstampMasteringCode = + addPlaceholders ? RequiredIfExistsValue : string.Empty; info.CommonDiscInfo.Layer0MouldSID = addPlaceholders ? RequiredIfExistsValue : string.Empty; info.CommonDiscInfo.Layer1MouldSID = addPlaceholders ? RequiredIfExistsValue : string.Empty; - info.CommonDiscInfo.Layer0AdditionalMould = addPlaceholders ? RequiredIfExistsValue : string.Empty; + info.CommonDiscInfo.Layer0AdditionalMould = + addPlaceholders ? RequiredIfExistsValue : string.Empty; } // If we have a dual-layer disc else { - info.CommonDiscInfo.Layer0MasteringRing = addPlaceholders ? RequiredIfExistsValue : string.Empty; + info.CommonDiscInfo.Layer0MasteringRing = + addPlaceholders ? RequiredIfExistsValue : string.Empty; info.CommonDiscInfo.Layer0MasteringSID = addPlaceholders ? RequiredIfExistsValue : string.Empty; - info.CommonDiscInfo.Layer0ToolstampMasteringCode = addPlaceholders ? RequiredIfExistsValue : string.Empty; + info.CommonDiscInfo.Layer0ToolstampMasteringCode = + addPlaceholders ? RequiredIfExistsValue : string.Empty; info.CommonDiscInfo.Layer0MouldSID = addPlaceholders ? RequiredIfExistsValue : string.Empty; - info.CommonDiscInfo.Layer0AdditionalMould = addPlaceholders ? RequiredIfExistsValue : string.Empty; + info.CommonDiscInfo.Layer0AdditionalMould = + addPlaceholders ? RequiredIfExistsValue : string.Empty; - info.CommonDiscInfo.Layer1MasteringRing = addPlaceholders ? RequiredIfExistsValue : string.Empty; + info.CommonDiscInfo.Layer1MasteringRing = + addPlaceholders ? RequiredIfExistsValue : string.Empty; info.CommonDiscInfo.Layer1MasteringSID = addPlaceholders ? RequiredIfExistsValue : string.Empty; - info.CommonDiscInfo.Layer1ToolstampMasteringCode = addPlaceholders ? RequiredIfExistsValue : string.Empty; + info.CommonDiscInfo.Layer1ToolstampMasteringCode = + addPlaceholders ? RequiredIfExistsValue : string.Empty; info.CommonDiscInfo.Layer1MouldSID = addPlaceholders ? RequiredIfExistsValue : string.Empty; } @@ -725,16 +782,24 @@ private static bool ProcessMediaType(SubmissionInfo info, MediaType? mediaType, // Both single- and dual-layer discs have two "layers" for the ring info.CommonDiscInfo.Layer0MasteringRing = addPlaceholders ? RequiredIfExistsValue : string.Empty; info.CommonDiscInfo.Layer0MasteringSID = addPlaceholders ? RequiredIfExistsValue : string.Empty; - info.CommonDiscInfo.Layer0ToolstampMasteringCode = addPlaceholders ? RequiredIfExistsValue : string.Empty; + info.CommonDiscInfo.Layer0ToolstampMasteringCode = + addPlaceholders ? RequiredIfExistsValue : string.Empty; info.CommonDiscInfo.Layer0MouldSID = addPlaceholders ? RequiredIfExistsValue : string.Empty; info.CommonDiscInfo.Layer1MasteringRing = addPlaceholders ? RequiredIfExistsValue : string.Empty; info.CommonDiscInfo.Layer1MasteringSID = addPlaceholders ? RequiredIfExistsValue : string.Empty; - info.CommonDiscInfo.Layer1ToolstampMasteringCode = addPlaceholders ? RequiredIfExistsValue : string.Empty; - - info.SizeAndChecksums.CRC32 ??= (addPlaceholders ? RequiredValue + " [Not automatically generated for UMD]" : string.Empty); - info.SizeAndChecksums.MD5 ??= (addPlaceholders ? RequiredValue + " [Not automatically generated for UMD]" : string.Empty); - info.SizeAndChecksums.SHA1 ??= (addPlaceholders ? RequiredValue + " [Not automatically generated for UMD]" : string.Empty); + info.CommonDiscInfo.Layer1ToolstampMasteringCode = + addPlaceholders ? RequiredIfExistsValue : string.Empty; + + info.SizeAndChecksums.CRC32 ??= (addPlaceholders + ? RequiredValue + " [Not automatically generated for UMD]" + : string.Empty); + info.SizeAndChecksums.MD5 ??= (addPlaceholders + ? RequiredValue + " [Not automatically generated for UMD]" + : string.Empty); + info.SizeAndChecksums.SHA1 ??= (addPlaceholders + ? RequiredValue + " [Not automatically generated for UMD]" + : string.Empty); info.TracksAndWriteOffsets.ClrMameProData = null; break; } @@ -746,7 +811,8 @@ private static bool ProcessMediaType(SubmissionInfo info, MediaType? mediaType, /// /// Processes default data based on system type /// - private static bool ProcessSystem(SubmissionInfo info, RedumpSystem? system, Drive? drive, bool addPlaceholders, bool isDiscImageCreator, string basePath) + private static bool ProcessSystem(SubmissionInfo info, RedumpSystem? system, Drive? drive, bool addPlaceholders, + bool isDiscImageCreator, string basePath) { #pragma warning disable IDE0010 // Extract info based specifically on RedumpSystem @@ -822,6 +888,16 @@ private static bool ProcessSystem(SubmissionInfo info, RedumpSystem? system, Dri info.CommonDiscInfo.Category ??= DiscCategory.Multimedia; break; + case RedumpSystem.IBMPCcompatible: + case RedumpSystem.AppleMacintosh: + info.CommonDiscInfo.CommentsSpecialFields[SiteCode.SteamAppID] = + PhysicalTool.GetSteamAppInfo(drive) ?? string.Empty; + info.CommonDiscInfo.ContentsSpecialFields[SiteCode.SteamSimSidDepotID] = + PhysicalTool.GetSteamSimSidInfo(drive) ?? string.Empty; + info.CommonDiscInfo.ContentsSpecialFields[SiteCode.SteamCsmCsdDepotID] = + PhysicalTool.GetSteamCsmCsdInfo(drive) ?? string.Empty; + break; + case RedumpSystem.IncredibleTechnologiesEagle: info.CommonDiscInfo.EXEDateBuildDate ??= addPlaceholders ? RequiredValue : string.Empty; break; @@ -839,10 +915,13 @@ private static bool ProcessSystem(SubmissionInfo info, RedumpSystem? system, Dri // TODO: Remove this hack when DIC supports build date output if (isDiscImageCreator) - info.CommonDiscInfo.EXEDateBuildDate = DiscImageCreator.GetPlayStationEXEDate($"{basePath}_volDesc.txt", kp2Exe); + info.CommonDiscInfo.EXEDateBuildDate = + DiscImageCreator.GetPlayStationEXEDate($"{basePath}_volDesc.txt", kp2Exe); - SetCommentFieldIfNotExists(info, SiteCode.InternalSerialName, drive, PhysicalTool.GetPlayStationSerial); - info.CommonDiscInfo.EXEDateBuildDate ??= PhysicalTool.GetFileDate(drive, kp2Exe, fixTwoDigitYear: true); + SetCommentFieldIfNotExists(info, SiteCode.InternalSerialName, drive, + PhysicalTool.GetPlayStationSerial); + info.CommonDiscInfo.EXEDateBuildDate ??= + PhysicalTool.GetFileDate(drive, kp2Exe, fixTwoDigitYear: true); if (CommentFieldExists(info, SiteCode.InternalSerialName, out kp2Exe)) info.CommonDiscInfo.Region = ProcessingTool.GetPlayStationRegion(kp2Exe); @@ -867,13 +946,17 @@ private static bool ProcessSystem(SubmissionInfo info, RedumpSystem? system, Dri break; case RedumpSystem.MicrosoftXboxOne: - info.CommonDiscInfo.CommentsSpecialFields[SiteCode.Filename] = PhysicalTool.GetXboxFilenames(drive) ?? string.Empty; - info.CommonDiscInfo.CommentsSpecialFields[SiteCode.TitleID] = PhysicalTool.GetXboxTitleID(drive) ?? string.Empty; + info.CommonDiscInfo.CommentsSpecialFields[SiteCode.Filename] = + PhysicalTool.GetXboxFilenames(drive) ?? string.Empty; + info.CommonDiscInfo.CommentsSpecialFields[SiteCode.TitleID] = + PhysicalTool.GetXboxTitleID(drive) ?? string.Empty; break; case RedumpSystem.MicrosoftXboxSeriesXS: - info.CommonDiscInfo.CommentsSpecialFields[SiteCode.Filename] = PhysicalTool.GetXboxFilenames(drive) ?? string.Empty; - info.CommonDiscInfo.CommentsSpecialFields[SiteCode.TitleID] = PhysicalTool.GetXboxTitleID(drive) ?? string.Empty; + info.CommonDiscInfo.CommentsSpecialFields[SiteCode.Filename] = + PhysicalTool.GetXboxFilenames(drive) ?? string.Empty; + info.CommonDiscInfo.CommentsSpecialFields[SiteCode.TitleID] = + PhysicalTool.GetXboxTitleID(drive) ?? string.Empty; break; case RedumpSystem.NamcoSegaNintendoTriforce: @@ -931,10 +1014,13 @@ private static bool ProcessSystem(SubmissionInfo info, RedumpSystem? system, Dri // TODO: Remove this hack when DIC supports build date output if (isDiscImageCreator) - info.CommonDiscInfo.EXEDateBuildDate = DiscImageCreator.GetPlayStationEXEDate($"{basePath}_volDesc.txt", ps1Exe, psx: true); + info.CommonDiscInfo.EXEDateBuildDate = + DiscImageCreator.GetPlayStationEXEDate($"{basePath}_volDesc.txt", ps1Exe, psx: true); - SetCommentFieldIfNotExists(info, SiteCode.InternalSerialName, drive, PhysicalTool.GetPlayStationSerial); - info.CommonDiscInfo.EXEDateBuildDate ??= PhysicalTool.GetFileDate(drive, ps1Exe, fixTwoDigitYear: true); + SetCommentFieldIfNotExists(info, SiteCode.InternalSerialName, drive, + PhysicalTool.GetPlayStationSerial); + info.CommonDiscInfo.EXEDateBuildDate ??= + PhysicalTool.GetFileDate(drive, ps1Exe, fixTwoDigitYear: true); if (CommentFieldExists(info, SiteCode.InternalSerialName, out ps1Exe)) info.CommonDiscInfo.Region = ProcessingTool.GetPlayStationRegion(ps1Exe); @@ -947,10 +1033,13 @@ private static bool ProcessSystem(SubmissionInfo info, RedumpSystem? system, Dri // TODO: Remove this hack when DIC supports build date output if (isDiscImageCreator) - info.CommonDiscInfo.EXEDateBuildDate = DiscImageCreator.GetPlayStationEXEDate($"{basePath}_volDesc.txt", ps2Exe); + info.CommonDiscInfo.EXEDateBuildDate = + DiscImageCreator.GetPlayStationEXEDate($"{basePath}_volDesc.txt", ps2Exe); - SetCommentFieldIfNotExists(info, SiteCode.InternalSerialName, drive, PhysicalTool.GetPlayStationSerial); - info.CommonDiscInfo.EXEDateBuildDate ??= PhysicalTool.GetFileDate(drive, ps2Exe, fixTwoDigitYear: true); + SetCommentFieldIfNotExists(info, SiteCode.InternalSerialName, drive, + PhysicalTool.GetPlayStationSerial); + info.CommonDiscInfo.EXEDateBuildDate ??= + PhysicalTool.GetFileDate(drive, ps2Exe, fixTwoDigitYear: true); if (CommentFieldExists(info, SiteCode.InternalSerialName, out ps2Exe)) info.CommonDiscInfo.Region = ProcessingTool.GetPlayStationRegion(ps2Exe); @@ -962,19 +1051,22 @@ private static bool ProcessSystem(SubmissionInfo info, RedumpSystem? system, Dri info.Extras.DiscKey ??= addPlaceholders ? RequiredValue : string.Empty; info.Extras.DiscID ??= addPlaceholders ? RequiredValue : string.Empty; - SetCommentFieldIfNotExists(info, SiteCode.InternalSerialName, drive, PhysicalTool.GetPlayStation3Serial); + SetCommentFieldIfNotExists(info, SiteCode.InternalSerialName, drive, + PhysicalTool.GetPlayStation3Serial); SetVersionIfNotExists(info, drive, PhysicalTool.GetPlayStation3Version); SetContentFieldIfNotExists(info, SiteCode.Patches, drive, FormatPlayStation3FirmwareVersion); break; case RedumpSystem.SonyPlayStation4: - SetCommentFieldIfNotExists(info, SiteCode.InternalSerialName, drive, PhysicalTool.GetPlayStation4Serial); + SetCommentFieldIfNotExists(info, SiteCode.InternalSerialName, drive, + PhysicalTool.GetPlayStation4Serial); SetVersionIfNotExists(info, drive, PhysicalTool.GetPlayStation4Version); SetContentFieldIfNotExists(info, SiteCode.Games, drive, PhysicalTool.GetPlayStation4PkgInfo); break; case RedumpSystem.SonyPlayStation5: - SetCommentFieldIfNotExists(info, SiteCode.InternalSerialName, drive, PhysicalTool.GetPlayStation5Serial); + SetCommentFieldIfNotExists(info, SiteCode.InternalSerialName, drive, + PhysicalTool.GetPlayStation5Serial); SetVersionIfNotExists(info, drive, PhysicalTool.GetPlayStation5Version); SetContentFieldIfNotExists(info, SiteCode.Games, drive, PhysicalTool.GetPlayStation5PkgInfo); break; @@ -1027,7 +1119,8 @@ private static bool CommentFieldExists(SubmissionInfo info, SiteCode key, out st /// /// Set a comment field if it doesn't already have a value /// - private static void SetCommentFieldIfNotExists(SubmissionInfo info, SiteCode key, Drive? drive, Func valueFunc) + private static void SetCommentFieldIfNotExists(SubmissionInfo info, SiteCode key, Drive? drive, + Func valueFunc) { // If the field has a valid value, skip if (CommentFieldExists(info, key, out _)) @@ -1061,7 +1154,8 @@ private static bool ContentFieldExists(SubmissionInfo info, SiteCode key, out st /// /// Set a content field if it doesn't already have a value /// - private static void SetContentFieldIfNotExists(SubmissionInfo info, SiteCode key, Drive? drive, Func valueFunc) + private static void SetContentFieldIfNotExists(SubmissionInfo info, SiteCode key, Drive? drive, + Func valueFunc) { // If the field has a valid value, skip if (ContentFieldExists(info, key, out _)) @@ -1091,7 +1185,8 @@ private static void SetVersionIfNotExists(SubmissionInfo info, Drive? drive, Fun /// /// ProtectionDictionary to format /// Reformatted dictionary on success, empty on error - private static Dictionary?> ReformatProtectionDictionary(Dictionary>? oldDict) + private static Dictionary?> ReformatProtectionDictionary( + Dictionary>? oldDict) { // Null or empty protections return empty if (oldDict is null || oldDict.Count == 0)