From 020390af6508fcad5b579cb2ca7c62235482e9eb Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Mon, 22 Sep 2025 15:30:48 -0400 Subject: [PATCH] Cleanup last commits, add tests --- .../Tools/ProtectionToolTests.cs | 118 ++++++++++++++++++ MPF.Frontend/Tools/ProtectionTool.cs | 80 +++++++----- 2 files changed, 164 insertions(+), 34 deletions(-) diff --git a/MPF.Frontend.Test/Tools/ProtectionToolTests.cs b/MPF.Frontend.Test/Tools/ProtectionToolTests.cs index 9952b60c..00f09b30 100644 --- a/MPF.Frontend.Test/Tools/ProtectionToolTests.cs +++ b/MPF.Frontend.Test/Tools/ProtectionToolTests.cs @@ -8,6 +8,107 @@ namespace MPF.Frontend.Test.Tools { public class ProtectionToolTests { + #region SanitizeContextSensitiveProtections + + [Fact] + public void SanitizeContextSensitiveProtections_Empty_NoException() + { + Dictionary>? protections = []; + var actual = ProtectionTool.SanitizeContextSensitiveProtections(protections); + Assert.NotNull(actual); + Assert.Empty(actual); + } + + [Fact] + public void SanitizeContextSensitiveProtections_NoMatch_NoChange() + { + Dictionary>? protections = []; + protections["File1"] = ["Protection 1", "Protection 2"]; + + var actual = ProtectionTool.SanitizeContextSensitiveProtections(protections); + Assert.NotNull(actual); + + string[] keys = [.. actual.Keys]; + Assert.Contains("File1", keys); + } + + [Fact] + public void SanitizeContextSensitiveProtections_Match_NoSub_NoChange() + { + Dictionary>? protections = []; + protections["File1"] = ["Protection 1", "Protection 2"]; + protections["File2"] = ["SecuROM Release Control - ANYTHING", "Protection 2"]; + protections["File3"] = ["Protection 1", "SecuROM Release Control -"]; + + var actual = ProtectionTool.SanitizeContextSensitiveProtections(protections); + Assert.NotNull(actual); + + string[] keys = [.. actual.Keys]; + Assert.Contains("File1", keys); + Assert.Contains("File2", keys); + Assert.Contains("File3", keys); + } + + [Fact] + public void SanitizeContextSensitiveProtections_Match_Sub_Change() + { + Dictionary>? protections = []; + protections["File1"] = ["Protection 1", "Protection 2"]; + protections["File2"] = ["SecuROM Release Control - ANYTHING"]; + protections["File2/FileA"] = ["ANYTHING GitHub ANYTHING"]; + protections["File2/FileB"] = ["SecuROM 7"]; + protections["File2/FileC"] = ["SecuROM 8"]; + protections["File2/FileD"] = ["SecuROM Content Activation"]; + protections["File2/FileE"] = ["SecuROM Data File Activation"]; + protections["File2/FileF"] = ["Unlock"]; + + var actual = ProtectionTool.SanitizeContextSensitiveProtections(protections); + Assert.NotNull(actual); + + string[] keys = [.. actual.Keys]; + Assert.Contains("File1", keys); + Assert.Contains("File2", keys); + Assert.Contains("File2/FileA", keys); + Assert.DoesNotContain("File2/FileB", keys); + Assert.DoesNotContain("File2/FileC", keys); + Assert.DoesNotContain("File2/FileD", keys); + Assert.DoesNotContain("File2/FileE", keys); + Assert.DoesNotContain("File2/FileF", keys); + } + + [Fact] + public void SanitizeContextSensitiveProtections_MultiMatch_Sub_Change() + { + Dictionary>? protections = []; + protections["File1"] = ["Protection 1", "Protection 2"]; + protections["File2"] = ["SecuROM Release Control - ANYTHING"]; + protections["File2/FileA"] = ["ANYTHING GitHub ANYTHING"]; + protections["File2/FileB"] = ["SecuROM 7"]; + protections["File2/FileC"] = ["SecuROM 8"]; + protections["File3"] = ["SecuROM Release Control - ANYTHING"]; + protections["File3/FileD"] = ["SecuROM Content Activation"]; + protections["File3/FileE"] = ["SecuROM Data File Activation"]; + protections["File3/FileF"] = ["Unlock"]; + + var actual = ProtectionTool.SanitizeContextSensitiveProtections(protections); + Assert.NotNull(actual); + + string[] keys = [.. actual.Keys]; + Assert.Contains("File1", keys); + Assert.Contains("File2", keys); + Assert.Contains("File2/FileA", keys); + Assert.DoesNotContain("File2/FileB", keys); + Assert.DoesNotContain("File2/FileC", keys); + Assert.Contains("File3", keys); + Assert.DoesNotContain("File3/FileD", keys); + Assert.DoesNotContain("File3/FileE", keys); + Assert.DoesNotContain("File3/FileF", keys); + } + + #endregion + + #region SanitizeFoundProtections + [Fact] public void SanitizeFoundProtections_Exception() { @@ -616,6 +717,21 @@ namespace MPF.Frontend.Test.Tools Assert.Equal(expected, sanitized); } + [Fact] + public void SanitizeFoundProtections_SecuROM() + { + List protections = + [ + "SecuROM Release Control", + "SecuROM Release Control - ANYTHING", + "SecuROM Release Control - ANYTHING ELSE", + "SecuROM Release Control - EVEN MORE", + ]; + + string sanitized = ProtectionTool.SanitizeFoundProtections(protections); + Assert.Equal("SecuROM Release Control", sanitized); + } + [Theory] [InlineData(0)] [InlineData(1)] @@ -670,5 +786,7 @@ namespace MPF.Frontend.Test.Tools } #endregion + + #endregion } } diff --git a/MPF.Frontend/Tools/ProtectionTool.cs b/MPF.Frontend/Tools/ProtectionTool.cs index 6311f07b..ed1810f4 100644 --- a/MPF.Frontend/Tools/ProtectionTool.cs +++ b/MPF.Frontend/Tools/ProtectionTool.cs @@ -119,7 +119,7 @@ namespace MPF.Frontend.Tools return "None found [OMIT FROM SUBMISSION]"; // Sanitize context-sensitive protections - SanitizeContextSensitiveProtections(protections); + protections = SanitizeContextSensitiveProtections(protections); // Get a list of distinct found protections #if NET20 @@ -192,45 +192,60 @@ namespace MPF.Frontend.Tools /// Sanitize unnecessary protections where context matters /// /// Dictionary of file to list of protection mappings - public static void SanitizeContextSensitiveProtections(Dictionary>? protections) + /// Dictionary with all necessary items filtered out + public static Dictionary> SanitizeContextSensitiveProtections(Dictionary> protections) { - // Ignore empty dictionaries - if (protections == null) - return; + // Setup the output dictionary + Dictionary> filtered = []; // Setup a list for keys that need additional processing - List keys = []; - + List foundKeys = []; + // Loop through the keys and add relevant ones - foreach (var key in protections.Keys) + string[] paths = [.. protections.Keys]; + foreach (var path in paths) { - var values = protections[key]; - if (values.Count == 0) + if (!protections.TryGetValue(path, out var values) || values == null || values.Count == 0) continue; - foreach (var value in values) - if (value.Contains("SecuROM Release Control -")) - keys.Add(key); + // Always copy the values if they're valid + filtered[path] = values; + + if (values.Exists(s => s.StartsWith("SecuROM Release Control -"))) + foundKeys.Add(path); } // If there are no keys found - if (keys.Count == 0) - return; + if (foundKeys.Count == 0) + return filtered; // Process the keys as necessary - foreach (var key in keys) - foreach (var releaseControlValue in protections[key]) - if (releaseControlValue.Contains("SecuROM Release Control -")) - foreach (var protection in protections) - if (protection.Key.Contains(key)) - foreach (var value in protection.Value) - if (!value.Contains("GitHub") && - (value.Contains("SecuROM 7") || - value.Contains("SecuROM 8") || - value.Contains("SecuROM Content Activation") || - value.Contains("SecuROM Data File Activation") || - value.Contains("Unlock"))) - protections.Remove(protection.Key); + foreach (var key in foundKeys) + { + // Get all matching paths + var matchingPaths = Array.FindAll(paths, s => s != key && s.StartsWith(key)); + if (matchingPaths.Length == 0) + continue; + + // Loop through the matching paths + foreach (var path in matchingPaths) + { + if (!filtered.TryGetValue(path, out var values) || values == null || values.Count == 0) + continue; + + if (values.Exists(s => !s.Contains("GitHub") && + (s.Contains("SecuROM 7") + || s.Contains("SecuROM 8") + || s.Contains("SecuROM Content Activation") + || s.Contains("SecuROM Data File Activation") + || s.Contains("Unlock")))) + { + filtered.Remove(path); + } + } + } + + return filtered; } /// @@ -483,15 +498,12 @@ namespace MPF.Frontend.Tools } // SecuROM - // TODO: Figure this one out - - // Remove verbose game identification - if (foundProtections.Exists(p => p.StartsWith("SecuROM Release Control -"))) + if (foundProtections.Exists(p => p.StartsWith("SecuROM Release Control"))) { - foundProtections = foundProtections.FindAll(p => !p.StartsWith("SecuROM Release Control -")); + foundProtections = foundProtections.FindAll(p => !p.StartsWith("SecuROM Release Control")); foundProtections.Add("SecuROM Release Control"); } - + // SolidShield // TODO: Figure this one out