Be smarter about Linq usage

This commit is contained in:
Matt Nadareski
2024-11-12 22:18:08 -05:00
parent 4d0f48be10
commit d8d149446f
22 changed files with 281 additions and 274 deletions

View File

@@ -1,6 +1,7 @@
### WIP (xxxx-xx-xx)
- Update Redumper to build 438
- Be smarter about Linq usage
### 3.2.3 (2024-11-06)

View File

@@ -1082,7 +1082,7 @@ namespace MPF.ExecutionContexts.Aaru
if (string.IsNullOrEmpty(InputValue))
return null;
if (InputValue.Contains(' '))
if (InputValue!.Contains(" "))
parameters.Add($"\"{InputValue!.TrimEnd('\\')}\"");
else
parameters.Add(InputValue!.TrimEnd('\\'));

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
#if NET462_OR_GREATER || NETCOREAPP
@@ -223,7 +224,7 @@ namespace MPF.Frontend
/// </summary>
public void RefreshDrive()
{
var driveInfo = DriveInfo.GetDrives().FirstOrDefault(d => d?.Name == Name);
var driveInfo = Array.Find(DriveInfo.GetDrives(), d => d?.Name == Name);
PopulateFromDriveInfo(driveInfo);
}
@@ -252,20 +253,18 @@ namespace MPF.Frontend
// TODO: Reduce reliance on `DriveInfo`
// https://github.com/aaru-dps/Aaru/blob/5164a154e2145941472f2ee0aeb2eff3338ecbb3/Aaru.Devices/Windows/ListDevices.cs#L66
// Create an output drive list
var drives = new List<Drive>();
// Create an output drive array
Drive[] drives = [];
// Get all standard supported drive types
try
{
drives = DriveInfo.GetDrives()
.Where(d => desiredDriveTypes.Contains(d.DriveType))
.Select(d => Create(ToInternalDriveType(d.DriveType), d.Name) ?? new Drive())
.ToList();
var filteredDrives = Array.FindAll(DriveInfo.GetDrives(), d => desiredDriveTypes.Contains(d.DriveType));
drives = Array.ConvertAll(filteredDrives, d => Create(ToInternalDriveType(d.DriveType), d.Name) ?? new Drive());
}
catch
{
return drives;
return [.. drives];
}
// Find and update all floppy drives
@@ -282,7 +281,11 @@ namespace MPF.Frontend
if (mediaType != null && ((mediaType > 0 && mediaType < 11) || (mediaType > 12 && mediaType < 22)))
{
char devId = (properties["Caption"].Value as string ?? string.Empty)[0];
drives.ForEach(d => { if (d?.Name != null && d.Name[0] == devId) { d.InternalDriveType = Frontend.InternalDriveType.Floppy; } });
Array.ForEach(drives, d =>
{
if (d?.Name != null && d.Name[0] == devId)
d.InternalDriveType = Frontend.InternalDriveType.Floppy;
});
}
}
}
@@ -292,7 +295,7 @@ namespace MPF.Frontend
}
#endif
return drives;
return [.. drives];
}
/// <summary>

View File

