diff --git a/CHANGELIST.md b/CHANGELIST.md index 0968821b..05e8fa03 100644 --- a/CHANGELIST.md +++ b/CHANGELIST.md @@ -45,6 +45,7 @@ - Explicitly sanitize '?' from path - Combine cases in protection scan - Convert status label to TextBlock +- Add option for copy protection file output ### 2.3 (2022-02-05) - Start overhauling Redump information pulling, again diff --git a/MPF.Check/Program.cs b/MPF.Check/Program.cs index affc32ad..67ac3b00 100644 --- a/MPF.Check/Program.cs +++ b/MPF.Check/Program.cs @@ -69,7 +69,7 @@ namespace MPF.Check string username = null, password = null; string internalProgram = "DiscImageCreator"; string path = string.Empty; - bool scan = false, compress = false, json = false; + bool scan = false, protectFile = false, compress = false, json = false; // Loop through and process options int startIndex = 2; @@ -117,6 +117,12 @@ namespace MPF.Check scan = true; } + // Output protection to separate file (requires scan for protection) + else if (args[startIndex].Equals("-f") || args[startIndex].Equals("--protect-file")) + { + protectFile = true; + } + // Output submission JSON else if (args[startIndex].Equals("-j") || args[startIndex].Equals("--json")) { @@ -175,6 +181,7 @@ namespace MPF.Check { InternalProgram = EnumConverter.ToInternalProgram(internalProgram), ScanForProtection = scan && !string.IsNullOrWhiteSpace(path), + OutputSeparateProtectionFile = scan && protectFile && !string.IsNullOrWhiteSpace(path), PromptForDiscInformation = false, ShowDiscEjectReminder = false, OutputSubmissionJSON = json, @@ -219,6 +226,7 @@ namespace MPF.Check Console.WriteLine("-u, --use Dumping program output type"); Console.WriteLine("-p, --path Physical drive path for additional checks"); Console.WriteLine("-s, --scan Enable copy protection scan (requires --path)"); + Console.WriteLine("-f, --protect-file Output protection to separate file (requires --scan)"); Console.WriteLine("-j, --json Enable submission JSON output"); Console.WriteLine("-z, --zip Enable log file compression"); Console.WriteLine(); diff --git a/MPF.Core/Data/Options.cs b/MPF.Core/Data/Options.cs index 096bc5ab..37dafdf5 100644 --- a/MPF.Core/Data/Options.cs +++ b/MPF.Core/Data/Options.cs @@ -288,6 +288,15 @@ namespace MPF.Core.Data set { _settings["ScanForProtection"] = value.ToString(); } } + /// + /// Output all found protections to a separate file in the directory + /// + public bool OutputSeparateProtectionFile + { + get { return GetBooleanSetting(_settings, "OutputSeparateProtectionFile", false); } + set { _settings["OutputSeparateProtectionFile"] = value.ToString(); } + } + /// /// Add placeholder values in the submission info /// diff --git a/MPF.Library/DumpEnvironment.cs b/MPF.Library/DumpEnvironment.cs index 69997f17..eff55878 100644 --- a/MPF.Library/DumpEnvironment.cs +++ b/MPF.Library/DumpEnvironment.cs @@ -373,6 +373,17 @@ namespace MPF.Library else resultProgress?.Report(Result.Failure("Writing could not complete!")); + // Write the copy protection output + if (Options.ScanForProtection && Options.OutputSeparateProtectionFile) + { + resultProgress?.Report(Result.Success("Writing protection to !protectionInfo.txt...")); + success = InfoTool.WriteProtectionData(this.OutputDirectory, submissionInfo); + if (success) + resultProgress?.Report(Result.Success("Writing complete!")); + else + resultProgress?.Report(Result.Failure("Writing could not complete!")); + } + // Write the JSON output, if required if (Options.OutputSubmissionJSON) { diff --git a/MPF.Library/InfoTool.cs b/MPF.Library/InfoTool.cs index eca9961d..761d488f 100644 --- a/MPF.Library/InfoTool.cs +++ b/MPF.Library/InfoTool.cs @@ -234,8 +234,9 @@ namespace MPF.Library case RedumpSystem.PocketPC: case RedumpSystem.RainbowDisc: resultProgress?.Report(Result.Success("Running copy protection scan... this might take a while!")); - (string protectionString, Dictionary> _) = await GetCopyProtection(drive, options, protectionProgress); + (string protectionString, Dictionary> fullProtections) = await GetCopyProtection(drive, options, protectionProgress); info.CopyProtection.Protection = protectionString; + info.CopyProtection.FullProtections = fullProtections; resultProgress?.Report(Result.Success("Copy protection scan complete!")); break; @@ -1009,6 +1010,38 @@ namespace MPF.Library return true; } + /// + /// Write the protection data to the output folder + /// + /// Output folder to write to + /// SubmissionInfo object containing the protection information + /// True on success, false on error + public static bool WriteProtectionData(string outputDirectory, SubmissionInfo info) + { + // Check to see if the inputs are valid + if (info?.CopyProtection?.FullProtections == null || !info.CopyProtection.FullProtections.Any()) + return true; + + // Now write out to a generic file + try + { + using (StreamWriter sw = new StreamWriter(File.Open(Path.Combine(outputDirectory, "!protectionInfo.txt"), FileMode.Create, FileAccess.Write))) + { + foreach (var kvp in info.CopyProtection.FullProtections) + { + sw.WriteLine($"{kvp.Key}: {string.Join(", ", kvp.Value)}"); + } + } + } + catch (Exception ex) + { + // We don't care what the error is right now + return false; + } + + return true; + } + /// /// Add the properly formatted key and value, if possible /// diff --git a/MPF/Windows/OptionsWindow.xaml b/MPF/Windows/OptionsWindow.xaml index 0fce047a..80828154 100644 --- a/MPF/Windows/OptionsWindow.xaml +++ b/MPF/Windows/OptionsWindow.xaml @@ -123,7 +123,7 @@ - + + + diff --git a/RedumpLib/Data/SubmissionInfo.cs b/RedumpLib/Data/SubmissionInfo.cs index 9898cc8e..a85bdaa2 100644 --- a/RedumpLib/Data/SubmissionInfo.cs +++ b/RedumpLib/Data/SubmissionInfo.cs @@ -402,6 +402,9 @@ namespace RedumpLib.Data [JsonProperty(PropertyName = "d_protection", NullValueHandling = NullValueHandling.Ignore)] public string Protection { get; set; } + [JsonIgnore] + public Dictionary> FullProtections { get; set; } + [JsonProperty(PropertyName = "d_securom", NullValueHandling = NullValueHandling.Ignore)] public string SecuROMData { get; set; } @@ -413,6 +416,7 @@ namespace RedumpLib.Data LibCrypt = this.LibCrypt, LibCryptData = this.LibCryptData, Protection = this.Protection, + FullProtections = this.FullProtections.ToDictionary(kvp => kvp.Key, kvp => kvp.Value), SecuROMData = this.SecuROMData, }; }