From 8e8e3368d0e8ab2bcfefd19403a4b723d5d457f4 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Wed, 22 Nov 2023 15:56:43 -0500 Subject: [PATCH] Re-enable .NET Framework 4.0 building in Core --- CHANGELIST.md | 1 + MPF.Check/Program.cs | 6 +- MPF.Core/Converters/EnumConverter.cs | 19 +++- MPF.Core/Data/Constants.cs | 4 +- MPF.Core/Data/Drive.cs | 57 +++++++++-- MPF.Core/Data/IniFile.cs | 4 +- MPF.Core/Data/Options.cs | 2 +- MPF.Core/Data/ProcessingQueue.cs | 25 ++++- MPF.Core/DumpEnvironment.cs | 23 +++-- MPF.Core/Hashing/Hasher.cs | 2 +- MPF.Core/Hashing/OptimizedCRC.cs | 4 +- MPF.Core/InfoTool.cs | 94 +++++++++---------- MPF.Core/MPF.Core.csproj | 23 ++--- MPF.Core/Modules/Aaru/Parameters.cs | 34 +++---- MPF.Core/Modules/BaseParameters.cs | 11 ++- MPF.Core/Modules/CleanRIp/Parameters.cs | 6 +- .../Modules/DiscImageCreator/Parameters.cs | 22 ++--- MPF.Core/Modules/Redumper/Parameters.cs | 38 ++++---- .../Modules/UmdImageCreator/Parameters.cs | 2 +- MPF.Core/Protection.cs | 16 ++-- MPF.Core/SubmissionInfoTool.cs | 31 +++--- MPF.Core/UI/ViewModels/MainViewModel.cs | 18 ++-- MPF.Core/UI/ViewModels/OptionsViewModel.cs | 4 +- MPF.Core/Utilities/Logging.cs | 26 +++-- MPF.Core/Utilities/OptionsLoader.cs | 4 +- MPF.Core/Utilities/Tools.cs | 4 +- MPF.Test/Library/InfoToolTests.cs | 2 +- MPF.Test/RedumpLib/ExtensionsTests.cs | 8 +- MPF.UI.Core/Constants.cs | 2 +- .../Windows/DiscInformationWindow.xaml.cs | 16 ++-- MPF.UI.Core/Windows/MainWindow.xaml.cs | 6 +- 31 files changed, 309 insertions(+), 205 deletions(-) diff --git a/CHANGELIST.md b/CHANGELIST.md index c2adcf59..9c2ae32b 100644 --- a/CHANGELIST.md +++ b/CHANGELIST.md @@ -27,6 +27,7 @@ - Support proper async in .NET Framework 4.0 - Temporarily remove .NET Framework 4.0 - Update to BinaryObjectScanner 3.0.2 +- Re-enable .NET Framework 4.0 building in Core ### 3.0.0 (2023-11-14) diff --git a/MPF.Check/Program.cs b/MPF.Check/Program.cs index 6f766399..9cd955c1 100644 --- a/MPF.Check/Program.cs +++ b/MPF.Check/Program.cs @@ -50,7 +50,7 @@ namespace MPF.Check #else (bool? _, string? message) = RedumpHttpClient.ValidateCredentials(options.RedumpUsername ?? string.Empty, options.RedumpPassword ?? string.Empty).ConfigureAwait(false).GetAwaiter().GetResult(); #endif - if (!string.IsNullOrWhiteSpace(message)) + if (!string.IsNullOrEmpty(message)) Console.WriteLine(message); // Loop through all the rest of the args @@ -68,13 +68,13 @@ namespace MPF.Check // Now populate an environment Drive? drive = null; - if (!string.IsNullOrWhiteSpace(path)) + if (!string.IsNullOrEmpty(path)) drive = Drive.Create(null, path!); var env = new DumpEnvironment(options, filepath, drive, knownSystem, mediaType, internalProgram: null, parameters: null); // Finally, attempt to do the output dance -#if NET40 +#if NET20 || NET35 || NET40 var result = env.VerifyAndSaveDumpOutput(resultProgress, protectionProgress); #else var result = env.VerifyAndSaveDumpOutput(resultProgress, protectionProgress).ConfigureAwait(false).GetAwaiter().GetResult(); diff --git a/MPF.Core/Converters/EnumConverter.cs b/MPF.Core/Converters/EnumConverter.cs index 9f035ac9..11032b5c 100644 --- a/MPF.Core/Converters/EnumConverter.cs +++ b/MPF.Core/Converters/EnumConverter.cs @@ -1,5 +1,9 @@ using System; +#if NET20 || NET35 +using System.Collections.Generic; +#else using System.Collections.Concurrent; +#endif using System.IO; using System.Reflection; using MPF.Core.Data; @@ -34,7 +38,11 @@ namespace MPF.Core.Converters /// /// Long name method cache /// - private static readonly ConcurrentDictionary LongNameMethods = new(); +#if NET20 || NET35 + private static readonly Dictionary LongNameMethods = []; +#else + private static readonly ConcurrentDictionary LongNameMethods = []; +#endif /// /// Get the string representation of a generic enumerable value @@ -51,10 +59,13 @@ namespace MPF.Core.Converters if (!LongNameMethods.TryGetValue(sourceType, out var method)) { method = typeof(Extensions).GetMethod("LongName", [typeof(Nullable<>).MakeGenericType(sourceType)]); - if (method == null) - method = typeof(EnumConverter).GetMethod("LongName", [typeof(Nullable<>).MakeGenericType(sourceType)]); + method ??= typeof(EnumConverter).GetMethod("LongName", [typeof(Nullable<>).MakeGenericType(sourceType)]); +#if NET20 || NET35 + LongNameMethods[sourceType] = method; +#else LongNameMethods.TryAdd(sourceType, method); +#endif } if (method != null) @@ -99,7 +110,7 @@ namespace MPF.Core.Converters }; } - #endregion +#endregion #region Convert From String diff --git a/MPF.Core/Data/Constants.cs b/MPF.Core/Data/Constants.cs index 973a695f..716d6bd4 100644 --- a/MPF.Core/Data/Constants.cs +++ b/MPF.Core/Data/Constants.cs @@ -17,7 +17,7 @@ namespace MPF.Core.Data public static readonly byte[] SaturnSectorZeroStart = [0x53, 0x45, 0x47, 0x41, 0x20, 0x53, 0x45, 0x47, 0x41, 0x53, 0x41, 0x54, 0x55, 0x52, 0x4E, 0x20]; // Lists of known drive speed ranges -#if NET40 +#if NET20 || NET35 || NET40 public static IList CD { get; } = new List { 1, 2, 3, 4, 6, 8, 12, 16, 20, 24, 32, 40, 44, 48, 52, 56, 72 }; public static IList DVD { get; } = CD.Where(s => s <= 24).ToList(); public static IList HDDVD { get; } = CD.Where(s => s <= 24).ToList(); @@ -36,7 +36,7 @@ namespace MPF.Core.Data /// /// MediaType? that represents the current item /// Read-only list of drive speeds -#if NET40 +#if NET20 || NET35 || NET40 public static IList GetSpeedsForMediaType(MediaType? type) #else public static IReadOnlyList GetSpeedsForMediaType(MediaType? type) diff --git a/MPF.Core/Data/Drive.cs b/MPF.Core/Data/Drive.cs index 44884282..ad823bb7 100644 --- a/MPF.Core/Data/Drive.cs +++ b/MPF.Core/Data/Drive.cs @@ -66,7 +66,7 @@ namespace MPF.Core.Data string? volumeLabel = Template.DiscNotDetected; if (this.MarkedActive) { - if (string.IsNullOrWhiteSpace(this.VolumeLabel)) + if (string.IsNullOrEmpty(this.VolumeLabel)) volumeLabel = "track"; else volumeLabel = this.VolumeLabel; @@ -106,7 +106,7 @@ namespace MPF.Core.Data }; // If we have an invalid device path, return null - if (string.IsNullOrWhiteSpace(devicePath)) + if (string.IsNullOrEmpty(devicePath)) return null; // Sanitize a Windows-formatted long device path @@ -251,7 +251,7 @@ namespace MPF.Core.Data public RedumpSystem? GetRedumpSystem(RedumpSystem? defaultValue) { // If we can't read the media in that drive, we can't do anything - if (string.IsNullOrWhiteSpace(this.Name) || !Directory.Exists(this.Name)) + if (string.IsNullOrEmpty(this.Name) || !Directory.Exists(this.Name)) return defaultValue; // We're going to assume for floppies, HDDs, and removable drives @@ -269,7 +269,11 @@ namespace MPF.Core.Data // Bandai Playdia Quick Interactive System try { +#if NET20 || NET35 + List files = Directory.GetFiles(this.Name, "*", SearchOption.TopDirectoryOnly).ToList(); +#else List files = Directory.EnumerateFiles(this.Name, "*", SearchOption.TopDirectoryOnly).ToList(); +#endif if (files.Any(f => f.EndsWith(".AJS", StringComparison.OrdinalIgnoreCase)) && files.Any(f => f.EndsWith(".GLB", StringComparison.OrdinalIgnoreCase))) @@ -286,7 +290,11 @@ namespace MPF.Core.Data } // Mattel Fisher-Price iXL +#if NET20 || NET35 + if (File.Exists(Path.Combine(Path.Combine(this.Name, "iXL"), "iXLUpdater.exe"))) +#else if (File.Exists(Path.Combine(this.Name, "iXL", "iXLUpdater.exe"))) +#endif { return RedumpSystem.MattelFisherPriceiXL; } @@ -295,7 +303,11 @@ namespace MPF.Core.Data try { if (Directory.Exists(Path.Combine(this.Name, "$SystemUpdate")) +#if NET20 || NET35 + && Directory.GetFiles(Path.Combine(this.Name, "$SystemUpdate")).Any() +#else && Directory.EnumerateFiles(Path.Combine(this.Name, "$SystemUpdate")).Any() +#endif && this.TotalSize <= 500_000_000) { return RedumpSystem.MicrosoftXbox360; @@ -307,7 +319,11 @@ namespace MPF.Core.Data try { if (Directory.Exists(Path.Combine(this.Name, "MSXC")) +#if NET20 || NET35 + && Directory.GetFiles(Path.Combine(this.Name, "MSXC")).Any()) +#else && Directory.EnumerateFiles(Path.Combine(this.Name, "MSXC")).Any()) +#endif { return RedumpSystem.MicrosoftXboxOne; } @@ -321,10 +337,17 @@ namespace MPF.Core.Data } // Sega Mega-CD / Sega-CD +#if NET20 || NET35 + if (File.Exists(Path.Combine(Path.Combine(this.Name, "_BOOT"), "IP.BIN")) + || File.Exists(Path.Combine(Path.Combine(this.Name, "_BOOT"), "SP.BIN")) + || File.Exists(Path.Combine(Path.Combine(this.Name, "_BOOT"), "SP_AS.BIN")) + || File.Exists(Path.Combine(this.Name, "FILESYSTEM.BIN"))) +#else if (File.Exists(Path.Combine(this.Name, "_BOOT", "IP.BIN")) || File.Exists(Path.Combine(this.Name, "_BOOT", "SP.BIN")) || File.Exists(Path.Combine(this.Name, "_BOOT", "SP_AS.BIN")) || File.Exists(Path.Combine(this.Name, "FILESYSTEM.BIN"))) +#endif { return RedumpSystem.SegaMegaCDSegaCD; } @@ -370,7 +393,11 @@ namespace MPF.Core.Data // Is used as an on-disc update for the base game app without needing to get update from the internet. // "/addcont/GAME_SERIAL/CONTENT_ID/ac.pkg" can be found in Redump entry 97619. // Originally on disc as "/addcont/CUSA00288/FFXIVEXPS400001A/ac.pkg". +#if NET20 || NET35 + if (File.Exists(Path.Combine(Path.Combine(Path.Combine(this.Name, "PS4"), "UPDATE"), "PS4UPDATE.PUP"))) +#else if (File.Exists(Path.Combine(this.Name, "PS4", "UPDATE", "PS4UPDATE.PUP"))) +#endif { return RedumpSystem.SonyPlayStation4; } @@ -381,7 +408,7 @@ namespace MPF.Core.Data return RedumpSystem.VTechVFlashVSmilePro; } - #endregion +#endregion #region Computers @@ -406,13 +433,21 @@ namespace MPF.Core.Data try { if (Directory.Exists(Path.Combine(this.Name, "AUDIO_TS")) +#if NET20 || NET35 + && Directory.GetFiles(Path.Combine(this.Name, "AUDIO_TS")).Any()) +#else && Directory.EnumerateFiles(Path.Combine(this.Name, "AUDIO_TS")).Any()) +#endif { return RedumpSystem.DVDAudio; } else if (Directory.Exists(Path.Combine(this.Name, "VIDEO_TS")) +#if NET20 || NET35 + && Directory.GetFiles(Path.Combine(this.Name, "VIDEO_TS")).Any()) +#else && Directory.EnumerateFiles(Path.Combine(this.Name, "VIDEO_TS")).Any()) +#endif { return RedumpSystem.DVDVideo; } @@ -423,7 +458,11 @@ namespace MPF.Core.Data try { if (Directory.Exists(Path.Combine(this.Name, "HVDVD_TS")) +#if NET20 || NET35 + && Directory.GetFiles(Path.Combine(this.Name, "HVDVD_TS")).Any()) +#else && Directory.EnumerateFiles(Path.Combine(this.Name, "HVDVD_TS")).Any()) +#endif { return RedumpSystem.HDDVDVideo; } @@ -434,14 +473,18 @@ namespace MPF.Core.Data try { if (Directory.Exists(Path.Combine(this.Name, "VCD")) +#if NET20 || NET35 + && Directory.GetFiles(Path.Combine(this.Name, "VCD")).Any()) +#else && Directory.EnumerateFiles(Path.Combine(this.Name, "VCD")).Any()) +#endif { return RedumpSystem.VideoCD; } } catch { } - #endregion +#endregion // Default return return defaultValue; @@ -454,7 +497,7 @@ namespace MPF.Core.Data public RedumpSystem? GetRedumpSystemFromVolumeLabel() { // If the volume label is empty, we can't do anything - if (string.IsNullOrWhiteSpace(this.VolumeLabel)) + if (string.IsNullOrEmpty(this.VolumeLabel)) return null; // Audio CD @@ -507,7 +550,7 @@ namespace MPF.Core.Data this.PopulateFromDriveInfo(driveInfo); } - #endregion +#endregion #region Helpers diff --git a/MPF.Core/Data/IniFile.cs b/MPF.Core/Data/IniFile.cs index d60e6b22..aba4e019 100644 --- a/MPF.Core/Data/IniFile.cs +++ b/MPF.Core/Data/IniFile.cs @@ -102,7 +102,7 @@ namespace MPF.Core.Data var line = sr.ReadLine()?.Trim(); // Empty lines are skipped - if (string.IsNullOrWhiteSpace(line)) + if (string.IsNullOrEmpty(line)) { // No-op, we don't process empty lines } @@ -127,7 +127,7 @@ namespace MPF.Core.Data // If the value field contains an '=', we need to put them back in string key = data[0].Trim(); - string value = string.Join("=", data.Skip(1)).Trim(); + string value = string.Join("=", data.Skip(1).ToArray()).Trim(); // Section names are prepended to the key with a '.' separating if (!string.IsNullOrEmpty(section)) diff --git a/MPF.Core/Data/Options.cs b/MPF.Core/Data/Options.cs index f9f32db0..f9861304 100644 --- a/MPF.Core/Data/Options.cs +++ b/MPF.Core/Data/Options.cs @@ -598,7 +598,7 @@ namespace MPF.Core.Data /// /// Determine if a complete set of Redump credentials might exist /// - public bool HasRedumpLogin { get => !string.IsNullOrWhiteSpace(RedumpUsername) && !string.IsNullOrWhiteSpace(RedumpPassword); } + public bool HasRedumpLogin { get => !string.IsNullOrEmpty(RedumpUsername) && !string.IsNullOrEmpty(RedumpPassword); } #endregion diff --git a/MPF.Core/Data/ProcessingQueue.cs b/MPF.Core/Data/ProcessingQueue.cs index 9001349c..9d695524 100644 --- a/MPF.Core/Data/ProcessingQueue.cs +++ b/MPF.Core/Data/ProcessingQueue.cs @@ -1,5 +1,9 @@ using System; +#if NET20 || NET35 +using System.Collections.Generic; +#else using System.Collections.Concurrent; +#endif using System.Threading; using System.Threading.Tasks; @@ -10,7 +14,11 @@ namespace MPF.Core.Data /// /// Internal queue to hold data to process /// +#if NET20 || NET35 + private readonly Queue InternalQueue; +#else private readonly ConcurrentQueue InternalQueue; +#endif /// /// Custom processing step for dequeued data @@ -24,10 +32,16 @@ namespace MPF.Core.Data public ProcessingQueue(Action customProcessing) { +#if NET20 || NET35 + this.InternalQueue = new Queue(); +#else this.InternalQueue = new ConcurrentQueue(); +#endif this.CustomProcessing = customProcessing; this.TokenSource = new CancellationTokenSource(); -#if NET40 +#if NET20 || NET35 + Task.Run(() => ProcessQueue()); +#elif NET40 Task.Factory.StartNew(() => ProcessQueue()); #else Task.Run(() => ProcessQueue(), this.TokenSource.Token); @@ -58,7 +72,11 @@ namespace MPF.Core.Data while (true) { // Nothing in the queue means we get to idle +#if NET20 || NET35 + if (InternalQueue.Count == 0) +#else if (InternalQueue.IsEmpty) +#endif { if (this.TokenSource.IsCancellationRequested) break; @@ -67,12 +85,17 @@ namespace MPF.Core.Data continue; } +#if NET20 || NET35 + // Get the next item from the queue and invoke the lambda, if possible + this.CustomProcessing?.Invoke(this.InternalQueue.Dequeue()); +#else // Get the next item from the queue if (!this.InternalQueue.TryDequeue(out var nextItem)) continue; // Invoke the lambda, if possible this.CustomProcessing?.Invoke(nextItem); +#endif } } } diff --git a/MPF.Core/DumpEnvironment.cs b/MPF.Core/DumpEnvironment.cs index f9255d8d..bbeea768 100644 --- a/MPF.Core/DumpEnvironment.cs +++ b/MPF.Core/DumpEnvironment.cs @@ -65,7 +65,7 @@ namespace MPF.Core /// /// Generic way of reporting a message /// -#if NET40 +#if NET20 || NET35 || NET40 public EventHandler? ReportStatus; #else public EventHandler? ReportStatus; @@ -79,7 +79,7 @@ namespace MPF.Core /// /// Event handler for data returned from a process /// -#if NET40 +#if NET20 || NET35 || NET40 private void OutputToLog(object? proc, BaseParameters.StringEventArgs args) => outputQueue?.Enqueue(args.Value); #else private void OutputToLog(object? proc, string args) => outputQueue?.Enqueue(args); @@ -88,7 +88,7 @@ namespace MPF.Core /// /// Process the outputs in the queue /// -#if NET40 +#if NET20 || NET35 || NET40 private void ProcessOutputs(string nextOutput) => ReportStatus?.Invoke(this, new BaseParameters.StringEventArgs { Value = nextOutput }); #else private void ProcessOutputs(string nextOutput) => ReportStatus?.Invoke(this, nextOutput); @@ -211,7 +211,7 @@ namespace MPF.Core /// /// Reset the current drive using DiscImageCreator - /// \ + /// public async Task ResetDrive() => await RunStandaloneDiscImageCreatorCommand(Modules.DiscImageCreator.CommandStrings.Reset); @@ -219,7 +219,11 @@ namespace MPF.Core /// Execute the initial invocation of the dumping programs /// /// Optional result progress callback +#if NET20 || NET35 || NET40 + public Result Run(IProgress? progress = null) +#else public async Task Run(IProgress? progress = null) +#endif { // If we don't have parameters if (Parameters == null) @@ -242,11 +246,12 @@ namespace MPF.Core progress?.Report(Result.Success($"Executing {InternalProgram}... {(Options.ToolsInSeparateWindow ? "please wait!" : "see log for output!")}")); var directoryName = Path.GetDirectoryName(OutputPath); - if (!string.IsNullOrWhiteSpace(directoryName)) + if (!string.IsNullOrEmpty(directoryName)) Directory.CreateDirectory(directoryName); -#if NET40 - await Task.Factory.StartNew(() => Parameters.ExecuteInternalProgram(Options.ToolsInSeparateWindow)); +#if NET20 || NET35 || NET40 + var executeTask = Task.Factory.StartNew(() => Parameters.ExecuteInternalProgram(Options.ToolsInSeparateWindow)); + executeTask.Wait(); #else await Task.Run(() => Parameters.ExecuteInternalProgram(Options.ToolsInSeparateWindow)); #endif @@ -442,7 +447,7 @@ namespace MPF.Core private static async Task ExecuteInternalProgram(BaseParameters parameters) { Process childProcess; -#if NET40 +#if NET20 || NET35 || NET40 string output = await Task.Factory.StartNew(() => #else string output = await Task.Run(() => @@ -512,7 +517,7 @@ namespace MPF.Core private bool RequiredProgramsExist() { // Validate that the path is configured - if (string.IsNullOrWhiteSpace(Options.DiscImageCreatorPath)) + if (string.IsNullOrEmpty(Options.DiscImageCreatorPath)) return false; // Validate that the required program exists diff --git a/MPF.Core/Hashing/Hasher.cs b/MPF.Core/Hashing/Hasher.cs index b12e4483..66398eff 100644 --- a/MPF.Core/Hashing/Hasher.cs +++ b/MPF.Core/Hashing/Hasher.cs @@ -277,7 +277,7 @@ namespace MPF.Core.Hashing ha.TransformBlock(buffer, 0, size, null, 0); break; case NonCryptographicHashAlgorithm ncha: -#if NET40 +#if NET20 || NET35 || NET40 byte[] bufferSpan = new byte[size]; Array.Copy(buffer, bufferSpan, size); #else diff --git a/MPF.Core/Hashing/OptimizedCRC.cs b/MPF.Core/Hashing/OptimizedCRC.cs index 11b30340..cffeed7d 100644 --- a/MPF.Core/Hashing/OptimizedCRC.cs +++ b/MPF.Core/Hashing/OptimizedCRC.cs @@ -31,7 +31,7 @@ namespace MPF.Core.Hashing /// internal abstract class NonCryptographicHashAlgorithm { -#if NET40 +#if NET20 || NET35 || NET40 /// /// When overridden in a derived class, appends the contents of source to /// the data already processed for the current hash computation. @@ -109,7 +109,7 @@ namespace MPF.Core.Hashing } /// -#if NET40 +#if NET20 || NET35 || NET40 public override void Append(byte[] source) { Update(source, 0, source.Length); diff --git a/MPF.Core/InfoTool.cs b/MPF.Core/InfoTool.cs index 044eaa52..7fafc0d8 100644 --- a/MPF.Core/InfoTool.cs +++ b/MPF.Core/InfoTool.cs @@ -45,7 +45,7 @@ namespace MPF.Core // Then get the base path for all checking string basePath; - if (string.IsNullOrWhiteSpace(outputDirectory)) + if (string.IsNullOrEmpty(outputDirectory)) basePath = outputFilename; else basePath = Path.Combine(outputDirectory, outputFilename); @@ -122,7 +122,7 @@ namespace MPF.Core internal static Datafile? GetDatafile(string? dat) { // If there's no path, we can't read the file - if (string.IsNullOrWhiteSpace(dat)) + if (string.IsNullOrEmpty(dat)) return null; // If the file doesn't exist, we can't read it @@ -182,7 +182,7 @@ namespace MPF.Core /// Filled DateTime on success, null on failure internal static DateTime? GetFileModifiedDate(string? filename, bool fallback = false) { - if (string.IsNullOrWhiteSpace(filename)) + if (string.IsNullOrEmpty(filename)) return fallback ? (DateTime?)DateTime.UtcNow : null; else if (!File.Exists(filename)) return fallback ? (DateTime?)DateTime.UtcNow : null; @@ -248,7 +248,7 @@ namespace MPF.Core { size = -1; crc32 = null; md5 = null; sha1 = null; - if (string.IsNullOrWhiteSpace(hashData)) + if (string.IsNullOrEmpty(hashData)) return false; var hashreg = new Regex(@"True if the process succeeded, false otherwise public static (bool, string) CompressLogFiles(string? outputDirectory, string? filenameSuffix, string outputFilename, BaseParameters? parameters) { -#if NET40 - return (false, "Log compression is not available for .NET Framework 4.0"); +#if NET20 || NET35 || NET40 + return (false, "Log compression is not available for this framework version"); #else // If there are no parameters if (parameters == null) @@ -1101,7 +1101,7 @@ namespace MPF.Core // Prepare the necessary paths outputFilename = Path.GetFileNameWithoutExtension(outputFilename); string combinedBase; - if (string.IsNullOrWhiteSpace(outputDirectory)) + if (string.IsNullOrEmpty(outputDirectory)) combinedBase = outputFilename; else combinedBase = Path.Combine(outputDirectory, outputFilename); @@ -1136,7 +1136,7 @@ namespace MPF.Core zf = ZipFile.Open(archiveName, ZipArchiveMode.Create); foreach (string file in files) { - if (string.IsNullOrWhiteSpace(outputDirectory)) + if (string.IsNullOrEmpty(outputDirectory)) { zf.CreateEntryFromFile(file, file, CompressionLevel.Optimal); } @@ -1191,7 +1191,7 @@ namespace MPF.Core // Prepare the necessary paths outputFilename = Path.GetFileNameWithoutExtension(outputFilename); string combinedBase; - if (string.IsNullOrWhiteSpace(outputDirectory)) + if (string.IsNullOrEmpty(outputDirectory)) combinedBase = outputFilename; else combinedBase = Path.Combine(outputDirectory, outputFilename); @@ -1240,13 +1240,13 @@ namespace MPF.Core { // Get the file path var path = string.Empty; - if (string.IsNullOrWhiteSpace(outputDirectory) && string.IsNullOrWhiteSpace(filenameSuffix)) + if (string.IsNullOrEmpty(outputDirectory) && string.IsNullOrEmpty(filenameSuffix)) path = "!submissionInfo.txt"; - else if (string.IsNullOrWhiteSpace(outputDirectory) && !string.IsNullOrWhiteSpace(filenameSuffix)) + else if (string.IsNullOrEmpty(outputDirectory) && !string.IsNullOrEmpty(filenameSuffix)) path = $"!submissionInfo_{filenameSuffix}.txt"; - else if (!string.IsNullOrWhiteSpace(outputDirectory) && string.IsNullOrWhiteSpace(filenameSuffix)) + else if (!string.IsNullOrEmpty(outputDirectory) && string.IsNullOrEmpty(filenameSuffix)) path = Path.Combine(outputDirectory, "!submissionInfo.txt"); - else if (!string.IsNullOrWhiteSpace(outputDirectory) && !string.IsNullOrWhiteSpace(filenameSuffix)) + else if (!string.IsNullOrEmpty(outputDirectory) && !string.IsNullOrEmpty(filenameSuffix)) path = Path.Combine(outputDirectory, $"!submissionInfo_{filenameSuffix}.txt"); using var sw = new StreamWriter(File.Open(path, FileMode.Create, FileAccess.Write)); @@ -1288,13 +1288,13 @@ namespace MPF.Core if (includedArtifacts) { var path = string.Empty; - if (string.IsNullOrWhiteSpace(outputDirectory) && string.IsNullOrWhiteSpace(filenameSuffix)) + if (string.IsNullOrEmpty(outputDirectory) && string.IsNullOrEmpty(filenameSuffix)) path = "!submissionInfo.json.gz"; - else if (string.IsNullOrWhiteSpace(outputDirectory) && !string.IsNullOrWhiteSpace(filenameSuffix)) + else if (string.IsNullOrEmpty(outputDirectory) && !string.IsNullOrEmpty(filenameSuffix)) path = $"!submissionInfo_{filenameSuffix}.json.gz"; - else if (!string.IsNullOrWhiteSpace(outputDirectory) && string.IsNullOrWhiteSpace(filenameSuffix)) + else if (!string.IsNullOrEmpty(outputDirectory) && string.IsNullOrEmpty(filenameSuffix)) path = Path.Combine(outputDirectory, "!submissionInfo.json.gz"); - else if (!string.IsNullOrWhiteSpace(outputDirectory) && !string.IsNullOrWhiteSpace(filenameSuffix)) + else if (!string.IsNullOrEmpty(outputDirectory) && !string.IsNullOrEmpty(filenameSuffix)) path = Path.Combine(outputDirectory, $"!submissionInfo_{filenameSuffix}.json.gz"); using var fs = File.Create(path); @@ -1306,13 +1306,13 @@ namespace MPF.Core else { var path = string.Empty; - if (string.IsNullOrWhiteSpace(outputDirectory) && string.IsNullOrWhiteSpace(filenameSuffix)) + if (string.IsNullOrEmpty(outputDirectory) && string.IsNullOrEmpty(filenameSuffix)) path = "!submissionInfo.json"; - else if (string.IsNullOrWhiteSpace(outputDirectory) && !string.IsNullOrWhiteSpace(filenameSuffix)) + else if (string.IsNullOrEmpty(outputDirectory) && !string.IsNullOrEmpty(filenameSuffix)) path = $"!submissionInfo_{filenameSuffix}.json"; - else if (!string.IsNullOrWhiteSpace(outputDirectory) && string.IsNullOrWhiteSpace(filenameSuffix)) + else if (!string.IsNullOrEmpty(outputDirectory) && string.IsNullOrEmpty(filenameSuffix)) path = Path.Combine(outputDirectory, "!submissionInfo.json"); - else if (!string.IsNullOrWhiteSpace(outputDirectory) && !string.IsNullOrWhiteSpace(filenameSuffix)) + else if (!string.IsNullOrEmpty(outputDirectory) && !string.IsNullOrEmpty(filenameSuffix)) path = Path.Combine(outputDirectory, $"!submissionInfo_{filenameSuffix}.json"); using var fs = File.Create(path); @@ -1346,13 +1346,13 @@ namespace MPF.Core try { var path = string.Empty; - if (string.IsNullOrWhiteSpace(outputDirectory) && string.IsNullOrWhiteSpace(filenameSuffix)) + if (string.IsNullOrEmpty(outputDirectory) && string.IsNullOrEmpty(filenameSuffix)) path = "!protectionInfo.txt"; - else if (string.IsNullOrWhiteSpace(outputDirectory) && !string.IsNullOrWhiteSpace(filenameSuffix)) + else if (string.IsNullOrEmpty(outputDirectory) && !string.IsNullOrEmpty(filenameSuffix)) path = $"!protectionInfo{filenameSuffix}.txt"; - else if (!string.IsNullOrWhiteSpace(outputDirectory) && string.IsNullOrWhiteSpace(filenameSuffix)) + else if (!string.IsNullOrEmpty(outputDirectory) && string.IsNullOrEmpty(filenameSuffix)) path = Path.Combine(outputDirectory, "!protectionInfo.txt"); - else if (!string.IsNullOrWhiteSpace(outputDirectory) && !string.IsNullOrWhiteSpace(filenameSuffix)) + else if (!string.IsNullOrEmpty(outputDirectory) && !string.IsNullOrEmpty(filenameSuffix)) path = Path.Combine(outputDirectory, $"!protectionInfo{filenameSuffix}.txt"); using var sw = new StreamWriter(File.Open(path, FileMode.Create, FileAccess.Write)); @@ -1383,7 +1383,7 @@ namespace MPF.Core { var files = new List(); - if (string.IsNullOrWhiteSpace(outputDirectory) && string.IsNullOrWhiteSpace(filenameSuffix)) + if (string.IsNullOrEmpty(outputDirectory) && string.IsNullOrEmpty(filenameSuffix)) { if (File.Exists("!submissionInfo.txt")) files.Add("!submissionInfo.txt"); @@ -1394,7 +1394,7 @@ namespace MPF.Core if (File.Exists("!protectionInfo.txt")) files.Add("!protectionInfo.txt"); } - else if (string.IsNullOrWhiteSpace(outputDirectory) && !string.IsNullOrWhiteSpace(filenameSuffix)) + else if (string.IsNullOrEmpty(outputDirectory) && !string.IsNullOrEmpty(filenameSuffix)) { if (File.Exists($"!submissionInfo_{filenameSuffix}.txt")) files.Add($"!submissionInfo_{filenameSuffix}.txt"); @@ -1405,7 +1405,7 @@ namespace MPF.Core if (File.Exists($"!protectionInfo_{filenameSuffix}.txt")) files.Add($"!protectionInfo_{filenameSuffix}.txt"); } - else if (!string.IsNullOrWhiteSpace(outputDirectory) && string.IsNullOrWhiteSpace(filenameSuffix)) + else if (!string.IsNullOrEmpty(outputDirectory) && string.IsNullOrEmpty(filenameSuffix)) { if (File.Exists(Path.Combine(outputDirectory, "!submissionInfo.txt"))) files.Add(Path.Combine(outputDirectory, "!submissionInfo.txt")); @@ -1416,7 +1416,7 @@ namespace MPF.Core if (File.Exists(Path.Combine(outputDirectory, "!protectionInfo.txt"))) files.Add(Path.Combine(outputDirectory, "!protectionInfo.txt")); } - else if (!string.IsNullOrWhiteSpace(outputDirectory) && !string.IsNullOrWhiteSpace(filenameSuffix)) + else if (!string.IsNullOrEmpty(outputDirectory) && !string.IsNullOrEmpty(filenameSuffix)) { if (File.Exists(Path.Combine(outputDirectory, $"!submissionInfo_{filenameSuffix}.txt"))) files.Add(Path.Combine(outputDirectory, $"!submissionInfo_{filenameSuffix}.txt")); @@ -1477,11 +1477,11 @@ namespace MPF.Core public static string NormalizeDiscTitle(string title, Language language) { // If we have an invalid title, just return it as-is - if (string.IsNullOrWhiteSpace(title)) + if (string.IsNullOrEmpty(title)) return title; // Get the title split into parts - string[] splitTitle = title.Split(' ').Where(s => !string.IsNullOrWhiteSpace(s)).ToArray(); + string[] splitTitle = title.Split(' ').Where(s => !string.IsNullOrEmpty(s)).ToArray(); // If we only have one part, we can't do anything if (splitTitle.Length <= 1) @@ -1838,7 +1838,7 @@ namespace MPF.Core try { // If we have an invalid path - if (string.IsNullOrWhiteSpace(path)) + if (string.IsNullOrEmpty(path)) return string.Empty; // Remove quotes from path @@ -1860,7 +1860,7 @@ namespace MPF.Core foreach (char c in Path.GetInvalidFileNameChars()) fullFile = fullFile.Replace(c, '_'); - if (string.IsNullOrWhiteSpace(fullDirectory)) + if (string.IsNullOrEmpty(fullDirectory)) return fullFile; else return Path.Combine(fullDirectory, fullFile); diff --git a/MPF.Core/MPF.Core.csproj b/MPF.Core/MPF.Core.csproj index b086519b..85bd60f8 100644 --- a/MPF.Core/MPF.Core.csproj +++ b/MPF.Core/MPF.Core.csproj @@ -2,7 +2,7 @@ - net452;net462;net472;net48;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0 + net40;net452;net462;net472;net48;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0 win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64;osx-arm64 false latest @@ -25,20 +25,21 @@ - + + + + + + + + - - - - + - + @@ -53,7 +54,7 @@ runtime; compile; build; native; analyzers; buildtransitive - + diff --git a/MPF.Core/Modules/Aaru/Parameters.cs b/MPF.Core/Modules/Aaru/Parameters.cs index 835110ce..e673431b 100644 --- a/MPF.Core/Modules/Aaru/Parameters.cs +++ b/MPF.Core/Modules/Aaru/Parameters.cs @@ -223,11 +223,11 @@ namespace MPF.Core.Modules.Aaru if (GetDiscType(sidecar, out var discType, out var discSubType)) { string fullDiscType = string.Empty; - if (!string.IsNullOrWhiteSpace(discType) && !string.IsNullOrWhiteSpace(discSubType)) + if (!string.IsNullOrEmpty(discType) && !string.IsNullOrEmpty(discSubType)) fullDiscType = $"{discType} ({discSubType})"; - else if (!string.IsNullOrWhiteSpace(discType) && string.IsNullOrWhiteSpace(discSubType)) + else if (!string.IsNullOrEmpty(discType) && string.IsNullOrEmpty(discSubType)) fullDiscType = discType!; - else if (string.IsNullOrWhiteSpace(discType) && !string.IsNullOrWhiteSpace(discSubType)) + else if (string.IsNullOrEmpty(discType) && !string.IsNullOrEmpty(discSubType)) fullDiscType = discSubType!; info.DumpingInfo.ReportedDiscType = fullDiscType; @@ -285,7 +285,7 @@ namespace MPF.Core.Modules.Aaru layerbreak = info.SizeAndChecksums!.Size > 25_025_314_816 ? "25025314816" : null; // If we have a single-layer disc - if (string.IsNullOrWhiteSpace(layerbreak)) + if (string.IsNullOrEmpty(layerbreak)) { // Currently no-op } @@ -456,7 +456,7 @@ namespace MPF.Core.Modules.Aaru BaseCommand ??= CommandStrings.NONE; - if (!string.IsNullOrWhiteSpace(BaseCommand)) + if (!string.IsNullOrEmpty(BaseCommand)) parameters.Add(BaseCommand); else return null; @@ -1082,7 +1082,7 @@ namespace MPF.Core.Modules.Aaru case CommandStrings.ImagePrefixLong + " " + CommandStrings.ImageVerify: case CommandStrings.MediaPrefixLong + " " + CommandStrings.MediaInfo: case CommandStrings.MediaPrefixLong + " " + CommandStrings.MediaScan: - if (string.IsNullOrWhiteSpace(InputValue)) + if (string.IsNullOrEmpty(InputValue)) return null; parameters.Add($"\"{InputValue}\""); @@ -1090,7 +1090,7 @@ namespace MPF.Core.Modules.Aaru // Two input values case CommandStrings.ImagePrefixLong + " " + CommandStrings.ImageCompareLong: - if (string.IsNullOrWhiteSpace(Input1Value) || string.IsNullOrWhiteSpace(Input2Value)) + if (string.IsNullOrEmpty(Input1Value) || string.IsNullOrEmpty(Input2Value)) return null; parameters.Add($"\"{Input1Value}\""); @@ -1101,7 +1101,7 @@ namespace MPF.Core.Modules.Aaru case CommandStrings.FilesystemPrefixLong + " " + CommandStrings.FilesystemExtract: case CommandStrings.ImagePrefixLong + " " + CommandStrings.ImageConvert: case CommandStrings.MediaPrefixLong + " " + CommandStrings.MediaDump: - if (string.IsNullOrWhiteSpace(InputValue) || string.IsNullOrWhiteSpace(OutputValue)) + if (string.IsNullOrEmpty(InputValue) || string.IsNullOrEmpty(OutputValue)) return null; parameters.Add($"\"{InputValue}\""); @@ -1111,7 +1111,7 @@ namespace MPF.Core.Modules.Aaru // Remote host value only case CommandStrings.DevicePrefixLong + " " + CommandStrings.DeviceList: case CommandStrings.Remote: - if (string.IsNullOrWhiteSpace(RemoteHostValue)) + if (string.IsNullOrEmpty(RemoteHostValue)) return null; parameters.Add($"\"{RemoteHostValue}\""); @@ -1601,7 +1601,7 @@ namespace MPF.Core.Modules.Aaru BaseCommand = CommandStrings.NONE; // The string has to be valid by itself first - if (string.IsNullOrWhiteSpace(parameters)) + if (string.IsNullOrEmpty(parameters)) return false; // Now split the string into parts for easier validation @@ -1646,7 +1646,7 @@ namespace MPF.Core.Modules.Aaru // Determine what the commandline should look like given the first item BaseCommand = NormalizeCommand(parts, ref start); - if (string.IsNullOrWhiteSpace(BaseCommand)) + if (string.IsNullOrEmpty(BaseCommand)) return false; // Set the start position @@ -2151,7 +2151,7 @@ namespace MPF.Core.Modules.Aaru private static string? NormalizeCommand(string baseCommand) { // If the base command is inavlid, just return nulls - if (string.IsNullOrWhiteSpace(baseCommand)) + if (string.IsNullOrEmpty(baseCommand)) return null; // Split the command otherwise @@ -2273,11 +2273,11 @@ namespace MPF.Core.Modules.Aaru } // If the command itself is invalid, then return null - if (string.IsNullOrWhiteSpace(command)) + if (string.IsNullOrEmpty(command)) return null; // Combine the result - if (!string.IsNullOrWhiteSpace(family)) + if (!string.IsNullOrEmpty(family)) return $"{family} {command}"; else return command; @@ -2753,7 +2753,7 @@ namespace MPF.Core.Modules.Aaru // Build each row in consecutive order string pvd = string.Empty; -#if NET40 +#if NET20 || NET35 || NET40 byte[] pvdLine = new byte[16]; Array.Copy(pvdData, 0, pvdLine, 0, 16); pvd += GenerateSectorOutputLine("0320", pvdLine); @@ -3024,7 +3024,7 @@ namespace MPF.Core.Modules.Aaru // Loop through each OpticalDisc in the metadata foreach (OpticalDiscType opticalDisc in cicmSidecar.OpticalDisc) { - if (!string.IsNullOrWhiteSpace(opticalDisc.CopyProtection)) + if (!string.IsNullOrEmpty(opticalDisc.CopyProtection)) copyrightProtectionSystemType += $", {opticalDisc.CopyProtection}"; } @@ -3076,7 +3076,7 @@ namespace MPF.Core.Modules.Aaru var line = sr.ReadLine()?.Trim(); // Initialize on seeing the open tag - if (string.IsNullOrWhiteSpace(line)) + if (string.IsNullOrEmpty(line)) continue; else if (line!.StartsWith("")) totalErrors = 0; diff --git a/MPF.Core/Modules/BaseParameters.cs b/MPF.Core/Modules/BaseParameters.cs index a96b3d76..66f22710 100644 --- a/MPF.Core/Modules/BaseParameters.cs +++ b/MPF.Core/Modules/BaseParameters.cs @@ -14,7 +14,7 @@ namespace MPF.Core.Modules { #region Event Handlers -#if NET40 +#if NET20 || NET35 || NET40 /// /// Wrapper event args class for old .NET /// @@ -262,7 +262,7 @@ namespace MPF.Core.Modules /// /// String possibly representing parameters /// True if the parameters were set correctly, false otherwise - protected virtual bool ValidateAndSetParameters(string? parameters) => !string.IsNullOrWhiteSpace(parameters); + protected virtual bool ValidateAndSetParameters(string? parameters) => !string.IsNullOrEmpty(parameters); #endregion @@ -294,8 +294,13 @@ namespace MPF.Core.Modules // Start processing tasks, if necessary if (!separateWindow) { +#if NET40 + Logging.OutputToLog(process.StandardOutput, this, ReportStatus); + Logging.OutputToLog(process.StandardError, this, ReportStatus); +#else _ = Logging.OutputToLog(process.StandardOutput, this, ReportStatus); _ = Logging.OutputToLog(process.StandardError, this, ReportStatus); +#endif } process.WaitForExit(); @@ -926,7 +931,7 @@ namespace MPF.Core.Modules return null; } - else if (string.IsNullOrWhiteSpace(parts[i + 1])) + else if (string.IsNullOrEmpty(parts[i + 1])) { if (missingAllowed) this[longFlagString] = true; diff --git a/MPF.Core/Modules/CleanRIp/Parameters.cs b/MPF.Core/Modules/CleanRIp/Parameters.cs index 6ca5ff1f..29c69c56 100644 --- a/MPF.Core/Modules/CleanRIp/Parameters.cs +++ b/MPF.Core/Modules/CleanRIp/Parameters.cs @@ -167,7 +167,7 @@ namespace MPF.Core.Modules.CleanRip while (!sr.EndOfStream) { var line = sr.ReadLine()?.Trim(); - if (string.IsNullOrWhiteSpace(line)) + if (string.IsNullOrEmpty(line)) continue; else if (line!.StartsWith("CRC32")) crc = line.Substring(7).ToLowerInvariant(); @@ -253,7 +253,7 @@ namespace MPF.Core.Modules.CleanRip while (!sr.EndOfStream) { var line = sr.ReadLine()?.Trim(); - if (string.IsNullOrWhiteSpace(line)) + if (string.IsNullOrEmpty(line)) continue; else if (line!.StartsWith("CRC32")) crc = line.Substring(7).ToLowerInvariant(); @@ -299,7 +299,7 @@ namespace MPF.Core.Modules.CleanRip while (!sr.EndOfStream) { var line = sr.ReadLine()?.Trim(); - if (string.IsNullOrWhiteSpace(line)) + if (string.IsNullOrEmpty(line)) { continue; } diff --git a/MPF.Core/Modules/DiscImageCreator/Parameters.cs b/MPF.Core/Modules/DiscImageCreator/Parameters.cs index b17a032f..4428456f 100644 --- a/MPF.Core/Modules/DiscImageCreator/Parameters.cs +++ b/MPF.Core/Modules/DiscImageCreator/Parameters.cs @@ -442,7 +442,7 @@ namespace MPF.Core.Modules.DiscImageCreator // Attempt to get multisession data string cdMultiSessionInfo = GetMultisessionInformation($"{basePath}_disc.txt") ?? string.Empty; - if (!string.IsNullOrWhiteSpace(cdMultiSessionInfo)) + if (!string.IsNullOrEmpty(cdMultiSessionInfo)) info.CommonDiscInfo.CommentsSpecialFields![SiteCode.Multisession] = cdMultiSessionInfo; break; @@ -543,7 +543,7 @@ namespace MPF.Core.Modules.DiscImageCreator case RedumpSystem.MicrosoftXbox: string xmidString; - if (string.IsNullOrWhiteSpace(outputDirectory)) + if (string.IsNullOrEmpty(outputDirectory)) xmidString = GetXGD1XMID($"{basePath}_DMI.bin"); else xmidString = GetXGD1XMID(Path.Combine(outputDirectory, $"{basePath}_DMI.bin")); @@ -592,7 +592,7 @@ namespace MPF.Core.Modules.DiscImageCreator case RedumpSystem.MicrosoftXbox360: string xemidString; - if (string.IsNullOrWhiteSpace(outputDirectory)) + if (string.IsNullOrEmpty(outputDirectory)) xemidString = GetXGD23XeMID($"{basePath}_DMI.bin"); else xemidString = GetXGD23XeMID(Path.Combine(outputDirectory, $"{basePath}_DMI.bin")); @@ -887,7 +887,7 @@ namespace MPF.Core.Modules.DiscImageCreator BaseCommand ??= CommandStrings.NONE; - if (!string.IsNullOrWhiteSpace(BaseCommand)) + if (!string.IsNullOrEmpty(BaseCommand)) parameters.Add(BaseCommand); else return null; @@ -1913,7 +1913,7 @@ namespace MPF.Core.Modules.DiscImageCreator BaseCommand = CommandStrings.NONE; // The string has to be valid by itself first - if (string.IsNullOrWhiteSpace(parameters)) + if (string.IsNullOrEmpty(parameters)) return false; // Now split the string into parts for easier validation @@ -2556,7 +2556,7 @@ namespace MPF.Core.Modules.DiscImageCreator private static (string?, string?) GetCommandFilePathAndVersion(string basePath) { // If we have an invalid base path, we can do nothing - if (string.IsNullOrWhiteSpace(basePath)) + if (string.IsNullOrEmpty(basePath)) return (null, null); // Generate the matching regex based on the base path @@ -2565,12 +2565,12 @@ namespace MPF.Core.Modules.DiscImageCreator // Find the first match for the command file var parentDirectory = Path.GetDirectoryName(basePath); - if (string.IsNullOrWhiteSpace(parentDirectory)) + if (string.IsNullOrEmpty(parentDirectory)) return (null, null); var currentFiles = Directory.GetFiles(parentDirectory); var commandPath = currentFiles.FirstOrDefault(f => cmdFilenameRegex.IsMatch(f)); - if (string.IsNullOrWhiteSpace(commandPath)) + if (string.IsNullOrEmpty(commandPath)) return (null, null); // Extract the version string @@ -2886,7 +2886,7 @@ namespace MPF.Core.Modules.DiscImageCreator serial = null; version = null; date = null; // If the input header is null, we can't do a thing - if (string.IsNullOrWhiteSpace(segaHeader)) + if (string.IsNullOrEmpty(segaHeader)) return false; // Now read it in cutting it into lines for easier parsing @@ -3326,7 +3326,7 @@ namespace MPF.Core.Modules.DiscImageCreator serial = null; version = null; date = null; // If the input header is null, we can't do a thing - if (string.IsNullOrWhiteSpace(segaHeader)) + if (string.IsNullOrEmpty(segaHeader)) return false; // Now read it in cutting it into lines for easier parsing @@ -3359,7 +3359,7 @@ namespace MPF.Core.Modules.DiscImageCreator serial = null; date = null; // If the input header is null, we can't do a thing - if (string.IsNullOrWhiteSpace(segaHeader)) + if (string.IsNullOrEmpty(segaHeader)) return false; // Now read it in cutting it into lines for easier parsing diff --git a/MPF.Core/Modules/Redumper/Parameters.cs b/MPF.Core/Modules/Redumper/Parameters.cs index 062fb52b..5c64857a 100644 --- a/MPF.Core/Modules/Redumper/Parameters.cs +++ b/MPF.Core/Modules/Redumper/Parameters.cs @@ -289,7 +289,7 @@ namespace MPF.Core.Modules.Redumper // Attempt to get multisession data string cdMultiSessionInfo = GetMultisessionInformation($"{basePath}.log") ?? string.Empty; - if (!string.IsNullOrWhiteSpace(cdMultiSessionInfo)) + if (!string.IsNullOrEmpty(cdMultiSessionInfo)) info.CommonDiscInfo.CommentsSpecialFields![SiteCode.Multisession] = cdMultiSessionInfo; // Attempt to get the universal hash, if it's an audio disc @@ -724,7 +724,7 @@ namespace MPF.Core.Modules.Redumper // Skip if (this[FlagStrings.Skip] == true) { - if (!string.IsNullOrWhiteSpace(SkipValue)) + if (!string.IsNullOrEmpty(SkipValue)) parameters.Add($"{FlagStrings.Skip}={SkipValue}"); } @@ -982,17 +982,17 @@ namespace MPF.Core.Modules.Redumper } // Set the output paths - if (!string.IsNullOrWhiteSpace(filename)) + if (!string.IsNullOrEmpty(filename)) { var imagePath = Path.GetDirectoryName(filename); - if (!string.IsNullOrWhiteSpace(imagePath)) + if (!string.IsNullOrEmpty(imagePath)) { this[FlagStrings.ImagePath] = true; ImagePathValue = $"\"{imagePath}\""; } string imageName = Path.GetFileNameWithoutExtension(filename); - if (!string.IsNullOrWhiteSpace(imageName)) + if (!string.IsNullOrEmpty(imageName)) { this[FlagStrings.ImageName] = true; ImageNameValue = $"\"{imageName}\""; @@ -1009,7 +1009,7 @@ namespace MPF.Core.Modules.Redumper BaseCommand = CommandStrings.NONE; // The string has to be valid by itself first - if (string.IsNullOrWhiteSpace(parameters)) + if (string.IsNullOrEmpty(parameters)) return false; // Now split the string into parts for easier validation @@ -1087,7 +1087,7 @@ namespace MPF.Core.Modules.Redumper // Drive stringValue = ProcessStringParameter(parts, FlagStrings.Drive, ref i); - if (!string.IsNullOrWhiteSpace(stringValue)) + if (!string.IsNullOrEmpty(stringValue)) DriveValue = stringValue; // Speed @@ -1102,12 +1102,12 @@ namespace MPF.Core.Modules.Redumper // Image Path stringValue = ProcessStringParameter(parts, FlagStrings.ImagePath, ref i); - if (!string.IsNullOrWhiteSpace(stringValue)) + if (!string.IsNullOrEmpty(stringValue)) ImagePathValue = $"\"{stringValue!.Trim('"')}\""; // Image Name stringValue = ProcessStringParameter(parts, FlagStrings.ImageName, ref i); - if (!string.IsNullOrWhiteSpace(stringValue)) + if (!string.IsNullOrEmpty(stringValue)) ImageNameValue = $"\"{stringValue!.Trim('"')}\""; // Overwrite @@ -1119,7 +1119,7 @@ namespace MPF.Core.Modules.Redumper // Drive Type stringValue = ProcessStringParameter(parts, FlagStrings.DriveType, ref i); - if (!string.IsNullOrWhiteSpace(stringValue)) + if (!string.IsNullOrEmpty(stringValue)) DriveTypeValue = stringValue; // Drive Read Offset @@ -1139,12 +1139,12 @@ namespace MPF.Core.Modules.Redumper // Drive Read Method stringValue = ProcessStringParameter(parts, FlagStrings.DriveReadMethod, ref i); - if (!string.IsNullOrWhiteSpace(stringValue)) + if (!string.IsNullOrEmpty(stringValue)) DriveReadMethodValue = stringValue; // Drive Sector Order stringValue = ProcessStringParameter(parts, FlagStrings.DriveSectorOrder, ref i); - if (!string.IsNullOrWhiteSpace(stringValue)) + if (!string.IsNullOrEmpty(stringValue)) DriveSectorOrderValue = stringValue; #endregion @@ -1222,12 +1222,12 @@ namespace MPF.Core.Modules.Redumper // Skip stringValue = ProcessStringParameter(parts, FlagStrings.Skip, ref i); - if (!string.IsNullOrWhiteSpace(stringValue)) + if (!string.IsNullOrEmpty(stringValue)) SkipValue = stringValue; // Skip intValue = ProcessInt32Parameter(parts, FlagStrings.DumpReadSize, ref i); - if (!string.IsNullOrWhiteSpace(stringValue)) + if (!string.IsNullOrEmpty(stringValue)) DumpReadSizeValue = intValue; // Overread Leadout @@ -1237,7 +1237,7 @@ namespace MPF.Core.Modules.Redumper } // If the image name was not set, set it with a default value - if (string.IsNullOrWhiteSpace(this.ImageNameValue)) + if (string.IsNullOrEmpty(this.ImageNameValue)) this.ImageNameValue = "track"; return true; @@ -1268,7 +1268,7 @@ namespace MPF.Core.Modules.Redumper // Now that we're at the relevant entries, read each line in and concatenate string? cueString = string.Empty, line = sr.ReadLine()?.Trim(); - while (!string.IsNullOrWhiteSpace(line)) + while (!string.IsNullOrEmpty(line)) { cueString += line + "\n"; line = sr.ReadLine()?.Trim(); @@ -1409,7 +1409,7 @@ namespace MPF.Core.Modules.Redumper vobKeys = string.Empty; line = sr.ReadLine()?.Trim(); - while (!string.IsNullOrWhiteSpace(line)) + while (!string.IsNullOrEmpty(line)) { var match = Regex.Match(line, @"^(.*?): (.*?)$", RegexOptions.Compiled); if (match.Success) @@ -1906,7 +1906,7 @@ namespace MPF.Core.Modules.Redumper serial = null; version = null; date = null; // If the input header is null, we can't do a thing - if (string.IsNullOrWhiteSpace(segaHeader)) + if (string.IsNullOrEmpty(segaHeader)) return false; // Now read it in cutting it into lines for easier parsing @@ -2182,7 +2182,7 @@ namespace MPF.Core.Modules.Redumper // Extract the version string var match = regex.Match(sr.ReadLine()?.Trim() ?? string.Empty); var version = match.Groups[1].Value; - return string.IsNullOrWhiteSpace(version) ? null : version; + return string.IsNullOrEmpty(version) ? null : version; } catch { diff --git a/MPF.Core/Modules/UmdImageCreator/Parameters.cs b/MPF.Core/Modules/UmdImageCreator/Parameters.cs index 911d6037..10988085 100644 --- a/MPF.Core/Modules/UmdImageCreator/Parameters.cs +++ b/MPF.Core/Modules/UmdImageCreator/Parameters.cs @@ -93,7 +93,7 @@ namespace MPF.Core.Modules.UmdImageCreator info.VersionAndEditions!.Version = umdversion ?? string.Empty; info.SizeAndChecksums!.Size = umdsize; - if (!string.IsNullOrWhiteSpace(umdlayer)) + if (!string.IsNullOrEmpty(umdlayer)) info.SizeAndChecksums.Layerbreak = Int64.Parse(umdlayer ?? "-1"); } diff --git a/MPF.Core/Protection.cs b/MPF.Core/Protection.cs index 83bfb993..a1a2ff8f 100644 --- a/MPF.Core/Protection.cs +++ b/MPF.Core/Protection.cs @@ -23,7 +23,7 @@ namespace MPF.Core { try { -#if NET40 +#if NET20 || NET35 || NET40 var found = await Task.Factory.StartNew(() => { var scanner = new BinaryObjectScanner.Scanner( @@ -92,7 +92,7 @@ namespace MPF.Core // Sanitize and join protections for writing string protectionString = SanitizeFoundProtections(orderedDistinctProtections); - if (string.IsNullOrWhiteSpace(protectionString)) + if (string.IsNullOrEmpty(protectionString)) return "None found [OMIT FROM SUBMISSION]"; return protectionString; @@ -109,7 +109,7 @@ namespace MPF.Core if (string.IsNullOrEmpty(path)) return false; -#if NET40 +#if NET20 || NET35 || NET40 return await Task.Factory.StartNew(() => { try @@ -121,7 +121,7 @@ namespace MPF.Core { byte[] fileContent = File.ReadAllBytes(file); var protection = antiModchip.CheckContents(file, fileContent, false); - if (!string.IsNullOrWhiteSpace(protection)) + if (!string.IsNullOrEmpty(protection)) return true; } catch { } @@ -143,7 +143,7 @@ namespace MPF.Core { byte[] fileContent = File.ReadAllBytes(file); var protection = antiModchip.CheckContents(file, fileContent, false); - if (!string.IsNullOrWhiteSpace(protection)) + if (!string.IsNullOrEmpty(protection)) return true; } catch { } @@ -167,7 +167,7 @@ namespace MPF.Core if (!File.Exists(sub)) return null; - return LibCrypt.CheckSubfile(sub); + return LibCrypt.DetectLibCrypt([sub]); } /// @@ -180,7 +180,7 @@ namespace MPF.Core if (foundProtections.Any(p => p.StartsWith("[Exception opening file"))) { foundProtections = foundProtections.Where(p => !p.StartsWith("[Exception opening file")); -#if NET40 || NET452 || NET462 +#if NET20 || NET35 || NET40 || NET452 || NET462 var tempList = new List { "Exception occurred while scanning [RESCAN NEEDED]" }; tempList.AddRange(foundProtections); foundProtections = tempList.OrderBy(p => p); @@ -270,7 +270,7 @@ namespace MPF.Core if (foundProtections.Any(p => !p.StartsWith("SafeDisc"))) { -#if NET40 || NET452 || NET462 +#if NET20 || NET35 || NET40 || NET452 || NET462 var tempList = new List(); tempList.AddRange(foundProtections); tempList.Add("Cactus Data Shield 300"); diff --git a/MPF.Core/SubmissionInfoTool.cs b/MPF.Core/SubmissionInfoTool.cs index 61fb6dca..05147629 100644 --- a/MPF.Core/SubmissionInfoTool.cs +++ b/MPF.Core/SubmissionInfoTool.cs @@ -62,7 +62,7 @@ namespace MPF.Core // Create the SubmissionInfo object with all user-inputted values by default string combinedBase; - if (string.IsNullOrWhiteSpace(outputDirectory)) + if (string.IsNullOrEmpty(outputDirectory)) combinedBase = outputFilename; else combinedBase = Path.Combine(outputDirectory, outputFilename); @@ -99,10 +99,14 @@ namespace MPF.Core // Get a list of matching IDs for each line in the DAT if (!string.IsNullOrEmpty(info.TracksAndWriteOffsets!.ClrMameProData) && options.HasRedumpLogin) +#if NET20 || NET35 || NET40 + _ = FillFromRedump(options, info, resultProgress); +#else _ = await FillFromRedump(options, info, resultProgress); +#endif // If we have both ClrMamePro and Size and Checksums data, remove the ClrMamePro - if (!string.IsNullOrWhiteSpace(info.SizeAndChecksums?.CRC32)) + if (!string.IsNullOrEmpty(info.SizeAndChecksums?.CRC32)) info.TracksAndWriteOffsets.ClrMameProData = null; // Add the volume label to comments, if possible or necessary @@ -441,15 +445,14 @@ namespace MPF.Core /// Options object representing user-defined options /// Existing SubmissionInfo object to fill /// Optional result progress callback - /// TODO: All instances of Task.Factory.StartNew should be propigated down to RedumpLib -#if NET40 +#if NET20 || NET35 || NET40 public static bool FillFromRedump(Options options, SubmissionInfo info, IProgress? resultProgress = null) #else public async static Task FillFromRedump(Options options, SubmissionInfo info, IProgress? resultProgress = null) #endif { // If no username is provided - if (string.IsNullOrWhiteSpace(options.RedumpUsername) || string.IsNullOrWhiteSpace(options.RedumpPassword)) + if (string.IsNullOrEmpty(options.RedumpUsername) || string.IsNullOrEmpty(options.RedumpPassword)) return false; // Set the current dumper based on username @@ -487,7 +490,7 @@ namespace MPF.Core foreach (string hashData in splitData ?? []) { // Catch any errant blank lines - if (string.IsNullOrWhiteSpace(hashData)) + if (string.IsNullOrEmpty(hashData)) { trackCount--; resultProgress?.Report(Result.Success("Blank line found, skipping!")); @@ -507,8 +510,8 @@ namespace MPF.Core continue; } -#if NET40 - var validateTask = Task.Factory.StartNew(() => Validator.ValidateSingleTrack(wc, info, hashData)); +#if NET20 || NET35 || NET40 + var validateTask = Validator.ValidateSingleTrack(wc, info, hashData); validateTask.Wait(); (bool singleFound, var foundIds, string? result) = validateTask.Result; #else @@ -540,8 +543,8 @@ namespace MPF.Core // If we don't have any matches but we have a universal hash if (!info.PartiallyMatchedIDs.Any() && info.CommonDiscInfo?.CommentsSpecialFields?.ContainsKey(SiteCode.UniversalHash) == true) { -#if NET40 - var validateTask = Task.Factory.StartNew(() => Validator.ValidateUniversalHash(wc, info)); +#if NET20 || NET35 || NET40 + var validateTask = Validator.ValidateUniversalHash(wc, info); validateTask.Wait(); (bool singleFound, var foundIds, string? result) = validateTask.Result; #else @@ -583,8 +586,8 @@ namespace MPF.Core for (int i = 0; i < totalMatchedIDsCount; i++) { // Skip if the track count doesn't match -#if NET40 - var validateTask = Task.Factory.StartNew(() => Validator.ValidateTrackCount(wc, fullyMatchedIDs[i], trackCount)); +#if NET20 || NET35 || NET40 + var validateTask = Validator.ValidateTrackCount(wc, fullyMatchedIDs[i], trackCount); validateTask.Wait(); if (!validateTask.Result) #else @@ -594,7 +597,7 @@ namespace MPF.Core // Fill in the fields from the existing ID resultProgress?.Report(Result.Success($"Filling fields from existing ID {fullyMatchedIDs[i]}...")); -#if NET40 +#if NET20 || NET35 || NET40 var fillTask = Task.Factory.StartNew(() => Builder.FillFromId(wc, info, fullyMatchedIDs[i], options.PullAllInformation)); fillTask.Wait(); _ = fillTask.Result; @@ -620,6 +623,6 @@ namespace MPF.Core return true; } - #endregion +#endregion } } diff --git a/MPF.Core/UI/ViewModels/MainViewModel.cs b/MPF.Core/UI/ViewModels/MainViewModel.cs index 8b77ab39..19b17acb 100644 --- a/MPF.Core/UI/ViewModels/MainViewModel.cs +++ b/MPF.Core/UI/ViewModels/MainViewModel.cs @@ -1411,7 +1411,7 @@ namespace MPF.Core.UI.ViewModels /// /// Scan and show copy protection for the current disc /// -#if NET40 +#if NET20 || NET35 || NET40 public (string?, string?) ScanAndShowProtection() #else public async Task<(string?, string?)> ScanAndShowProtection() @@ -1435,7 +1435,7 @@ namespace MPF.Core.UI.ViewModels var progress = new Progress(); progress.ProgressChanged += ProgressUpdated; -#if NET40 +#if NET20 || NET35 || NET40 var protectionTask = Protection.RunProtectionScanOnPath(this.CurrentDrive.Name, this.Options, progress); protectionTask.Wait(); var (protections, error) = protectionTask.Result; @@ -1603,7 +1603,11 @@ namespace MPF.Core.UI.ViewModels _environment.ReportStatus += ProgressUpdated; // Run the program with the parameters +#if NET20 || NET35 || NET40 + Result result = _environment.Run(resultProgress); +#else Result result = await _environment.Run(resultProgress); +#endif // If we didn't execute a dumping command we cannot get submission output if (_environment.Parameters?.IsDumpingCommand() != true) @@ -1679,7 +1683,7 @@ namespace MPF.Core.UI.ViewModels private bool ValidateBeforeDumping() { // Validate that we have an output path of any sort - if (string.IsNullOrWhiteSpace(_environment?.OutputPath)) + if (string.IsNullOrEmpty(_environment?.OutputPath)) { if (_displayUserMessage != null) _ = _displayUserMessage("Missing Path", "No output path was provided so dumping cannot continue.", 1, false); @@ -1721,7 +1725,7 @@ namespace MPF.Core.UI.ViewModels // Validate that at least some space exists // TODO: Tie this to the size of the disc, type of disc, etc. string fullPath; - if (string.IsNullOrWhiteSpace(outputDirectory)) + if (string.IsNullOrEmpty(outputDirectory)) fullPath = Path.GetFullPath(_environment.OutputPath); else fullPath = Path.GetFullPath(outputDirectory); @@ -1741,14 +1745,14 @@ namespace MPF.Core.UI.ViewModels return true; } - #endregion +#endregion #region Progress Reporting /// /// Handler for Result ProgressChanged event /// -#if NET40 +#if NET20 || NET35 || NET40 private void ProgressUpdated(object? sender, BaseParameters.StringEventArgs value) #else private void ProgressUpdated(object? sender, string value) @@ -1756,7 +1760,7 @@ namespace MPF.Core.UI.ViewModels { try { -#if NET40 +#if NET20 || NET35 || NET40 value.Value ??= string.Empty; LogLn(value.Value); #else diff --git a/MPF.Core/UI/ViewModels/OptionsViewModel.cs b/MPF.Core/UI/ViewModels/OptionsViewModel.cs index 6e4f71ec..13495e8b 100644 --- a/MPF.Core/UI/ViewModels/OptionsViewModel.cs +++ b/MPF.Core/UI/ViewModels/OptionsViewModel.cs @@ -82,7 +82,9 @@ namespace MPF.Core.UI.ViewModels public static async Task<(bool?, string?)> TestRedumpLogin(string username, string password) #endif { -#if NET40 +#if NET20 || NET35 + return await Task.Run(() => RedumpWebClient.ValidateCredentials(username, password)); +#elif NET40 return Task.Factory.StartNew(() => RedumpWebClient.ValidateCredentials(username, password)); #elif NETFRAMEWORK return await Task.Run(() => RedumpWebClient.ValidateCredentials(username, password)); diff --git a/MPF.Core/Utilities/Logging.cs b/MPF.Core/Utilities/Logging.cs index 89429ae1..1bbe0438 100644 --- a/MPF.Core/Utilities/Logging.cs +++ b/MPF.Core/Utilities/Logging.cs @@ -14,7 +14,9 @@ namespace MPF.Core.Utilities /// TextReader representing the input /// Invoking class, passed on to the event handler /// Event handler to be invoked to write to log -#if NET40 +#if NET20 || NET35 + public static async Task OutputToLog(TextReader reader, object baseClass, EventHandler? handler) +#elif NET40 public static void OutputToLog(TextReader reader, object baseClass, EventHandler? handler) #else public static async Task OutputToLog(TextReader reader, object baseClass, EventHandler? handler) @@ -30,7 +32,9 @@ namespace MPF.Core.Utilities while (true) { // Try to read the next chunk of characters -#if NET40 +#if NET20 || NET35 + read = await Task.Run(() => reader.Read(buffer, 0, buffer.Length)); +#elif NET40 var readTask = Task.Factory.StartNew(() => reader.Read(buffer, 0, buffer.Length)); readTask.Wait(); read = readTask.Result; @@ -74,7 +78,7 @@ namespace MPF.Core.Utilities catch { } finally { -#if NET40 +#if NET20 || NET35 || NET40 handler?.Invoke(baseClass, new Modules.BaseParameters.StringEventArgs { Value = sb.ToString() }); #else handler?.Invoke(baseClass, sb.ToString()); @@ -89,7 +93,7 @@ namespace MPF.Core.Utilities /// Current line to process /// Invoking class, passed on to the event handler /// Event handler to be invoked to write to log -#if NET40 +#if NET20 || NET35 || NET40 private static void ProcessNewLines(StringBuilder sb, string line, object baseClass, EventHandler? handler) #else private static void ProcessNewLines(StringBuilder sb, string line, object baseClass, EventHandler? handler) @@ -114,12 +118,13 @@ namespace MPF.Core.Utilities if (i == 0) { sb.Append(split[i]); -#if NET40 +#if NET20 || NET35 || NET40 handler?.Invoke(baseClass, new Modules.BaseParameters.StringEventArgs { Value = sb.ToString() }); + sb = new(); #else handler?.Invoke(baseClass, sb.ToString()); -#endif sb.Clear(); +#endif } // For the last item, just append so it's dealt with the next time @@ -131,7 +136,7 @@ namespace MPF.Core.Utilities // For everything else, directly write out else { -#if NET40 +#if NET20 || NET35 || NET40 handler?.Invoke(baseClass, new Modules.BaseParameters.StringEventArgs { Value = split[i] }); #else handler?.Invoke(baseClass, split[i]); @@ -147,7 +152,7 @@ namespace MPF.Core.Utilities /// Current line to process /// Invoking class, passed on to the event handler /// Event handler to be invoked to write to log -#if NET40 +#if NET20 || NET35 || NET40 private static void ProcessCarriageReturns(StringBuilder sb, string line, object baseClass, EventHandler? handler) #else private static void ProcessCarriageReturns(StringBuilder sb, string line, object baseClass, EventHandler? handler) @@ -157,14 +162,15 @@ namespace MPF.Core.Utilities // Append and log the first sb.Append(split[0]); -#if NET40 +#if NET20 || NET35 || NET40 handler?.Invoke(baseClass, new Modules.BaseParameters.StringEventArgs { Value = sb.ToString() }); + sb = new(); #else handler?.Invoke(baseClass, sb.ToString()); + sb.Clear(); #endif // Append the last - sb.Clear(); sb.Append($"\r{split[split.Length - 1]}"); } } diff --git a/MPF.Core/Utilities/OptionsLoader.cs b/MPF.Core/Utilities/OptionsLoader.cs index 35eda948..243c4549 100644 --- a/MPF.Core/Utilities/OptionsLoader.cs +++ b/MPF.Core/Utilities/OptionsLoader.cs @@ -219,8 +219,8 @@ namespace MPF.Core.Utilities } // Now deal with the complex options - options.ScanForProtection = scan && !string.IsNullOrWhiteSpace(parsedPath); - options.OutputSeparateProtectionFile = scan && protectFile && !string.IsNullOrWhiteSpace(parsedPath); + options.ScanForProtection = scan && !string.IsNullOrEmpty(parsedPath); + options.OutputSeparateProtectionFile = scan && protectFile && !string.IsNullOrEmpty(parsedPath); return (options, info, parsedPath, startIndex); } diff --git a/MPF.Core/Utilities/Tools.cs b/MPF.Core/Utilities/Tools.cs index e913ecba..79d72f36 100644 --- a/MPF.Core/Utilities/Tools.cs +++ b/MPF.Core/Utilities/Tools.cs @@ -231,8 +231,8 @@ namespace MPF.Core.Utilities /// private static (string? tag, string? url) GetRemoteVersionAndUrl() { -#if NET40 - // Not supported in .NET Framework 4.0 +#if NET20 || NET35 || NET40 + // Not supported in .NET Frameworks 2.0, 3.5, or 4.0 return (null, null); #else using var hc = new System.Net.Http.HttpClient(); diff --git a/MPF.Test/Library/InfoToolTests.cs b/MPF.Test/Library/InfoToolTests.cs index 12619ed5..2d3f16d4 100644 --- a/MPF.Test/Library/InfoToolTests.cs +++ b/MPF.Test/Library/InfoToolTests.cs @@ -20,7 +20,7 @@ namespace MPF.Test.Library [InlineData("superhero\\blah&foo.bin", "superhero\\blah&foo.bin")] public void NormalizeOutputPathsTest(string? outputPath, string? expectedPath) { - if (!string.IsNullOrWhiteSpace(expectedPath)) + if (!string.IsNullOrEmpty(expectedPath)) expectedPath = Path.GetFullPath(expectedPath); string actualPath = InfoTool.NormalizeOutputPaths(outputPath, true); diff --git a/MPF.Test/RedumpLib/ExtensionsTests.cs b/MPF.Test/RedumpLib/ExtensionsTests.cs index a1a173cf..90ee81f1 100644 --- a/MPF.Test/RedumpLib/ExtensionsTests.cs +++ b/MPF.Test/RedumpLib/ExtensionsTests.cs @@ -269,7 +269,7 @@ namespace MPF.Test.RedumpLib foreach (Language? language in fullLanguages) { var code = language.TwoLetterCode(); - if (string.IsNullOrWhiteSpace(code)) + if (string.IsNullOrEmpty(code)) continue; // Throw if the code already exists @@ -296,7 +296,7 @@ namespace MPF.Test.RedumpLib foreach (Language? language in fullLanguages) { var code = language.ThreeLetterCode(); - if (string.IsNullOrWhiteSpace(code)) + if (string.IsNullOrEmpty(code)) continue; // Throw if the code already exists @@ -323,7 +323,7 @@ namespace MPF.Test.RedumpLib foreach (Language? language in fullLanguages) { var code = language.ThreeLetterCodeAlt(); - if (string.IsNullOrWhiteSpace(code)) + if (string.IsNullOrEmpty(code)) continue; // Throw if the code already exists @@ -492,7 +492,7 @@ namespace MPF.Test.RedumpLib foreach (Region? region in fullRegions) { var code = region.ShortName(); - if (string.IsNullOrWhiteSpace(code)) + if (string.IsNullOrEmpty(code)) continue; // Throw if the code already exists diff --git a/MPF.UI.Core/Constants.cs b/MPF.UI.Core/Constants.cs index 48184f75..5c2627a6 100644 --- a/MPF.UI.Core/Constants.cs +++ b/MPF.UI.Core/Constants.cs @@ -17,7 +17,7 @@ namespace MPF.UI.Core public static DoubleCollection SpeedsForHDDVDAsCollection { get; } = GetDoubleCollectionFromIntList(HDDVD); public static DoubleCollection SpeedsForBDAsCollection { get; } = GetDoubleCollectionFromIntList(BD); -#if NET40 +#if NET20 || NET35 || NET40 private static DoubleCollection GetDoubleCollectionFromIntList(IList list) #else private static DoubleCollection GetDoubleCollectionFromIntList(IReadOnlyList list) diff --git a/MPF.UI.Core/Windows/DiscInformationWindow.xaml.cs b/MPF.UI.Core/Windows/DiscInformationWindow.xaml.cs index 073d7c1f..bf76f155 100644 --- a/MPF.UI.Core/Windows/DiscInformationWindow.xaml.cs +++ b/MPF.UI.Core/Windows/DiscInformationWindow.xaml.cs @@ -144,13 +144,13 @@ namespace MPF.UI.Core.Windows DMIHash.Visibility = Visibility.Collapsed; if (submissionInfo.EDC?.EDC == null) EDC.Visibility = Visibility.Collapsed; - if (string.IsNullOrWhiteSpace(submissionInfo.CommonDiscInfo?.ErrorsCount)) + if (string.IsNullOrEmpty(submissionInfo.CommonDiscInfo?.ErrorsCount)) ErrorsCount.Visibility = Visibility.Collapsed; - if (string.IsNullOrWhiteSpace(submissionInfo.CommonDiscInfo?.EXEDateBuildDate)) + if (string.IsNullOrEmpty(submissionInfo.CommonDiscInfo?.EXEDateBuildDate)) EXEDateBuildDate.Visibility = Visibility.Collapsed; if (submissionInfo.CommonDiscInfo?.CommentsSpecialFields?.ContainsKey(SiteCode.Filename) != true) Filename.Visibility = Visibility.Collapsed; - if (string.IsNullOrWhiteSpace(submissionInfo.Extras?.Header)) + if (string.IsNullOrEmpty(submissionInfo.Extras?.Header)) Header.Visibility = Visibility.Collapsed; if (submissionInfo.CommonDiscInfo?.CommentsSpecialFields?.ContainsKey(SiteCode.InternalName) != true) InternalName.Visibility = Visibility.Collapsed; @@ -160,21 +160,21 @@ namespace MPF.UI.Core.Windows Multisession.Visibility = Visibility.Collapsed; if (submissionInfo.CopyProtection?.LibCrypt == null) LibCrypt.Visibility = Visibility.Collapsed; - if (string.IsNullOrWhiteSpace(submissionInfo.CopyProtection?.LibCryptData)) + if (string.IsNullOrEmpty(submissionInfo.CopyProtection?.LibCryptData)) LibCryptData.Visibility = Visibility.Collapsed; if (submissionInfo.CommonDiscInfo?.CommentsSpecialFields?.ContainsKey(SiteCode.PFIHash) != true) PFIHash.Visibility = Visibility.Collapsed; - if (string.IsNullOrWhiteSpace(submissionInfo.Extras?.PIC)) + if (string.IsNullOrEmpty(submissionInfo.Extras?.PIC)) PIC.Visibility = Visibility.Collapsed; - if (string.IsNullOrWhiteSpace(submissionInfo.Extras?.PVD)) + if (string.IsNullOrEmpty(submissionInfo.Extras?.PVD)) PVD.Visibility = Visibility.Collapsed; if (submissionInfo.CommonDiscInfo?.CommentsSpecialFields?.ContainsKey(SiteCode.RingNonZeroDataStart) != true) RingNonZeroDataStart.Visibility = Visibility.Collapsed; - if (string.IsNullOrWhiteSpace(submissionInfo.CopyProtection?.SecuROMData)) + if (string.IsNullOrEmpty(submissionInfo.CopyProtection?.SecuROMData)) SecuROMData.Visibility = Visibility.Collapsed; if (submissionInfo.CommonDiscInfo?.CommentsSpecialFields?.ContainsKey(SiteCode.SSHash) != true) SSHash.Visibility = Visibility.Collapsed; - if (string.IsNullOrWhiteSpace(submissionInfo.Extras?.SecuritySectorRanges)) + if (string.IsNullOrEmpty(submissionInfo.Extras?.SecuritySectorRanges)) SecuritySectorRanges.Visibility = Visibility.Collapsed; if (submissionInfo.CommonDiscInfo?.CommentsSpecialFields?.ContainsKey(SiteCode.SSVersion) != true) SSVersion.Visibility = Visibility.Collapsed; diff --git a/MPF.UI.Core/Windows/MainWindow.xaml.cs b/MPF.UI.Core/Windows/MainWindow.xaml.cs index 3a9cd322..9449baa5 100644 --- a/MPF.UI.Core/Windows/MainWindow.xaml.cs +++ b/MPF.UI.Core/Windows/MainWindow.xaml.cs @@ -112,11 +112,11 @@ namespace MPF.UI.Core.Windows { // Get the current path, if possible string currentPath = MainViewModel.OutputPath; - if (string.IsNullOrWhiteSpace(currentPath) && !string.IsNullOrWhiteSpace(MainViewModel.Options.DefaultOutputPath)) + if (string.IsNullOrEmpty(currentPath) && !string.IsNullOrEmpty(MainViewModel.Options.DefaultOutputPath)) currentPath = Path.Combine(MainViewModel.Options.DefaultOutputPath, "track.bin"); - else if (string.IsNullOrWhiteSpace(currentPath)) + else if (string.IsNullOrEmpty(currentPath)) currentPath = "track.bin"; - if (string.IsNullOrWhiteSpace(currentPath)) + if (string.IsNullOrEmpty(currentPath)) currentPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory!, "track.bin"); // Get the full path