@@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text;
#if NET40
using System.Threading;
@@ -503,7 +502,7 @@ namespace MPF.Frontend
resultProgress?.Report(ResultEventArgs.Failure(txtResult));
// Write the copy protection output
if (submissionInfo?.CopyProtection?.FullProtections != null && submissionInfo.CopyProtection.FullProtections.Any())
if (submissionInfo?.CopyProtection?.FullProtections != null && submissionInfo.CopyProtection.FullProtections.Count > 0)
{
if (_options.ScanForProtection)
{
@@ -755,7 +754,7 @@ namespace MPF.Frontend
private static bool WriteProtectionData(string? outputDirectory, string? filenameSuffix, SubmissionInfo? info, bool hideDriveLetters)
{
// Check to see if the inputs are valid
if (info?.CopyProtection?.FullProtections == null || !info.CopyProtection.FullProtections.Any())
if (info?.CopyProtection?.FullProtections == null || info.CopyProtection.FullProtections.Count == 0)
return true;
// Now write out to a generic file
@@ -773,7 +772,9 @@ namespace MPF.Frontend
using var sw = new StreamWriter(File.Open(path, FileMode.Create, FileAccess.Write), Encoding.UTF8);
List<string> sortedKeys = [.. info.CopyProtection.FullProtections.Keys.OrderBy(k => k)];
List<string> sortedKeys = [.. info.CopyProtection.FullProtections.Keys];
sortedKeys.Sort();
foreach (string key in sortedKeys)
{
string scanPath = key;

View File

@@ -1,5 +1,4 @@
using System.Collections.Generic;
using System.Linq;
using SabreTools.RedumpLib.Data;
namespace MPF.Frontend
@@ -17,34 +16,34 @@ namespace MPF.Frontend
/// <summary>
/// Set of accepted speeds for CD and GD media
/// </summary>
public static IList<int> CD => _speedValues.Where(s => s <= 72).ToList();
public static List<int> CD => _speedValues.FindAll(s => s <= 72);
/// <summary>
/// Set of accepted speeds for DVD media
/// </summary>
public static IList<int> DVD => _speedValues.Where(s => s <= 24).ToList();
public static List<int> DVD => _speedValues.FindAll(s => s <= 24);
/// <summary>
/// Set of accepted speeds for HD-DVD media
/// </summary>
public static IList<int> HDDVD => _speedValues.Where(s => s <= 24).ToList();
public static List<int> HDDVD => _speedValues.FindAll(s => s <= 24);
/// <summary>
/// Set of accepted speeds for BD media
/// </summary>
public static IList<int> BD => _speedValues.Where(s => s <= 16).ToList();
public static List<int> BD => _speedValues.FindAll(s => s <= 16);
/// <summary>
/// Set of accepted speeds for all other media
/// </summary>
public static IList<int> Unknown => _speedValues.Where(s => s <= 1).ToList();
public static List<int> Unknown => _speedValues.FindAll(s => s <= 1);
/// <summary>
/// Get list of all drive speeds for a given MediaType
/// </summary>
/// <param name="type">MediaType? that represents the current item</param>
/// <returns>Read-only list of drive speeds</returns>
public static IList<int> GetSpeedsForMediaType(MediaType? type)
public static List<int> GetSpeedsForMediaType(MediaType? type)
{
return type switch
{

View File

@@ -1,6 +1,5 @@
using System;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using SabreTools.RedumpLib.Data;
@@ -115,7 +114,7 @@ namespace MPF.Frontend.Tools
}
// If we didn't already try English, try it now
if (!languages.Contains(Language.English))
if (!Array.Exists(languages, l => l == Language.English))
return NormalizeDiscTitle(title, Language.English);
// If all fails, then the title didn't need normalization
@@ -143,7 +142,7 @@ namespace MPF.Frontend.Tools
language = Language.English;
// Get the title split into parts
string[] splitTitle = title!.Split(' ').Where(s => !string.IsNullOrEmpty(s)).ToArray();
string[] splitTitle = Array.FindAll(title!.Split(' '), s => !string.IsNullOrEmpty(s));
// If we only have one part, we can't do anything
if (splitTitle.Length <= 1)

View File

@@ -1,6 +1,5 @@
using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using Newtonsoft.Json;
@@ -576,7 +575,7 @@ namespace MPF.Frontend.Tools
try
{
var files = Directory.GetFiles(msxc, "*", SearchOption.TopDirectoryOnly);
var filenames = files.Select(Path.GetFileName).ToArray();
var filenames = Array.ConvertAll(files, Path.GetFileName);
return string.Join("\n", filenames);
}
catch

View File

@@ -409,7 +409,7 @@ namespace MPF.Frontend.Tools
if (foundProtections.Any(p => p == "XCP") && foundProtections.Any(p => p.StartsWith("XCP") && p.Length > "XCP".Length))
foundProtections = foundProtections.Where(p => p != "XCP");
return string.Join(", ", foundProtections.ToArray());
return string.Join(", ", [.. foundProtections]);
}
}
}

View File

@@ -159,7 +159,9 @@ namespace MPF.Frontend.Tools
/// <param name="options">Options object representing user-defined options</param>
/// <param name="info">Existing SubmissionInfo object to fill</param>
/// <param name="resultProgress">Optional result progress callback</param>
public async static Task<bool> FillFromRedump(Frontend.Options options, SubmissionInfo info, IProgress<ResultEventArgs>? resultProgress = null)
public async static Task<bool> FillFromRedump(Frontend.Options options,
SubmissionInfo info,
IProgress<ResultEventArgs>? resultProgress = null)
{
// If no username is provided
if (string.IsNullOrEmpty(options.RedumpUsername) || string.IsNullOrEmpty(options.RedumpPassword))
@@ -240,28 +242,28 @@ namespace MPF.Frontend.Tools
}
// If all tracks were found, check if there are any fully-matched IDs
List<int>? fullyMatchedIDs = null;
HashSet<int>? fullyMatchedIdsSet = null;
if (allFound)
{
fullyMatchedIDs = null;
fullyMatchedIdsSet = null;
foreach (var set in foundIdSets)
{
// First track is always all IDs
if (fullyMatchedIDs == null)
if (fullyMatchedIdsSet == null)
{
fullyMatchedIDs = [.. set];
fullyMatchedIdsSet = [.. set];
continue;
}
// Try to intersect with all known IDs
fullyMatchedIDs = fullyMatchedIDs.Intersect(set).ToList();
if (!fullyMatchedIDs.Any())
fullyMatchedIdsSet.IntersectWith(set);
if (fullyMatchedIdsSet.Count == 0)
break;
}
}
// 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 (info.PartiallyMatchedIDs.Count == 0 && info.CommonDiscInfo?.CommentsSpecialFields?.ContainsKey(SiteCode.UniversalHash) == true)
{
string sha1 = info.CommonDiscInfo.CommentsSpecialFields[SiteCode.UniversalHash];
var foundIds = await Validator.ValidateUniversalHash(wc, info);
@@ -276,50 +278,56 @@ namespace MPF.Frontend.Tools
allFound = (foundIds != null && foundIds.Count == 1);
// If we found a match, then the disc is a match
if ((foundIds != null && foundIds.Count == 1) && foundIds != null)
fullyMatchedIDs = foundIds;
if (foundIds != null && foundIds.Count == 1)
fullyMatchedIdsSet = [.. foundIds];
else
fullyMatchedIDs = [];
fullyMatchedIdsSet = [];
}
// Make sure we only have unique IDs
info.PartiallyMatchedIDs = [.. info.PartiallyMatchedIDs.Distinct().OrderBy(id => id)];
// Get a list version of the fully matched IDs
List<int> fullyMatchedIdsList = fullyMatchedIdsSet != null ? [.. fullyMatchedIdsSet] : [];
resultProgress?.Report(ResultEventArgs.Success("Match finding complete! " + (fullyMatchedIDs != null && fullyMatchedIDs.Count > 0
? "Fully Matched IDs: " + string.Join(",", fullyMatchedIDs.Select(i => i.ToString()).ToArray())
// Make sure we only have unique IDs
var partiallyMatchedIds = new HashSet<int>();
partiallyMatchedIds.IntersectWith(info.PartiallyMatchedIDs);
info.PartiallyMatchedIDs = [.. partiallyMatchedIds];
info.PartiallyMatchedIDs.Sort();
resultProgress?.Report(ResultEventArgs.Success("Match finding complete! " + (fullyMatchedIdsList != null && fullyMatchedIdsList.Count > 0
? "Fully Matched IDs: " + string.Join(",", [.. fullyMatchedIdsList.ConvertAll(i => i.ToString())])
: "No matches found")));
// Exit early if one failed or there are no matched IDs
if (!allFound || fullyMatchedIDs == null || fullyMatchedIDs.Count == 0)
if (!allFound || fullyMatchedIdsList == null || fullyMatchedIdsList.Count == 0)
return false;
// Find the first matched ID where the track count matches, we can grab a bunch of info from it
int totalMatchedIDsCount = fullyMatchedIDs.Count;
int totalMatchedIDsCount = fullyMatchedIdsList.Count;
for (int i = 0; i < totalMatchedIDsCount; i++)
{
// Skip if the track count doesn't match
#if NET40
var validateTask = Validator.ValidateTrackCount(wc, fullyMatchedIDs[i], trackCount);
var validateTask = Validator.ValidateTrackCount(wc, fullyMatchedIdsList[i], trackCount);
validateTask.Wait();
if (!validateTask.Result)
#else
if (!await Validator.ValidateTrackCount(wc, fullyMatchedIDs[i], trackCount))
if (!await Validator.ValidateTrackCount(wc, fullyMatchedIdsList[i], trackCount))
#endif
continue;
// Fill in the fields from the existing ID
resultProgress?.Report(ResultEventArgs.Success($"Filling fields from existing ID {fullyMatchedIDs[i]}..."));
resultProgress?.Report(ResultEventArgs.Success($"Filling fields from existing ID {fullyMatchedIdsList[i]}..."));
#if NET40
var fillTask = Task.Factory.StartNew(() => Builder.FillFromId(wc, info, fullyMatchedIDs[i], options.PullAllInformation));
var fillTask = Task.Factory.StartNew(() => Builder.FillFromId(wc, info, fullyMatchedIdsList[i], options.PullAllInformation));
fillTask.Wait();
_ = fillTask.Result;
#else
_ = await Builder.FillFromId(wc, info, fullyMatchedIDs[i], options.PullAllInformation);
_ = await Builder.FillFromId(wc, info, fullyMatchedIdsList[i], options.PullAllInformation);
#endif
resultProgress?.Report(ResultEventArgs.Success("Information filling complete!"));
// Set the fully matched ID to the current
info.FullyMatchedID = fullyMatchedIDs[i];
info.FullyMatchedID = fullyMatchedIdsList[i];
break;
}
@@ -450,7 +458,7 @@ namespace MPF.Frontend.Tools
}
// Ensure that no labels are empty
volLabels = volLabels.Where(l => !string.IsNullOrEmpty(l?.Trim())).ToList();
volLabels = volLabels.FindAll(l => !string.IsNullOrEmpty(l?.Trim()));
// Print each label separated by a comma and a space
if (volLabels.Count == 0)

View File

@@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using BinaryObjectScanner;
using MPF.Frontend.ComboBoxItems;
@@ -260,7 +259,7 @@ namespace MPF.Frontend.ViewModels
CancelButtonEnabled = true;
MediaTypes = [];
Systems = RedumpSystemComboBoxItem.GenerateElements().ToList();
Systems = [.. RedumpSystemComboBoxItem.GenerateElements()];
InternalPrograms = [];
PopulateMediaType();
@@ -296,7 +295,7 @@ namespace MPF.Frontend.ViewModels
public void ChangeSystem()
{
PopulateMediaType();
this.CheckDumpButtonEnabled = ShouldEnableCheckDumpButton();
CheckDumpButtonEnabled = ShouldEnableCheckDumpButton();
}
/// <summary>
@@ -304,7 +303,7 @@ namespace MPF.Frontend.ViewModels
/// </summary>
public void ChangeMediaType()
{
this.CheckDumpButtonEnabled = ShouldEnableCheckDumpButton();
CheckDumpButtonEnabled = ShouldEnableCheckDumpButton();
}
/// <summary>
@@ -312,7 +311,7 @@ namespace MPF.Frontend.ViewModels
/// </summary>
public void ChangeDumpingProgram()
{
this.CheckDumpButtonEnabled = ShouldEnableCheckDumpButton();
CheckDumpButtonEnabled = ShouldEnableCheckDumpButton();
}
/// <summary>
@@ -320,7 +319,7 @@ namespace MPF.Frontend.ViewModels
/// </summary>
public void ChangeInputPath()
{
this.CheckDumpButtonEnabled = ShouldEnableCheckDumpButton();
CheckDumpButtonEnabled = ShouldEnableCheckDumpButton();
}
#endregion
@@ -368,20 +367,20 @@ namespace MPF.Frontend.ViewModels
bool cachedCanExecuteSelectionChanged = CanExecuteSelectionChanged;
DisableEventHandlers();
if (this.CurrentSystem != null)
if (CurrentSystem != null)
{
var mediaTypeValues = this.CurrentSystem.MediaTypes();
int index = mediaTypeValues.FindIndex(m => m == this.CurrentMediaType);
var mediaTypeValues = CurrentSystem.MediaTypes();
int index = mediaTypeValues.FindIndex(m => m == CurrentMediaType);
MediaTypes = mediaTypeValues.Select(m => new Element<MediaType>(m ?? MediaType.NONE)).ToList();
this.MediaTypeComboBoxEnabled = MediaTypes.Count > 1;
this.CurrentMediaType = (index > -1 ? MediaTypes[index] : MediaTypes[0]);
MediaTypes = mediaTypeValues.ConvertAll(m => new Element<MediaType>(m ?? MediaType.NONE));
MediaTypeComboBoxEnabled = MediaTypes.Count > 1;
CurrentMediaType = (index > -1 ? MediaTypes[index] : MediaTypes[0]);
}
else
{
this.MediaTypeComboBoxEnabled = false;
this.MediaTypes = null;
this.CurrentMediaType = null;
MediaTypeComboBoxEnabled = false;
MediaTypes = null;
CurrentMediaType = null;
}
// Reenable event handlers, if necessary
@@ -398,15 +397,15 @@ namespace MPF.Frontend.ViewModels
DisableEventHandlers();
// Get the current internal program
InternalProgram internalProgram = this.Options.InternalProgram;
InternalProgram internalProgram = Options.InternalProgram;
// Create a static list of supported Check programs, not everything
var internalPrograms = new List<InternalProgram> { InternalProgram.Redumper, InternalProgram.Aaru, InternalProgram.DiscImageCreator, InternalProgram.CleanRip, InternalProgram.PS3CFW, InternalProgram.UmdImageCreator, InternalProgram.XboxBackupCreator };
InternalPrograms = internalPrograms.Select(ip => new Element<InternalProgram>(ip)).ToList();
InternalPrograms = internalPrograms.ConvertAll(ip => new Element<InternalProgram>(ip));
// Select the current default dumping program
int currentIndex = InternalPrograms.FindIndex(m => m == internalProgram);
this.CurrentProgram = (currentIndex > -1 ? InternalPrograms[currentIndex].Value : InternalPrograms[0].Value);
CurrentProgram = (currentIndex > -1 ? InternalPrograms[currentIndex].Value : InternalPrograms[0].Value);
// Reenable event handlers, if necessary
if (cachedCanExecuteSelectionChanged) EnableEventHandlers();
@@ -418,7 +417,7 @@ namespace MPF.Frontend.ViewModels
private bool ShouldEnableCheckDumpButton()
{
return this.CurrentSystem != null && this.CurrentMediaType != null && !string.IsNullOrEmpty(this.InputPath);
return CurrentSystem != null && CurrentMediaType != null && !string.IsNullOrEmpty(InputPath);
}
/// <summary>
@@ -450,7 +449,7 @@ namespace MPF.Frontend.ViewModels
if (string.IsNullOrEmpty(InputPath))
return "Invalid Input path";
if (!File.Exists(this.InputPath!.Trim('"')))
if (!File.Exists(InputPath!.Trim('"')))
return "Input Path is not a valid file";
// Disable UI while Check is running
@@ -459,7 +458,7 @@ namespace MPF.Frontend.ViewModels
DisableEventHandlers();
// Populate an environment
var env = new DumpEnvironment(Options, Path.GetFullPath(this.InputPath.Trim('"')), null, this.CurrentSystem, this.CurrentMediaType, this.CurrentProgram, parameters: null);
var env = new DumpEnvironment(Options, Path.GetFullPath(InputPath.Trim('"')), null, CurrentSystem, CurrentMediaType, CurrentProgram, parameters: null);
// Make new Progress objects
var resultProgress = new Progress<ResultEventArgs>();

View File

@@ -1,5 +1,5 @@
using System.Collections.Generic;
using System.Linq;
using System;
using System.Collections.Generic;
using MPF.Frontend.ComboBoxItems;
using MPF.Frontend.Tools;
using SabreTools.RedumpLib.Data;
@@ -27,12 +27,14 @@ namespace MPF.Frontend.ViewModels
/// <summary>
/// List of available disc categories
/// </summary>
public List<Element<DiscCategory>> Categories { get; private set; } = Element<DiscCategory>.GenerateElements().ToList();
public List<Element<DiscCategory>> Categories { get; private set; }
= [.. Element<DiscCategory>.GenerateElements()];
/// <summary>
/// List of available regions
/// </summary>
public List<Element<Region>> Regions { get; private set; } = Element<Region>.GenerateElements().ToList();
public List<Element<Region>> Regions { get; private set; }
= [.. Element<Region>.GenerateElements()];
/// <summary>
/// List of Redump-supported Regions
@@ -123,7 +125,8 @@ namespace MPF.Frontend.ViewModels
/// <summary>
/// List of available languages
/// </summary>
public List<Element<Language>> Languages { get; private set; } = Element<Language>.GenerateElements().ToList();
public List<Element<Language>> Languages { get; private set; }
= [.. Element<Language>.GenerateElements()];
/// <summary>
/// List of Redump-supported Languages
@@ -183,7 +186,8 @@ namespace MPF.Frontend.ViewModels
/// <summary>
/// List of available languages
/// </summary>
public List<Element<LanguageSelection>> LanguageSelections { get; private set; } = Element<LanguageSelection>.GenerateElements().ToList();
public List<Element<LanguageSelection>> LanguageSelections { get; private set; }
= [.. Element<LanguageSelection>.GenerateElements()];
#endregion
@@ -205,9 +209,9 @@ namespace MPF.Frontend.ViewModels
public void Load()
{
if (SubmissionInfo.CommonDiscInfo?.Languages != null)
Languages.ForEach(l => l.IsChecked = SubmissionInfo.CommonDiscInfo.Languages.Contains(l));
Languages.ForEach(l => l.IsChecked = Array.IndexOf(SubmissionInfo.CommonDiscInfo.Languages, l) > -1);
if (SubmissionInfo.CommonDiscInfo?.LanguageSelection != null)
LanguageSelections.ForEach(ls => ls.IsChecked = SubmissionInfo.CommonDiscInfo.LanguageSelection.Contains(ls));
LanguageSelections.ForEach(ls => ls.IsChecked = Array.IndexOf(SubmissionInfo.CommonDiscInfo.LanguageSelection, ls) > -1);
}
/// <summary>
@@ -218,10 +222,10 @@ namespace MPF.Frontend.ViewModels
{
if (SubmissionInfo.CommonDiscInfo == null)
SubmissionInfo.CommonDiscInfo = new CommonDiscInfoSection();
SubmissionInfo.CommonDiscInfo.Languages = Languages.Where(l => l.IsChecked).Select(l => l?.Value).ToArray();
if (!SubmissionInfo.CommonDiscInfo.Languages.Any())
SubmissionInfo.CommonDiscInfo.Languages = [.. Languages.FindAll(l => l.IsChecked).ConvertAll(l => l?.Value)];
if (SubmissionInfo.CommonDiscInfo.Languages.Length == 0)
SubmissionInfo.CommonDiscInfo.Languages = [null];
SubmissionInfo.CommonDiscInfo.LanguageSelection = LanguageSelections.Where(ls => ls.IsChecked).Select(ls => ls?.Value).ToArray();
SubmissionInfo.CommonDiscInfo.LanguageSelection = [.. LanguageSelections.FindAll(ls => ls.IsChecked).ConvertAll(ls => ls?.Value)];
SubmissionInfo.CommonDiscInfo.Title = FrontendTool.NormalizeDiscTitle(SubmissionInfo.CommonDiscInfo.Title, SubmissionInfo.CommonDiscInfo.Languages);
}
@@ -230,7 +234,7 @@ namespace MPF.Frontend.ViewModels
/// </summary>
public void SetRedumpLanguages()
{
this.Languages = RedumpLanguages.Select(l => new Element<Language>(l)).ToList();
Languages = RedumpLanguages.ConvertAll(l => new Element<Language>(l));
}
/// <summary>
@@ -238,7 +242,7 @@ namespace MPF.Frontend.ViewModels
/// </summary>
public void SetRedumpRegions()
{
this.Regions = RedumpRegions.Select(r => new Element<Region>(r)).ToList();
Regions = RedumpRegions.ConvertAll(r => new Element<Region>(r));
}
#endregion

View File

@@ -556,7 +556,7 @@ namespace MPF.Frontend.ViewModels
LogPanelExpanded = _options.OpenLogWindowAtStartup;
MediaTypes = [];
Systems = RedumpSystemComboBoxItem.GenerateElements().ToList();
Systems = [.. RedumpSystemComboBoxItem.GenerateElements()];
InternalPrograms = [];
}
@@ -612,18 +612,18 @@ namespace MPF.Frontend.ViewModels
VerboseLogLn("Scanning for drives..");
// Always enable the media scan
this.MediaScanButtonEnabled = true;
this.UpdateVolumeLabelEnabled = true;
MediaScanButtonEnabled = true;
UpdateVolumeLabelEnabled = true;
// If we have a selected drive, keep track of it
char? lastSelectedDrive = this.CurrentDrive?.Name?[0] ?? null;
char? lastSelectedDrive = CurrentDrive?.Name?[0] ?? null;
// Populate the list of drives and add it to the combo box
Drives = Drive.CreateListOfDrives(this.Options.IgnoreFixedDrives);
Drives = Drive.CreateListOfDrives(Options.IgnoreFixedDrives);
if (Drives.Count > 0)
{
VerboseLogLn($"Found {Drives.Count} drives: {string.Join(", ", Drives.Select(d => d.Name).ToArray())}");
VerboseLogLn($"Found {Drives.Count} drives: {string.Join(", ", [.. Drives.ConvertAll(d => d.Name)])}");
// Check for the last selected drive, if possible
int index = -1;
@@ -644,23 +644,23 @@ namespace MPF.Frontend.ViewModels
// Set the selected index
CurrentDrive = (index != -1 ? Drives[index] : Drives[0]);
this.Status = "Valid drive found! Choose your Media Type";
this.CopyProtectScanButtonEnabled = true;
Status = "Valid drive found! Choose your Media Type";
CopyProtectScanButtonEnabled = true;
// Get the current system type
if (index != -1)
DetermineSystemType();
// Only enable the start/stop if we don't have the default selected
this.StartStopButtonEnabled = ShouldEnableDumpingButton();
StartStopButtonEnabled = ShouldEnableDumpingButton();
}
else
{
VerboseLogLn("Found no drives");
this.CurrentDrive = null;
this.Status = "No valid drive found!";
this.StartStopButtonEnabled = false;
this.CopyProtectScanButtonEnabled = false;
CurrentDrive = null;
Status = "No valid drive found!";
StartStopButtonEnabled = false;
CopyProtectScanButtonEnabled = false;
}
// Reenable event handlers, if necessary
@@ -676,22 +676,22 @@ namespace MPF.Frontend.ViewModels
bool cachedCanExecuteSelectionChanged = CanExecuteSelectionChanged;
DisableEventHandlers();
if (this.CurrentSystem != null)
if (CurrentSystem != null)
{
var mediaTypeValues = this.CurrentSystem.MediaTypes();
int index = mediaTypeValues.FindIndex(m => m == this.CurrentMediaType);
if (this.CurrentMediaType != null && index == -1)
var mediaTypeValues = CurrentSystem.MediaTypes();
int index = mediaTypeValues.FindIndex(m => m == CurrentMediaType);
if (CurrentMediaType != null && index == -1)
VerboseLogLn($"Disc of type '{CurrentMediaType.LongName()}' found, but the current system does not support it!");
MediaTypes = mediaTypeValues.Select(m => new Element<MediaType>(m ?? MediaType.NONE)).ToList();
this.MediaTypeComboBoxEnabled = MediaTypes.Count > 1;
this.CurrentMediaType = (index > -1 ? MediaTypes[index] : MediaTypes[0]);
MediaTypes = mediaTypeValues.ConvertAll(m => new Element<MediaType>(m ?? MediaType.NONE));
MediaTypeComboBoxEnabled = MediaTypes.Count > 1;
CurrentMediaType = (index > -1 ? MediaTypes[index] : MediaTypes[0]);
}
else
{
this.MediaTypeComboBoxEnabled = false;
this.MediaTypes = null;
this.CurrentMediaType = null;
MediaTypeComboBoxEnabled = false;
MediaTypes = null;
CurrentMediaType = null;
}
// Reenable event handlers, if necessary
@@ -708,21 +708,24 @@ namespace MPF.Frontend.ViewModels
DisableEventHandlers();
// Create a static list of supported programs, not everything
InternalPrograms = Enum.GetValues(typeof(InternalProgram)).Cast<InternalProgram>().Where(ip => InternalProgramExists(ip)).Select(ip => new Element<InternalProgram>(ip)).ToList();
InternalPrograms = Enum.GetValues(typeof(InternalProgram))
.Cast<InternalProgram>()
.Where(ip => InternalProgramExists(ip))
.Select(ip => new Element<InternalProgram>(ip)).ToList();
// Get the current internal program
InternalProgram internalProgram = this.Options.InternalProgram;
InternalProgram internalProgram = Options.InternalProgram;
// Select the current default dumping program
if (InternalPrograms.Count == 0)
{
// If no programs are found, default to InternalProgram.NONE
this.CurrentProgram = InternalProgram.NONE;
CurrentProgram = InternalProgram.NONE;
}
else
{
int currentIndex = InternalPrograms.FindIndex(m => m == internalProgram);
this.CurrentProgram = (currentIndex > -1 ? InternalPrograms[currentIndex].Value : InternalPrograms[0].Value);
CurrentProgram = (currentIndex > -1 ? InternalPrograms[currentIndex].Value : InternalPrograms[0].Value);
}
// Reenable event handlers, if necessary
@@ -738,7 +741,7 @@ namespace MPF.Frontend.ViewModels
/// </summary>
public void ChangeDumpingProgram()
{
VerboseLogLn($"Changed dumping program to: {((InternalProgram?)this.CurrentProgram).LongName()}");
VerboseLogLn($"Changed dumping program to: {((InternalProgram?)CurrentProgram).LongName()}");
EnsureDiscInformation();
// New output name depends on new environment
GetOutputNames(false);
@@ -764,7 +767,7 @@ namespace MPF.Frontend.ViewModels
/// </summary>
public void ChangeSystem()
{
VerboseLogLn($"Changed system to: {this.CurrentSystem.LongName()}");
VerboseLogLn($"Changed system to: {CurrentSystem.LongName()}");
PopulateMediaType();
GetOutputNames(false);
EnsureDiscInformation();
@@ -947,15 +950,15 @@ namespace MPF.Frontend.ViewModels
public void ToggleStartStop()
{
// Dump or stop the dump
if (this.StartStopButtonText as string == StartDumpingValue)
if (StartStopButtonText as string == StartDumpingValue)
{
StartDumping();
}
else if (this.StartStopButtonText as string == StopDumpingValue)
else if (StartStopButtonText as string == StopDumpingValue)
{
VerboseLogLn("Canceling dumping process...");
_environment?.CancelDumping();
this.CopyProtectScanButtonEnabled = true;
CopyProtectScanButtonEnabled = true;
}
}
@@ -971,7 +974,7 @@ namespace MPF.Frontend.ViewModels
// Ensure the first run flag is unset
var continuingOptions = new Frontend.Options(optionsToSave) { FirstRun = false };
this.Options = continuingOptions;
Options = continuingOptions;
// If settings were changed, reinitialize the UI
if (savedSettings)
@@ -1044,14 +1047,14 @@ namespace MPF.Frontend.ViewModels
public void FastUpdateLabel(bool removeEventHandlers)
{
// Disable the dumping button
this.StartStopButtonEnabled = false;
StartStopButtonEnabled = false;
// Safely uncheck the parameters box, just in case
if (this.ParametersCheckBoxEnabled == true)
if (ParametersCheckBoxEnabled == true)
{
bool cachedCanExecuteSelectionChanged = CanExecuteSelectionChanged;
this.DisableEventHandlers();
this.ParametersCheckBoxEnabled = false;
DisableEventHandlers();
ParametersCheckBoxEnabled = false;
if (cachedCanExecuteSelectionChanged) EnableEventHandlers();
}
@@ -1060,7 +1063,7 @@ namespace MPF.Frontend.ViewModels
DisableEventHandlers();
// Refresh the drive info
this.CurrentDrive?.RefreshDrive();
CurrentDrive?.RefreshDrive();
// Set the initial environment and UI values
_environment = DetermineEnvironment();
@@ -1071,7 +1074,7 @@ namespace MPF.Frontend.ViewModels
EnableEventHandlers();
// Enable the dumping button, if necessary
this.StartStopButtonEnabled = ShouldEnableDumpingButton();
StartStopButtonEnabled = ShouldEnableDumpingButton();
}
/// <summary>
@@ -1169,25 +1172,26 @@ namespace MPF.Frontend.ViewModels
private void CacheCurrentDiscType()
{
// If the selected item is invalid, we just skip
if (this.CurrentDrive == null)
if (CurrentDrive == null)
return;
// Get reasonable default values based on the current system
MediaType? defaultMediaType = this.CurrentSystem.MediaTypes().FirstOrDefault() ?? MediaType.CDROM;
var mediaTypes = CurrentSystem.MediaTypes();
MediaType? defaultMediaType = mediaTypes.Count > 0 ? mediaTypes[0] : MediaType.CDROM;
if (defaultMediaType == MediaType.NONE)
defaultMediaType = MediaType.CDROM;
// If we're skipping detection, set the default value
if (this.Options.SkipMediaTypeDetection)
if (Options.SkipMediaTypeDetection)
{
VerboseLogLn($"Media type detection disabled, defaulting to {defaultMediaType.LongName()}.");
CurrentMediaType = defaultMediaType;
}
// If the drive is marked active, try to read from it
else if (this.CurrentDrive.MarkedActive)
else if (CurrentDrive.MarkedActive)
{
VerboseLog($"Trying to detect media type for drive {this.CurrentDrive.Name} [{this.CurrentDrive.DriveFormat}] using size and filesystem.. ");
MediaType? detectedMediaType = this.CurrentDrive.GetMediaType(this.CurrentSystem);
VerboseLog($"Trying to detect media type for drive {CurrentDrive.Name} [{CurrentDrive.DriveFormat}] using size and filesystem.. ");
MediaType? detectedMediaType = CurrentDrive.GetMediaType(CurrentSystem);
// If we got either an error or no media, default to the current System default
if (detectedMediaType == null)
@@ -1214,17 +1218,17 @@ namespace MPF.Frontend.ViewModels
/// <summary>
/// Create a DumpEnvironment with all current settings
/// </summary>
/// <returns>Filled DumpEnvironment this.Parent</returns>
/// <returns>Filled DumpEnvironment Parent</returns>
private DumpEnvironment DetermineEnvironment()
{
return new DumpEnvironment(
this.Options,
EvaluateOutputPath(this.OutputPath),
this.CurrentDrive,
this.CurrentSystem,
this.CurrentMediaType,
this.CurrentProgram,
this.Parameters);
Options,
EvaluateOutputPath(OutputPath),
CurrentDrive,
CurrentSystem,
CurrentMediaType,
CurrentProgram,
Parameters);
}
/// <summary>
@@ -1232,32 +1236,32 @@ namespace MPF.Frontend.ViewModels
/// </summary>
private void DetermineSystemType()
{
if (Drives == null || Drives.Count == 0 || this.CurrentDrive == null)
if (Drives == null || Drives.Count == 0 || CurrentDrive == null)
{
VerboseLogLn("Skipping system type detection because no valid drives found!");
}
else if (this.CurrentDrive?.MarkedActive != true)
else if (CurrentDrive?.MarkedActive != true)
{
VerboseLogLn("Skipping system type detection because drive not marked as active!");
}
else if (!this.Options.SkipSystemDetection)
else if (!Options.SkipSystemDetection)
{
VerboseLog($"Trying to detect system for drive {this.CurrentDrive.Name}.. ");
VerboseLog($"Trying to detect system for drive {CurrentDrive.Name}.. ");
var currentSystem = GetRedumpSystem(CurrentDrive, Options.DefaultSystem) ?? Options.DefaultSystem;
VerboseLogLn(currentSystem == null ? "unable to detect." : ($"detected {currentSystem.LongName()}."));
if (currentSystem != null)
{
int sysIndex = Systems.FindIndex(s => s == currentSystem);
this.CurrentSystem = Systems[sysIndex];
CurrentSystem = Systems[sysIndex];
}
}
else if (this.Options.SkipSystemDetection && this.Options.DefaultSystem != null)
else if (Options.SkipSystemDetection && Options.DefaultSystem != null)
{
var currentSystem = this.Options.DefaultSystem;
var currentSystem = Options.DefaultSystem;
VerboseLogLn($"System detection disabled, setting to default of {currentSystem.LongName()}.");
int sysIndex = Systems.FindIndex(s => s == currentSystem);
this.CurrentSystem = Systems[sysIndex];
CurrentSystem = Systems[sysIndex];
}
}
@@ -1315,23 +1319,23 @@ namespace MPF.Frontend.ViewModels
// Get the status to write out
ResultEventArgs result = _environment.GetSupportStatus();
if (this.CurrentProgram == InternalProgram.NONE)
this.Status = "No dumping program found";
if (CurrentProgram == InternalProgram.NONE)
Status = "No dumping program found";
else
this.Status = result.Message;
Status = result.Message;
// Enable or disable the button
this.StartStopButtonEnabled = result && ShouldEnableDumpingButton();
StartStopButtonEnabled = result && ShouldEnableDumpingButton();
// If we're in a type that doesn't support drive speeds
this.DriveSpeedComboBoxEnabled = _environment.DoesSupportDriveSpeed();
DriveSpeedComboBoxEnabled = _environment.DoesSupportDriveSpeed();
// If input params are not enabled, generate the full parameters from the environment
if (!this.ParametersCheckBoxEnabled)
if (!ParametersCheckBoxEnabled)
{
var generated = _environment.GetFullParameters(this.DriveSpeed);
var generated = _environment.GetFullParameters(DriveSpeed);
if (generated != null)
this.Parameters = generated;
Parameters = generated;
}
}
@@ -1342,16 +1346,16 @@ namespace MPF.Frontend.ViewModels
/// <returns>String with %-delimited variables evaluated</returns>
public string EvaluateOutputPath(string outputPath)
{
string systemLong = this._currentSystem.LongName() ?? "Unknown System";
string systemLong = _currentSystem.LongName() ?? "Unknown System";
if (string.IsNullOrEmpty(systemLong))
systemLong = "Unknown System";
string systemShort = this._currentSystem.ShortName() ?? "unknown";
string systemShort = _currentSystem.ShortName() ?? "unknown";
if (string.IsNullOrEmpty(systemShort))
systemShort = "unknown";
string mediaLong = this._currentMediaType.LongName() ?? "Unknown Media";
string mediaLong = _currentMediaType.LongName() ?? "Unknown Media";
if (string.IsNullOrEmpty(mediaLong))
mediaLong = "Unknown Media";
string program = this._currentProgram.ToString() ?? "Unknown Program";
string program = _currentProgram.ToString() ?? "Unknown Program";
if (string.IsNullOrEmpty(program))
program = "Unknown Program";
string programShort = program == "DiscImageCreator" ? "DIC" : program;
@@ -1384,20 +1388,20 @@ namespace MPF.Frontend.ViewModels
/// <param name="driveChanged">Force an updated name if the drive letter changes</param>
public void GetOutputNames(bool driveChanged)
{
if (Drives == null || Drives.Count == 0 || this.CurrentDrive == null)
if (Drives == null || Drives.Count == 0 || CurrentDrive == null)
{
VerboseLogLn("Skipping output name building because no valid drives found!");
return;
}
// Get the extension for the file for the next two statements
var extension = _environment?.GetDefaultExtension(this.CurrentMediaType);
var extension = _environment?.GetDefaultExtension(CurrentMediaType);
// Set the output filename, if it's not already
if (string.IsNullOrEmpty(this.OutputPath))
if (string.IsNullOrEmpty(OutputPath))
{
var label = GetFormattedVolumeLabel(CurrentDrive) ?? this.CurrentSystem.LongName();
var directory = this.Options.DefaultOutputPath;
var label = GetFormattedVolumeLabel(CurrentDrive) ?? CurrentSystem.LongName();
var directory = Options.DefaultOutputPath;
string filename = $"{label}{extension ?? ".bin"}";
// If the path ends with the label already
@@ -1406,19 +1410,19 @@ namespace MPF.Frontend.ViewModels
if (directory != null && label != null)
#if NET20 || NET35
this.OutputPath = Path.Combine(Path.Combine(directory, label), filename);
OutputPath = Path.Combine(Path.Combine(directory, label), filename);
#else
this.OutputPath = Path.Combine(directory, label, filename);
OutputPath = Path.Combine(directory, label, filename);
#endif
else
this.OutputPath = filename;
OutputPath = filename;
}
// Set the output filename, if we changed drives
else if (driveChanged)
{
var label = GetFormattedVolumeLabel(CurrentDrive) ?? this.CurrentSystem.LongName();
string oldPath = FrontendTool.NormalizeOutputPaths(this.OutputPath, false);
var label = GetFormattedVolumeLabel(CurrentDrive) ?? CurrentSystem.LongName();
string oldPath = FrontendTool.NormalizeOutputPaths(OutputPath, false);
string oldFilename = Path.GetFileNameWithoutExtension(oldPath);
var directory = Path.GetDirectoryName(oldPath);
string filename = $"{label}{extension ?? ".bin"}";
@@ -1433,26 +1437,26 @@ namespace MPF.Frontend.ViewModels
if (directory != null && label != null)
#if NET20 || NET35
this.OutputPath = Path.Combine(Path.Combine(directory, label), filename);
OutputPath = Path.Combine(Path.Combine(directory, label), filename);
#else
this.OutputPath = Path.Combine(directory, label, filename);
OutputPath = Path.Combine(directory, label, filename);
#endif
else
this.OutputPath = filename;
OutputPath = filename;
}
// Otherwise, reset the extension of the currently set path
else
{
string oldPath = FrontendTool.NormalizeOutputPaths(this.OutputPath, false);
string oldPath = FrontendTool.NormalizeOutputPaths(OutputPath, false);
string filename = Path.GetFileNameWithoutExtension(oldPath);
var directory = Path.GetDirectoryName(oldPath);
filename = $"{filename}{extension ?? ".bin"}";
if (directory != null)
this.OutputPath = Path.Combine(directory, filename);
OutputPath = Path.Combine(directory, filename);
else
this.OutputPath = filename;
OutputPath = filename;
}
}
@@ -1503,14 +1507,10 @@ namespace MPF.Frontend.ViewModels
// Bandai Playdia Quick Interactive System
try
{
#if NET20 || NET35
List<string> files = [.. Directory.GetFiles(drive.Name, "*", SearchOption.TopDirectoryOnly)];
#else
List<string> files = Directory.EnumerateFiles(drive.Name, "*", SearchOption.TopDirectoryOnly).ToList();
#endif
if (files.Any(f => f.EndsWith(".AJS", StringComparison.OrdinalIgnoreCase))
&& files.Any(f => f.EndsWith(".GLB", StringComparison.OrdinalIgnoreCase)))
if (files.Exists(f => f.EndsWith(".AJS", StringComparison.OrdinalIgnoreCase))
&& files.Exists(f => f.EndsWith(".GLB", StringComparison.OrdinalIgnoreCase)))
{
return RedumpSystem.BandaiPlaydiaQuickInteractiveSystem;
}
@@ -1790,7 +1790,7 @@ namespace MPF.Frontend.ViewModels
public void ProcessCustomParameters()
{
// Set the execution context and processor
if (_environment?.SetExecutionContext(this.Parameters) != true)
if (_environment?.SetExecutionContext(Parameters) != true)
return;
if (_environment?.SetProcessor() != true)
return;
@@ -1798,21 +1798,22 @@ namespace MPF.Frontend.ViewModels
// Catch this in case there's an input path issue
try
{
int driveIndex = Drives.Select(d => d.Name?[0] ?? '\0').ToList().IndexOf(_environment.ContextInputPath?[0] ?? default);
this.CurrentDrive = (driveIndex != -1 ? Drives[driveIndex] : Drives[0]);
int driveIndex = Drives.ConvertAll(d => d.Name?[0] ?? '\0')
.IndexOf(_environment.ContextInputPath?[0] ?? default);
CurrentDrive = (driveIndex != -1 ? Drives[driveIndex] : Drives[0]);
}
catch { }
int driveSpeed = _environment.Speed ?? -1;
if (driveSpeed > 0)
this.DriveSpeed = driveSpeed;
DriveSpeed = driveSpeed;
else
_environment.Speed = this.DriveSpeed;
_environment.Speed = DriveSpeed;
// Disable change handling
DisableEventHandlers();
this.OutputPath = FrontendTool.NormalizeOutputPaths(_environment.ContextOutputPath, false);
OutputPath = FrontendTool.NormalizeOutputPaths(_environment.ContextOutputPath, false);
if (MediaTypes != null)
{
@@ -1820,7 +1821,7 @@ namespace MPF.Frontend.ViewModels
if (mediaType != null)
{
int mediaTypeIndex = MediaTypes.FindIndex(m => m == mediaType);
this.CurrentMediaType = (mediaTypeIndex > -1 ? MediaTypes[mediaTypeIndex] : MediaTypes[0]);
CurrentMediaType = (mediaTypeIndex > -1 ? MediaTypes[mediaTypeIndex] : MediaTypes[0]);
}
}
@@ -1841,20 +1842,20 @@ namespace MPF.Frontend.ViewModels
_environment ??= DetermineEnvironment();
// If we don't have a valid drive
if (this.CurrentDrive?.Name == null)
if (CurrentDrive?.Name == null)
{
ErrorLogLn("No valid drive found!");
return null;
}
VerboseLogLn($"Scanning for copy protection in {this.CurrentDrive.Name}");
VerboseLogLn($"Scanning for copy protection in {CurrentDrive.Name}");
var tempContent = this.Status;
this.Status = "Scanning for copy protection... this might take a while!";
this.StartStopButtonEnabled = false;
this.MediaScanButtonEnabled = false;
this.UpdateVolumeLabelEnabled = false;
this.CopyProtectScanButtonEnabled = false;
var tempContent = Status;
Status = "Scanning for copy protection... this might take a while!";
StartStopButtonEnabled = false;
MediaScanButtonEnabled = false;
UpdateVolumeLabelEnabled = false;
CopyProtectScanButtonEnabled = false;
var progress = new Progress<ProtectionProgress>();
progress.ProgressChanged += ProgressUpdated;
@@ -1862,20 +1863,20 @@ namespace MPF.Frontend.ViewModels
try
{
#if NET40
var protectionTask = ProtectionTool.RunProtectionScanOnPath(this.CurrentDrive.Name, this.Options, progress);
var protectionTask = ProtectionTool.RunProtectionScanOnPath(CurrentDrive.Name, Options, progress);
protectionTask.Wait();
var protections = protectionTask.Result;
#else
var protections = await ProtectionTool.RunProtectionScanOnPath(this.CurrentDrive.Name, this.Options, progress);
var protections = await ProtectionTool.RunProtectionScanOnPath(CurrentDrive.Name, Options, progress);
#endif
var output = ProtectionTool.FormatProtections(protections);
LogLn($"Detected the following protections in {this.CurrentDrive.Name}:\r\n\r\n{output}");
LogLn($"Detected the following protections in {CurrentDrive.Name}:\r\n\r\n{output}");
this.Status = tempContent;
this.StartStopButtonEnabled = ShouldEnableDumpingButton();
this.MediaScanButtonEnabled = true;
this.UpdateVolumeLabelEnabled = true;
this.CopyProtectScanButtonEnabled = true;
Status = tempContent;
StartStopButtonEnabled = ShouldEnableDumpingButton();
MediaScanButtonEnabled = true;
UpdateVolumeLabelEnabled = true;
CopyProtectScanButtonEnabled = true;
return output;
}
@@ -1953,10 +1954,10 @@ namespace MPF.Frontend.ViewModels
// Now set the selected item, if possible
int index = MediaTypes.FindIndex(kvp => kvp.Value == CurrentMediaType);
if (this.CurrentMediaType != null && index == -1)
if (CurrentMediaType != null && index == -1)
VerboseLogLn($"Disc of type '{CurrentMediaType.LongName()}' found, but the current system does not support it!");
this.CurrentMediaType = (index > -1 ? MediaTypes[index] : MediaTypes[0]);
CurrentMediaType = (index > -1 ? MediaTypes[index] : MediaTypes[0]);
}
/// <summary>
@@ -1965,14 +1966,14 @@ namespace MPF.Frontend.ViewModels
public void SetSupportedDriveSpeed()
{
// Set the drive speed list that's appropriate
this.DriveSpeeds = (List<int>)InterfaceConstants.GetSpeedsForMediaType(CurrentMediaType);
VerboseLogLn($"Supported media speeds: {string.Join(", ", this.DriveSpeeds.Select(ds => ds.ToString()).ToArray())}");
DriveSpeeds = (List<int>)InterfaceConstants.GetSpeedsForMediaType(CurrentMediaType);
VerboseLogLn($"Supported media speeds: {string.Join(", ", [.. DriveSpeeds.ConvertAll(ds => ds.ToString())])}");
// Set the selected speed
int speed = FrontendTool.GetDefaultSpeedForMediaType(CurrentMediaType, Options);
VerboseLogLn($"Setting drive speed to: {speed}");
this.DriveSpeed = speed;
DriveSpeed = speed;
}
/// <summary>
@@ -1982,8 +1983,8 @@ namespace MPF.Frontend.ViewModels
{
return Drives != null
&& Drives.Count > 0
&& this.CurrentSystem != null
&& this.CurrentMediaType != null
&& CurrentSystem != null
&& CurrentMediaType != null
&& ProgramSupportsMedia();
}
@@ -2050,12 +2051,12 @@ namespace MPF.Frontend.ViewModels
_environment.RefreshDrive();
// If still in custom parameter mode, check that users meant to continue or not
if (this.ParametersCheckBoxEnabled == true && _displayUserMessage != null)
if (ParametersCheckBoxEnabled == true && _displayUserMessage != null)
{
bool? result = _displayUserMessage("Custom Changes", "It looks like you have custom parameters that have not been saved. Would you like to apply those changes before starting to dump?", 3, true);
if (result == true)
{
this.ParametersCheckBoxEnabled = false;
ParametersCheckBoxEnabled = false;
ProcessCustomParameters();
}
else if (result == null)
@@ -2081,7 +2082,7 @@ namespace MPF.Frontend.ViewModels
_environment.RefreshDrive();
// Output to the label and log
this.Status = "Starting dumping process... please wait!";
Status = "Starting dumping process... please wait!";
LogLn("Starting dumping process... please wait!");
LogLn("Look for the separate command window for more details");
@@ -2099,7 +2100,7 @@ namespace MPF.Frontend.ViewModels
if (!_environment.IsDumpingCommand())
{
LogLn("No dumping command was run, submission information will not be gathered.");
this.Status = "Execution complete!";
Status = "Execution complete!";
// Reset all UI elements
EnableAllUIElements();
@@ -2114,13 +2115,13 @@ namespace MPF.Frontend.ViewModels
else
{
ErrorLogLn(result.Message);
this.Status = "Execution failed!";
Status = "Execution failed!";
}
}
catch (Exception ex)
{
ErrorLogLn(ex.ToString());
this.Status = "An exception occurred!";
Status = "An exception occurred!";
}
finally
{
@@ -2259,9 +2260,9 @@ namespace MPF.Frontend.ViewModels
{
return program switch
{
InternalProgram.Redumper => File.Exists(this.Options.RedumperPath),
InternalProgram.Aaru => File.Exists(this.Options.AaruPath),
InternalProgram.DiscImageCreator => File.Exists(this.Options.DiscImageCreatorPath),
InternalProgram.Redumper => File.Exists(Options.RedumperPath),
InternalProgram.Aaru => File.Exists(Options.AaruPath),
InternalProgram.DiscImageCreator => File.Exists(Options.DiscImageCreatorPath),
_ => false,
};
}
@@ -2295,10 +2296,10 @@ namespace MPF.Frontend.ViewModels
var message = value?.Message;
// Update the label with only the first line of output
if (message != null && message.Contains('\n'))
this.Status = value?.Message?.Split('\n')[0] + " (See log output)";
if (message != null && message.Contains("\n"))
Status = value?.Message?.Split('\n')[0] + " (See log output)";
else
this.Status = value?.Message ?? string.Empty;
Status = value?.Message ?? string.Empty;
// Log based on success or failure
if (value != null && value)
@@ -2313,7 +2314,7 @@ namespace MPF.Frontend.ViewModels
private void ProgressUpdated(object? sender, ProtectionProgress value)
{
string message = $"{value.Percentage * 100:N2}%: {value.Filename} - {value.Protection}";
this.Status = message;
Status = message;
VerboseLogLn(message);
}

View File

@@ -1,9 +1,6 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Threading.Tasks;
using MPF.Frontend.ComboBoxItems;
using SabreTools.RedumpLib.Web;
using RedumperReadMethod = MPF.ExecutionContexts.Redumper.ReadMethod;
using RedumperSectorOrder = MPF.ExecutionContexts.Redumper.SectorOrder;
@@ -65,7 +62,7 @@ namespace MPF.Frontend.ViewModels
/// <summary>
/// Current list of supported system profiles
/// </summary>
public static List<RedumpSystemComboBoxItem> Systems => RedumpSystemComboBoxItem.GenerateElements().ToList();
public static List<RedumpSystemComboBoxItem> Systems => [.. RedumpSystemComboBoxItem.GenerateElements()];
#endregion
@@ -93,7 +90,7 @@ namespace MPF.Frontend.ViewModels
private static List<Element<InternalProgram>> PopulateInternalPrograms()
{
var internalPrograms = new List<InternalProgram> { InternalProgram.Redumper, InternalProgram.DiscImageCreator, InternalProgram.Aaru };
return internalPrograms.Select(ip => new Element<InternalProgram>(ip)).ToList();
return internalPrograms.ConvertAll(ip => new Element<InternalProgram>(ip));
}
/// <summary>
@@ -102,7 +99,7 @@ namespace MPF.Frontend.ViewModels
private static List<Element<RedumperReadMethod>> PopulateRedumperReadMethods()
{
var readMethods = new List<RedumperReadMethod> { RedumperReadMethod.NONE, RedumperReadMethod.D8, RedumperReadMethod.BE, RedumperReadMethod.BE_CDDA };
return readMethods.Select(rm => new Element<RedumperReadMethod>(rm)).ToList();
return readMethods.ConvertAll(rm => new Element<RedumperReadMethod>(rm));
}
/// <summary>
@@ -111,7 +108,7 @@ namespace MPF.Frontend.ViewModels
private static List<Element<RedumperSectorOrder>> PopulateRedumperSectorOrders()
{
var sectorOrders = new List<RedumperSectorOrder> { RedumperSectorOrder.NONE, RedumperSectorOrder.DATA_C2_SUB, RedumperSectorOrder.DATA_SUB_C2, RedumperSectorOrder.DATA_SUB, RedumperSectorOrder.DATA_C2 };
return sectorOrders.Select(so => new Element<RedumperSectorOrder>(so)).ToList();
return sectorOrders.ConvertAll(so => new Element<RedumperSectorOrder>(so));
}
#endregion

View File

@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Schema;
@@ -732,13 +731,13 @@ namespace MPF.Processors
// Now generate the byte array data
var pvdData = new List<byte>();
pvdData.AddRange(new string(' ', 13).ToCharArray().Select(c => (byte)c));
pvdData.AddRange(Array.ConvertAll(new string(' ', 13).ToCharArray(), c => (byte)c));
pvdData.AddRange(GeneratePVDDateTimeBytes(creation));
pvdData.AddRange(GeneratePVDDateTimeBytes(modification));
pvdData.AddRange(GeneratePVDDateTimeBytes(expiration));
pvdData.AddRange(GeneratePVDDateTimeBytes(effective));
pvdData.Add(0x01);
pvdData.AddRange(new string((char)0, 14).ToCharArray().Select(c => (byte)c));
pvdData.AddRange(Array.ConvertAll(new string((char)0, 14).ToCharArray(), c => (byte)c));
// Return the filled array
return [.. pvdData];
@@ -780,7 +779,7 @@ namespace MPF.Processors
}
// Get and return the byte array
List<byte> dateTimeList = dateTimeString.ToCharArray().Select(c => (byte)c).ToList();
List<byte> dateTimeList = [.. Array.ConvertAll(dateTimeString.ToCharArray(), c => (byte)c)];
dateTimeList.Add(timeZoneNumber);
return [.. dateTimeList];
}
@@ -798,11 +797,11 @@ namespace MPF.Processors
return null;
string pvdLine = $"{row} : ";
pvdLine += BitConverter.ToString(bytes.Take(8).ToArray()).Replace("-", " ");
pvdLine += BitConverter.ToString(bytes, 0, 8).Replace("-", " ");
pvdLine += " ";
pvdLine += BitConverter.ToString(bytes.Skip(8).Take(8).ToArray()).Replace("-", " ");
pvdLine += BitConverter.ToString(bytes, 8, 8).Replace("-", " ");
pvdLine += " ";
pvdLine += Encoding.ASCII.GetString([.. bytes]).Replace((char)0, '.').Replace('?', '.');
pvdLine += Encoding.ASCII.GetString(bytes).Replace((char)0, '.').Replace('?', '.');
pvdLine += "\n";
return pvdLine;
@@ -986,7 +985,7 @@ namespace MPF.Processors
foreach (OpticalDiscType opticalDisc in cicmSidecar.OpticalDisc)
{
// If there's no hardware information, skip
if (opticalDisc.DumpHardwareArray == null || !opticalDisc.DumpHardwareArray.Any())
if (opticalDisc.DumpHardwareArray == null || opticalDisc.DumpHardwareArray.Length == 0)
continue;
foreach (DumpHardwareType hardware in opticalDisc.DumpHardwareArray)

View File

@@ -94,7 +94,7 @@ namespace MPF.Processors
var generatedFiles = GetGeneratedFilePaths(outputDirectory, filenameSuffix);
// Don't create an archive if there are no paths
if (!zippableFiles.Any() && !generatedFiles.Any())
if (zippableFiles.Count == 0 && generatedFiles.Count == 0)
{
status = "No files to compress!";
return true;
@@ -156,7 +156,7 @@ namespace MPF.Processors
// Get the list of deleteable files from the parameters object
var files = GetDeleteableFilePaths(combinedBase);
if (!files.Any())
if (files.Count == 0)
{
status = "No files to delete!";
return true;
@@ -413,7 +413,7 @@ namespace MPF.Processors
return [];
// Filter down to deleteable files
var deleteableFiles = outputFiles.Where(of => of.IsDeleteable);
var deleteableFiles = outputFiles.FindAll(of => of.IsDeleteable);
return deleteableFiles.SelectMany(of => of.Filenames).ToList();
}
@@ -518,7 +518,7 @@ namespace MPF.Processors
return [];
// Filter down to zippable files
var zippableFiles = outputFiles.Where(of => of.IsZippable);
var zippableFiles = outputFiles.FindAll(of => of.IsZippable);
return zippableFiles.SelectMany(of => of.Filenames).ToList();
}

View File

@@ -326,7 +326,7 @@ namespace MPF.Processors
// Take only the first 16 lines for GD-ROM
if (!string.IsNullOrEmpty(info.Extras.Header))
info.Extras.Header = string.Join("\n", info.Extras.Header.Split('\n').Take(16).ToArray());
info.Extras.Header = string.Join("\n", info.Extras.Header.Split('\n'), 0, 16);
if (GetGDROMBuildInfo(info.Extras.Header,
out var serial,
@@ -347,7 +347,7 @@ namespace MPF.Processors
// Take only the last 16 lines for Sega CD
if (!string.IsNullOrEmpty(info.Extras.Header))
info.Extras.Header = string.Join("\n", info.Extras.Header.Split('\n').Skip(16).ToArray());
info.Extras.Header = string.Join("\n", info.Extras.Header.Split('\n'), 0, 16);
if (GetSegaCDBuildInfo(info.Extras.Header, out var scdSerial, out var fixedDate))
{
@@ -365,7 +365,7 @@ namespace MPF.Processors
// Take only the first 16 lines for GD-ROM
if (!string.IsNullOrEmpty(info.Extras.Header))
info.Extras.Header = string.Join("\n", info.Extras.Header.Split('\n').Take(16).ToArray());
info.Extras.Header = string.Join("\n", info.Extras.Header.Split('\n'), 0, 16);
if (GetGDROMBuildInfo(info.Extras.Header,
out var serial,
@@ -388,7 +388,7 @@ namespace MPF.Processors
// Take only the first 16 lines for GD-ROM
if (!string.IsNullOrEmpty(info.Extras.Header))
info.Extras.Header = string.Join("\n", info.Extras.Header.Split('\n').Take(16).ToArray());
info.Extras.Header = string.Join("\n", info.Extras.Header.Split('\n'), 0, 16);
if (GetGDROMBuildInfo(info.Extras.Header,
out var serial,
@@ -411,7 +411,7 @@ namespace MPF.Processors
// Take only the first 16 lines for GD-ROM
if (!string.IsNullOrEmpty(info.Extras.Header))
info.Extras.Header = string.Join("\n", info.Extras.Header.Split('\n').Take(16).ToArray());
info.Extras.Header = string.Join("\n", info.Extras.Header.Split('\n'), 0, 16);
if (GetGDROMBuildInfo(info.Extras.Header,
out var serial,
@@ -434,7 +434,7 @@ namespace MPF.Processors
// Take only the first 16 lines for GD-ROM
if (!string.IsNullOrEmpty(info.Extras.Header))
info.Extras.Header = string.Join("\n", info.Extras.Header.Split('\n').Take(16).ToArray());
info.Extras.Header = string.Join("\n", info.Extras.Header.Split('\n'), 0, 16);
if (GetGDROMBuildInfo(info.Extras.Header,
out var serial,
@@ -455,7 +455,7 @@ namespace MPF.Processors
// Take only the first 16 lines for Saturn
if (!string.IsNullOrEmpty(info.Extras.Header))
info.Extras.Header = string.Join("\n", info.Extras.Header.Split('\n').Take(16).ToArray());
info.Extras.Header = string.Join("\n", info.Extras.Header.Split('\n'), 0, 16);
if (GetSaturnBuildInfo(info.Extras.Header, out var saturnSerial, out var saturnVersion, out var buildDate))
{
@@ -746,7 +746,7 @@ namespace MPF.Processors
return null;
var currentFiles = Directory.GetFiles(parentDirectory);
commandPath = currentFiles.FirstOrDefault(f => cmdFilenameRegex.IsMatch(f));
commandPath = Array.Find(currentFiles, f => cmdFilenameRegex.IsMatch(f));
if (string.IsNullOrEmpty(value: commandPath))
return null;
@@ -882,8 +882,8 @@ namespace MPF.Processors
}
// Create the output string
if (discTypeOrBookTypeSet.Any())
discTypeOrBookType = string.Join(", ", [.. discTypeOrBookTypeSet.OrderBy(s => s)]);
if (discTypeOrBookTypeSet.Count > 0)
discTypeOrBookType = string.Join(", ", [.. discTypeOrBookTypeSet]);
return true;
}
@@ -1181,7 +1181,7 @@ namespace MPF.Processors
else if (xgd && line.StartsWith("LayerBreak"))
{
// LayerBreak: <size> (L0 Video: <size>, L0 Middle: <size>, L0 Game: <size>)
string[] split = line.Split(' ').Where(s => !string.IsNullOrEmpty(s)).ToArray();
string[] split = Array.FindAll(line.Split(' '), s => !string.IsNullOrEmpty(s));
return split[1];
}
@@ -1189,7 +1189,7 @@ namespace MPF.Processors
else if (!xgd && line.StartsWith("LayerZeroSector"))
{
// LayerZeroSector: <size> (<hex>)
string[] split = line.Split(' ').Where(s => !string.IsNullOrEmpty(s)).ToArray();
string[] split = Array.FindAll(line.Split(' '), s => !string.IsNullOrEmpty(s));
return split[1];
}
@@ -1920,13 +1920,14 @@ namespace MPF.Processors
sr.ReadLine(); // Separator line
// Now that we're at the offsets, attempt to get the sample offset
string offset = sr.ReadLine()?.Split(' ')?.LastOrDefault() ?? string.Empty;
var offsetLine = sr.ReadLine()?.Split(' ');
string offset = offsetLine != null ? offsetLine[offsetLine.Length - 1] : string.Empty;
offsets.Add(offset);
}
// Deduplicate the offsets
offsets = offsets
.Where(s => !string.IsNullOrEmpty(s))
.FindAll(s => !string.IsNullOrEmpty(s))
.Distinct()
.ToList();
@@ -1963,9 +1964,9 @@ namespace MPF.Processors
if (roms == null || roms.Length == 0)
return false;
dmihash = roms.FirstOrDefault(r => r.Name?.EndsWith("DMI.bin") == true)?.CRC?.ToUpperInvariant();
pfihash = roms.FirstOrDefault(r => r.Name?.EndsWith("PFI.bin") == true)?.CRC?.ToUpperInvariant();
sshash = roms.FirstOrDefault(r => r.Name?.EndsWith("SS.bin") == true)?.CRC?.ToUpperInvariant();
dmihash = Array.Find(roms, r => r.Name?.EndsWith("DMI.bin") == true)?.CRC?.ToUpperInvariant();
pfihash = Array.Find(roms, r => r.Name?.EndsWith("PFI.bin") == true)?.CRC?.ToUpperInvariant();
sshash = Array.Find(roms, r => r.Name?.EndsWith("SS.bin") == true)?.CRC?.ToUpperInvariant();
return true;
}

View File

@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using SabreTools.Hashing;
using SabreTools.Models.CueSheets;
@@ -996,7 +995,7 @@ namespace MPF.Processors
else if (line.StartsWith("data "))
{
// data { LBA: <startLBA> .. <endLBA>, length: <length>, hLBA: <startLBA> .. <endLBA> }
string[] split = line.Split(' ').Where(s => !string.IsNullOrEmpty(s)).ToArray();
string[] split = Array.FindAll(line.Split(' '), s => !string.IsNullOrEmpty(s));
layerbreak1 ??= split[7].TrimEnd(',');
}

View File

@@ -1,8 +1,9 @@
using System;
using System.IO;
#if NET452_OR_GREATER || NETCOREAPP
using System.IO.Compression;
#endif
using System.Linq;
#endif
using System.Text.RegularExpressions;
namespace MPF.Processors
@@ -55,7 +56,7 @@ namespace MPF.Processors
var directoryFiles = Directory.GetFiles(baseDirectory);
foreach (string file in directoryFiles)
{
if (Filenames.Any(pattern => Regex.IsMatch(file, pattern)))
if (Array.FindIndex(Filenames, pattern => Regex.IsMatch(file, pattern)) > -1)
return true;
}

View File

@@ -1,7 +1,5 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using SabreTools.Hashing;
using SabreTools.Models.Logiqx;
using SabreTools.RedumpLib;

View File

@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using MPF.Frontend;
using Xunit;
@@ -47,7 +46,7 @@ namespace MPF.Test.Frontend
var testData = new List<object?[]>() { new object?[] { null, true } };
foreach (DriveType driveType in Enum.GetValues(typeof(DriveType)))
{
if (_mappableDriveTypes.Contains(driveType))
if (Array.IndexOf(_mappableDriveTypes, driveType) > -1)
testData.Add([driveType, false]);
else
testData.Add([driveType, true]);

View File

@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Media;
using static MPF.Frontend.InterfaceConstants;
@@ -34,7 +33,7 @@ namespace MPF.UI
/// <summary>
/// Create a DoubleCollection out of a list of integer values
/// </summary>
private static DoubleCollection GetDoubleCollectionFromIntList(IList<int> list)
=> new(list.Select(i => Convert.ToDouble(i)).ToList());
private static DoubleCollection GetDoubleCollectionFromIntList(List<int> list)
=> [.. list.ConvertAll(i => Convert.ToDouble(i))];
}
}

View File

@@ -301,7 +301,7 @@ namespace MPF.UI.Windows
if (submissionInfo.PartiallyMatchedIDs == null)
_PartiallyMatchedIDs!.Visibility = Visibility.Collapsed;
else
_PartiallyMatchedIDs!.Text = string.Join(", ", submissionInfo.PartiallyMatchedIDs.Select(i => i.ToString()).ToArray());
_PartiallyMatchedIDs!.Text = string.Join(", ", [.. submissionInfo.PartiallyMatchedIDs.ConvertAll(i => i.ToString())]);
if (string.IsNullOrEmpty(submissionInfo.TracksAndWriteOffsets?.ClrMameProData))
_HashData!.Visibility = Visibility.Collapsed;
if (submissionInfo.SizeAndChecksums?.Size == null || submissionInfo.SizeAndChecksums.Size == 0)
@@ -374,7 +374,7 @@ namespace MPF.UI.Windows
if (submissionInfo.PartiallyMatchedIDs == null)
PartiallyMatchedIDs.Visibility = Visibility.Collapsed;
else
PartiallyMatchedIDs.Text = string.Join(", ", submissionInfo.PartiallyMatchedIDs.Select(i => i.ToString()).ToArray());
PartiallyMatchedIDs.Text = string.Join(", ", [.. submissionInfo.PartiallyMatchedIDs.ConvertAll(i => i.ToString())]);
if (string.IsNullOrEmpty(submissionInfo.TracksAndWriteOffsets?.ClrMameProData))
HashData!.Visibility = Visibility.Collapsed;
if (submissionInfo.SizeAndChecksums?.Size == null)