From eaa77dbeed898d1d264d28b8e3ff23efadf291d9 Mon Sep 17 00:00:00 2001 From: Deterous <138427222+Deterous@users.noreply.github.com> Date: Sun, 15 Dec 2024 09:58:09 +0900 Subject: [PATCH] Better deal with volume labels (#780) * Better deal with volume labels * Add missing using * use nullable string * Deal with review comments * Fix issues * Better deal with Xbox/Xbox360 labels * Use FirstOrDefault * Add todo --- CHANGELIST.md | 1 + MPF.Frontend/Tools/FrontendTool.cs | 25 +++++++--- MPF.Frontend/Tools/SubmissionGenerator.cs | 58 ++++++++++++++++++++++- MPF.Processors/DiscImageCreator.cs | 4 +- 4 files changed, 77 insertions(+), 11 deletions(-) diff --git a/CHANGELIST.md b/CHANGELIST.md index e9225573..8bed3c64 100644 --- a/CHANGELIST.md +++ b/CHANGELIST.md @@ -72,6 +72,7 @@ - Simplify prefix filtering - Fix issue with odd quoting - Add DumpingParameters for DIC and Redumper +- Better deal with volume labels ### 3.2.4 (2024-11-24) diff --git a/MPF.Frontend/Tools/FrontendTool.cs b/MPF.Frontend/Tools/FrontendTool.cs index 8a7c96b2..710f79c4 100644 --- a/MPF.Frontend/Tools/FrontendTool.cs +++ b/MPF.Frontend/Tools/FrontendTool.cs @@ -59,15 +59,26 @@ namespace MPF.Frontend.Tools return RedumpSystem.MicrosoftXbox; // Microsoft Xbox 360 - if (volumeLabel.Equals("XBOX360", StringComparison.OrdinalIgnoreCase)) + if (volumeLabel.Equals("XBOX360")) return RedumpSystem.MicrosoftXbox360; - else if (volumeLabel.Equals("XGD2DVD_NTSC", StringComparison.OrdinalIgnoreCase)) + else if (volumeLabel.Equals("XGD2DVD_NTSC")) return RedumpSystem.MicrosoftXbox360; - - // Microsoft Xbox 360 - Too overly broad even if a lot of discs use this - //if (volumeLabel.Equals("CD_ROM", StringComparison.OrdinalIgnoreCase)) - // return RedumpSystem.MicrosoftXbox360; // Also for Xbox One? - //if (volumeLabel.Equals("DVD_ROM", StringComparison.OrdinalIgnoreCase)) + else if (volumeLabel.Equals("XBOX_TINYTEST")) + return RedumpSystem.MicrosoftXbox360; + else if (volumeLabel.Equals("13599")) + return RedumpSystem.MicrosoftXbox360; + else if (volumeLabel.Equals("14719")) + return RedumpSystem.MicrosoftXbox360; + else if (volumeLabel.Equals("15574")) + return RedumpSystem.MicrosoftXbox360; + else if (volumeLabel.Equals("16197")) + return RedumpSystem.MicrosoftXbox360; + else if (volumeLabel.Equals("16197")) + return RedumpSystem.MicrosoftXbox360; + else if (volumeLabel.Equals("17349")) + return RedumpSystem.MicrosoftXbox360; + // DVD_ROM and CD_ROM have too many false positives + //else if (volumeLabel.Equals("DVD_ROM")) // return RedumpSystem.MicrosoftXbox360; // Sega Mega-CD / Sega-CD diff --git a/MPF.Frontend/Tools/SubmissionGenerator.cs b/MPF.Frontend/Tools/SubmissionGenerator.cs index 862c7a76..83877c0a 100644 --- a/MPF.Frontend/Tools/SubmissionGenerator.cs +++ b/MPF.Frontend/Tools/SubmissionGenerator.cs @@ -4,6 +4,7 @@ using System.IO; #if NET35_OR_GREATER || NETCOREAPP using System.Linq; #endif +using System.Text; using System.Threading.Tasks; using BinaryObjectScanner; using MPF.Processors; @@ -396,6 +397,30 @@ namespace MPF.Frontend.Tools return internalProgram.LongName(); } + /// + /// Simplifies a volume label into uppercase alphanumeric only string + /// + /// Volume label to simplify + /// Simplified volume label + private static string? SimplifyVolumeLabel(string? label) + { + if (label == null || label.Length == 0) + return null; + + var labelBuilder = new StringBuilder(); + foreach (char c in label) + { + if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9')) + labelBuilder.Append(char.ToUpper(c)); + } + string? simpleLabel = labelBuilder.ToString(); + + if (simpleLabel == null || simpleLabel.Length == 0) + return null; + else + return simpleLabel; + } + /// /// Formats a list of volume labels and their corresponding filesystems /// @@ -403,6 +428,10 @@ namespace MPF.Frontend.Tools /// Formatted string of volume labels and their filesystems private static string? FormatVolumeLabels(string? driveLabel, Dictionary>? labels) { + // Treat empty label as null + if (driveLabel != null && driveLabel.Length == 0) + driveLabel = null; + // Must have at least one label to format if (driveLabel == null && (labels == null || labels.Count == 0)) return null; @@ -417,7 +446,32 @@ namespace MPF.Frontend.Tools return driveLabel; } - // If only one label, don't mention fs + // Get the default label to compare against + // TODO: Full pairwise comparison of all labels, not just comparing against drive/UDF label. + string? defaultLabel = null; + if (driveLabel != null && driveLabel.Length != 0) + defaultLabel = SimplifyVolumeLabel(driveLabel); +#if NET35_OR_GREATER || NETCOREAPP + else + defaultLabel = labels.Where(label => label.Value.Contains("UDF")).Select(label => label.Key).FirstOrDefault(); +#endif + + // Remove duplicate/useless volume labels + if (defaultLabel != null && defaultLabel.Length != 0) + { + List keysToRemove = new List(); + foreach (KeyValuePair> label in labels) + { + string? tempLabel = SimplifyVolumeLabel(label.Key); + // Remove duplicate volume labels and remove "DVD_ROM" / "CD_ROM" labels + if (defaultLabel == tempLabel || label.Key == "DVD_ROM" || label.Key == "CD_ROM") + keysToRemove.Add(label.Key); + } + foreach (string key in keysToRemove) + labels.Remove(key); + } + + // If only one unique label left, don't mention fs #if NET20 string[] keyArr = new string[labels.Count]; labels.Keys.CopyTo(keyArr, 0); @@ -450,7 +504,7 @@ namespace MPF.Frontend.Tools } // Ensure that no labels are empty - volLabels = volLabels.FindAll(l => !string.IsNullOrEmpty(l?.Trim())); + volLabels = volLabels.FindAll(label => !string.IsNullOrEmpty(label?.Trim())); // Print each label separated by a comma and a space if (volLabels.Count == 0) diff --git a/MPF.Processors/DiscImageCreator.cs b/MPF.Processors/DiscImageCreator.cs index fafd5bd7..3852f43b 100644 --- a/MPF.Processors/DiscImageCreator.cs +++ b/MPF.Processors/DiscImageCreator.cs @@ -1963,8 +1963,8 @@ namespace MPF.Processors if (Convert.ToUInt32(label[0]) == 0x7F || Convert.ToUInt32(label[0]) < 0x20) label = label.Substring(1); - // Skip if label is blank - if (label == null || label.Length <= 0) + // Skip if label is blank, and skip Joliet (DIC Joliet parsing is broken?) + if (label == null || label.Length <= 0 || volType == "Joliet") { volType = "UNKNOWN"; line = sr.ReadLine();