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();