Compare commits

...

18 Commits
2.7.5 ... 3.0.0

Author SHA1 Message Date
Matt Nadareski
4d46b7db5c Bump version 2023-11-14 16:39:19 -05:00
Matt Nadareski
21f5f29ac0 Update to .NET 8 (fixes #593) 2023-11-14 16:37:41 -05:00
Matt Nadareski
436e198826 Bump library versions 2023-11-14 16:32:32 -05:00
Matt Nadareski
91eb8c96c3 Update changelog 2023-11-08 21:03:27 -05:00
Matt Nadareski
edf0bcb4fe Update documentation for BOS change 2023-11-08 21:03:09 -05:00
Matt Nadareski
1526714ab9 Remove Unshield reference 2023-11-07 14:32:18 -05:00
Matt Nadareski
767e0bb05b Remove .NET Framework 4.8 from issue report 2023-11-07 12:03:45 -05:00
Matt Nadareski
52e781329c Make releases less verbose 2023-11-07 11:13:12 -05:00
Matt Nadareski
0c1395d3ec Remove lingering script reference 2023-11-07 00:23:55 -05:00
Matt Nadareski
791d9cdb7b Consolidate build script information 2023-11-07 00:22:54 -05:00
Matt Nadareski
7d7dc4ee4e Even more README cleanup 2023-11-07 00:18:54 -05:00
Matt Nadareski
97fd04b13a Remove 4.8 note from build script 2023-11-06 23:38:27 -05:00
Matt Nadareski
899db4c8c0 Remove redundant information 2023-11-06 23:15:27 -05:00
Matt Nadareski
bba204cbfe Update README for Legacy 2023-11-06 23:13:08 -05:00
Matt Nadareski
145660e9f9 Address lingering modern .NET syntax 2023-11-06 23:06:11 -05:00
Matt Nadareski
24de14aea5 Remove .NET Framework 4.8 gated code 2023-11-06 22:07:40 -05:00
Matt Nadareski
d57161e4d1 Remove .NET Framework 4.8 from projects 2023-11-06 21:00:07 -05:00
Matt Nadareski
a066a5234a Remove .NET Framework 4.8 from build 2023-11-06 20:57:03 -05:00
66 changed files with 2091 additions and 6014 deletions

4
.editorconfig Normal file
View File

@@ -0,0 +1,4 @@
[*.cs]
# SYSLIB1045: Convert to 'GeneratedRegexAttribute'.
dotnet_diagnostic.SYSLIB1045.severity = silent

View File

@@ -8,8 +8,9 @@ assignees: mnadareski
---
**Before You Submit**
- Remember to try the [latest WIP build](https://ci.appveyor.com/project/mnadareski/mpf/build/artifacts) to see if the feature already exists.
- Is it copy protection related? If so, report the issue [here](https://github.com/mnadareski/BurnOutSharp/issues) instead.
- Is it copy protection related? If so, report the issue [here](hhttps://github.com/SabreTools/BinaryObjectScanner/issues) instead.
- Check [previous issues](https://github.com/SabreTools/MPF/issues) to see if any of those are related to what you're about to ask for.
If none of those apply, then continue...

View File

@@ -8,8 +8,9 @@ assignees: mnadareski
---
**Before You Submit**
- Remember to try the [latest WIP build](https://ci.appveyor.com/project/mnadareski/mpf/build/artifacts) to see if the feature already exists.
- Is it copy protection related? If so, report the issue [here](https://github.com/mnadareski/BurnOutSharp/issues) instead.
- Is it copy protection related? If so, report the issue [here](hhttps://github.com/SabreTools/BinaryObjectScanner/issues) instead.
- Check [previous issues](https://github.com/SabreTools/MPF/issues) to see if any of those are related to what you're about to ask for.
If none of those apply, then continue...
@@ -18,4 +19,4 @@ If none of those apply, then continue...
A clear and concise description of what the information is. Ex. With the latest build of DumpingProgram, it [...]
**Additional context**
Add any other context or screenshots about the information here.
Add any other context or screenshots about the information here.

View File

@@ -8,15 +8,16 @@ assignees: mnadareski
---
**Before You Submit**
- Remember to try the [latest WIP build](https://ci.appveyor.com/project/mnadareski/mpf/build/artifacts) to see if the issue has already been addressed.
- Is it copy protection related? If so, report the issue [here](https://github.com/mnadareski/BurnOutSharp/issues) instead.
- Is it copy protection related? If so, report the issue [here](hhttps://github.com/SabreTools/BinaryObjectScanner/issues) instead.
- Check multiple discs to help narrow down the issue
- Check the Options to see if changing any of those affects your issue.
If all of those fail, then continue...
**Version**
What version are you using?
What version are you using?
- [ ] Stable release (version here)
- [ ] WIP release (version here)
@@ -24,15 +25,15 @@ What version are you using?
**Build**
What runtime version are you using?
- [ ] .NET Framework 4.8 running on (Operating System)
- [ ] .NET 6.0 running on (Operating System)
- [ ] .NET 7.0 running on (Operating System)
- [ ] .NET 8.0 running on (Operating System)
**Describe the issue**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'

View File

@@ -1,3 +1,22 @@
### 3.0.0 (2023-11-14)
- Remove .NET Framework 4.8 from build
- Remove .NET Framework 4.8 from projects
- Remove .NET Framework 4.8 gated code
- Address lingering modern .NET syntax
- Update README for Legacy
- Remove redundant information
- Remove 4.8 note from build script
- Even more README cleanup
- Consolidate build script information
- Remove lingering script reference
- Make releases less verbose
- Remove .NET Framework 4.8 from issue report
- Remove Unshield reference
- Update documentation for BOS change
- Bump library versions
- Update to .NET 8
### 2.7.5 (2023-11-06)
- Remove psxt001z Pkg Ref in MPF.Test (Deterous)

View File

@@ -1,18 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net48;net6.0;net7.0</TargetFrameworks>
<TargetFrameworks>net6.0;net8.0</TargetFrameworks>
<RuntimeIdentifiers>win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
<OutputType>Exe</OutputType>
<Nullable>enable</Nullable>
<Title>MPF Check</Title>
<Description>Validator for various dumping programs</Description>
<Authors>Matt Nadareski;ReignStumble;Jakz</Authors>
<Copyright>Copyright (c)2019-2023</Copyright>
<VersionPrefix>2.7.5</VersionPrefix>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)'!='net48'">
<Nullable>enable</Nullable>
<VersionPrefix>3.0.0</VersionPrefix>
</PropertyGroup>
<ItemGroup>
@@ -24,14 +21,14 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="BurnOutSharp" PrivateAssets="build; analyzers" ExcludeAssets="contentFiles" Version="2.9.0" GeneratePathProperty="true">
<PackageReference Include="BinaryObjectScanner" PrivateAssets="build; analyzers" ExcludeAssets="contentFiles" Version="3.0.0" GeneratePathProperty="true">
<IncludeAssets>runtime; compile; build; native; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="SabreTools.RedumpLib" Version="1.1.1" />
<PackageReference Include="SabreTools.RedumpLib" Version="1.2.0" />
</ItemGroup>
<ItemGroup>
<Content Include="$(PkgBurnOutSharp)\content\**" PackagePath="contentFiles\any\any;content" CopyToOutputDirectory="Always" PackageCopyToOutput="true" />
<Content Include="$(PkgBinaryObjectScanner)\content\**" PackagePath="contentFiles\any\any;content" CopyToOutputDirectory="Always" PackageCopyToOutput="true" />
</ItemGroup>
</Project>

View File

@@ -45,11 +45,7 @@ namespace MPF.Check
protectionProgress.ProgressChanged += ConsoleLogger.ProgressUpdated;
// Validate the supplied credentials
#if NET48
(bool? _, string message) = RedumpWebClient.ValidateCredentials(options?.RedumpUsername, options?.RedumpPassword);
#else
(bool? _, string? message) = RedumpHttpClient.ValidateCredentials(options.RedumpUsername ?? string.Empty, options.RedumpPassword ?? string.Empty).ConfigureAwait(false).GetAwaiter().GetResult();
#endif
if (!string.IsNullOrWhiteSpace(message))
Console.WriteLine(message);
@@ -67,11 +63,7 @@ namespace MPF.Check
string filepath = Path.GetFullPath(args[i].Trim('"'));
// Now populate an environment
#if NET48
Drive drive = null;
#else
Drive? drive = null;
#endif
if (!string.IsNullOrWhiteSpace(path))
drive = Drive.Create(null, path);
@@ -87,11 +79,7 @@ namespace MPF.Check
/// Display help for MPF.Check
/// </summary>
/// <param name="error">Error string to prefix the help text with</param>
#if NET48
private static void DisplayHelp(string error = null)
#else
private static void DisplayHelp(string? error = null)
#endif
{
if (error != null)
Console.WriteLine(error);

View File

@@ -9,11 +9,7 @@ namespace MPF.Core
/// <summary>
/// Simple process counter to write to console
/// </summary>
#if NET48
public static void ProgressUpdated(object sender, Result value)
#else
public static void ProgressUpdated(object? sender, Result value)
#endif
{
Console.WriteLine(value.Message);
}
@@ -21,11 +17,7 @@ namespace MPF.Core
/// <summary>
/// Simple process counter to write to console
/// </summary>
#if NET48
public static void ProgressUpdated(object sender, ProtectionProgress value)
#else
public static void ProgressUpdated(object? sender, ProtectionProgress value)
#endif
{
Console.WriteLine($"{value.Percentage * 100:N2}%: {value.Filename} - {value.Protection}");
}

View File

@@ -18,17 +18,13 @@ namespace MPF.Core.Converters
/// <returns>InternalDriveType, if possible, null on error</returns>
public static InternalDriveType? ToInternalDriveType(this DriveType driveType)
{
switch (driveType)
return driveType switch
{
case DriveType.CDRom:
return InternalDriveType.Optical;
case DriveType.Fixed:
return InternalDriveType.HardDisk;
case DriveType.Removable:
return InternalDriveType.Removable;
default:
return null;
}
DriveType.CDRom => (InternalDriveType?)InternalDriveType.Optical,
DriveType.Fixed => (InternalDriveType?)InternalDriveType.HardDisk,
DriveType.Removable => (InternalDriveType?)InternalDriveType.Removable,
_ => null,
};
}
#endregion
@@ -38,11 +34,7 @@ namespace MPF.Core.Converters
/// <summary>
/// Long name method cache
/// </summary>
#if NET48
private static readonly ConcurrentDictionary<Type, MethodInfo> LongNameMethods = new ConcurrentDictionary<Type, MethodInfo>();
#else
private static readonly ConcurrentDictionary<Type, MethodInfo?> LongNameMethods = new ConcurrentDictionary<Type, MethodInfo?>();
#endif
private static readonly ConcurrentDictionary<Type, MethodInfo?> LongNameMethods = new();
/// <summary>
/// Get the string representation of a generic enumerable value
@@ -84,39 +76,30 @@ namespace MPF.Core.Converters
/// <returns>String representing the value, if possible</returns>
public static string LongName(this InternalProgram? prog)
{
switch (prog)
return (prog) switch
{
#region Dumping support
case InternalProgram.Aaru:
return "Aaru";
case InternalProgram.DiscImageCreator:
return "DiscImageCreator";
case InternalProgram.Redumper:
return "Redumper";
InternalProgram.Aaru => "Aaru",
InternalProgram.DiscImageCreator => "DiscImageCreator",
InternalProgram.Redumper => "Redumper",
#endregion
#region Verification support only
case InternalProgram.CleanRip:
return "CleanRip";
case InternalProgram.DCDumper:
return "DCDumper";
case InternalProgram.UmdImageCreator:
return "UmdImageCreator";
InternalProgram.CleanRip => "CleanRip",
InternalProgram.DCDumper => "DCDumper",
InternalProgram.UmdImageCreator => "UmdImageCreator",
#endregion
case InternalProgram.NONE:
default:
return "Unknown";
}
InternalProgram.NONE => "Unknown",
_ => "Unknown",
};
}
#endregion
#endregion
#region Convert From String
@@ -125,46 +108,35 @@ namespace MPF.Core.Converters
/// </summary>
/// <param name="internalProgram">String value to convert</param>
/// <returns>InternalProgram represented by the string, if possible</returns>
#if NET48
public static InternalProgram ToInternalProgram(string internalProgram)
#else
public static InternalProgram ToInternalProgram(string? internalProgram)
#endif
{
switch (internalProgram?.ToLowerInvariant())
return (internalProgram?.ToLowerInvariant()) switch
{
// Dumping support
case "aaru":
case "chef":
case "dichef":
case "discimagechef":
return InternalProgram.Aaru;
case "creator":
case "dic":
case "dicreator":
case "discimagecreator":
return InternalProgram.DiscImageCreator;
case "rd":
case "redumper":
return InternalProgram.Redumper;
"aaru"
or "chef"
or "dichef"
or "discimagechef" => InternalProgram.Aaru,
"creator"
or "dic"
or "dicreator"
or "discimagecreator" => InternalProgram.DiscImageCreator,
"rd"
or "redumper" => InternalProgram.Redumper,
// Verification support only
case "cleanrip":
case "cr":
return InternalProgram.CleanRip;
case "dc":
case "dcd":
case "dcdumper":
return InternalProgram.DCDumper;
case "uic":
case "umd":
case "umdcreator":
case "umdimagecreator":
return InternalProgram.UmdImageCreator;
"cleanrip"
or "cr" => InternalProgram.CleanRip,
"dc"
or "dcd"
or "dcdumper" => InternalProgram.DCDumper,
"uic"
or "umd"
or "umdcreator"
or "umdimagecreator" => InternalProgram.UmdImageCreator,
default:
return InternalProgram.NONE;
}
_ => InternalProgram.NONE,
};
}
/// <summary>
@@ -174,170 +146,140 @@ namespace MPF.Core.Converters
/// <returns>MediaType represented by the string, if possible</returns>
public static MediaType ToMediaType(string type)
{
switch (type.ToLowerInvariant())
return (type.ToLowerInvariant()) switch
{
#region Punched Media
case "aperture":
case "aperturecard":
case "aperture card":
return MediaType.ApertureCard;
case "jacquardloom":
case "jacquardloomcard":
case "jacquard loom card":
return MediaType.JacquardLoomCard;
case "magneticstripe":
case "magneticstripecard":
case "magnetic stripe card":
return MediaType.MagneticStripeCard;
case "opticalphone":
case "opticalphonecard":
case "optical phonecard":
return MediaType.OpticalPhonecard;
case "punchcard":
case "punchedcard":
case "punched card":
return MediaType.PunchedCard;
case "punchtape":
case "punchedtape":
case "punched tape":
return MediaType.PunchedTape;
"aperture"
or "aperturecard"
or "aperture card" => MediaType.ApertureCard,
"jacquardloom"
or "jacquardloomcard"
or "jacquard loom card" => MediaType.JacquardLoomCard,
"magneticstripe"
or "magneticstripecard"
or "magnetic stripe card" => MediaType.MagneticStripeCard,
"opticalphone"
or "opticalphonecard"
or "optical phonecard" => MediaType.OpticalPhonecard,
"punchcard"
or "punchedcard"
or "punched card" => MediaType.PunchedCard,
"punchtape"
or "punchedtape"
or "punched tape" => MediaType.PunchedTape,
#endregion
#region Tape
case "openreel":
case "openreeltape":
case "open reel tape":
return MediaType.OpenReel;
case "datacart":
case "datacartridge":
case "datatapecartridge":
case "data tape cartridge":
return MediaType.DataCartridge;
case "cassette":
case "cassettetape":
case "cassette tape":
return MediaType.Cassette;
"openreel"
or "openreeltape"
or "open reel tape" => MediaType.OpenReel,
"datacart"
or "datacartridge"
or "datatapecartridge"
or "data tape cartridge" => MediaType.DataCartridge,
"cassette"
or "cassettetape"
or "cassette tape" => MediaType.Cassette,
#endregion
#region Disc / Disc
case "bd":
case "bdrom":
case "bd-rom":
case "bluray":
return MediaType.BluRay;
case "cd":
case "cdrom":
case "cd-rom":
return MediaType.CDROM;
case "dvd":
case "dvd5":
case "dvd-5":
case "dvd9":
case "dvd-9":
case "dvdrom":
case "dvd-rom":
return MediaType.DVD;
case "fd":
case "floppy":
case "floppydisk":
case "floppy disk":
case "floppy diskette":
return MediaType.FloppyDisk;
case "floptical":
return MediaType.Floptical;
case "gd":
case "gdrom":
case "gd-rom":
return MediaType.GDROM;
case "hddvd":
case "hd-dvd":
case "hddvdrom":
case "hd-dvd-rom":
return MediaType.HDDVD;
case "hdd":
case "harddisk":
case "hard disk":
return MediaType.HardDisk;
case "bernoullidisk":
case "iomegabernoullidisk":
case "bernoulli disk":
case "iomega bernoulli disk":
return MediaType.IomegaBernoulliDisk;
case "jaz":
case "iomegajaz":
case "iomega jaz":
return MediaType.IomegaJaz;
case "zip":
case "zipdisk":
case "iomegazip":
case "iomega zip":
return MediaType.IomegaZip;
case "ldrom":
case "lvrom":
case "ld-rom":
case "lv-rom":
case "laserdisc":
case "laservision":
case "ld-rom / lv-rom":
return MediaType.LaserDisc;
case "64dd":
case "n64dd":
case "64dddisk":
case "n64dddisk":
case "64dd disk":
case "n64dd disk":
return MediaType.Nintendo64DD;
case "fds":
case "famicom":
case "nfds":
case "nintendofamicom":
case "famicomdisksystem":
case "famicom disk system":
case "famicom disk system disk":
return MediaType.NintendoFamicomDiskSystem;
case "gc":
case "gamecube":
case "nintendogamecube":
case "nintendo gamecube":
case "gamecube disc":
case "gamecube game disc":
return MediaType.NintendoGameCubeGameDisc;
case "wii":
case "nintendowii":
case "nintendo wii":
case "nintendo wii disc":
case "wii optical disc":
return MediaType.NintendoWiiOpticalDisc;
case "wiiu":
case "nintendowiiu":
case "nintendo wiiu":
case "nintendo wiiu disc":
case "wiiu optical disc":
case "wii u optical disc":
return MediaType.NintendoWiiUOpticalDisc;
case "umd":
return MediaType.UMD;
"bd"
or "bdrom"
or "bd-rom"
or "bluray" => MediaType.BluRay,
"cd"
or "cdrom"
or "cd-rom" => MediaType.CDROM,
"dvd"
or "dvd5"
or "dvd-5"
or "dvd9"
or "dvd-9"
or "dvdrom"
or "dvd-rom" => MediaType.DVD,
"fd"
or "floppy"
or "floppydisk"
or "floppy disk"
or "floppy diskette" => MediaType.FloppyDisk,
"floptical" => MediaType.Floptical,
"gd"
or "gdrom"
or "gd-rom" => MediaType.GDROM,
"hddvd"
or "hd-dvd"
or "hddvdrom"
or "hd-dvd-rom" => MediaType.HDDVD,
"hdd"
or "harddisk"
or "hard disk" => MediaType.HardDisk,
"bernoullidisk"
or "iomegabernoullidisk"
or "bernoulli disk"
or "iomega bernoulli disk" => MediaType.IomegaBernoulliDisk,
"jaz"
or "iomegajaz"
or "iomega jaz" => MediaType.IomegaJaz,
"zip"
or "zipdisk"
or "iomegazip"
or "iomega zip" => MediaType.IomegaZip,
"ldrom"
or "lvrom"
or "ld-rom"
or "lv-rom"
or "laserdisc"
or "laservision"
or "ld-rom / lv-rom" => MediaType.LaserDisc,
"64dd"
or "n64dd"
or "64dddisk"
or "n64dddisk"
or "64dd disk"
or "n64dd disk" => MediaType.Nintendo64DD,
"fds"
or "famicom"
or "nfds"
or "nintendofamicom"
or "famicomdisksystem"
or "famicom disk system"
or "famicom disk system disk" => MediaType.NintendoFamicomDiskSystem,
"gc"
or "gamecube"
or "nintendogamecube"
or "nintendo gamecube"
or "gamecube disc"
or "gamecube game disc" => MediaType.NintendoGameCubeGameDisc,
"wii"
or "nintendowii"
or "nintendo wii"
or "nintendo wii disc"
or "wii optical disc" => MediaType.NintendoWiiOpticalDisc,
"wiiu"
or "nintendowiiu"
or "nintendo wiiu"
or "nintendo wiiu disc"
or "wiiu optical disc"
or "wii u optical disc" => MediaType.NintendoWiiUOpticalDisc,
"umd" => MediaType.UMD,
#endregion
// Unsorted Formats
case "cartridge":
return MediaType.Cartridge;
case "ced":
case "rcaced":
case "rca ced":
case "videodisc":
case "rca videodisc":
return MediaType.CED;
"cartridge" => MediaType.Cartridge,
"ced"
or "rcaced"
or "rca ced"
or "videodisc"
or "rca videodisc" => MediaType.CED,
default:
return MediaType.NONE;
}
_ => MediaType.NONE,
};
}
#endregion

View File

@@ -30,22 +30,17 @@ namespace MPF.Core.Data
/// <returns>Read-only list of drive speeds</returns>
public static IReadOnlyList<int> GetSpeedsForMediaType(MediaType? type)
{
switch (type)
return type switch
{
case MediaType.CDROM:
case MediaType.GDROM:
return CD;
case MediaType.DVD:
case MediaType.NintendoGameCubeGameDisc:
case MediaType.NintendoWiiOpticalDisc:
return DVD;
case MediaType.HDDVD:
return HDDVD;
case MediaType.BluRay:
return BD;
default:
return Unknown;
}
MediaType.CDROM
or MediaType.GDROM => CD,
MediaType.DVD
or MediaType.NintendoGameCubeGameDisc
or MediaType.NintendoWiiOpticalDisc => DVD,
MediaType.HDDVD => HDDVD,
MediaType.BluRay => BD,
_ => Unknown,
};
}
}

View File

@@ -27,20 +27,12 @@ namespace MPF.Core.Data
/// <summary>
/// Drive partition format
/// </summary>
#if NET48
public string DriveFormat { get; private set; } = null;
#else
public string? DriveFormat { get; private set; } = null;
#endif
/// <summary>
/// Windows drive path
/// </summary>
#if NET48
public string Name { get; private set; } = null;
#else
public string? Name { get; private set; } = null;
#endif
/// <summary>
/// Represents if Windows has marked the drive as active
@@ -56,11 +48,7 @@ namespace MPF.Core.Data
/// Media label as read by Windows
/// </summary>
/// <remarks>The try/catch is needed because Windows will throw an exception if the drive is not marked as active</remarks>
#if NET48
public string VolumeLabel { get; private set; } = null;
#else
public string? VolumeLabel { get; private set; } = null;
#endif
#endregion
@@ -69,11 +57,7 @@ namespace MPF.Core.Data
/// <summary>
/// Media label as read by Windows, formatted to avoid odd outputs
/// </summary>
#if NET48
public string FormattedVolumeLabel
#else
public string? FormattedVolumeLabel
#endif
{
get
{
@@ -111,11 +95,7 @@ namespace MPF.Core.Data
/// </summary>
/// <param name="driveType">InternalDriveType value representing the drive type</param>
/// <param name="devicePath">Path to the device according to the local machine</param>
#if NET48
public static Drive Create(InternalDriveType? driveType, string devicePath)
#else
public static Drive? Create(InternalDriveType? driveType, string devicePath)
#endif
{
// Create a new, empty drive object
var drive = new Drive()
@@ -129,11 +109,7 @@ namespace MPF.Core.Data
// Sanitize a Windows-formatted long device path
if (devicePath.StartsWith("\\\\.\\"))
#if NET48
devicePath = devicePath.Substring("\\\\.\\".Length);
#else
devicePath = devicePath["\\\\.\\".Length..];
#endif
// Create and validate the drive info object
var driveInfo = new DriveInfo(devicePath);
@@ -150,11 +126,7 @@ namespace MPF.Core.Data
/// Populate all fields from a DriveInfo object
/// </summary>
/// <param name="driveInfo">DriveInfo object to populate from</param>
#if NET48
private void PopulateFromDriveInfo(DriveInfo driveInfo)
#else
private void PopulateFromDriveInfo(DriveInfo? driveInfo)
#endif
{
// If we have an invalid DriveInfo, just return
if (driveInfo == null || driveInfo == default)
@@ -196,11 +168,7 @@ namespace MPF.Core.Data
/// </summary>
/// <param name="system"></param>
/// <returns></returns>
#if NET48
public (MediaType?, string) GetMediaType(RedumpSystem? system)
#else
public (MediaType?, string?) GetMediaType(RedumpSystem? system)
#endif
{
// Take care of the non-optical stuff first
switch (this.InternalDriveType)

View File

@@ -8,22 +8,13 @@ namespace MPF.Core.Data
{
public class IniFile : IDictionary<string, string>
{
#if NET48
private Dictionary<string, string> _keyValuePairs = new Dictionary<string, string>();
#else
private Dictionary<string, string> _keyValuePairs = new();
#endif
public string this[string key]
{
get
{
#if NET48
if (_keyValuePairs == null)
_keyValuePairs = new Dictionary<string, string>();
#else
_keyValuePairs ??= new Dictionary<string, string>();
#endif
key = key.ToLowerInvariant();
if (_keyValuePairs.ContainsKey(key))
@@ -33,12 +24,7 @@ namespace MPF.Core.Data
}
set
{
#if NET48
if (_keyValuePairs == null)
_keyValuePairs = new Dictionary<string, string>();
#else
_keyValuePairs ??= new Dictionary<string, string>();
#endif
key = key.ToLowerInvariant();
_keyValuePairs[key] = value;
@@ -93,10 +79,8 @@ namespace MPF.Core.Data
if (!File.Exists(path))
return false;
using (var fileStream = File.OpenRead(path))
{
return Parse(fileStream);
}
using var fileStream = File.OpenRead(path);
return Parse(fileStream);
}
/// <summary>
@@ -111,55 +95,49 @@ namespace MPF.Core.Data
// Keys are case-insensitive by default
try
{
using (var sr = new StreamReader(stream))
using var sr = new StreamReader(stream);
string section = string.Empty;
while (!sr.EndOfStream)
{
string section = string.Empty;
while (!sr.EndOfStream)
var line = sr.ReadLine()?.Trim();
// Empty lines are skipped
if (string.IsNullOrWhiteSpace(line))
{
var line = sr.ReadLine()?.Trim();
// Empty lines are skipped
if (string.IsNullOrWhiteSpace(line))
{
// No-op, we don't process empty lines
}
// Comments start with ';'
else if (line.StartsWith(";"))
{
// No-op, we don't process comments
}
// Section titles are surrounded by square brackets
else if (line.StartsWith("["))
{
section = line.TrimStart('[').TrimEnd(']');
}
// Valid INI lines are in the format key=value
#if NET48
else if (line.Contains("="))
#else
else if (line.Contains('='))
#endif
{
// Split the line by '=' for key-value pairs
string[] data = line.Split('=');
// 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();
// Section names are prepended to the key with a '.' separating
if (!string.IsNullOrEmpty(section))
key = $"{section}.{key}";
// Set or overwrite keys in the returned dictionary
_keyValuePairs[key.ToLowerInvariant()] = value;
}
// All other lines are ignored
// No-op, we don't process empty lines
}
// Comments start with ';'
else if (line.StartsWith(";"))
{
// No-op, we don't process comments
}
// Section titles are surrounded by square brackets
else if (line.StartsWith("["))
{
section = line.TrimStart('[').TrimEnd(']');
}
// Valid INI lines are in the format key=value
else if (line.Contains('='))
{
// Split the line by '=' for key-value pairs
string[] data = line.Split('=');
// 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();
// Section names are prepended to the key with a '.' separating
if (!string.IsNullOrEmpty(section))
key = $"{section}.{key}";
// Set or overwrite keys in the returned dictionary
_keyValuePairs[key.ToLowerInvariant()] = value;
}
// All other lines are ignored
}
}
catch
@@ -180,10 +158,8 @@ namespace MPF.Core.Data
if (_keyValuePairs == null || _keyValuePairs.Count == 0)
return false;
using (var fileStream = File.OpenWrite(path))
{
return Write(fileStream);
}
using var fileStream = File.OpenWrite(path);
return Write(fileStream);
}
/// <summary>
@@ -201,39 +177,37 @@ namespace MPF.Core.Data
try
{
using (var sw = new StreamWriter(stream))
// Order the dictionary by keys to link sections together
using var sw = new StreamWriter(stream);
var orderedKeyValuePairs = _keyValuePairs.OrderBy(kvp => kvp.Key);
string section = string.Empty;
foreach (var keyValuePair in orderedKeyValuePairs)
{
// Order the dictionary by keys to link sections together
var orderedKeyValuePairs = _keyValuePairs.OrderBy(kvp => kvp.Key);
// Extract the key and value
string key = keyValuePair.Key;
string value = keyValuePair.Value;
string section = string.Empty;
foreach (var keyValuePair in orderedKeyValuePairs)
// We assume '.' is a section name separator
if (key.Contains('.'))
{
// Extract the key and value
string key = keyValuePair.Key;
string value = keyValuePair.Value;
// Split the key by '.'
string[] data = keyValuePair.Key.Split('.');
// We assume '.' is a section name separator
if (key.Contains('.'))
// If the key contains an '.', we need to put them back in
string newSection = data[0].Trim();
key = string.Join(".", data.Skip(1)).Trim();
// If we have a new section, write it out
if (!string.Equals(newSection, section, StringComparison.OrdinalIgnoreCase))
{
// Split the key by '.'
string[] data = keyValuePair.Key.Split('.');
// If the key contains an '.', we need to put them back in
string newSection = data[0].Trim();
key = string.Join(".", data.Skip(1)).Trim();
// If we have a new section, write it out
if (!string.Equals(newSection, section, StringComparison.OrdinalIgnoreCase))
{
sw.WriteLine($"[{newSection}]");
section = newSection;
}
sw.WriteLine($"[{newSection}]");
section = newSection;
}
// Now write out the key and value in a standardized way
sw.WriteLine($"{key}={value}");
}
// Now write out the key and value in a standardized way
sw.WriteLine($"{key}={value}");
}
}
catch

View File

@@ -9,11 +9,7 @@ namespace MPF.Core.Data
/// <summary>
/// All settings in the form of a dictionary
/// </summary>
#if NET48
public Dictionary<string, string> Settings { get; private set; }
#else
public Dictionary<string, string?> Settings { get; private set; }
#endif
/// <summary>
/// Indicate if the program is being run with a clean configuration
@@ -29,11 +25,7 @@ namespace MPF.Core.Data
/// <summary>
/// Path to Aaru
/// </summary>
#if NET48
public string AaruPath
#else
public string? AaruPath
#endif
{
get { return GetStringSetting(Settings, "AaruPath", "Programs\\Aaru\\Aaru.exe"); }
set { Settings["AaruPath"] = value; }
@@ -42,11 +34,7 @@ namespace MPF.Core.Data
/// <summary>
/// Path to DiscImageCreator
/// </summary>
#if NET48
public string DiscImageCreatorPath
#else
public string? DiscImageCreatorPath
#endif
{
get { return GetStringSetting(Settings, "DiscImageCreatorPath", "Programs\\Creator\\DiscImageCreator.exe"); }
set { Settings["DiscImageCreatorPath"] = value; }
@@ -55,11 +43,7 @@ namespace MPF.Core.Data
/// <summary>
/// Path to Redumper
/// </summary>
#if NET48
public string RedumperPath
#else
public string? RedumperPath
#endif
{
get { return GetStringSetting(Settings, "RedumperPath", "Programs\\Redumper\\redumper.exe"); }
set { Settings["RedumperPath"] = value; }
@@ -116,11 +100,7 @@ namespace MPF.Core.Data
/// <summary>
/// Default output path for dumps
/// </summary>
#if NET48
public string DefaultOutputPath
#else
public string? DefaultOutputPath
#endif
{
get { return GetStringSetting(Settings, "DefaultOutputPath", "ISO"); }
set { Settings["DefaultOutputPath"] = value; }
@@ -599,22 +579,14 @@ namespace MPF.Core.Data
#region Redump Login Information
#if NET48
public string RedumpUsername
#else
public string? RedumpUsername
#endif
{
get { return GetStringSetting(Settings, "RedumpUsername", ""); }
set { Settings["RedumpUsername"] = value; }
}
// TODO: Figure out a way to keep this encrypted in some way, BASE64 to start?
#if NET48
public string RedumpPassword
#else
public string? RedumpPassword
#endif
{
get
{
@@ -634,44 +606,24 @@ namespace MPF.Core.Data
/// Constructor taking a dictionary for settings
/// </summary>
/// <param name="settings"></param>
#if NET48
public Options(Dictionary<string, string> settings = null)
#else
public Options(Dictionary<string, string?>? settings = null)
#endif
{
#if NET48
this.Settings = settings ?? new Dictionary<string, string>();
#else
this.Settings = settings ?? new Dictionary<string, string?>();
#endif
}
/// <summary>
/// Constructor taking an existing Options object
/// </summary>
/// <param name="source"></param>
#if NET48
public Options(Options source)
#else
public Options(Options? source)
#endif
{
#if NET48
Settings = new Dictionary<string, string>(source?.Settings ?? new Dictionary<string, string>());
#else
Settings = new Dictionary<string, string?>(source?.Settings ?? new Dictionary<string, string?>());
#endif
}
/// <summary>
/// Accessor for the internal dictionary
/// </summary>
#if NET48
public string this[string key]
#else
public string? this[string key]
#endif
{
get => this.Settings[key];
set => this.Settings[key] = value;
@@ -686,11 +638,7 @@ namespace MPF.Core.Data
/// <param name="key">Setting key to get a value for</param>
/// <param name="defaultValue">Default value to return if no value is found</param>
/// <returns>Setting value if possible, default value otherwise</returns>
#if NET48
private static bool GetBooleanSetting(Dictionary<string, string> settings, string key, bool defaultValue)
#else
private static bool GetBooleanSetting(Dictionary<string, string?> settings, string key, bool defaultValue)
#endif
{
if (settings.ContainsKey(key))
{
@@ -712,11 +660,7 @@ namespace MPF.Core.Data
/// <param name="key">Setting key to get a value for</param>
/// <param name="defaultValue">Default value to return if no value is found</param>
/// <returns>Setting value if possible, default value otherwise</returns>
#if NET48
private static int GetInt32Setting(Dictionary<string, string> settings, string key, int defaultValue)
#else
private static int GetInt32Setting(Dictionary<string, string?> settings, string key, int defaultValue)
#endif
{
if (settings.ContainsKey(key))
{
@@ -738,11 +682,7 @@ namespace MPF.Core.Data
/// <param name="key">Setting key to get a value for</param>
/// <param name="defaultValue">Default value to return if no value is found</param>
/// <returns>Setting value if possible, default value otherwise</returns>
#if NET48
private static string GetStringSetting(Dictionary<string, string> settings, string key, string defaultValue)
#else
private static string? GetStringSetting(Dictionary<string, string?> settings, string key, string? defaultValue)
#endif
{
if (settings.ContainsKey(key))
return settings[key];

View File

@@ -5,7 +5,7 @@ using System.Threading.Tasks;
namespace MPF.Core.Data
{
public class ProcessingQueue<T> : IDisposable
public sealed class ProcessingQueue<T> : IDisposable
{
/// <summary>
/// Internal queue to hold data to process
@@ -54,7 +54,7 @@ namespace MPF.Core.Data
while (true)
{
// Nothing in the queue means we get to idle
if (this.InternalQueue.Count == 0)
if (InternalQueue.IsEmpty)
{
if (this.TokenSource.IsCancellationRequested)
break;

View File

@@ -24,33 +24,25 @@
/// <summary>
/// Create a default success result with no message
/// </summary>
public static Result Success() => new Result(true, "");
public static Result Success() => new(true, "");
/// <summary>
/// Create a success result with a custom message
/// </summary>
/// <param name="message">String to add as a message</param>
#if NET48
public static Result Success(string message) => new Result(true, message);
#else
public static Result Success(string? message) => new Result(true, message ?? string.Empty);
#endif
public static Result Success(string? message) => new(true, message ?? string.Empty);
/// <summary>
/// Create a default failure result with no message
/// </summary>
/// <returns></returns>
public static Result Failure() => new Result(false, "");
public static Result Failure() => new(false, "");
/// <summary>
/// Create a failure result with a custom message
/// </summary>
/// <param name="message">String to add as a message</param>
#if NET48
public static Result Failure(string message) => new Result(false, message);
#else
public static Result Failure(string? message) => new Result(false, message ?? string.Empty);
#endif
public static Result Failure(string? message) => new(false, message ?? string.Empty);
/// <summary>
/// Results can be compared to boolean values based on the success value

View File

@@ -31,11 +31,7 @@ namespace MPF.Core
/// <summary>
/// Drive object representing the current drive
/// </summary>
#if NET48
public Drive Drive { get; private set; }
#else
public Drive? Drive { get; private set; }
#endif
/// <summary>
/// Currently selected system
@@ -60,11 +56,7 @@ namespace MPF.Core
/// <summary>
/// Parameters object representing what to send to the internal program
/// </summary>
#if NET48
public BaseParameters Parameters { get; private set; }
#else
public BaseParameters? Parameters { get; private set; }
#endif
#endregion
@@ -73,29 +65,17 @@ namespace MPF.Core
/// <summary>
/// Generic way of reporting a message
/// </summary>
#if NET48
public EventHandler<string> ReportStatus;
#else
public EventHandler<string>? ReportStatus;
#endif
/// <summary>
/// Queue of items that need to be logged
/// </summary>
#if NET48
private ProcessingQueue<string> outputQueue;
#else
private ProcessingQueue<string>? outputQueue;
#endif
/// <summary>
/// Event handler for data returned from a process
/// </summary>
#if NET48
private void OutputToLog(object proc, string args) => outputQueue?.Enqueue(args);
#else
private void OutputToLog(object? proc, string args) => outputQueue?.Enqueue(args);
#endif
/// <summary>
/// Process the outputs in the queue
@@ -116,19 +96,11 @@ namespace MPF.Core
/// <param name="parameters"></param>
public DumpEnvironment(Data.Options options,
string outputPath,
#if NET48
Drive drive,
#else
Drive? drive,
#endif
RedumpSystem? system,
MediaType? type,
InternalProgram? internalProgram,
#if NET48
string parameters)
#else
string? parameters)
#endif
{
// Set options object
Options = options;
@@ -152,47 +124,8 @@ namespace MPF.Core
/// Set the parameters object based on the internal program and parameters string
/// </summary>
/// <param name="parameters">String representation of the parameters</param>
#if NET48
public void SetParameters(string parameters)
#else
public void SetParameters(string? parameters)
#endif
{
#if NET48
switch (InternalProgram)
{
// Dumping support
case InternalProgram.Aaru:
Parameters = new Modules.Aaru.Parameters(parameters) { ExecutablePath = Options.AaruPath };
break;
case InternalProgram.DiscImageCreator:
Parameters = new Modules.DiscImageCreator.Parameters(parameters) { ExecutablePath = Options.DiscImageCreatorPath };
break;
case InternalProgram.Redumper:
Parameters = new Modules.Redumper.Parameters(parameters) { ExecutablePath = Options.RedumperPath };
break;
// Verification support only
case InternalProgram.CleanRip:
Parameters = new Modules.CleanRip.Parameters(parameters) { ExecutablePath = null };
break;
case InternalProgram.DCDumper:
Parameters = null; // TODO: Create correct parameter type when supported
break;
case InternalProgram.UmdImageCreator:
Parameters = new Modules.UmdImageCreator.Parameters(parameters) { ExecutablePath = null };
break;
// This should never happen, but it needs a fallback
default:
Parameters = new Modules.DiscImageCreator.Parameters(parameters) { ExecutablePath = Options.DiscImageCreatorPath };
break;
}
#else
Parameters = InternalProgram switch
{
// Dumping support
@@ -208,7 +141,6 @@ namespace MPF.Core
// This should never happen, but it needs a fallback
_ => new Modules.DiscImageCreator.Parameters(parameters) { ExecutablePath = Options.DiscImageCreatorPath },
};
#endif
// Set system and type
if (Parameters != null)
@@ -223,11 +155,7 @@ namespace MPF.Core
/// </summary>
/// <param name="driveSpeed">Nullable int representing the drive speed</param>
/// <returns>String representing the params, null on error</returns>
#if NET48
public string GetFullParameters(int? driveSpeed)
#else
public string? GetFullParameters(int? driveSpeed)
#endif
{
// Populate with the correct params for inputs (if we're not on the default option)
if (System != null && Type != MediaType.NONE)
@@ -237,27 +165,6 @@ namespace MPF.Core
return null;
// Set the proper parameters
#if NET48
switch (InternalProgram)
{
case InternalProgram.Aaru:
Parameters = new Modules.Aaru.Parameters(System, Type, Drive.Name, OutputPath, driveSpeed, Options);
break;
case InternalProgram.DiscImageCreator:
Parameters = new Modules.DiscImageCreator.Parameters(System, Type, Drive.Name, OutputPath, driveSpeed, Options);
break;
case InternalProgram.Redumper:
Parameters = new Modules.Redumper.Parameters(System, Type, Drive.Name, OutputPath, driveSpeed, Options);
break;
// This should never happen, but it needs a fallback
default:
Parameters = new Modules.DiscImageCreator.Parameters(System, Type, Drive.Name, OutputPath, driveSpeed, Options);
break;
}
#else
Parameters = InternalProgram switch
{
InternalProgram.Aaru => new Modules.Aaru.Parameters(System, Type, Drive.Name, OutputPath, driveSpeed, Options),
@@ -267,7 +174,6 @@ namespace MPF.Core
// This should never happen, but it needs a fallback
_ => new Modules.DiscImageCreator.Parameters(System, Type, Drive.Name, OutputPath, driveSpeed, Options),
};
#endif
// Generate and return the param string
return Parameters.GenerateParameters();
@@ -288,32 +194,20 @@ namespace MPF.Core
/// <summary>
/// Eject the disc using DiscImageCreator
/// </summary>
#if NET48
public async Task<string> EjectDisc() =>
#else
public async Task<string?> EjectDisc() =>
#endif
await RunStandaloneDiscImageCreatorCommand(Modules.DiscImageCreator.CommandStrings.Eject);
/// <summary>
/// Reset the current drive using DiscImageCreator
/// </summary>
#if NET48
public async Task<string> ResetDrive() =>
#else
public async Task<string?> ResetDrive() =>
#endif
await RunStandaloneDiscImageCreatorCommand(Modules.DiscImageCreator.CommandStrings.Reset);
/// <summary>
/// Execute the initial invocation of the dumping programs
/// </summary>
/// <param name="progress">Optional result progress callback</param>
#if NET48
public async Task<Result> Run(IProgress<Result> progress = null)
#else
public async Task<Result> Run(IProgress<Result>? progress = null)
#endif
{
// If we don't have parameters
if (Parameters == null)
@@ -361,17 +255,10 @@ namespace MPF.Core
/// <param name="seedInfo">A seed SubmissionInfo object that contains user data</param>
/// <returns>Result instance with the outcome</returns>
public async Task<Result> VerifyAndSaveDumpOutput(
#if NET48
IProgress<Result> resultProgress = null,
IProgress<ProtectionProgress> protectionProgress = null,
Func<SubmissionInfo, (bool?, SubmissionInfo)> processUserInfo = null,
SubmissionInfo seedInfo = null)
#else
IProgress<Result>? resultProgress = null,
IProgress<ProtectionProgress>? protectionProgress = null,
Func<SubmissionInfo?, (bool?, SubmissionInfo?)>? processUserInfo = null,
SubmissionInfo? seedInfo = null)
#endif
{
resultProgress?.Report(Result.Success("Gathering submission information... please wait!"));
@@ -620,11 +507,7 @@ namespace MPF.Core
/// </summary>
/// <param name="command">Command string to run</param>
/// <returns>The output of the command on success, null on error</returns>
#if NET48
private async Task<string> RunStandaloneDiscImageCreatorCommand(string command)
#else
private async Task<string?> RunStandaloneDiscImageCreatorCommand(string command)
#endif
{
// Validate that DiscImageCreator is all set
if (!RequiredProgramsExist())

View File

@@ -16,52 +16,28 @@ namespace MPF.Core.Hashing
/// <summary>
/// Hash type associated with the current state
/// </summary>
#if NET48
public Hash HashType { get; private set; }
#else
public Hash HashType { get; init; }
#endif
/// <summary>
/// Current hash in bytes
/// </summary>
#if NET48
public byte[] CurrentHashBytes
#else
public byte[]? CurrentHashBytes
#endif
{
get
{
#if NET48
switch (_hasher)
{
case HashAlgorithm ha:
return ha.Hash;
case NonCryptographicHashAlgorithm ncha:
return ncha.GetCurrentHash().Reverse().ToArray();
default:
return null;
}
#else
return (_hasher) switch
{
HashAlgorithm ha => ha.Hash,
NonCryptographicHashAlgorithm ncha => ncha.GetCurrentHash().Reverse().ToArray(),
_ => null,
};
#endif
}
}
/// <summary>
/// Current hash as a string
/// </summary>
#if NET48
public string CurrentHashString => ByteArrayToString(CurrentHashBytes);
#else
public string? CurrentHashString => ByteArrayToString(CurrentHashBytes);
#endif
#endregion
@@ -71,11 +47,7 @@ namespace MPF.Core.Hashing
/// Internal hasher being used for processing
/// </summary>
/// <remarks>May be either a HashAlgorithm or NonCryptographicHashAlgorithm</remarks>
#if NET48
private object _hasher;
#else
private object? _hasher;
#endif
#endregion
@@ -96,38 +68,6 @@ namespace MPF.Core.Hashing
/// </summary>
private void GetHasher()
{
#if NET48
switch (HashType)
{
case Hash.CRC32:
_hasher = new Crc32();
break;
case Hash.CRC64:
_hasher = new Crc64();
break;
case Hash.MD5:
_hasher = MD5.Create();
break;
case Hash.SHA1:
_hasher = SHA1.Create();
break;
case Hash.SHA256:
_hasher = SHA256.Create();
break;
case Hash.SHA384:
_hasher = SHA384.Create();
break;
case Hash.SHA512:
_hasher = SHA512.Create();
break;
case Hash.XxHash32:
_hasher = new XxHash32();
break;
case Hash.XxHash64:
_hasher = new XxHash64();
break;
}
#else
_hasher = HashType switch
{
Hash.CRC32 => new Crc32(),
@@ -141,7 +81,6 @@ namespace MPF.Core.Hashing
Hash.XxHash64 => new XxHash64(),
_ => null,
};
#endif
}
/// <inheritdoc/>
@@ -160,11 +99,7 @@ namespace MPF.Core.Hashing
/// </summary>
/// <param name="filename">Path to the input file</param>
/// <returns>True if hashing was successful, false otherwise</returns>
#if NET48
public static bool GetFileHashes(string filename, out long size, out string crc32, out string md5, out string sha1)
#else
public static bool GetFileHashes(string filename, out long size, out string? crc32, out string? md5, out string? sha1)
#endif
{
// Set all initial values
crc32 = null; md5 = null; sha1 = null;
@@ -186,11 +121,7 @@ namespace MPF.Core.Hashing
/// </summary>
/// <param name="filename">Path to the input file</param>
/// <returns>Dictionary containing hashes on success, null on error</returns>
#if NET48
public static Dictionary<Hash, string> GetFileHashes(string filename, out long size)
#else
public static Dictionary<Hash, string?>? GetFileHashes(string filename, out long size)
#endif
{
// If the file doesn't exist, we can't do anything
if (!File.Exists(filename))
@@ -202,13 +133,6 @@ namespace MPF.Core.Hashing
// Set the file size
size = new FileInfo(filename).Length;
// Create the output dictionary
#if NET48
var hashDict = new Dictionary<Hash, string>();
#else
var hashDict = new Dictionary<Hash, string?>();
#endif
// Open the input file
var input = File.OpenRead(filename);
@@ -221,18 +145,10 @@ namespace MPF.Core.Hashing
/// </summary>
/// <param name="input">Stream to hash</param>
/// <returns>Dictionary containing hashes on success, null on error</returns>
#if NET48
public static Dictionary<Hash, string> GetStreamHashes(Stream input)
#else
public static Dictionary<Hash, string?>? GetStreamHashes(Stream input)
#endif
{
// Create the output dictionary
#if NET48
var hashDict = new Dictionary<Hash, string>();
#else
var hashDict = new Dictionary<Hash, string?>();
#endif
try
{
@@ -375,11 +291,7 @@ namespace MPF.Core.Hashing
/// <param name="bytes">Byte array to convert</param>
/// <returns>Hex string representing the byte array</returns>
/// <link>http://stackoverflow.com/questions/311165/how-do-you-convert-byte-array-to-hexadecimal-string-and-vice-versa</link>
#if NET48
private static string ByteArrayToString(byte[] bytes)
#else
private static string? ByteArrayToString(byte[]? bytes)
#endif
{
// If we get null in, we send null out
if (bytes == null)

View File

@@ -5,17 +5,13 @@ using System.Threading;
//namespace Compress.ThreadReaders
namespace MPF.Core.Hashing
{
public class ThreadLoadBuffer : IDisposable
public sealed class ThreadLoadBuffer : IDisposable
{
private readonly AutoResetEvent _waitEvent;
private readonly AutoResetEvent _outEvent;
private readonly Thread _tWorker;
#if NET48
private byte[] _buffer;
#else
private byte[]? _buffer;
#endif
private int _size;
private readonly Stream _ds;
private bool _finished;

View File

@@ -19,6 +19,8 @@ using SabreTools.Models.PIC;
using SabreTools.RedumpLib.Data;
using Formatting = Newtonsoft.Json.Formatting;
#pragma warning disable SYSLIB1045 // Convert to 'GeneratedRegexAttribute'.
namespace MPF.Core
{
public static class InfoTool
@@ -33,11 +35,7 @@ namespace MPF.Core
/// <param name="parameters">Parameters object representing what to send to the internal program</param>
/// <param name="preCheck">True if this is a check done before a dump, false if done after</param>
/// <returns>Tuple of true if all required files exist, false otherwise and a list representing missing files</returns>
#if NET48
internal static (bool, List<string>) FoundAllFiles(string outputDirectory, string outputFilename, BaseParameters parameters, bool preCheck)
#else
internal static (bool, List<string>) FoundAllFiles(string? outputDirectory, string outputFilename, BaseParameters? parameters, bool preCheck)
#endif
{
// If there are no parameters set
if (parameters == null)
@@ -62,11 +60,7 @@ namespace MPF.Core
/// </summary>
/// <param name="datafile">.dat file location</param>
/// <returns>Relevant pieces of the datfile, null on error</returns>
#if NET48
internal static string GenerateDatfile(Datafile datafile)
#else
internal static string? GenerateDatfile(Datafile? datafile)
#endif
{
// If we don't have a valid datafile, we can't do anything
if (datafile?.Games == null || datafile.Games.Length == 0)
@@ -110,11 +104,7 @@ namespace MPF.Core
/// <param name="options">Options object that determines what to scan</param>
/// <param name="progress">Optional progress callback</param>
/// <returns>Detected copy protection(s) if possible, null on error</returns>
#if NET48
internal static async Task<(string, Dictionary<string, List<string>>)> GetCopyProtection(Drive drive, Data.Options options, IProgress<ProtectionProgress> progress = null)
#else
internal static async Task<(string?, Dictionary<string, List<string>>?)> GetCopyProtection(Drive? drive, Data.Options options, IProgress<ProtectionProgress>? progress = null)
#endif
{
if (options.ScanForProtection && drive?.Name != null)
{
@@ -130,11 +120,7 @@ namespace MPF.Core
/// </summary>
/// <param name="dat">Path to the DAT file to parse</param>
/// <returns>Filled Datafile on success, null on error</returns>
#if NET48
internal static Datafile GetDatafile(string dat)
#else
internal static Datafile? GetDatafile(string? dat)
#endif
{
// If there's no path, we can't read the file
if (string.IsNullOrWhiteSpace(dat))
@@ -177,11 +163,7 @@ namespace MPF.Core
/// <param name="pic">Path to a PIC.bin file</param>
/// <returns>Filled DiscInformation on success, null on error</returns>
/// <remarks>This omits the emergency brake information, if it exists</remarks>
#if NET48
internal static DiscInformation GetDiscInformation(string pic)
#else
internal static DiscInformation? GetDiscInformation(string pic)
#endif
{
try
{
@@ -199,11 +181,7 @@ namespace MPF.Core
/// </summary>
/// <param name="filename">Path to the input file</param>
/// <returns>Filled DateTime on success, null on failure</returns>
#if NET48
internal static DateTime? GetFileModifiedDate(string filename, bool fallback = false)
#else
internal static DateTime? GetFileModifiedDate(string? filename, bool fallback = false)
#endif
{
if (string.IsNullOrWhiteSpace(filename))
return fallback ? (DateTime?)DateTime.UtcNow : null;
@@ -220,11 +198,7 @@ namespace MPF.Core
/// <param name="filename">file location</param>
/// <param name="binary">True if should read as binary, false otherwise (default)</param>
/// <returns>Full text of the file, null on error</returns>
#if NET48
internal static string GetFullFile(string filename, bool binary = false)
#else
internal static string? GetFullFile(string filename, bool binary = false)
#endif
{
// If the file doesn't exist, we can't get info from it
if (!File.Exists(filename))
@@ -245,11 +219,7 @@ namespace MPF.Core
/// </summary>
/// <param name="datafile">Datafile represenging the hash data</param>
/// <returns>True if extraction was successful, false otherwise</returns>
#if NET48
internal static bool GetISOHashValues(Datafile datafile, out long size, out string crc32, out string md5, out string sha1)
#else
internal static bool GetISOHashValues(Datafile? datafile, out long size, out string? crc32, out string? md5, out string? sha1)
#endif
{
size = -1; crc32 = null; md5 = null; sha1 = null;
@@ -275,11 +245,7 @@ namespace MPF.Core
/// </summary>
/// <param name="hashData">String representing the combined hash data</param>
/// <returns>True if extraction was successful, false otherwise</returns>
#if NET48
internal static bool GetISOHashValues(string hashData, out long size, out string crc32, out string md5, out string sha1)
#else
internal static bool GetISOHashValues(string? hashData, out long size, out string? crc32, out string? md5, out string? sha1)
#endif
{
size = -1; crc32 = null; md5 = null; sha1 = null;
@@ -307,11 +273,7 @@ namespace MPF.Core
/// </summary>
/// <param name="di">Disc information containing unformatted data</param>
/// <returns>True if layerbreak info was set, false otherwise</returns>
#if NET48
internal static bool GetLayerbreaks(DiscInformation di, out long? layerbreak1, out long? layerbreak2, out long? layerbreak3)
#else
internal static bool GetLayerbreaks(DiscInformation? di, out long? layerbreak1, out long? layerbreak2, out long? layerbreak3)
#endif
{
// Set the default values
layerbreak1 = null; layerbreak2 = null; layerbreak3 = null;
@@ -320,11 +282,7 @@ namespace MPF.Core
if (di?.Units == null || di.Units.Length <= 1)
return false;
#if NET48
int ReadFromArrayBigEndian(byte[] bytes, int offset)
#else
static int ReadFromArrayBigEndian(byte[]? bytes, int offset)
#endif
{
if (bytes == null)
return default;
@@ -370,11 +328,7 @@ namespace MPF.Core
/// <returns>Status of the LibCrypt data, if possible</returns>
internal static void GetLibCryptDetected(SubmissionInfo info, string basePath)
{
#if NET48
if (info.CopyProtection == null) info.CopyProtection = new CopyProtectionSection();
#else
info.CopyProtection ??= new CopyProtectionSection();
#endif
bool? psLibCryptStatus = Protection.GetLibCryptDetected(basePath + ".sub");
if (psLibCryptStatus == true)
@@ -414,11 +368,7 @@ namespace MPF.Core
/// </summary>
/// <param name="di">Disc information containing the data</param>
/// <returns>String representing the PIC identifier, null on error</returns>
#if NET48
internal static string GetPICIdentifier(DiscInformation di)
#else
internal static string? GetPICIdentifier(DiscInformation? di)
#endif
{
// If we don't have valid disc information, we can't do anything
if (di?.Units == null || di.Units.Length <= 1)
@@ -436,11 +386,7 @@ namespace MPF.Core
/// <param name="region">Output region, if possible</param>
/// <param name="date">Output EXE date in "yyyy-mm-dd" format if possible, null on error</param>
/// <returns></returns>
#if NET48
internal static bool GetPlayStationExecutableInfo(char? driveLetter, out string serial, out Region? region, out string date)
#else
internal static bool GetPlayStationExecutableInfo(char? driveLetter, out string? serial, out Region? region, out string? date)
#endif
{
serial = null; region = null; date = null;
@@ -461,11 +407,7 @@ namespace MPF.Core
/// <param name="region">Output region, if possible</param>
/// <param name="date">Output EXE date in "yyyy-mm-dd" format if possible, null on error</param>
/// <returns></returns>
#if NET48
internal static bool GetPlayStationExecutableInfo(string drivePath, out string serial, out Region? region, out string date)
#else
internal static bool GetPlayStationExecutableInfo(string? drivePath, out string? serial, out Region? region, out string? date)
#endif
{
serial = null; region = null; date = null;
@@ -482,11 +424,7 @@ namespace MPF.Core
string systemCnfPath = Path.Combine(drivePath, "SYSTEM.CNF");
// Try both of the common paths that contain information
#if NET48
string exeName = null;
#else
string? exeName = null;
#endif
// Read the CNF file as an INI file
var systemCnf = new IniFile(systemCnfPath);
@@ -552,11 +490,7 @@ namespace MPF.Core
/// </summary>
/// <param name="driveLetter">Drive letter to use to check</param>
/// <returns>Game version if possible, null on error</returns>
#if NET48
internal static string GetPlayStation2Version(char? driveLetter)
#else
internal static string? GetPlayStation2Version(char? driveLetter)
#endif
{
// If there's no drive letter, we can't do this part
if (driveLetter == null)
@@ -572,11 +506,7 @@ namespace MPF.Core
/// </summary>
/// <param name="drivePath">Drive path to use to check</param>
/// <returns>Game version if possible, null on error</returns>
#if NET48
internal static string GetPlayStation2Version(string drivePath)
#else
internal static string? GetPlayStation2Version(string? drivePath)
#endif
{
// If there's no drive path, we can't do this part
if (string.IsNullOrWhiteSpace(drivePath))
@@ -603,11 +533,7 @@ namespace MPF.Core
/// </summary>
/// <param name="driveLetter">Drive letter to use to check</param>
/// <returns>Internal disc serial if possible, null on error</returns>
#if NET48
internal static string GetPlayStation3Serial(char? driveLetter)
#else
internal static string? GetPlayStation3Serial(char? driveLetter)
#endif
{
// If there's no drive letter, we can't do this part
if (driveLetter == null)
@@ -623,11 +549,7 @@ namespace MPF.Core
/// </summary>
/// <param name="drivePath">Drive path to use to check</param>
/// <returns>Internal disc serial if possible, null on error</returns>
#if NET48
internal static string GetPlayStation3Serial(string drivePath)
#else
internal static string? GetPlayStation3Serial(string? drivePath)
#endif
{
// If there's no drive path, we can't do this part
if (string.IsNullOrWhiteSpace(drivePath))
@@ -643,11 +565,9 @@ namespace MPF.Core
{
try
{
using (var br = new BinaryReader(File.OpenRead(sfbPath)))
{
br.BaseStream.Seek(0x220, SeekOrigin.Begin);
return new string(br.ReadChars(0x10));
}
using var br = new BinaryReader(File.OpenRead(sfbPath));
br.BaseStream.Seek(0x220, SeekOrigin.Begin);
return new string(br.ReadChars(0x10));
}
catch
{
@@ -662,11 +582,9 @@ namespace MPF.Core
{
try
{
using (var br = new BinaryReader(File.OpenRead(sfoPath)))
{
br.BaseStream.Seek(-0x18, SeekOrigin.End);
return new string(br.ReadChars(9));
}
using var br = new BinaryReader(File.OpenRead(sfoPath));
br.BaseStream.Seek(-0x18, SeekOrigin.End);
return new string(br.ReadChars(9));
}
catch
{
@@ -683,11 +601,7 @@ namespace MPF.Core
/// </summary>
/// <param name="driveLetter">Drive letter to use to check</param>
/// <returns>Game version if possible, null on error</returns>
#if NET48
internal static string GetPlayStation3Version(char? driveLetter)
#else
internal static string? GetPlayStation3Version(char? driveLetter)
#endif
{
// If there's no drive letter, we can't do this part
if (driveLetter == null)
@@ -703,11 +617,7 @@ namespace MPF.Core
/// </summary>
/// <param name="drivePath">Drive path to use to check</param>
/// <returns>Game version if possible, null on error</returns>
#if NET48
internal static string GetPlayStation3Version(string drivePath)
#else
internal static string? GetPlayStation3Version(string? drivePath)
#endif
{
// If there's no drive path, we can't do this part
if (string.IsNullOrWhiteSpace(drivePath))
@@ -723,13 +633,11 @@ namespace MPF.Core
{
try
{
using (var br = new BinaryReader(File.OpenRead(sfbPath)))
{
br.BaseStream.Seek(0x230, SeekOrigin.Begin);
var discVersion = new string(br.ReadChars(0x10)).TrimEnd('\0');
if (!string.IsNullOrWhiteSpace(discVersion))
return discVersion;
}
using var br = new BinaryReader(File.OpenRead(sfbPath));
br.BaseStream.Seek(0x230, SeekOrigin.Begin);
var discVersion = new string(br.ReadChars(0x10)).TrimEnd('\0');
if (!string.IsNullOrWhiteSpace(discVersion))
return discVersion;
}
catch
{
@@ -744,11 +652,9 @@ namespace MPF.Core
{
try
{
using (var br = new BinaryReader(File.OpenRead(sfoPath)))
{
br.BaseStream.Seek(-0x08, SeekOrigin.End);
return new string(br.ReadChars(5));
}
using var br = new BinaryReader(File.OpenRead(sfoPath));
br.BaseStream.Seek(-0x08, SeekOrigin.End);
return new string(br.ReadChars(5));
}
catch
{
@@ -765,11 +671,7 @@ namespace MPF.Core
/// </summary>
/// <param name="driveLetter">Drive letter to use to check</param>
/// <returns>Firmware version if possible, null on error</returns>
#if NET48
internal static string GetPlayStation3FirmwareVersion(char? driveLetter)
#else
internal static string? GetPlayStation3FirmwareVersion(char? driveLetter)
#endif
{
// If there's no drive letter, we can't do this part
if (driveLetter == null)
@@ -785,11 +687,7 @@ namespace MPF.Core
/// </summary>
/// <param name="drivePath">Drive path to use to check</param>
/// <returns>Firmware version if possible, null on error</returns>
#if NET48
internal static string GetPlayStation3FirmwareVersion(string drivePath)
#else
internal static string? GetPlayStation3FirmwareVersion(string? drivePath)
#endif
{
// If there's no drive path, we can't do this part
if (string.IsNullOrWhiteSpace(drivePath))
@@ -806,16 +704,14 @@ namespace MPF.Core
try
{
using (var br = new BinaryReader(File.OpenRead(pupPath)))
{
br.BaseStream.Seek(0x3E, SeekOrigin.Begin);
byte[] buf = new byte[2];
br.Read(buf, 0, 2);
Array.Reverse(buf);
short location = BitConverter.ToInt16(buf, 0);
br.BaseStream.Seek(location, SeekOrigin.Begin);
return new string(br.ReadChars(4));
}
using var br = new BinaryReader(File.OpenRead(pupPath));
br.BaseStream.Seek(0x3E, SeekOrigin.Begin);
byte[] buf = new byte[2];
br.Read(buf, 0, 2);
Array.Reverse(buf);
short location = BitConverter.ToInt16(buf, 0);
br.BaseStream.Seek(location, SeekOrigin.Begin);
return new string(br.ReadChars(4));
}
catch
{
@@ -829,11 +725,7 @@ namespace MPF.Core
/// </summary>
/// <param name="driveLetter">Drive letter to use to check</param>
/// <returns>Internal disc serial if possible, null on error</returns>
#if NET48
internal static string GetPlayStation4Serial(char? driveLetter)
#else
internal static string? GetPlayStation4Serial(char? driveLetter)
#endif
{
// If there's no drive letter, we can't do this part
if (driveLetter == null)
@@ -849,11 +741,7 @@ namespace MPF.Core
/// </summary>
/// <param name="drivePath">Drive path to use to check</param>
/// <returns>Internal disc serial if possible, null on error</returns>
#if NET48
internal static string GetPlayStation4Serial(string drivePath)
#else
internal static string? GetPlayStation4Serial(string? drivePath)
#endif
{
// If there's no drive path, we can't do this part
if (string.IsNullOrWhiteSpace(drivePath))
@@ -871,11 +759,9 @@ namespace MPF.Core
// Let's try reading param.sfo to find the serial at the end of the file
try
{
using (var br = new BinaryReader(File.OpenRead(paramSfoPath)))
{
br.BaseStream.Seek(-0x14, SeekOrigin.End);
return new string(br.ReadChars(9));
}
using var br = new BinaryReader(File.OpenRead(paramSfoPath));
br.BaseStream.Seek(-0x14, SeekOrigin.End);
return new string(br.ReadChars(9));
}
catch
{
@@ -889,11 +775,7 @@ namespace MPF.Core
/// </summary>
/// <param name="driveLetter">Drive letter to use to check</param>
/// <returns>Game version if possible, null on error</returns>
#if NET48
internal static string GetPlayStation4Version(char? driveLetter)
#else
internal static string? GetPlayStation4Version(char? driveLetter)
#endif
{
// If there's no drive letter, we can't do this part
if (driveLetter == null)
@@ -909,11 +791,7 @@ namespace MPF.Core
/// </summary>
/// <param name="drivePath">Drive path to use to check</param>
/// <returns>Game version if possible, null on error</returns>
#if NET48
internal static string GetPlayStation4Version(string drivePath)
#else
internal static string? GetPlayStation4Version(string? drivePath)
#endif
{
// If there's no drive path, we can't do this part
if (string.IsNullOrWhiteSpace(drivePath))
@@ -931,11 +809,9 @@ namespace MPF.Core
// Let's try reading param.sfo to find the version at the end of the file
try
{
using (var br = new BinaryReader(File.OpenRead(paramSfoPath)))
{
br.BaseStream.Seek(-0x08, SeekOrigin.End);
return new string(br.ReadChars(5));
}
using var br = new BinaryReader(File.OpenRead(paramSfoPath));
br.BaseStream.Seek(-0x08, SeekOrigin.End);
return new string(br.ReadChars(5));
}
catch
{
@@ -949,11 +825,7 @@ namespace MPF.Core
/// </summary>
/// <param name="driveLetter">Drive letter to use to check</param>
/// <returns>Internal disc serial if possible, null on error</returns>
#if NET48
internal static string GetPlayStation5Serial(char? driveLetter)
#else
internal static string? GetPlayStation5Serial(char? driveLetter)
#endif
{
// If there's no drive letter, we can't do this part
if (driveLetter == null)
@@ -969,11 +841,7 @@ namespace MPF.Core
/// </summary>
/// <param name="drivePath">Drive path to use to check</param>
/// <returns>Internal disc serial if possible, null on error</returns>
#if NET48
internal static string GetPlayStation5Serial(string drivePath)
#else
internal static string? GetPlayStation5Serial(string? drivePath)
#endif
{
// Attempt to get the param.json file
var json = GetPlayStation5ParamsJsonFromDrive(drivePath);
@@ -996,11 +864,7 @@ namespace MPF.Core
/// </summary>
/// <param name="driveLetter">Drive letter to use to check</param>
/// <returns>Game version if possible, null on error</returns>
#if NET48
internal static string GetPlayStation5Version(char? driveLetter)
#else
internal static string? GetPlayStation5Version(char? driveLetter)
#endif
{
// If there's no drive letter, we can't do this part
if (driveLetter == null)
@@ -1016,11 +880,7 @@ namespace MPF.Core
/// </summary>
/// <param name="drivePath">Drive path to use to check</param>
/// <returns>Game version if possible, null on error</returns>
#if NET48
internal static string GetPlayStation5Version(string drivePath)
#else
internal static string? GetPlayStation5Version(string? drivePath)
#endif
{
// Attempt to get the param.json file
var json = GetPlayStation5ParamsJsonFromDrive(drivePath);
@@ -1043,11 +903,7 @@ namespace MPF.Core
/// </summary>
/// <param name="drivePath">Drive path to use to check</param>
/// <returns>JObject representing the JSON on success, null on error</returns>
#if NET48
private static JObject GetPlayStation5ParamsJsonFromDrive(string drivePath)
#else
private static JObject? GetPlayStation5ParamsJsonFromDrive(string? drivePath)
#endif
{
// If there's no drive path, we can't do this part
if (string.IsNullOrWhiteSpace(drivePath))
@@ -1067,11 +923,7 @@ namespace MPF.Core
/// </summary>
/// <param name="filename">Filename to check</param>
/// <returns>JObject representing the JSON on success, null on error</returns>
#if NET48
private static JObject GetPlayStation5ParamsJsonFromFile(string filename)
#else
private static JObject? GetPlayStation5ParamsJsonFromFile(string? filename)
#endif
{
// If the file doesn't exist
if (string.IsNullOrWhiteSpace(filename) || !File.Exists(filename))
@@ -1080,12 +932,10 @@ namespace MPF.Core
// Let's try reading param.json to find the version in the unencrypted JSON
try
{
using (var br = new BinaryReader(File.OpenRead(filename)))
{
br.BaseStream.Seek(0x800, SeekOrigin.Begin);
byte[] jsonBytes = br.ReadBytes((int)(br.BaseStream.Length - 0x800));
return JsonConvert.DeserializeObject(Encoding.ASCII.GetString(jsonBytes)) as JObject;
}
using var br = new BinaryReader(File.OpenRead(filename));
br.BaseStream.Seek(0x800, SeekOrigin.Begin);
byte[] jsonBytes = br.ReadBytes((int)(br.BaseStream.Length - 0x800));
return JsonConvert.DeserializeObject(Encoding.ASCII.GetString(jsonBytes)) as JObject;
}
catch
{
@@ -1103,21 +953,8 @@ namespace MPF.Core
/// </summary>
/// <param name="region">String representing the category</param>
/// <returns>Category, if possible</returns>
#if NET48
internal static DiscCategory? GetUMDCategory(string category)
#else
internal static DiscCategory? GetUMDCategory(string? category)
#endif
{
#if NET48
switch (category)
{
case "GAME": return DiscCategory.Games;
case "VIDEO": return DiscCategory.Video;
case "AUDIO": return DiscCategory.Audio;
default: return null;
}
#else
return category switch
{
"GAME" => DiscCategory.Games,
@@ -1125,7 +962,6 @@ namespace MPF.Core
"AUDIO" => DiscCategory.Audio,
_ => null,
};
#endif
}
#endregion
@@ -1137,11 +973,7 @@ namespace MPF.Core
/// </summary>
/// <param name="serial">PlayStation serial code</param>
/// <returns>Region mapped from name, if possible</returns>
#if NET48
internal static Region? GetPlayStationRegion(string serial)
#else
internal static Region? GetPlayStationRegion(string? serial)
#endif
{
// If we have a fully invalid serial
if (string.IsNullOrWhiteSpace(serial))
@@ -1161,50 +993,28 @@ namespace MPF.Core
case 'U': return Region.UnitedStatesOfAmerica;
case 'P':
// Region of S_P_ serials may be Japan, Asia, or SouthKorea
switch (serial[3])
return serial[3] switch
{
case 'S':
// Check first two digits of S_PS serial
#if NET48
switch (serial.Substring(5, 2))
{
case "46": return Region.SouthKorea;
case "51": return Region.Asia;
case "56": return Region.SouthKorea;
case "55": return Region.Asia;
default: return Region.Japan;
}
#else
return serial.Substring(5, 2) switch
{
"46" => Region.SouthKorea,
"51" => Region.Asia,
"56" => Region.SouthKorea,
"55" => Region.Asia,
_ => Region.Japan,
};
#endif
case 'M':
// Check first three digits of S_PM serial
#if NET48
switch (serial.Substring(5, 3))
{
case "645": return Region.SouthKorea;
case "675": return Region.SouthKorea;
case "885": return Region.SouthKorea;
default: return Region.Japan; // Remaining S_PM serials may be Japan or Asia
}
#else
return serial.Substring(5, 3) switch
{
"645" => Region.SouthKorea,
"675" => Region.SouthKorea,
"885" => Region.SouthKorea,
_ => Region.Japan, // Remaining S_PM serials may be Japan or Asia
};
#endif
default: return Region.Japan;
}
// Check first two digits of S_PS serial
'S' => (Region?)(serial.Substring(5, 2) switch
{
"46" => Region.SouthKorea,
"51" => Region.Asia,
"56" => Region.SouthKorea,
"55" => Region.Asia,
_ => Region.Japan,
}),
// Check first three digits of S_PM serial
'M' => (Region?)(serial.Substring(5, 3) switch
{
"645" => Region.SouthKorea,
"675" => Region.SouthKorea,
"885" => Region.SouthKorea,
_ => Region.Japan, // Remaining S_PM serials may be Japan or Asia
}),
_ => (Region?)Region.Japan,
};
}
}
@@ -1250,17 +1060,17 @@ namespace MPF.Core
/// <returns>Region, if possible</returns>
internal static Region? GetXGDRegion(char? region)
{
switch (region)
return region switch
{
case 'W': return Region.World;
case 'A': return Region.UnitedStatesOfAmerica;
case 'J': return Region.JapanAsia;
case 'E': return Region.Europe;
case 'K': return Region.USAJapan;
case 'L': return Region.USAEurope;
case 'H': return Region.JapanEurope;
default: return null;
}
'W' => (Region?)Region.World,
'A' => (Region?)Region.UnitedStatesOfAmerica,
'J' => (Region?)Region.JapanAsia,
'E' => (Region?)Region.Europe,
'K' => (Region?)Region.USAJapan,
'L' => (Region?)Region.USAEurope,
'H' => (Region?)Region.JapanEurope,
_ => null,
};
}
#endregion
@@ -1275,11 +1085,7 @@ namespace MPF.Core
/// <param name="outputFilename">Output filename to use as the base path</param>
/// <param name="parameters">Parameters object to use to derive log file paths</param>
/// <returns>True if the process succeeded, false otherwise</returns>
#if NET48
public static (bool, string) CompressLogFiles(string outputDirectory, string filenameSuffix, string outputFilename, BaseParameters parameters)
#else
public static (bool, string) CompressLogFiles(string? outputDirectory, string? filenameSuffix, string outputFilename, BaseParameters? parameters)
#endif
{
// If there are no parameters
if (parameters == null)
@@ -1317,11 +1123,7 @@ namespace MPF.Core
}
// Add the log files to the archive and delete the uncompressed file after
#if NET48
ZipArchive zf = null;
#else
ZipArchive? zf = null;
#endif
try
{
zf = ZipFile.Open(archiveName, ZipArchiveMode.Create);
@@ -1333,13 +1135,8 @@ namespace MPF.Core
}
else
{
#if NET48
string entryName = file.Substring(outputDirectory.Length).TrimStart(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
zf.CreateEntryFromFile(file, entryName, CompressionLevel.Optimal);
#else
string entryName = file[outputDirectory.Length..].TrimStart(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
zf.CreateEntryFromFile(file, entryName, CompressionLevel.SmallestSize);
#endif
}
// If the file is MPF-specific, don't delete
@@ -1372,11 +1169,7 @@ namespace MPF.Core
/// <param name="outputFilename">Output filename to use as the base path</param>
/// <param name="parameters">Parameters object to use to derive log file paths</param>
/// <returns>True if the process succeeded, false otherwise</returns>
#if NET48
public static (bool, string) DeleteUnnecessaryFiles(string outputDirectory, string outputFilename, BaseParameters parameters)
#else
public static (bool, string) DeleteUnnecessaryFiles(string? outputDirectory, string outputFilename, BaseParameters? parameters)
#endif
{
// If there are no parameters
if (parameters == null)
@@ -1422,11 +1215,7 @@ namespace MPF.Core
/// <param name="info">Information object that should contain normalized values</param>
/// <param name="options">Options object representing user-defined options</param>
/// <returns>List of strings representing each line of an output file, null on error</returns>
#if NET48
public static (List<string>, string) FormatOutputData(SubmissionInfo info, Data.Options options)
#else
public static (List<string>?, string?) FormatOutputData(SubmissionInfo? info, Data.Options options)
#endif
{
// Check to see if the inputs are valid
if (info == null)
@@ -1649,11 +1438,7 @@ namespace MPF.Core
AddIfExists(output, Template.ReportedDiscType, info.DumpingInfo?.ReportedDiscType, 1);
// Make sure there aren't any instances of two blank lines in a row
#if NET48
string last = null;
#else
string? last = null;
#endif
for (int i = 0; i < output.Count;)
{
if (output[i] == last && string.IsNullOrWhiteSpace(last))
@@ -1686,11 +1471,7 @@ namespace MPF.Core
/// <param name="layerbreak3">Third layerbreak value, as applicable</param>
/// <returns>String representation of the media, including layer specification</returns>
/// TODO: Figure out why we have this and NormalizeDiscType as well
#if NET48
public static string GetFixedMediaType(MediaType? mediaType, string picIdentifier, long? size, long? layerbreak, long? layerbreak2, long? layerbreak3)
#else
public static string? GetFixedMediaType(MediaType? mediaType, string? picIdentifier, long? size, long? layerbreak, long? layerbreak2, long? layerbreak3)
#endif
{
switch (mediaType)
{
@@ -1733,11 +1514,7 @@ namespace MPF.Core
/// Process any fields that have to be combined
/// </summary>
/// <param name="info">Information object to normalize</param>
#if NET48
public static void ProcessSpecialFields(SubmissionInfo info)
#else
public static void ProcessSpecialFields(SubmissionInfo? info)
#endif
{
// If there is no submission info
if (info == null)
@@ -1801,11 +1578,7 @@ namespace MPF.Core
/// <param name="filenameSuffix">Optional suffix to append to the filename</param>
/// <param name="lines">Preformatted list of lines to write out to the file</param>
/// <returns>True on success, false on error</returns>
#if NET48
public static (bool, string) WriteOutputData(string outputDirectory, string filenameSuffix, List<string> lines)
#else
public static (bool, string) WriteOutputData(string? outputDirectory, string? filenameSuffix, List<string>? lines)
#endif
{
// Check to see if the inputs are valid
if (lines == null)
@@ -1825,12 +1598,10 @@ namespace MPF.Core
else if (!string.IsNullOrWhiteSpace(outputDirectory) && !string.IsNullOrWhiteSpace(filenameSuffix))
path = Path.Combine(outputDirectory, $"!submissionInfo_{filenameSuffix}.txt");
using (var sw = new StreamWriter(File.Open(path, FileMode.Create, FileAccess.Write)))
using var sw = new StreamWriter(File.Open(path, FileMode.Create, FileAccess.Write));
foreach (string line in lines)
{
foreach (string line in lines)
{
sw.WriteLine(line);
}
sw.WriteLine(line);
}
}
catch (Exception ex)
@@ -1849,11 +1620,7 @@ namespace MPF.Core
/// <param name="info">SubmissionInfo object representing the JSON to write out to the file</param>
/// <param name="includedArtifacts">True if artifacts were included, false otherwise</param>
/// <returns>True on success, false on error</returns>
#if NET48
public static bool WriteOutputData(string outputDirectory, string filenameSuffix, SubmissionInfo info, bool includedArtifacts)
#else
public static bool WriteOutputData(string? outputDirectory, string? filenameSuffix, SubmissionInfo? info, bool includedArtifacts)
#endif
{
// Check to see if the input is valid
if (info == null)
@@ -1878,11 +1645,9 @@ namespace MPF.Core
else if (!string.IsNullOrWhiteSpace(outputDirectory) && !string.IsNullOrWhiteSpace(filenameSuffix))
path = Path.Combine(outputDirectory, $"!submissionInfo_{filenameSuffix}.json.gz");
using (var fs = File.Create(path))
using (var gs = new GZipStream(fs, CompressionMode.Compress))
{
gs.Write(jsonBytes, 0, jsonBytes.Length);
}
using var fs = File.Create(path);
using var gs = new GZipStream(fs, CompressionMode.Compress);
gs.Write(jsonBytes, 0, jsonBytes.Length);
}
// Otherwise, write out to a normal JSON
@@ -1898,10 +1663,8 @@ namespace MPF.Core
else if (!string.IsNullOrWhiteSpace(outputDirectory) && !string.IsNullOrWhiteSpace(filenameSuffix))
path = Path.Combine(outputDirectory, $"!submissionInfo_{filenameSuffix}.json");
using (var fs = File.Create(path))
{
fs.Write(jsonBytes, 0, jsonBytes.Length);
}
using var fs = File.Create(path);
fs.Write(jsonBytes, 0, jsonBytes.Length);
}
}
catch
@@ -1920,11 +1683,7 @@ namespace MPF.Core
/// <param name="filenameSuffix">Optional suffix to append to the filename</param>
/// <param name="info">SubmissionInfo object containing the protection information</param>
/// <returns>True on success, false on error</returns>
#if NET48
public static bool WriteProtectionData(string outputDirectory, string filenameSuffix, SubmissionInfo info)
#else
public static bool WriteProtectionData(string? outputDirectory, string? filenameSuffix, SubmissionInfo? info)
#endif
{
// Check to see if the inputs are valid
if (info?.CopyProtection?.FullProtections == null || !info.CopyProtection.FullProtections.Any())
@@ -1943,15 +1702,13 @@ namespace MPF.Core
else if (!string.IsNullOrWhiteSpace(outputDirectory) && !string.IsNullOrWhiteSpace(filenameSuffix))
path = Path.Combine(outputDirectory, $"!protectionInfo{filenameSuffix}.txt");
using (var sw = new StreamWriter(File.Open(path, FileMode.Create, FileAccess.Write)))
using var sw = new StreamWriter(File.Open(path, FileMode.Create, FileAccess.Write));
foreach (var kvp in info.CopyProtection.FullProtections)
{
foreach (var kvp in info.CopyProtection.FullProtections)
{
if (kvp.Value == null)
sw.WriteLine($"{kvp.Key}: None");
else
sw.WriteLine($"{kvp.Key}: {string.Join(", ", kvp.Value)}");
}
if (kvp.Value == null)
sw.WriteLine($"{kvp.Key}: None");
else
sw.WriteLine($"{kvp.Key}: {string.Join(", ", kvp.Value)}");
}
}
catch
@@ -1970,11 +1727,7 @@ namespace MPF.Core
/// <param name="key">Name of the output key to write</param>
/// <param name="value">Name of the output value to write</param>
/// <param name="indent">Number of tabs to indent the line</param>
#if NET48
private static void AddIfExists(List<string> output, string key, string value, int indent)
#else
private static void AddIfExists(List<string> output, string key, string? value, int indent)
#endif
{
// If there's no valid value to write
if (value == null)
@@ -2000,11 +1753,7 @@ namespace MPF.Core
// If the value contains a newline
value = value.Replace("\r\n", "\n");
#if NET48
if (value.Contains("\n"))
#else
if (value.Contains('\n'))
#endif
{
output.Add(prefix + key + ":"); output.Add("");
string[] values = value.Split('\n');
@@ -2028,11 +1777,7 @@ namespace MPF.Core
/// <param name="key">Name of the output key to write</param>
/// <param name="value">Name of the output value to write</param>
/// <param name="indent">Number of tabs to indent the line</param>
#if NET48
private static void AddIfExists(List<string> output, string key, string[] value, int indent)
#else
private static void AddIfExists(List<string> output, string key, string?[]? value, int indent)
#endif
{
// If there's no valid value to write
if (value == null || value.Length == 0)
@@ -2068,11 +1813,7 @@ namespace MPF.Core
/// <param name="key">Name of the output key to write</param>
/// <param name="value">Name of the output value to write</param>
/// <param name="indent">Number of tabs to indent the line</param>
#if NET48
private static void AddIfExists(List<string> output, string key, List<int> value, int indent)
#else
private static void AddIfExists(List<string> output, string key, List<int>? value, int indent)
#endif
{
// If there's no valid value to write
if (value == null || value.Count == 0)
@@ -2087,11 +1828,7 @@ namespace MPF.Core
/// <param name="outputDirectory">Output folder to write to</param>
/// <param name="filenameSuffix">Optional suffix to append to the filename</param>
/// <returns>List of all log file paths, empty otherwise</returns>
#if NET48
private static List<string> GetGeneratedFilePaths(string outputDirectory, string filenameSuffix)
#else
private static List<string> GetGeneratedFilePaths(string? outputDirectory, string? filenameSuffix)
#endif
{
var files = new List<string>();
@@ -2611,11 +2348,7 @@ namespace MPF.Core
/// Normalize a split set of paths
/// </summary>
/// <param name="path">Path value to normalize</param>
#if NET48
public static string NormalizeOutputPaths(string path, bool getFullPath)
#else
public static string NormalizeOutputPaths(string? path, bool getFullPath)
#endif
{
// The easy way
try
@@ -2687,34 +2420,19 @@ namespace MPF.Core
/// <remarks>TODO: This should move to Extensions at some point</remarks>
private static bool IsBoolean(SiteCode? siteCode)
{
#if NET48
switch (siteCode)
{
case SiteCode.PostgapType:
case SiteCode.VCD:
return true;
default:
return false;
}
#else
return siteCode switch
{
SiteCode.PostgapType => true,
SiteCode.VCD => true,
_ => false,
};
#endif
}
/// <summary>
/// Order comment code tags according to Redump requirements
/// </summary>
/// <returns>Ordered list of KeyValuePairs representing the tags and values</returns>
#if NET48
private static List<KeyValuePair<SiteCode?, string>> OrderCommentTags(Dictionary<SiteCode?, string> tags)
#else
private static List<KeyValuePair<SiteCode?, string>> OrderCommentTags(Dictionary<SiteCode, string> tags)
#endif
{
var sorted = new List<KeyValuePair<SiteCode?, string>>();
@@ -2837,11 +2555,7 @@ namespace MPF.Core
/// Order content code tags according to Redump requirements
/// </summary>
/// <returns>Ordered list of KeyValuePairs representing the tags and values</returns>
#if NET48
private static List<KeyValuePair<SiteCode?, string>> OrderContentTags(Dictionary<SiteCode?, string> tags)
#else
private static List<KeyValuePair<SiteCode?, string>> OrderContentTags(Dictionary<SiteCode, string> tags)
#endif
{
var sorted = new List<KeyValuePair<SiteCode?, string>>();

View File

@@ -1,15 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net48;net6.0;net7.0</TargetFrameworks>
<TargetFrameworks>net6.0;net8.0</TargetFrameworks>
<RuntimeIdentifiers>win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
<Nullable>enable</Nullable>
<Authors>Matt Nadareski;ReignStumble;Jakz</Authors>
<Copyright>Copyright (c)2019-2023</Copyright>
<VersionPrefix>2.7.5</VersionPrefix>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)'!='net48'">
<Nullable>enable</Nullable>
<VersionPrefix>3.0.0</VersionPrefix>
</PropertyGroup>
<ItemGroup>
@@ -17,18 +14,18 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="BurnOutSharp" PrivateAssets="build; analyzers" ExcludeAssets="contentFiles" Version="2.9.0" GeneratePathProperty="true">
<PackageReference Include="BinaryObjectScanner" PrivateAssets="build; analyzers" ExcludeAssets="contentFiles" Version="3.0.0" GeneratePathProperty="true">
<IncludeAssets>runtime; compile; build; native; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Management.Infrastructure" Version="3.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="psxt001z" Version="0.21.0-beta1" />
<PackageReference Include="SabreTools.Models" Version="1.1.5" />
<PackageReference Include="SabreTools.RedumpLib" Version="1.1.1" />
<PackageReference Include="SabreTools.Serialization" Version="1.1.7" />
<PackageReference Include="psxt001z" Version="0.21.0-beta2" />
<PackageReference Include="SabreTools.Models" Version="1.2.0" />
<PackageReference Include="SabreTools.RedumpLib" Version="1.2.0" />
<PackageReference Include="SabreTools.Serialization" Version="1.2.0" />
<PackageReference Include="System.IO.Compression" Version="4.3.0" />
<PackageReference Include="System.IO.Compression.ZipFile" Version="4.3.0" />
<PackageReference Include="System.IO.Hashing" Version="7.0.0" />
<PackageReference Include="System.IO.Hashing" Version="8.0.0" />
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="6.0.0" />
</ItemGroup>

File diff suppressed because it is too large Load Diff

View File

@@ -18,11 +18,7 @@ namespace MPF.Core.Modules
/// Geneeic way of reporting a message
/// </summary>
/// <param name="message">String value to report</param>
#if NET48
public EventHandler<string> ReportStatus;
#else
public EventHandler<string>? ReportStatus;
#endif
#endregion
@@ -31,20 +27,12 @@ namespace MPF.Core.Modules
/// <summary>
/// Base command to run
/// </summary>
#if NET48
public string BaseCommand { get; set; }
#else
public string? BaseCommand { get; set; }
#endif
/// <summary>
/// Set of flags to pass to the executable
/// </summary>
#if NET48
protected Dictionary<string, bool?> flags = new Dictionary<string, bool?>();
#else
protected Dictionary<string, bool?> flags = new();
#endif
protected internal IEnumerable<string> Keys => flags.Keys;
/// <summary>
@@ -68,11 +56,7 @@ namespace MPF.Core.Modules
/// <summary>
/// Process to track external program
/// </summary>
#if NET48
private Process process;
#else
private Process? process;
#endif
#endregion
@@ -81,30 +65,18 @@ namespace MPF.Core.Modules
/// <summary>
/// Command to flag support mappings
/// </summary>
#if NET48
public Dictionary<string, List<string>> CommandSupport => GetCommandSupport();
#else
public Dictionary<string, List<string>>? CommandSupport => GetCommandSupport();
#endif
/// <summary>
/// Input path for operations
/// </summary>
#if NET48
public virtual string InputPath => null;
#else
public virtual string? InputPath => null;
#endif
/// <summary>
/// Output path for operations
/// </summary>
/// <returns>String representing the path, null on error</returns>
#if NET48
public virtual string OutputPath => null;
#else
public virtual string? OutputPath => null;
#endif
/// <summary>
/// Get the processing speed from the implementation
@@ -118,11 +90,7 @@ namespace MPF.Core.Modules
/// <summary>
/// Path to the executable
/// </summary>
#if NET48
public string ExecutablePath { get; set; }
#else
public string? ExecutablePath { get; set; }
#endif
/// <summary>
/// Program that this set of parameters represents
@@ -145,11 +113,7 @@ namespace MPF.Core.Modules
/// Populate a Parameters object from a param string
/// </summary>
/// <param name="parameters">String possibly representing a set of parameters</param>
#if NET48
public BaseParameters(string parameters)
#else
public BaseParameters(string? parameters)
#endif
{
// If any parameters are not valid, wipe out everything
if (!ValidateAndSetParameters(parameters))
@@ -165,11 +129,7 @@ namespace MPF.Core.Modules
/// <param name="filename">Filename to use</param>
/// <param name="driveSpeed">Drive speed to use</param>
/// <param name="options">Options object containing all settings that may be used for setting parameters</param>
#if NET48
public BaseParameters(RedumpSystem? system, MediaType? type, string drivePath, string filename, int? driveSpeed, Options options)
#else
public BaseParameters(RedumpSystem? system, MediaType? type, string? drivePath, string filename, int? driveSpeed, Options options)
#endif
{
this.System = system;
this.Type = type;
@@ -194,11 +154,7 @@ namespace MPF.Core.Modules
/// <param name="basePath">Base filename and path to use for checking</param>
/// <param name="drive">Drive representing the disc to get information from</param>
/// <param name="includeArtifacts">True to include output files as encoded artifacts, false otherwise</param>
#if NET48
public abstract void GenerateSubmissionInfo(SubmissionInfo submissionInfo, Options options, string basePath, Drive drive, bool includeArtifacts);
#else
public abstract void GenerateSubmissionInfo(SubmissionInfo submissionInfo, Options options, string basePath, Drive? drive, bool includeArtifacts);
#endif
#endregion
@@ -208,54 +164,34 @@ namespace MPF.Core.Modules
/// Get all commands mapped to the supported flags
/// </summary>
/// <returns>Mappings from command to supported flags</returns>
#if NET48
public virtual Dictionary<string, List<string>> GetCommandSupport() => null;
#else
public virtual Dictionary<string, List<string>>? GetCommandSupport() => null;
#endif
/// <summary>
/// Blindly generate a parameter string based on the inputs
/// </summary>
/// <returns>Parameter string for invocation, null on error</returns>
#if NET48
public virtual string GenerateParameters() => null;
#else
public virtual string? GenerateParameters() => null;
#endif
/// <summary>
/// Get the default extension for a given media type
/// </summary>
/// <param name="mediaType">MediaType value to check</param>
/// <returns>String representing the media type, null on error</returns>
#if NET48
public virtual string GetDefaultExtension(MediaType? mediaType) => null;
#else
public virtual string? GetDefaultExtension(MediaType? mediaType) => null;
#endif
/// <summary>
/// Generate a list of all deleteable files generated
/// </summary>
/// <param name="basePath">Base filename and path to use for checking</param>
/// <returns>List of all deleteable file paths, empty otherwise</returns>
#if NET48
public virtual List<string> GetDeleteableFilePaths(string basePath) => new List<string>();
#else
public virtual List<string> GetDeleteableFilePaths(string basePath) => new();
#endif
/// <summary>
/// Generate a list of all log files generated
/// </summary>
/// <param name="basePath">Base filename and path to use for checking</param>
/// <returns>List of all log file paths, empty otherwise</returns>
#if NET48
public virtual List<string> GetLogFilePaths(string basePath) => new List<string>();
#else
public virtual List<string> GetLogFilePaths(string basePath) => new();
#endif
/// <summary>
/// Get the MediaType from the current set of parameters
@@ -303,22 +239,14 @@ namespace MPF.Core.Modules
/// <param name="filename">Filename to use</param>
/// <param name="driveSpeed">Drive speed to use</param>
/// <param name="options">Options object containing all settings that may be used for setting parameters</param>
#if NET48
protected virtual void SetDefaultParameters(string drivePath, string filename, int? driveSpeed, Options options) { }
#else
protected virtual void SetDefaultParameters(string? drivePath, string filename, int? driveSpeed, Options options) { }
#endif
/// <summary>
/// Scan a possible parameter string and populate whatever possible
/// </summary>
/// <param name="parameters">String possibly representing parameters</param>
/// <returns>True if the parameters were set correctly, false otherwise</returns>
#if NET48
protected virtual bool ValidateAndSetParameters(string parameters) => !string.IsNullOrWhiteSpace(parameters);
#else
protected virtual bool ValidateAndSetParameters(string? parameters) => !string.IsNullOrWhiteSpace(parameters);
#endif
#endregion
@@ -392,11 +320,7 @@ namespace MPF.Core.Modules
/// </summary>
/// <param name="content">String content to encode</param>
/// <returns>Base64-encoded contents, if possible</returns>
#if NET48
protected static string GetBase64(string content)
#else
protected static string? GetBase64(string? content)
#endif
{
if (string.IsNullOrEmpty(content))
return null;
@@ -411,11 +335,7 @@ namespace MPF.Core.Modules
/// <param name="filename">file location</param>
/// <param name="binary">True if should read as binary, false otherwise (default)</param>
/// <returns>Full text of the file, null on error</returns>
#if NET48
protected static string GetFullFile(string filename, bool binary = false)
#else
protected static string? GetFullFile(string filename, bool binary = false)
#endif
{
// If the file doesn't exist, we can't get info from it
if (!File.Exists(filename))
@@ -545,11 +465,7 @@ namespace MPF.Core.Modules
/// <param name="longFlagString">Long flag string, if available</param>
/// <param name="i">Reference to the position in the parts</param>
/// <returns>True if the parameter was processed successfully or skipped, false otherwise</returns>
#if NET48
protected bool ProcessFlagParameter(List<string> parts, string shortFlagString, string longFlagString, ref int i)
#else
protected bool ProcessFlagParameter(List<string> parts, string? shortFlagString, string longFlagString, ref int i)
#endif
{
if (parts == null)
return false;
@@ -585,11 +501,7 @@ namespace MPF.Core.Modules
/// <param name="i">Reference to the position in the parts</param>
/// <param name="missingAllowed">True if missing values are allowed, false otherwise</param>
/// <returns>True if the parameter was processed successfully or skipped, false otherwise</returns>
#if NET48
protected bool ProcessBooleanParameter(List<string> parts, string shortFlagString, string longFlagString, ref int i, bool missingAllowed = false)
#else
protected bool ProcessBooleanParameter(List<string> parts, string? shortFlagString, string longFlagString, ref int i, bool missingAllowed = false)
#endif
{
if (parts == null)
return false;
@@ -664,11 +576,7 @@ namespace MPF.Core.Modules
/// <param name="i">Reference to the position in the parts</param>
/// <param name="missingAllowed">True if missing values are allowed, false otherwise</param>
/// <returns>SByte value if success, SByte.MinValue if skipped, null on error/returns>
#if NET48
protected sbyte? ProcessInt8Parameter(List<string> parts, string shortFlagString, string longFlagString, ref int i, bool missingAllowed = false)
#else
protected sbyte? ProcessInt8Parameter(List<string> parts, string? shortFlagString, string longFlagString, ref int i, bool missingAllowed = false)
#endif
{
if (parts == null)
return null;
@@ -746,11 +654,7 @@ namespace MPF.Core.Modules
/// <param name="i">Reference to the position in the parts</param>
/// <param name="missingAllowed">True if missing values are allowed, false otherwise</param>
/// <returns>Int16 value if success, Int16.MinValue if skipped, null on error/returns>
#if NET48
protected short? ProcessInt16Parameter(List<string> parts, string shortFlagString, string longFlagString, ref int i, bool missingAllowed = false)
#else
protected short? ProcessInt16Parameter(List<string> parts, string? shortFlagString, string longFlagString, ref int i, bool missingAllowed = false)
#endif
{
if (parts == null)
return null;
@@ -827,11 +731,7 @@ namespace MPF.Core.Modules
/// <param name="i">Reference to the position in the parts</param>
/// <param name="missingAllowed">True if missing values are allowed, false otherwise</param>
/// <returns>Int32 value if success, Int32.MinValue if skipped, null on error/returns>
#if NET48
protected int? ProcessInt32Parameter(List<string> parts, string shortFlagString, string longFlagString, ref int i, bool missingAllowed = false)
#else
protected int? ProcessInt32Parameter(List<string> parts, string? shortFlagString, string longFlagString, ref int i, bool missingAllowed = false)
#endif
{
if (parts == null)
return null;
@@ -908,11 +808,7 @@ namespace MPF.Core.Modules
/// <param name="i">Reference to the position in the parts</param>
/// <param name="missingAllowed">True if missing values are allowed, false otherwise</param>
/// <returns>Int64 value if success, Int64.MinValue if skipped, null on error/returns>
#if NET48
protected long? ProcessInt64Parameter(List<string> parts, string shortFlagString, string longFlagString, ref int i, bool missingAllowed = false)
#else
protected long? ProcessInt64Parameter(List<string> parts, string? shortFlagString, string longFlagString, ref int i, bool missingAllowed = false)
#endif
{
if (parts == null)
return null;
@@ -977,12 +873,8 @@ namespace MPF.Core.Modules
/// <param name="i">Reference to the position in the parts</param>
/// <param name="missingAllowed">True if missing values are allowed, false otherwise</param>
/// <returns>String value if possible, string.Empty on missing, null on error</returns>
#if NET48
protected string ProcessStringParameter(List<string> parts, string flagString, ref int i, bool missingAllowed = false)
#else
protected string? ProcessStringParameter(List<string> parts, string flagString, ref int i, bool missingAllowed = false)
#endif
=> ProcessStringParameter(parts, null, flagString, ref i, missingAllowed);
=> ProcessStringParameter(parts, null, flagString, ref i, missingAllowed);
/// <summary>
/// Process a string parameter
@@ -993,11 +885,7 @@ namespace MPF.Core.Modules
/// <param name="i">Reference to the position in the parts</param>
/// <param name="missingAllowed">True if missing values are allowed, false otherwise</param>
/// <returns>String value if possible, string.Empty on missing, null on error</returns>
#if NET48
protected string ProcessStringParameter(List<string> parts, string shortFlagString, string longFlagString, ref int i, bool missingAllowed = false)
#else
protected string? ProcessStringParameter(List<string> parts, string? shortFlagString, string longFlagString, ref int i, bool missingAllowed = false)
#endif
{
if (parts == null)
return null;
@@ -1072,11 +960,7 @@ namespace MPF.Core.Modules
/// <param name="i">Reference to the position in the parts</param>
/// <param name="missingAllowed">True if missing values are allowed, false otherwise</param>
/// <returns>Byte value if success, Byte.MinValue if skipped, null on error/returns>
#if NET48
protected byte? ProcessUInt8Parameter(List<string> parts, string shortFlagString, string longFlagString, ref int i, bool missingAllowed = false)
#else
protected byte? ProcessUInt8Parameter(List<string> parts, string? shortFlagString, string longFlagString, ref int i, bool missingAllowed = false)
#endif
{
if (parts == null)
return null;
@@ -1207,11 +1091,7 @@ namespace MPF.Core.Modules
/// <param name="trimLength">Number of characters to trim the PIC to, if -1, ignored</param>
/// <returns>PIC data as a hex string if possible, null on error</returns>
/// <remarks>https://stackoverflow.com/questions/9932096/add-separator-to-string-at-every-n-characters</remarks>
#if NET48
protected static string GetPIC(string picPath, int trimLength = -1)
#else
protected static string? GetPIC(string picPath, int trimLength = -1)
#endif
{
// If the file doesn't exist, we can't get the info
if (!File.Exists(picPath))
@@ -1224,11 +1104,7 @@ namespace MPF.Core.Modules
return null;
if (trimLength > -1)
#if NET48
hex = hex.Substring(0, trimLength);
#else
hex = hex[..trimLength];
#endif
return Regex.Replace(hex, ".{32}", "$0\n", RegexOptions.Compiled);
}

View File

@@ -23,18 +23,10 @@ namespace MPF.Core.Modules.CleanRip
#endregion
/// <inheritdoc/>
#if NET48
public Parameters(string parameters) : base(parameters) { }
#else
public Parameters(string? parameters) : base(parameters) { }
#endif
/// <inheritdoc/>
#if NET48
public Parameters(RedumpSystem? system, MediaType? type, string drivePath, string filename, int? driveSpeed, Options options)
#else
public Parameters(RedumpSystem? system, MediaType? type, string? drivePath, string filename, int? driveSpeed, Options options)
#endif
: base(system, type, drivePath, filename, driveSpeed, options)
{
}
@@ -69,21 +61,13 @@ namespace MPF.Core.Modules.CleanRip
}
/// <inheritdoc/>
#if NET48
public override void GenerateSubmissionInfo(SubmissionInfo info, Options options, string basePath, Drive drive, bool includeArtifacts)
#else
public override void GenerateSubmissionInfo(SubmissionInfo info, Options options, string basePath, Drive? drive, bool includeArtifacts)
#endif
{
// Ensure that required sections exist
info = SubmissionInfoTool.EnsureAllSections(info);
// TODO: Determine if there's a CleanRip version anywhere
#if NET48
info.DumpingInfo.DumpingProgram = EnumConverter.LongName(this.InternalProgram);
#else
info.DumpingInfo!.DumpingProgram = EnumConverter.LongName(this.InternalProgram);
#endif
info.DumpingInfo.DumpingDate = InfoTool.GetFileModifiedDate(basePath + "-dumpinfo.txt")?.ToString("yyyy-MM-dd HH:mm:ss");
var datafile = GenerateCleanripDatafile(basePath + ".iso", basePath + "-dumpinfo.txt");
@@ -91,11 +75,7 @@ namespace MPF.Core.Modules.CleanRip
// Get the individual hash data, as per internal
if (InfoTool.GetISOHashValues(datafile, out long size, out var crc32, out var md5, out var sha1))
{
#if NET48
info.SizeAndChecksums.Size = size;
#else
info.SizeAndChecksums!.Size = size;
#endif
info.SizeAndChecksums.CRC32 = crc32;
info.SizeAndChecksums.MD5 = md5;
info.SizeAndChecksums.SHA1 = sha1;
@@ -112,23 +92,13 @@ namespace MPF.Core.Modules.CleanRip
case MediaType.NintendoGameCubeGameDisc:
case MediaType.NintendoWiiOpticalDisc:
if (File.Exists(basePath + ".bca"))
#if NET48
info.Extras.BCA = GetBCA(basePath + ".bca");
#else
info.Extras!.BCA = GetBCA(basePath + ".bca");
#endif
if (GetGameCubeWiiInformation(basePath + "-dumpinfo.txt", out Region? gcRegion, out var gcVersion, out var gcName))
{
#if NET48
info.CommonDiscInfo.Region = gcRegion ?? info.CommonDiscInfo.Region;
info.VersionAndEditions.Version = gcVersion ?? info.VersionAndEditions.Version;
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.InternalName] = gcName ?? string.Empty;
#else
info.CommonDiscInfo!.Region = gcRegion ?? info.CommonDiscInfo.Region;
info.VersionAndEditions!.Version = gcVersion ?? info.VersionAndEditions.Version;
info.CommonDiscInfo.CommentsSpecialFields![SiteCode.InternalName] = gcName ?? string.Empty;
#endif
}
break;
@@ -137,11 +107,7 @@ namespace MPF.Core.Modules.CleanRip
// Fill in any artifacts that exist, Base64-encoded, if we need to
if (includeArtifacts)
{
#if NET48
if (info.Artifacts == null) info.Artifacts = new Dictionary<string, string>();
#else
info.Artifacts ??= new Dictionary<string, string>();
#endif
if (File.Exists(basePath + ".bca"))
info.Artifacts["bca"] = GetBase64(GetFullFile(basePath + ".bca", binary: true)) ?? string.Empty;
@@ -180,71 +146,56 @@ namespace MPF.Core.Modules.CleanRip
/// <param name="iso">Path to ISO file</param>
/// <param name="dumpinfo">Path to discinfo file</param>
/// <returns></returns>
#if NET48
private static Datafile GenerateCleanripDatafile(string iso, string dumpinfo)
#else
private static Datafile? GenerateCleanripDatafile(string iso, string dumpinfo)
#endif
{
// If the file doesn't exist, we can't get info from it
if (!File.Exists(dumpinfo))
// If the files don't exist, we can't get info from it
if (!File.Exists(iso) || !File.Exists(dumpinfo))
return null;
using (var sr = File.OpenText(dumpinfo))
long size = new FileInfo(iso).Length;
string crc = string.Empty;
string md5 = string.Empty;
string sha1 = string.Empty;
try
{
long size = new FileInfo(iso).Length;
string crc = string.Empty;
string md5 = string.Empty;
string sha1 = string.Empty;
// Make sure this file is a dumpinfo
using var sr = File.OpenText(dumpinfo);
if (sr.ReadLine()?.Contains("--File Generated by CleanRip") != true)
return null;
try
// Read all lines and gather dat information
while (!sr.EndOfStream)
{
// Make sure this file is a dumpinfo
if (sr.ReadLine()?.Contains("--File Generated by CleanRip") != true)
return null;
var line = sr.ReadLine()?.Trim();
if (string.IsNullOrWhiteSpace(line))
continue;
else if (line.StartsWith("CRC32"))
crc = line[7..].ToLowerInvariant();
else if (line.StartsWith("MD5"))
md5 = line[5..];
else if (line.StartsWith("SHA-1"))
sha1 = line[7..];
}
// Read all lines and gather dat information
while (!sr.EndOfStream)
return new Datafile
{
Games = new Game[]
{
var line = sr.ReadLine()?.Trim();
if (string.IsNullOrWhiteSpace(line))
continue;
#if NET48
else if (line.StartsWith("CRC32"))
crc = line.Substring(7).ToLowerInvariant();
else if (line.StartsWith("MD5"))
md5 = line.Substring(5);
else if (line.StartsWith("SHA-1"))
sha1 = line.Substring(7);
#else
else if (line.StartsWith("CRC32"))
crc = line[7..].ToLowerInvariant();
else if (line.StartsWith("MD5"))
md5 = line[5..];
else if (line.StartsWith("SHA-1"))
sha1 = line[7..];
#endif
}
return new Datafile
{
Games = new Game[]
new Game
{
new Game
Roms = new Rom[]
{
Roms = new Rom[]
{
new Rom { Name = Path.GetFileName(iso), Size = size.ToString(), Crc = crc, Md5 = md5, Sha1 = sha1 },
}
new Rom { Name = Path.GetFileName(iso), Size = size.ToString(), Crc = crc, Md5 = md5, Sha1 = sha1 },
}
}
};
}
catch
{
// We don't care what the exception is right now
return null;
}
}
};
}
catch
{
// We don't care what the exception is right now
return null;
}
}
@@ -254,11 +205,7 @@ namespace MPF.Core.Modules.CleanRip
/// <param name="bcaPath">Path to the BCA file associated with the dump</param>
/// <returns>BCA data as a hex string if possible, null on error</returns>
/// <remarks>https://stackoverflow.com/questions/9932096/add-separator-to-string-at-every-n-characters</remarks>
#if NET48
private static string GetBCA(string bcaPath)
#else
private static string? GetBCA(string bcaPath)
#endif
{
// If the file doesn't exist, we can't get the info
if (!File.Exists(bcaPath))
@@ -285,59 +232,44 @@ namespace MPF.Core.Modules.CleanRip
/// <param name="iso">Path to ISO file</param>
/// <param name="dumpinfo">Path to discinfo file</param>
/// <returns></returns>
#if NET48
private static string GetCleanripDatfile(string iso, string dumpinfo)
#else
private static string? GetCleanripDatfile(string iso, string dumpinfo)
#endif
{
// If the file doesn't exist, we can't get info from it
if (!File.Exists(dumpinfo))
// If the files don't exist, we can't get info from it
if (!File.Exists(iso) || !File.Exists(dumpinfo))
return null;
using (var sr = File.OpenText(dumpinfo))
long size = new FileInfo(iso).Length;
string crc = string.Empty;
string md5 = string.Empty;
string sha1 = string.Empty;
try
{
long size = new FileInfo(iso).Length;
string crc = string.Empty;
string md5 = string.Empty;
string sha1 = string.Empty;
try
{
// Make sure this file is a dumpinfo
if (sr.ReadLine()?.Contains("--File Generated by CleanRip") != true)
return null;
// Read all lines and gather dat information
while (!sr.EndOfStream)
{
var line = sr.ReadLine()?.Trim();
if (string.IsNullOrWhiteSpace(line))
continue;
#if NET48
else if (line.StartsWith("CRC32"))
crc = line.Substring(7).ToLowerInvariant();
else if (line.StartsWith("MD5"))
md5 = line.Substring(5);
else if (line.StartsWith("SHA-1"))
sha1 = line.Substring(7);
#else
else if (line.StartsWith("CRC32"))
crc = line[7..].ToLowerInvariant();
else if (line.StartsWith("MD5"))
md5 = line[5..];
else if (line.StartsWith("SHA-1"))
sha1 = line[7..];
#endif
}
return $"<rom name=\"{Path.GetFileName(iso)}\" size=\"{size}\" crc=\"{crc}\" md5=\"{md5}\" sha1=\"{sha1}\" />";
}
catch
{
// We don't care what the exception is right now
// Make sure this file is a dumpinfo
using var sr = File.OpenText(dumpinfo);
if (sr.ReadLine()?.Contains("--File Generated by CleanRip") != true)
return null;
// Read all lines and gather dat information
while (!sr.EndOfStream)
{
var line = sr.ReadLine()?.Trim();
if (string.IsNullOrWhiteSpace(line))
continue;
else if (line.StartsWith("CRC32"))
crc = line[7..].ToLowerInvariant();
else if (line.StartsWith("MD5"))
md5 = line[5..];
else if (line.StartsWith("SHA-1"))
sha1 = line[7..];
}
return $"<rom name=\"{Path.GetFileName(iso)}\" size=\"{size}\" crc=\"{crc}\" md5=\"{md5}\" sha1=\"{sha1}\" />";
}
catch
{
// We don't care what the exception is right now
return null;
}
}
@@ -349,11 +281,7 @@ namespace MPF.Core.Modules.CleanRip
/// <param name="version">Output internal version of the game</param>
/// <param name="name">Output internal name of the game</param>
/// <returns></returns>
#if NET48
private static bool GetGameCubeWiiInformation(string dumpinfo, out Region? region, out string version, out string name)
#else
private static bool GetGameCubeWiiInformation(string dumpinfo, out Region? region, out string? version, out string? name)
#endif
{
region = null; version = null; name = null;
@@ -361,111 +289,97 @@ namespace MPF.Core.Modules.CleanRip
if (!File.Exists(dumpinfo))
return false;
using (var sr = File.OpenText(dumpinfo))
try
{
try
// Make sure this file is a dumpinfo
using var sr = File.OpenText(dumpinfo);
if (sr.ReadLine()?.Contains("--File Generated by CleanRip") != true)
return false;
// Read all lines and gather dat information
while (!sr.EndOfStream)
{
// Make sure this file is a dumpinfo
if (sr.ReadLine()?.Contains("--File Generated by CleanRip") != true)
return false;
// Read all lines and gather dat information
while (!sr.EndOfStream)
var line = sr.ReadLine()?.Trim();
if (string.IsNullOrWhiteSpace(line))
{
var line = sr.ReadLine()?.Trim();
if (string.IsNullOrWhiteSpace(line))
{
continue;
}
else if (line.StartsWith("Version"))
{
#if NET48
version = line.Substring("Version: ".Length);
#else
version = line["Version: ".Length..];
#endif
}
else if (line.StartsWith("Internal Name"))
{
#if NET48
name = line.Substring("Internal Name: ".Length);
#else
name = line["Internal Name: ".Length..];
#endif
}
else if (line.StartsWith("Filename"))
{
#if NET48
string serial = line.Substring("Filename: ".Length);
#else
string serial = line["Filename: ".Length..];
#endif
continue;
}
else if (line.StartsWith("Version"))
{
version = line["Version: ".Length..];
}
else if (line.StartsWith("Internal Name"))
{
name = line["Internal Name: ".Length..];
}
else if (line.StartsWith("Filename"))
{
string serial = line["Filename: ".Length..];
// char gameType = serial[0];
// string gameid = serial[1] + serial[2];
// string version = serial[4] + serial[5]
// char gameType = serial[0];
// string gameid = serial[1] + serial[2];
// string version = serial[4] + serial[5]
switch (serial[3])
{
case 'A':
region = Region.World;
break;
case 'D':
region = Region.Germany;
break;
case 'E':
region = Region.UnitedStatesOfAmerica;
break;
case 'F':
region = Region.France;
break;
case 'I':
region = Region.Italy;
break;
case 'J':
region = Region.Japan;
break;
case 'K':
region = Region.SouthKorea;
break;
case 'L':
region = Region.Europe; // Japanese import to Europe
break;
case 'M':
region = Region.Europe; // American import to Europe
break;
case 'N':
region = Region.UnitedStatesOfAmerica; // Japanese import to USA
break;
case 'P':
region = Region.Europe;
break;
case 'R':
region = Region.RussianFederation;
break;
case 'S':
region = Region.Spain;
break;
case 'Q':
region = Region.SouthKorea; // Korea with Japanese language
break;
case 'T':
region = Region.SouthKorea; // Korea with English language
break;
case 'X':
region = null; // Not a real region code
break;
}
switch (serial[3])
{
case 'A':
region = Region.World;
break;
case 'D':
region = Region.Germany;
break;
case 'E':
region = Region.UnitedStatesOfAmerica;
break;
case 'F':
region = Region.France;
break;
case 'I':
region = Region.Italy;
break;
case 'J':
region = Region.Japan;
break;
case 'K':
region = Region.SouthKorea;
break;
case 'L':
region = Region.Europe; // Japanese import to Europe
break;
case 'M':
region = Region.Europe; // American import to Europe
break;
case 'N':
region = Region.UnitedStatesOfAmerica; // Japanese import to USA
break;
case 'P':
region = Region.Europe;
break;
case 'R':
region = Region.RussianFederation;
break;
case 'S':
region = Region.Spain;
break;
case 'Q':
region = Region.SouthKorea; // Korea with Japanese language
break;
case 'T':
region = Region.SouthKorea; // Korea with English language
break;
case 'X':
region = null; // Not a real region code
break;
}
}
}
return true;
}
catch
{
// We don't care what the exception is right now
return false;
}
return true;
}
catch
{
// We don't care what the exception is right now
return false;
}
}

View File

@@ -6,139 +6,67 @@ namespace MPF.Core.Modules
public class Datafile
{
[XmlElement("header")]
#if NET48
public Header Header;
#else
public Header? Header;
#endif
[XmlElement("game")]
#if NET48
public Game[] Games;
#else
public Game[]? Games;
#endif
}
public class Header
{
[XmlElement("name")]
#if NET48
public string Name;
#else
public string? Name;
#endif
[XmlElement("description")]
#if NET48
public string Description;
#else
public string? Description;
#endif
[XmlElement("version")]
#if NET48
public string Version;
#else
public string? Version;
#endif
[XmlElement("date")]
#if NET48
public string Date;
#else
public string? Date;
#endif
[XmlElement("author")]
#if NET48
public string Author;
#else
public string? Author;
#endif
[XmlElement("homepage")]
#if NET48
public string Homepage;
#else
public string? Homepage;
#endif
[XmlElement("url")]
#if NET48
public string Url;
#else
public string? Url;
#endif
}
public class Game
{
[XmlAttribute("name")]
#if NET48
public string Name;
#else
public string? Name;
#endif
[XmlElement("category")]
#if NET48
public string Category;
#else
public string? Category;
#endif
[XmlElement("description")]
#if NET48
public string Description;
#else
public string? Description;
#endif
[XmlElement("rom")]
#if NET48
public Rom[] Roms;
#else
public Rom[]? Roms;
#endif
}
public class Rom
{
[XmlAttribute("name")]
#if NET48
public string Name;
#else
public string? Name;
#endif
[XmlAttribute("size")]
#if NET48
public string Size;
#else
public string? Size;
#endif
[XmlAttribute("crc")]
#if NET48
public string Crc;
#else
public string? Crc;
#endif
[XmlAttribute("md5")]
#if NET48
public string Md5;
#else
public string? Md5;
#endif
[XmlAttribute("sha1")]
#if NET48
public string Sha1;
#else
public string? Sha1;
#endif
// TODO: Add extended hashes here
}

View File

@@ -13,33 +13,25 @@ namespace MPF.Core.Modules.DiscImageCreator
/// <returns>RedumpSystem if possible, null on error</returns>
public static RedumpSystem? ToRedumpSystem(string baseCommand)
{
switch (baseCommand)
return baseCommand switch
{
case CommandStrings.Audio:
return RedumpSystem.AudioCD;
case CommandStrings.CompactDisc:
case CommandStrings.Data:
case CommandStrings.DigitalVideoDisc:
case CommandStrings.Disk:
case CommandStrings.Floppy:
case CommandStrings.Tape:
return RedumpSystem.IBMPCcompatible;
case CommandStrings.GDROM:
case CommandStrings.Swap:
return RedumpSystem.SegaDreamcast;
case CommandStrings.BluRay:
return RedumpSystem.SonyPlayStation3;
case CommandStrings.SACD:
return RedumpSystem.SuperAudioCD;
case CommandStrings.XBOX:
case CommandStrings.XBOXSwap:
return RedumpSystem.MicrosoftXbox;
case CommandStrings.XGD2Swap:
case CommandStrings.XGD3Swap:
return RedumpSystem.MicrosoftXbox360;
default:
return null;
}
CommandStrings.Audio => (RedumpSystem?)RedumpSystem.AudioCD,
CommandStrings.CompactDisc
or CommandStrings.Data
or CommandStrings.DigitalVideoDisc
or CommandStrings.Disk
or CommandStrings.Floppy
or CommandStrings.Tape => (RedumpSystem?)RedumpSystem.IBMPCcompatible,
CommandStrings.GDROM
or CommandStrings.Swap => (RedumpSystem?)RedumpSystem.SegaDreamcast,
CommandStrings.BluRay => (RedumpSystem?)RedumpSystem.SonyPlayStation3,
CommandStrings.SACD => (RedumpSystem?)RedumpSystem.SuperAudioCD,
CommandStrings.XBOX
or CommandStrings.XBOXSwap => (RedumpSystem?)RedumpSystem.MicrosoftXbox,
CommandStrings.XGD2Swap
or CommandStrings.XGD3Swap => (RedumpSystem?)RedumpSystem.MicrosoftXbox360,
_ => null,
};
}
/// <summary>
@@ -48,41 +40,29 @@ namespace MPF.Core.Modules.DiscImageCreator
/// <param name="baseCommand">Command value to check</param>
/// <returns>MediaType if possible, null on error</returns>
/// <remarks>This takes the "safe" route by assuming the larger of any given format</remarks>
#if NET48
public static MediaType? ToMediaType(string baseCommand)
#else
public static MediaType? ToMediaType(string? baseCommand)
#endif
{
switch (baseCommand)
return baseCommand switch
{
case CommandStrings.Audio:
case CommandStrings.CompactDisc:
case CommandStrings.Data:
case CommandStrings.SACD:
return MediaType.CDROM;
case CommandStrings.GDROM:
case CommandStrings.Swap:
return MediaType.GDROM;
case CommandStrings.DigitalVideoDisc:
case CommandStrings.XBOX:
case CommandStrings.XBOXSwap:
case CommandStrings.XGD2Swap:
case CommandStrings.XGD3Swap:
return MediaType.DVD;
case CommandStrings.BluRay:
return MediaType.BluRay;
CommandStrings.Audio
or CommandStrings.CompactDisc
or CommandStrings.Data
or CommandStrings.SACD => (MediaType?)MediaType.CDROM,
CommandStrings.GDROM
or CommandStrings.Swap => (MediaType?)MediaType.GDROM,
CommandStrings.DigitalVideoDisc
or CommandStrings.XBOX
or CommandStrings.XBOXSwap
or CommandStrings.XGD2Swap
or CommandStrings.XGD3Swap => (MediaType?)MediaType.DVD,
CommandStrings.BluRay => (MediaType?)MediaType.BluRay,
// Non-optical
case CommandStrings.Floppy:
return MediaType.FloppyDisk;
case CommandStrings.Disk:
return MediaType.HardDisk;
case CommandStrings.Tape:
return MediaType.DataCartridge;
default:
return null;
}
CommandStrings.Floppy => (MediaType?)MediaType.FloppyDisk,
CommandStrings.Disk => (MediaType?)MediaType.HardDisk,
CommandStrings.Tape => (MediaType?)MediaType.DataCartridge,
_ => null,
};
}
/// <summary>
@@ -90,41 +70,29 @@ namespace MPF.Core.Modules.DiscImageCreator
/// </summary>
/// <param name="type">MediaType value to check</param>
/// <returns>Valid extension (with leading '.'), null on error</returns>
#if NET48
public static string Extension(MediaType? type)
#else
public static string? Extension(MediaType? type)
#endif
{
switch (type)
return type switch
{
case MediaType.CDROM:
case MediaType.GDROM:
case MediaType.Cartridge:
case MediaType.HardDisk:
case MediaType.CompactFlash:
case MediaType.MMC:
case MediaType.SDCard:
case MediaType.FlashDrive:
return ".bin";
case MediaType.DVD:
case MediaType.HDDVD:
case MediaType.BluRay:
case MediaType.NintendoWiiOpticalDisc:
return ".iso";
case MediaType.LaserDisc:
case MediaType.NintendoGameCubeGameDisc:
return ".raw";
case MediaType.NintendoWiiUOpticalDisc:
return ".wud";
case MediaType.FloppyDisk:
return ".img";
case MediaType.Cassette:
return ".wav";
case MediaType.NONE:
default:
return null;
}
MediaType.CDROM
or MediaType.GDROM
or MediaType.Cartridge
or MediaType.HardDisk
or MediaType.CompactFlash
or MediaType.MMC
or MediaType.SDCard
or MediaType.FlashDrive => ".bin",
MediaType.DVD
or MediaType.HDDVD
or MediaType.BluRay
or MediaType.NintendoWiiOpticalDisc => ".iso",
MediaType.LaserDisc
or MediaType.NintendoGameCubeGameDisc => ".raw",
MediaType.NintendoWiiUOpticalDisc => ".wud",
MediaType.FloppyDisk => ".img",
MediaType.Cassette => ".wav",
_ => null,
};
}
#endregion

File diff suppressed because it is too large Load Diff

View File

@@ -11,24 +11,16 @@ namespace MPF.Core.Modules.Redumper
/// </summary>
/// <param name="type">MediaType value to check</param>
/// <returns>Valid extension (with leading '.'), null on error</returns>
#if NET48
public static string Extension(MediaType? type)
#else
public static string? Extension(MediaType? type)
#endif
{
switch (type)
return type switch
{
case MediaType.CDROM:
return ".bin";
case MediaType.DVD:
case MediaType.HDDVD:
case MediaType.BluRay:
return ".iso";
case MediaType.NONE:
default:
return null;
}
MediaType.CDROM => ".bin",
MediaType.DVD
or MediaType.HDDVD
or MediaType.BluRay => ".iso",
_ => null,
};
}
#endregion

File diff suppressed because it is too large Load Diff

View File

@@ -22,18 +22,10 @@ namespace MPF.Core.Modules.UmdImageCreator
#endregion
/// <inheritdoc/>
#if NET48
public Parameters(string parameters) : base(parameters) { }
#else
public Parameters(string? parameters) : base(parameters) { }
#endif
/// <inheritdoc/>
#if NET48
public Parameters(RedumpSystem? system, MediaType? type, string drivePath, string filename, int? driveSpeed, Options options)
#else
public Parameters(RedumpSystem? system, MediaType? type, string? drivePath, string filename, int? driveSpeed, Options options)
#endif
: base(system, type, drivePath, filename, driveSpeed, options)
{
}
@@ -70,40 +62,24 @@ namespace MPF.Core.Modules.UmdImageCreator
}
/// <inheritdoc/>
#if NET48
public override void GenerateSubmissionInfo(SubmissionInfo info, Options options, string basePath, Drive drive, bool includeArtifacts)
#else
public override void GenerateSubmissionInfo(SubmissionInfo info, Options options, string basePath, Drive? drive, bool includeArtifacts)
#endif
{
// Ensure that required sections exist
info = SubmissionInfoTool.EnsureAllSections(info);
// TODO: Determine if there's a UMDImageCreator version anywhere
#if NET48
info.DumpingInfo.DumpingProgram = EnumConverter.LongName(this.InternalProgram);
#else
info.DumpingInfo!.DumpingProgram = EnumConverter.LongName(this.InternalProgram);
#endif
info.DumpingInfo.DumpingDate = InfoTool.GetFileModifiedDate(basePath + "_disc.txt")?.ToString("yyyy-MM-dd HH:mm:ss");
// Extract info based generically on MediaType
switch (this.Type)
{
case MediaType.UMD:
#if NET48
info.Extras.PVD = GetPVD(basePath + "_mainInfo.txt") ?? string.Empty;
#else
info.Extras!.PVD = GetPVD(basePath + "_mainInfo.txt") ?? string.Empty;
#endif
if (Hasher.GetFileHashes(basePath + ".iso", out long filesize, out var crc32, out var md5, out var sha1))
{
#if NET48
info.SizeAndChecksums.Size = filesize;
#else
info.SizeAndChecksums!.Size = filesize;
#endif
info.SizeAndChecksums.CRC32 = crc32;
info.SizeAndChecksums.MD5 = md5;
info.SizeAndChecksums.SHA1 = sha1;
@@ -111,17 +87,10 @@ namespace MPF.Core.Modules.UmdImageCreator
if (GetUMDAuxInfo(basePath + "_disc.txt", out var title, out DiscCategory? umdcat, out var umdversion, out var umdlayer, out long umdsize))
{
#if NET48
info.CommonDiscInfo.Title = title ?? string.Empty;
info.CommonDiscInfo.Category = umdcat ?? DiscCategory.Games;
info.VersionAndEditions.Version = umdversion ?? string.Empty;
info.SizeAndChecksums.Size = umdsize;
#else
info.CommonDiscInfo!.Title = title ?? string.Empty;
info.CommonDiscInfo.Category = umdcat ?? DiscCategory.Games;
info.VersionAndEditions!.Version = umdversion ?? string.Empty;
info.SizeAndChecksums!.Size = umdsize;
#endif
if (!string.IsNullOrWhiteSpace(umdlayer))
info.SizeAndChecksums.Layerbreak = Int64.Parse(umdlayer ?? "-1");
@@ -133,11 +102,7 @@ namespace MPF.Core.Modules.UmdImageCreator
// Fill in any artifacts that exist, Base64-encoded, if we need to
if (includeArtifacts)
{
#if NET48
if (info.Artifacts == null) info.Artifacts = new Dictionary<string, string>();
#else
info.Artifacts ??= new Dictionary<string, string>();
#endif
if (File.Exists(basePath + "_disc.txt"))
info.Artifacts["disc"] = GetBase64(GetFullFile(basePath + "_disc.txt")) ?? string.Empty;
@@ -185,38 +150,32 @@ namespace MPF.Core.Modules.UmdImageCreator
/// </summary>
/// <param name="mainInfo">_mainInfo.txt file location</param>
/// <returns>Newline-deliminated PVD if possible, null on error</returns>
#if NET48
private static string GetPVD(string mainInfo)
#else
private static string? GetPVD(string mainInfo)
#endif
{
// If the file doesn't exist, we can't get info from it
if (!File.Exists(mainInfo))
return null;
using (var sr = File.OpenText(mainInfo))
try
{
try
{
// Make sure we're in the right sector
while (sr.ReadLine()?.StartsWith("========== LBA[000016, 0x0000010]: Main Channel ==========") == false) ;
// Make sure we're in the right sector
using var sr = File.OpenText(mainInfo);
while (sr.ReadLine()?.StartsWith("========== LBA[000016, 0x0000010]: Main Channel ==========") == false) ;
// Fast forward to the PVD
while (sr.ReadLine()?.StartsWith("0310") == false) ;
// Fast forward to the PVD
while (sr.ReadLine()?.StartsWith("0310") == false) ;
// Now that we're at the PVD, read each line in and concatenate
string pvd = "";
for (int i = 0; i < 6; i++)
pvd += sr.ReadLine() + "\n"; // 320-370
// Now that we're at the PVD, read each line in and concatenate
string pvd = "";
for (int i = 0; i < 6; i++)
pvd += sr.ReadLine() + "\n"; // 320-370
return pvd;
}
catch
{
// We don't care what the exception is right now
return null;
}
return pvd;
}
catch
{
// We don't care what the exception is right now
return null;
}
}
@@ -225,11 +184,7 @@ namespace MPF.Core.Modules.UmdImageCreator
/// </summary>
/// <param name="disc">_disc.txt file location</param>
/// <returns>True on successful extraction of info, false otherwise</returns>
#if NET48
private static bool GetUMDAuxInfo(string disc, out string title, out DiscCategory? umdcat, out string umdversion, out string umdlayer, out long umdsize)
#else
private static bool GetUMDAuxInfo(string disc, out string? title, out DiscCategory? umdcat, out string? umdversion, out string? umdlayer, out long umdsize)
#endif
{
title = null; umdcat = null; umdversion = null; umdlayer = null; umdsize = -1;
@@ -237,45 +192,38 @@ namespace MPF.Core.Modules.UmdImageCreator
if (!File.Exists(disc))
return false;
using (var sr = File.OpenText(disc))
try
{
try
// Loop through everything to get the first instance of each required field
using var sr = File.OpenText(disc);
while (!sr.EndOfStream)
{
// Loop through everything to get the first instance of each required field
var line = string.Empty;
while (!sr.EndOfStream)
{
line = sr.ReadLine()?.Trim();
if (line == null)
break;
string? line = sr.ReadLine()?.Trim();
if (line == null)
break;
if (line.StartsWith("TITLE") && title == null)
#if NET48
title = line.Substring("TITLE: ".Length);
#else
title = line["TITLE: ".Length..];
#endif
else if (line.StartsWith("DISC_VERSION") && umdversion == null)
umdversion = line.Split(' ')[1];
else if (line.StartsWith("pspUmdTypes"))
umdcat = InfoTool.GetUMDCategory(line.Split(' ')[1]);
else if (line.StartsWith("L0 length"))
umdlayer = line.Split(' ')[2];
else if (line.StartsWith("FileSize:"))
umdsize = Int64.Parse(line.Split(' ')[1]);
}
// If the L0 length is the size of the full disc, there's no layerbreak
if (Int64.TryParse(umdlayer, out long umdlayerValue) && umdlayerValue * 2048 == umdsize)
umdlayer = null;
return true;
}
catch
{
// We don't care what the exception is right now
return false;
if (line.StartsWith("TITLE") && title == null)
title = line["TITLE: ".Length..];
else if (line.StartsWith("DISC_VERSION") && umdversion == null)
umdversion = line.Split(' ')[1];
else if (line.StartsWith("pspUmdTypes"))
umdcat = InfoTool.GetUMDCategory(line.Split(' ')[1]);
else if (line.StartsWith("L0 length"))
umdlayer = line.Split(' ')[2];
else if (line.StartsWith("FileSize:"))
umdsize = Int64.Parse(line.Split(' ')[1]);
}
// If the L0 length is the size of the full disc, there's no layerbreak
if (Int64.TryParse(umdlayer, out long umdlayerValue) && umdlayerValue * 2048 == umdsize)
umdlayer = null;
return true;
}
catch
{
// We don't care what the exception is right now
return false;
}
}

View File

@@ -8,6 +8,8 @@ using BinaryObjectScanner;
using BinaryObjectScanner.Protection;
using psxt001z;
#pragma warning disable SYSLIB1045 // Convert to 'GeneratedRegexAttribute'.
namespace MPF.Core
{
public static class Protection
@@ -19,11 +21,7 @@ namespace MPF.Core
/// <param name="options">Options object that determines what to scan</param>
/// <param name="progress">Optional progress callback</param>
/// <returns>Set of all detected copy protections with an optional error string</returns>
#if NET48
public static async Task<(Dictionary<string, List<string>>, string)> RunProtectionScanOnPath(string path, Data.Options options, IProgress<ProtectionProgress> progress = null)
#else
public static async Task<(Dictionary<string, List<string>>?, string?)> RunProtectionScanOnPath(string path, Data.Options options, IProgress<ProtectionProgress>? progress = null)
#endif
{
try
{
@@ -66,11 +64,7 @@ namespace MPF.Core
/// </summary>
/// <param name="protections">Dictionary of file to list of protection mappings</param>
/// <returns>Detected protections, if any</returns>
#if NET48
public static string FormatProtections(Dictionary<string, List<string>> protections)
#else
public static string? FormatProtections(Dictionary<string, List<string>>? protections)
#endif
{
// If the filtered list is empty in some way, return
if (protections == null || !protections.Any())
@@ -95,11 +89,7 @@ namespace MPF.Core
/// </summary>
/// <param name="path">Path to scan for anti-modchip strings</param>
/// <returns>Anti-modchip existence if possible, false on error</returns>
#if NET48
public static async Task<bool> GetPlayStationAntiModchipDetected(string path)
#else
public static async Task<bool> GetPlayStationAntiModchipDetected(string? path)
#endif
{
// If there is no valid path
if (string.IsNullOrEmpty(path))

File diff suppressed because it is too large Load Diff

View File

@@ -49,16 +49,21 @@ namespace MPF.Core.UI.ComboBoxItems
}
/// <inheritdoc/>
#if NET48
public bool Equals(Element<T> other)
#else
public override bool Equals(object? obj)
{
return Equals(obj as Element<T>);
}
/// <inheritdoc/>
public bool Equals(Element<T>? other)
#endif
{
if (other == null)
return false;
return Name == other.Name;
}
/// <inheritdoc/>
public override int GetHashCode() => base.GetHashCode();
}
}

View File

@@ -10,11 +10,7 @@ namespace MPF.Core.UI.ComboBoxItems
/// </summary>
public class RedumpSystemComboBoxItem : IEquatable<RedumpSystemComboBoxItem>, IElement
{
#if NET48
private readonly object Data;
#else
private readonly object? Data;
#endif
public RedumpSystemComboBoxItem(RedumpSystem? system) => Data = system;
public RedumpSystemComboBoxItem(SystemCategory? category) => Data = category;
@@ -85,16 +81,21 @@ namespace MPF.Core.UI.ComboBoxItems
}
/// <inheritdoc/>
#if NET48
public bool Equals(RedumpSystemComboBoxItem other)
#else
public override bool Equals(object? obj)
{
return Equals(obj as RedumpSystemComboBoxItem);
}
/// <inheritdoc/>
public bool Equals(RedumpSystemComboBoxItem? other)
#endif
{
if (other == null)
return false;
return Value == other.Value;
}
/// <inheritdoc/>
public override int GetHashCode() => base.GetHashCode();
}
}

View File

@@ -38,11 +38,7 @@ namespace MPF.Core.UI.ViewModels
/// <summary>
/// List of Redump-supported Regions
/// </summary>
#if NET48
private static readonly List<Region> RedumpRegions = new List<Region>
#else
private static readonly List<Region> RedumpRegions = new()
#endif
{
Region.Argentina,
Region.Asia,
@@ -133,11 +129,7 @@ namespace MPF.Core.UI.ViewModels
/// <summary>
/// List of Redump-supported Languages
/// </summary>
#if NET48
private static readonly List<Language> RedumpLanguages = new List<Language>
#else
private static readonly List<Language> RedumpLanguages = new()
#endif
{
Language.Afrikaans,
Language.Albanian,
@@ -199,11 +191,7 @@ namespace MPF.Core.UI.ViewModels
/// <summary>
/// Constructor
/// </summary>
#if NET48
public DiscInformationViewModel(Options options, SubmissionInfo submissionInfo)
#else
public DiscInformationViewModel(Options options, SubmissionInfo? submissionInfo)
#endif
{
Options = options;
SubmissionInfo = submissionInfo?.Clone() as SubmissionInfo ?? new SubmissionInfo();

View File

@@ -37,20 +37,12 @@ namespace MPF.Core.UI.ViewModels
public bool CanExecuteSelectionChanged { get; private set; } = false;
/// <inheritdoc/>
#if NET48
public event PropertyChangedEventHandler PropertyChanged;
#else
public event PropertyChangedEventHandler? PropertyChanged;
#endif
/// <summary>
/// Action to process logging statements
/// </summary>
#if NET48
private Action<LogLevel, string> _logger;
#else
private Action<LogLevel, string>? _logger;
#endif
/// <summary>
/// Display a message to a user
@@ -62,11 +54,7 @@ namespace MPF.Core.UI.ViewModels
/// T4 - true for inquiry, false otherwise
/// TResult - true for positive, false for negative, null for neutral
/// </remarks>
#if NET48
private Func<string, string, int, bool, bool?> _displayUserMessage;
#else
private Func<string, string, int, bool, bool?>? _displayUserMessage;
#endif
/// <summary>
/// Detected media type, distinct from the selected one
@@ -76,20 +64,12 @@ namespace MPF.Core.UI.ViewModels
/// <summary>
/// Current dumping environment
/// </summary>
#if NET48
private DumpEnvironment _environment;
#else
private DumpEnvironment? _environment;
#endif
/// <summary>
/// Function to process user information
/// </summary>
#if NET48
private Func<SubmissionInfo, (bool?, SubmissionInfo)> _processUserInfo;
#else
private Func<SubmissionInfo?, (bool?, SubmissionInfo?)>? _processUserInfo;
#endif
#endregion
@@ -210,11 +190,7 @@ namespace MPF.Core.UI.ViewModels
/// <summary>
/// Currently selected drive value
/// </summary>
#if NET48
public Drive CurrentDrive
#else
public Drive? CurrentDrive
#endif
{
get => _currentDrive;
set
@@ -223,11 +199,7 @@ namespace MPF.Core.UI.ViewModels
TriggerPropertyChanged(nameof(CurrentDrive));
}
}
#if NET48
private Drive _currentDrive;
#else
private Drive? _currentDrive;
#endif
/// <summary>
/// Indicates the status of the drive combo box
@@ -474,11 +446,7 @@ namespace MPF.Core.UI.ViewModels
/// <summary>
/// Current list of supported media types
/// </summary>
#if NET48
public List<Element<MediaType>> MediaTypes
#else
public List<Element<MediaType>>? MediaTypes
#endif
{
get => _mediaTypes;
set
@@ -487,11 +455,7 @@ namespace MPF.Core.UI.ViewModels
TriggerPropertyChanged(nameof(MediaTypes));
}
}
#if NET48
private List<Element<MediaType>> _mediaTypes;
#else
private List<Element<MediaType>>? _mediaTypes;
#endif
/// <summary>
/// Current list of supported system profiles
@@ -564,11 +528,7 @@ namespace MPF.Core.UI.ViewModels
public void Init(
Action<LogLevel, string> loggerAction,
Func<string, string, int, bool, bool?> displayUserMessage,
#if NET48
Func<SubmissionInfo, (bool?, SubmissionInfo)> processUserInfo)
#else
Func<SubmissionInfo?, (bool?, SubmissionInfo?)> processUserInfo)
#endif
{
// Set the callbacks
_logger = loggerAction;
@@ -765,11 +725,7 @@ namespace MPF.Core.UI.ViewModels
/// <summary>
/// Check for available updates
/// </summary>
#if NET48
public (bool, string, string) CheckForUpdates()
#else
public (bool, string, string?) CheckForUpdates()
#endif
{
(bool different, string message, var url) = Tools.CheckForNewVersion();
@@ -846,20 +802,12 @@ namespace MPF.Core.UI.ViewModels
EXEDateBuildDate = "19xx-xx-xx",
ErrorsCount = "0",
Comments = "Comment data line 1\r\nComment data line 2",
#if NET48
CommentsSpecialFields = new Dictionary<SiteCode?, string>()
#else
CommentsSpecialFields = new Dictionary<SiteCode, string>()
#endif
{
[SiteCode.ISBN] = "ISBN",
},
Contents = "Special contents 1\r\nSpecial contents 2",
#if NET48
ContentsSpecialFields = new Dictionary<SiteCode?, string>()
#else
ContentsSpecialFields = new Dictionary<SiteCode, string>()
#endif
{
[SiteCode.PlayableDemos] = "Game Demo 1",
},
@@ -982,18 +930,13 @@ namespace MPF.Core.UI.ViewModels
/// </summary>
/// <param name="savedSettings">Indicates if the settings were saved or not</param>
/// <param name="newOptions">Options representing the new, saved values</param>
#if NET48
public void UpdateOptions(bool savedSettings, Data.Options newOptions)
#else
public void UpdateOptions(bool savedSettings, Data.Options? newOptions)
#endif
{
// Get which options to save
var optionsToSave = savedSettings ? newOptions : Options;
// Ensure the first run flag is unset
var continuingOptions = new Data.Options(optionsToSave);
continuingOptions.FirstRun = false;
var continuingOptions = new Data.Options(optionsToSave) { FirstRun = false };
this.Options = continuingOptions;
// If settings were changed, reinitialize the UI
@@ -1467,19 +1410,10 @@ namespace MPF.Core.UI.ViewModels
/// <summary>
/// Scan and show copy protection for the current disc
/// </summary>
#if NET48
public async Task<(string, string)> ScanAndShowProtection()
#else
public async Task<(string?, string?)> ScanAndShowProtection()
#endif
{
// Determine current environment, just in case
#if NET48
if (_environment == null)
_environment = DetermineEnvironment();
#else
_environment ??= DetermineEnvironment();
#endif
// If we don't have a valid drive
if (this.CurrentDrive?.Name == null)
@@ -1563,30 +1497,6 @@ namespace MPF.Core.UI.ViewModels
VerboseLogLn($"Supported media speeds: {string.Join(", ", this.DriveSpeeds)}");
// Set the selected speed
#if NET48
int speed;
switch (CurrentMediaType)
{
case MediaType.CDROM:
case MediaType.GDROM:
speed = Options.PreferredDumpSpeedCD;
break;
case MediaType.DVD:
case MediaType.NintendoGameCubeGameDisc:
case MediaType.NintendoWiiOpticalDisc:
speed = Options.PreferredDumpSpeedDVD;
break;
case MediaType.HDDVD:
speed = Options.PreferredDumpSpeedHDDVD;
break;
case MediaType.BluRay:
speed = Options.PreferredDumpSpeedBD;
break;
default:
speed = Options.PreferredDumpSpeedCD;
break;
}
#else
int speed = (CurrentMediaType) switch
{
// CD dump speed
@@ -1607,7 +1517,6 @@ namespace MPF.Core.UI.ViewModels
// Default
_ => Options.PreferredDumpSpeedCD,
};
#endif
VerboseLogLn($"Setting drive speed to: {speed}");
this.DriveSpeed = speed;
@@ -1821,26 +1730,18 @@ namespace MPF.Core.UI.ViewModels
return true;
}
#endregion
#endregion
#region Progress Reporting
/// <summary>
/// Handler for Result ProgressChanged event
/// </summary>
#if NET48
private void ProgressUpdated(object sender, string value)
#else
private void ProgressUpdated(object? sender, string value)
#endif
{
try
{
#if NET48
value = value ?? string.Empty;
#else
value ??= string.Empty;
#endif
LogLn(value);
}
catch { }
@@ -1849,20 +1750,12 @@ namespace MPF.Core.UI.ViewModels
/// <summary>
/// Handler for Result ProgressChanged event
/// </summary>
#if NET48
private void ProgressUpdated(object sender, Result value)
#else
private void ProgressUpdated(object? sender, Result value)
#endif
{
var message = value?.Message;
// Update the label with only the first line of output
#if NET48
if (message != null && message.Contains("\n"))
#else
if (message != null && message.Contains('\n'))
#endif
this.Status = value?.Message?.Split('\n')[0] + " (See log output)";
else
this.Status = value?.Message ?? string.Empty;
@@ -1877,17 +1770,13 @@ namespace MPF.Core.UI.ViewModels
/// <summary>
/// Handler for ProtectionProgress ProgressChanged event
/// </summary>
#if NET48
private void ProgressUpdated(object sender, ProtectionProgress value)
#else
private void ProgressUpdated(object? sender, ProtectionProgress value)
#endif
{
string message = $"{value.Percentage * 100:N2}%: {value.Filename} - {value.Protection}";
this.Status = message;
VerboseLogLn(message);
}
#endregion
#endregion
}
}

View File

@@ -15,11 +15,7 @@ namespace MPF.Core.UI.ViewModels
/// <summary>
/// Title for the window
/// </summary>
#if NET48
public string Title
#else
public string? Title
#endif
{
get => _title;
set
@@ -28,11 +24,7 @@ namespace MPF.Core.UI.ViewModels
TriggerPropertyChanged(nameof(Title));
}
}
#if NET48
private string _title;
#else
private string? _title;
#endif
/// <summary>
/// Current set of options
@@ -45,25 +37,21 @@ namespace MPF.Core.UI.ViewModels
public bool SavedSettings { get; set; }
/// <inheritdoc/>
#if NET48
public event PropertyChangedEventHandler PropertyChanged;
#else
public event PropertyChangedEventHandler? PropertyChanged;
#endif
#endregion
#endregion
#region Lists
/// <summary>
/// List of available internal programs
/// </summary>
public List<Element<InternalProgram>> InternalPrograms => PopulateInternalPrograms();
public static List<Element<InternalProgram>> InternalPrograms => PopulateInternalPrograms();
/// <summary>
/// Current list of supported system profiles
/// </summary>
public List<RedumpSystemComboBoxItem> Systems => RedumpSystemComboBoxItem.GenerateElements().ToList();
public static List<RedumpSystemComboBoxItem> Systems => RedumpSystemComboBoxItem.GenerateElements().ToList();
#endregion
@@ -93,17 +81,9 @@ namespace MPF.Core.UI.ViewModels
/// <summary>
/// Test Redump login credentials
/// </summary>
#if NET48
public (bool?, string) TestRedumpLogin(string username, string password)
#else
public async Task<(bool?, string?)> TestRedumpLogin(string username, string password)
#endif
public static async Task<(bool?, string?)> TestRedumpLogin(string username, string password)
{
#if NET48
return RedumpWebClient.ValidateCredentials(username, password);
#else
return await RedumpHttpClient.ValidateCredentials(username, password);
#endif
}
#endregion

View File

@@ -15,26 +15,24 @@ namespace MPF.Core.Utilities
/// <returns>True if Windows show see a disc when dumping, false otherwise</returns>
public static bool DetectedByWindows(this RedumpSystem? system)
{
switch (system)
return system switch
{
case RedumpSystem.AmericanLaserGames3DO:
case RedumpSystem.AppleMacintosh:
case RedumpSystem.Atari3DO:
case RedumpSystem.AtariJaguarCDInteractiveMultimediaSystem:
case RedumpSystem.NewJatreCDi:
case RedumpSystem.NintendoGameCube:
case RedumpSystem.NintendoWii:
case RedumpSystem.NintendoWiiU:
case RedumpSystem.PhilipsCDi:
case RedumpSystem.PhilipsCDiDigitalVideo:
case RedumpSystem.Panasonic3DOInteractiveMultiplayer:
case RedumpSystem.PanasonicM2:
case RedumpSystem.PioneerLaserActive:
case RedumpSystem.SuperAudioCD:
return false;
default:
return true;
}
RedumpSystem.AmericanLaserGames3DO
or RedumpSystem.AppleMacintosh
or RedumpSystem.Atari3DO
or RedumpSystem.AtariJaguarCDInteractiveMultimediaSystem
or RedumpSystem.NewJatreCDi
or RedumpSystem.NintendoGameCube
or RedumpSystem.NintendoWii
or RedumpSystem.NintendoWiiU
or RedumpSystem.PhilipsCDi
or RedumpSystem.PhilipsCDiDigitalVideo
or RedumpSystem.Panasonic3DOInteractiveMultiplayer
or RedumpSystem.PanasonicM2
or RedumpSystem.PioneerLaserActive
or RedumpSystem.SuperAudioCD => false,
_ => true,
};
}
/// <summary>
@@ -44,19 +42,17 @@ namespace MPF.Core.Utilities
/// <returns>True if the media has variable dumping speeds, false otherwise</returns>
public static bool DoesSupportDriveSpeed(this MediaType? type)
{
switch (type)
return type switch
{
case MediaType.CDROM:
case MediaType.DVD:
case MediaType.GDROM:
case MediaType.HDDVD:
case MediaType.BluRay:
case MediaType.NintendoGameCubeGameDisc:
case MediaType.NintendoWiiOpticalDisc:
return true;
default:
return false;
}
MediaType.CDROM
or MediaType.DVD
or MediaType.GDROM
or MediaType.HDDVD
or MediaType.BluRay
or MediaType.NintendoGameCubeGameDisc
or MediaType.NintendoWiiOpticalDisc => true,
_ => false,
};
}
/// <summary>
@@ -66,17 +62,15 @@ namespace MPF.Core.Utilities
/// <returns>True if the system has reversed ringcodes, false otherwise</returns>
public static bool HasReversedRingcodes(this RedumpSystem? system)
{
switch (system)
return system switch
{
case RedumpSystem.SonyPlayStation2:
case RedumpSystem.SonyPlayStation3:
case RedumpSystem.SonyPlayStation4:
//case RedumpSystem.SonyPlayStation5:
case RedumpSystem.SonyPlayStationPortable:
return true;
default:
return false;
}
RedumpSystem.SonyPlayStation2
or RedumpSystem.SonyPlayStation3
or RedumpSystem.SonyPlayStation4
or RedumpSystem.SonyPlayStation5
or RedumpSystem.SonyPlayStationPortable => true,
_ => false,
};
}
/// <summary>
@@ -90,23 +84,21 @@ namespace MPF.Core.Utilities
/// </remarks>
public static bool IsAudio(this RedumpSystem? system)
{
switch (system)
return system switch
{
case RedumpSystem.AtariJaguarCDInteractiveMultimediaSystem:
case RedumpSystem.AudioCD:
case RedumpSystem.DVDAudio:
case RedumpSystem.HasbroiONEducationalGamingSystem:
case RedumpSystem.HasbroVideoNow:
case RedumpSystem.HasbroVideoNowColor:
case RedumpSystem.HasbroVideoNowJr:
case RedumpSystem.HasbroVideoNowXP:
case RedumpSystem.PhilipsCDi:
case RedumpSystem.PlayStationGameSharkUpdates:
case RedumpSystem.SuperAudioCD:
return true;
default:
return false;
}
RedumpSystem.AtariJaguarCDInteractiveMultimediaSystem
or RedumpSystem.AudioCD
or RedumpSystem.DVDAudio
or RedumpSystem.HasbroiONEducationalGamingSystem
or RedumpSystem.HasbroVideoNow
or RedumpSystem.HasbroVideoNowColor
or RedumpSystem.HasbroVideoNowJr
or RedumpSystem.HasbroVideoNowXP
or RedumpSystem.PhilipsCDi
or RedumpSystem.PlayStationGameSharkUpdates
or RedumpSystem.SuperAudioCD => true,
_ => false,
};
}
/// <summary>
@@ -116,16 +108,14 @@ namespace MPF.Core.Utilities
/// <returns>True if the system is XGD, false otherwise</returns>
public static bool IsXGD(this RedumpSystem? system)
{
switch (system)
return system switch
{
case RedumpSystem.MicrosoftXbox:
case RedumpSystem.MicrosoftXbox360:
case RedumpSystem.MicrosoftXboxOne:
case RedumpSystem.MicrosoftXboxSeriesXS:
return true;
default:
return false;
}
RedumpSystem.MicrosoftXbox
or RedumpSystem.MicrosoftXbox360
or RedumpSystem.MicrosoftXboxOne
or RedumpSystem.MicrosoftXboxSeriesXS => true,
_ => false,
};
}
/// <summary>

View File

@@ -14,11 +14,7 @@ namespace MPF.Core.Utilities
/// <param name="reader">TextReader representing the input</param>
/// <param name="baseClass">Invoking class, passed on to the event handler</param>
/// <param name="handler">Event handler to be invoked to write to log</param>
#if NET48
public static async Task OutputToLog(TextReader reader, object baseClass, EventHandler<string> handler)
#else
public static async Task OutputToLog(TextReader reader, object baseClass, EventHandler<string>? handler)
#endif
{
// Initialize the required variables
char[] buffer = new char[256];
@@ -38,18 +34,18 @@ namespace MPF.Core.Utilities
}
// Convert the characters into a string
string line = new string(buffer, 0, read);
string line = new(buffer, 0, read);
// If we have no newline characters, store in the string builder
if (!line.Contains("\r") && !line.Contains("\n"))
if (!line.Contains('\r') && !line.Contains('\n'))
sb.Append(line);
// If we have a newline, append and log
else if (line.Contains("\n") || line.Contains("\r\n"))
else if (line.Contains('\n') || line.Contains("\r\n"))
ProcessNewLines(sb, line, baseClass, handler);
// If we have a carriage return only, append and log first and last instances
else if (line.Contains("\r"))
else if (line.Contains('\r'))
ProcessCarriageReturns(sb, line, baseClass, handler);
}
}
@@ -67,18 +63,14 @@ namespace MPF.Core.Utilities
/// <param name="line">Current line to process</param>
/// <param name="baseClass">Invoking class, passed on to the event handler</param>
/// <param name="handler">Event handler to be invoked to write to log</param>
#if NET48
private static void ProcessNewLines(StringBuilder sb, string line, object baseClass, EventHandler<string> handler)
#else
private static void ProcessNewLines(StringBuilder sb, string line, object baseClass, EventHandler<string>? handler)
#endif
{
line = line.Replace("\r\n", "\n");
var split = line.Split('\n');
for (int i = 0; i < split.Length; i++)
{
// If the chunk contains a carriage return, handle it like a separate line
if (split[i].Contains("\r"))
if (split[i].Contains('\r'))
{
ProcessCarriageReturns(sb, split[i], baseClass, handler);
continue;
@@ -113,11 +105,7 @@ namespace MPF.Core.Utilities
/// <param name="line">Current line to process</param>
/// <param name="baseClass">Invoking class, passed on to the event handler</param>
/// <param name="handler">Event handler to be invoked to write to log</param>
#if NET48
private static void ProcessCarriageReturns(StringBuilder sb, string line, object baseClass, EventHandler<string> handler)
#else
private static void ProcessCarriageReturns(StringBuilder sb, string line, object baseClass, EventHandler<string>? handler)
#endif
{
var split = line.Split('\r');
@@ -127,7 +115,7 @@ namespace MPF.Core.Utilities
// Append the last
sb.Clear();
sb.Append($"\r{split[split.Length - 1]}");
sb.Append($"\r{split[^1]}");
}
}
}

View File

@@ -63,11 +63,7 @@ namespace MPF.Core.Utilities
/// Process common arguments for all functionality
/// </summary>
/// <returns>True if all arguments pass, false otherwise</returns>
#if NET48
public static (bool, MediaType, RedumpSystem?, string) ProcessCommonArguments(string[] args)
#else
public static (bool, MediaType, RedumpSystem?, string?) ProcessCommonArguments(string[] args)
#endif
{
// All other use requires at least 3 arguments
if (args.Length < 3)
@@ -89,11 +85,7 @@ namespace MPF.Core.Utilities
/// <summary>
/// Load the current set of options from application arguments
/// </summary>
#if NET48
public static (Options, SubmissionInfo, string, int) LoadFromArguments(string[] args, int startIndex = 0)
#else
public static (Options, SubmissionInfo?, string?, int) LoadFromArguments(string[] args, int startIndex = 0)
#endif
{
// Create the output values with defaults
var options = new Options()
@@ -108,13 +100,8 @@ namespace MPF.Core.Utilities
};
// Create the submission info to return, if necessary
#if NET48
SubmissionInfo info = null;
string parsedPath = null;
#else
SubmissionInfo? info = null;
string? parsedPath = null;
#endif
// These values require multiple parts to be active
bool scan = false, protectFile = false;
@@ -277,11 +264,7 @@ namespace MPF.Core.Utilities
var serializer = JsonSerializer.Create();
var reader = new StreamReader(ConfigurationPath);
#if NET48
var settings = serializer.Deserialize(reader, typeof(Dictionary<string, string>)) as Dictionary<string, string>;
#else
var settings = serializer.Deserialize(reader, typeof(Dictionary<string, string?>)) as Dictionary<string, string?>;
#endif
return new Options(settings);
}

View File

@@ -84,40 +84,6 @@ namespace MPF.Core.Utilities
return Result.Failure("Please select a valid system");
// If we're on an unsupported type, update the status accordingly
#if NET48
switch (type)
{
// Fully supported types
case MediaType.BluRay:
case MediaType.CDROM:
case MediaType.DVD:
case MediaType.FloppyDisk:
case MediaType.HardDisk:
case MediaType.CompactFlash:
case MediaType.SDCard:
case MediaType.FlashDrive:
case MediaType.HDDVD:
return Result.Success($"{type.LongName()} ready to dump");
// Partially supported types
case MediaType.GDROM:
case MediaType.NintendoGameCubeGameDisc:
case MediaType.NintendoWiiOpticalDisc:
return Result.Success($"{type.LongName()} partially supported for dumping");
// Special case for other supported tools
case MediaType.UMD:
return Result.Failure($"{type.LongName()} supported for submission info parsing");
// Specifically unknown type
case MediaType.NONE:
return Result.Failure($"Please select a valid media type");
// Undumpable but recognized types
default:
return Result.Failure($"{type.LongName()} media are not supported for dumping");
}
#else
return type switch
{
// Fully supported types
@@ -145,9 +111,8 @@ namespace MPF.Core.Utilities
// Undumpable but recognized types
_ => Result.Failure($"{type.LongName()} media are not supported for dumping"),
};
#endif
}
/// <summary>
/// Returns false if a given InternalProgram does not support a given MediaType
/// </summary>
@@ -157,51 +122,6 @@ namespace MPF.Core.Utilities
if (type == null || type == MediaType.NONE)
return false;
#if NET48
switch (program)
{
case InternalProgram.Redumper:
switch (type)
{
// Formats considered at least partially dumpable by Redumper
case MediaType.BluRay:
case MediaType.CDROM:
case MediaType.DVD:
case MediaType.GDROM:
case MediaType.HDDVD:
return true;
// All other formats considered unsupported
default:
return false;
}
case InternalProgram.Aaru:
case InternalProgram.DiscImageCreator:
switch (type)
{
// Formats considered at least partially supported
case MediaType.BluRay:
case MediaType.CDROM:
case MediaType.DVD:
case MediaType.FloppyDisk:
case MediaType.HardDisk:
case MediaType.CompactFlash:
case MediaType.SDCard:
case MediaType.FlashDrive:
case MediaType.HDDVD:
case MediaType.NintendoGameCubeGameDisc:
case MediaType.NintendoWiiOpticalDisc:
return true;
// All other formats considered unsupported
default:
return false;
}
// All other InternalPrograms are not used for dumping
default:
return false;
}
#else
return (program) switch
{
// Aaru
@@ -242,7 +162,6 @@ namespace MPF.Core.Utilities
// Default
_ => false,
};
#endif
}
#endregion
@@ -257,11 +176,7 @@ namespace MPF.Core.Utilities
/// String representing the message to display the the user.
/// String representing the new release URL.
/// </returns>
#if NET48
public static (bool different, string message, string url) CheckForNewVersion()
#else
public static (bool different, string message, string? url) CheckForNewVersion()
#endif
{
try
{
@@ -293,11 +208,7 @@ namespace MPF.Core.Utilities
/// <summary>
/// Get the current informational version formatted as a string
/// </summary>
#if NET48
public static string GetCurrentVersion()
#else
public static string? GetCurrentVersion()
#endif
{
try
{
@@ -317,47 +228,26 @@ namespace MPF.Core.Utilities
/// <summary>
/// Get the latest version of MPF from GitHub and the release URL
/// </summary>
#if NET48
private static (string tag, string url) GetRemoteVersionAndUrl()
#else
private static (string? tag, string? url) GetRemoteVersionAndUrl()
#endif
{
#if NET48
using (var wc = new System.Net.WebClient())
{
wc.Headers["User-Agent"] = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:64.0) Gecko/20100101 Firefox/64.0";
using var hc = new System.Net.Http.HttpClient();
// TODO: Figure out a better way than having this hardcoded...
string url = "https://api.github.com/repos/SabreTools/MPF/releases/latest";
string latestReleaseJsonString = wc.DownloadString(url);
var latestReleaseJson = JObject.Parse(latestReleaseJsonString);
string latestTag = latestReleaseJson["tag_name"].ToString();
string releaseUrl = latestReleaseJson["html_url"].ToString();
// TODO: Figure out a better way than having this hardcoded...
string url = "https://api.github.com/repos/SabreTools/MPF/releases/latest";
var message = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Get, url);
message.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:64.0) Gecko/20100101 Firefox/64.0");
var latestReleaseJsonString = hc.Send(message)?.Content?.ReadAsStringAsync().ConfigureAwait(false).GetAwaiter().GetResult();
if (latestReleaseJsonString == null)
return (null, null);
return (latestTag, releaseUrl);
}
#else
using (var hc = new System.Net.Http.HttpClient())
{
// TODO: Figure out a better way than having this hardcoded...
string url = "https://api.github.com/repos/SabreTools/MPF/releases/latest";
var message = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Get, url);
message.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:64.0) Gecko/20100101 Firefox/64.0");
var latestReleaseJsonString = hc.Send(message)?.Content?.ReadAsStringAsync().ConfigureAwait(false).GetAwaiter().GetResult();
if (latestReleaseJsonString == null)
return (null, null);
var latestReleaseJson = JObject.Parse(latestReleaseJsonString);
if (latestReleaseJson == null)
return (null, null);
var latestReleaseJson = JObject.Parse(latestReleaseJsonString);
if (latestReleaseJson == null)
return (null, null);
var latestTag = latestReleaseJson["tag_name"]?.ToString();
var releaseUrl = latestReleaseJson["html_url"]?.ToString();
var latestTag = latestReleaseJson["tag_name"]?.ToString();
var releaseUrl = latestReleaseJson["html_url"]?.ToString();
return (latestTag, releaseUrl);
}
#endif
return (latestTag, releaseUrl);
}
#endregion

View File

@@ -43,37 +43,21 @@ namespace MPF.Test.Core.Converters
/// Generate a test set of DriveType values
/// </summary>
/// <returns>MemberData-compatible list of DriveType values</returns>
#if NET48
public static List<object[]> GenerateDriveTypeMappingTestData()
#else
public static List<object?[]> GenerateDriveTypeMappingTestData()
#endif
{
#if NET48
var testData = new List<object[]>() { new object[] { null, true } };
#else
var testData = new List<object?[]>() { new object?[] { null, true } };
#endif
foreach (DriveType driveType in Enum.GetValues(typeof(DriveType)))
{
if (_mappableDriveTypes.Contains(driveType))
#if NET48
testData.Add(new object[] { driveType, false });
#else
testData.Add(new object?[] { driveType, false });
#endif
else
#if NET48
testData.Add(new object[] { driveType, true });
#else
testData.Add(new object?[] { driveType, true });
#endif
}
return testData;
}
#endregion
#endregion
#region Convert to Long Name
@@ -95,30 +79,18 @@ namespace MPF.Test.Core.Converters
/// Generate a test set of InternalProgram values
/// </summary>
/// <returns>MemberData-compatible list of InternalProgram values</returns>
#if NET48
public static List<object[]> GenerateInternalProgramTestData()
#else
public static List<object?[]> GenerateInternalProgramTestData()
#endif
{
#if NET48
var testData = new List<object[]>() { new object[] { null } };
#else
var testData = new List<object?[]>() { new object?[] { null } };
#endif
foreach (InternalProgram? internalProgram in Enum.GetValues(typeof(InternalProgram)))
{
#if NET48
testData.Add(new object[] { internalProgram });
#else
testData.Add(new object?[] { internalProgram });
#endif
}
return testData;
}
#endregion
#endregion
// TODO: Add from-string tests
}

View File

@@ -143,31 +143,15 @@ namespace MPF.Test.Core.Utilities
/// Generate a test set of MediaType values that support drive speeds
/// </summary>
/// <returns>MemberData-compatible list of MediaType values</returns>
#if NET48
public static List<object[]> GenerateSupportDriveSpeedsTestData()
#else
public static List<object?[]> GenerateSupportDriveSpeedsTestData()
#endif
{
#if NET48
var testData = new List<object[]>() { new object[] { null, false } };
#else
var testData = new List<object?[]>() { new object?[] { null, false } };
#endif
foreach (MediaType mediaType in Enum.GetValues(typeof(MediaType)))
{
if (_supportDriveSpeeds.Contains(mediaType))
#if NET48
testData.Add(new object[] { mediaType, true });
#else
testData.Add(new object?[] { mediaType, true });
#endif
else
#if NET48
testData.Add(new object[] { mediaType, false });
#else
testData.Add(new object?[] { mediaType, false });
#endif
}
return testData;
@@ -177,31 +161,15 @@ namespace MPF.Test.Core.Utilities
/// Generate a test set of RedumpSystem values that are considered Audio
/// </summary>
/// <returns>MemberData-compatible list of RedumpSystem values</returns>
#if NET48
public static List<object[]> GenerateAudioSystemsTestData()
#else
public static List<object?[]> GenerateAudioSystemsTestData()
#endif
{
#if NET48
var testData = new List<object[]>() { new object[] { null, false } };
#else
var testData = new List<object?[]>() { new object?[] { null, false } };
#endif
foreach (RedumpSystem redumpSystem in Enum.GetValues(typeof(RedumpSystem)))
{
if (_audioSystems.Contains(redumpSystem))
#if NET48
testData.Add(new object[] { redumpSystem, true });
#else
testData.Add(new object?[] { redumpSystem, true });
#endif
else
#if NET48
testData.Add(new object[] { redumpSystem, false });
#else
testData.Add(new object?[] { redumpSystem, false });
#endif
}
return testData;
@@ -211,31 +179,15 @@ namespace MPF.Test.Core.Utilities
/// Generate a test set of RedumpSystem values that are considered markers
/// </summary>
/// <returns>MemberData-compatible list of RedumpSystem values</returns>
#if NET48
public static List<object[]> GenerateMarkerSystemsTestData()
#else
public static List<object?[]> GenerateMarkerSystemsTestData()
#endif
{
#if NET48
var testData = new List<object[]>() { new object[] { null, false } };
#else
var testData = new List<object?[]>() { new object?[] { null, false } };
#endif
foreach (RedumpSystem redumpSystem in Enum.GetValues(typeof(RedumpSystem)))
{
if (_markerSystems.Contains(redumpSystem))
#if NET48
testData.Add(new object[] { redumpSystem, true });
#else
testData.Add(new object?[] { redumpSystem, true });
#endif
else
#if NET48
testData.Add(new object[] { redumpSystem, false });
#else
testData.Add(new object?[] { redumpSystem, false });
#endif
}
return testData;
@@ -245,31 +197,15 @@ namespace MPF.Test.Core.Utilities
/// Generate a test set of RedumpSystem values that are considered markers
/// </summary>
/// <returns>MemberData-compatible list of RedumpSystem values</returns>
#if NET48
public static List<object[]> GenerateReversedRingcodeSystemsTestData()
#else
public static List<object?[]> GenerateReversedRingcodeSystemsTestData()
#endif
{
#if NET48
var testData = new List<object[]>() { new object[] { null, false } };
#else
var testData = new List<object?[]>() { new object?[] { null, false } };
#endif
foreach (RedumpSystem redumpSystem in Enum.GetValues(typeof(RedumpSystem)))
{
if (_reverseRingcodeSystems.Contains(redumpSystem))
#if NET48
testData.Add(new object[] { redumpSystem, true });
#else
testData.Add(new object?[] { redumpSystem, true });
#endif
else
#if NET48
testData.Add(new object[] { redumpSystem, false });
#else
testData.Add(new object?[] { redumpSystem, false });
#endif
}
return testData;
@@ -279,31 +215,15 @@ namespace MPF.Test.Core.Utilities
/// Generate a test set of RedumpSystem values that are considered XGD
/// </summary>
/// <returns>MemberData-compatible list of RedumpSystem values</returns>
#if NET48
public static List<object[]> GenerateXGDSystemsTestData()
#else
public static List<object?[]> GenerateXGDSystemsTestData()
#endif
{
#if NET48
var testData = new List<object[]>() { new object[] { null, false } };
#else
var testData = new List<object?[]>() { new object?[] { null, false } };
#endif
foreach (RedumpSystem redumpSystem in Enum.GetValues(typeof(RedumpSystem)))
{
if (_xgdSystems.Contains(redumpSystem))
#if NET48
testData.Add(new object[] { redumpSystem, true });
#else
testData.Add(new object?[] { redumpSystem, true });
#endif
else
#if NET48
testData.Add(new object[] { redumpSystem, false });
#else
testData.Add(new object?[] { redumpSystem, false });
#endif
}
return testData;

View File

@@ -14,7 +14,7 @@ namespace MPF.Test.Library
[InlineData("fd A test.img", 'A', true, MediaType.FloppyDisk, true)]
[InlineData("dvd X test.iso 8 /raw", 'X', false, MediaType.FloppyDisk, false)]
[InlineData("stop D", 'D', false, MediaType.DVD, true)]
public void ParametersValidTest(string parameters, char letter, bool isFloppy, MediaType? mediaType, bool expected)
public void ParametersValidTest(string? parameters, char letter, bool isFloppy, MediaType? mediaType, bool expected)
{
var options = new Options() { InternalProgram = InternalProgram.DiscImageCreator };

View File

@@ -42,11 +42,7 @@ namespace MPF.Test.Library
long layerbreak,
long layerbreak2,
long layerbreak3,
#if NET48
string expected)
#else
string? expected)
#endif
{
// TODO: Add tests around BDU
var actual = InfoTool.GetFixedMediaType(mediaType, null, size, layerbreak, layerbreak2, layerbreak3);
@@ -62,11 +58,7 @@ namespace MPF.Test.Library
[InlineData("superhero\\blah.rev.bin", "superhero\\blah.rev.bin")]
[InlineData("super&hero\\blah.bin", "super&hero\\blah.bin")]
[InlineData("superhero\\blah&foo.bin", "superhero\\blah&foo.bin")]
#if NET48
public void NormalizeOutputPathsTest(string outputPath, string expectedPath)
#else
public void NormalizeOutputPathsTest(string? outputPath, string? expectedPath)
#endif
{
if (!string.IsNullOrWhiteSpace(expectedPath))
expectedPath = Path.GetFullPath(expectedPath);
@@ -84,21 +76,13 @@ namespace MPF.Test.Library
CommonDiscInfo = new CommonDiscInfoSection()
{
Comments = "This is a comments line\n[T:ISBN] ISBN Value",
#if NET48
CommentsSpecialFields = new Dictionary<SiteCode?, string>()
#else
CommentsSpecialFields = new Dictionary<SiteCode, string>()
#endif
{
[SiteCode.VolumeLabel] = "VOLUME_LABEL",
},
Contents = "This is a contents line\n[T:GF] Game Footage",
#if NET48
ContentsSpecialFields = new Dictionary<SiteCode?, string>()
#else
ContentsSpecialFields = new Dictionary<SiteCode, string>()
#endif
{
[SiteCode.Patches] = "1.04 patch",
},
@@ -148,21 +132,13 @@ namespace MPF.Test.Library
CommonDiscInfo = new CommonDiscInfoSection()
{
Comments = null,
#if NET48
CommentsSpecialFields = new Dictionary<SiteCode?, string>()
#else
CommentsSpecialFields = new Dictionary<SiteCode, string>()
#endif
{
[SiteCode.VolumeLabel] = "VOLUME_LABEL",
},
Contents = null,
#if NET48
ContentsSpecialFields = new Dictionary<SiteCode?, string>()
#else
ContentsSpecialFields = new Dictionary<SiteCode, string>()
#endif
{
[SiteCode.Patches] = "1.04 patch",
},

View File

@@ -11,7 +11,7 @@ namespace MPF.Test.Library
[Fact]
public void SanitizeFoundProtectionsActiveMARKTest()
{
List<string> protections = new List<string>()
List<string> protections = new()
{
"ActiveMARK",
"ActiveMARK 5",
@@ -24,7 +24,7 @@ namespace MPF.Test.Library
[Fact]
public void SanitizeFoundProtectionsCactusDataShieldTest()
{
List<string> protections = new List<string>()
List<string> protections = new()
{
"Cactus Data Shield 200",
"Cactus Data Shield 200 (Build 3.0.100a)",
@@ -37,7 +37,7 @@ namespace MPF.Test.Library
[Fact]
public void SanitizeFoundProtectionsCDCheckTest()
{
List<string> protections = new List<string>()
List<string> protections = new()
{
"Anything Else Protection",
"Executable-Based CD Check",
@@ -50,7 +50,7 @@ namespace MPF.Test.Library
[Fact]
public void SanitizeFoundProtectionsCDCopsTest()
{
List<string> protections = new List<string>()
List<string> protections = new()
{
"CD-Cops",
"CD-Cops v1.2.0",
@@ -63,7 +63,7 @@ namespace MPF.Test.Library
[Fact]
public void SanitizeFoundProtectionsCDKeyTest()
{
List<string> protections = new List<string>()
List<string> protections = new()
{
"Anything Else Protection",
"CD-Key / Serial",
@@ -76,7 +76,7 @@ namespace MPF.Test.Library
[Fact]
public void SanitizeFoundProtectionsEACdKeyTest()
{
List<string> protections = new List<string>()
List<string> protections = new()
{
"EA CdKey Registration Module",
"EA CdKey Registration Module v1.2.0",
@@ -89,7 +89,7 @@ namespace MPF.Test.Library
[Fact]
public void SanitizeFoundProtectionsEADRMTest()
{
List<string> protections = new List<string>()
List<string> protections = new()
{
"EA DRM Protection",
"EA DRM Protection v1.2.0",
@@ -102,7 +102,7 @@ namespace MPF.Test.Library
[Fact]
public void SanitizeFoundProtectionsGFWLTest()
{
List<string> protections = new List<string>()
List<string> protections = new()
{
"Games for Windows LIVE",
"Games for Windows LIVE v1.2.0",
@@ -115,7 +115,7 @@ namespace MPF.Test.Library
[Fact]
public void SanitizeFoundProtectionsGFWLZDPPTest()
{
List<string> protections = new List<string>()
List<string> protections = new()
{
"Games for Windows LIVE",
"Games for Windows LIVE Zero Day Piracy Protection",
@@ -128,7 +128,7 @@ namespace MPF.Test.Library
[Fact]
public void SanitizeFoundProtectionsImpulseReactorTest()
{
List<string> protections = new List<string>()
List<string> protections = new()
{
"Impulse Reactor",
"Impulse Reactor Core Module v1.2.0",
@@ -145,7 +145,7 @@ namespace MPF.Test.Library
[InlineData(3)]
public void SanitizeFoundProtectionsJoWoodXProtTest(int skip)
{
List<string> protections = new List<string>()
List<string> protections = new()
{
"JoWood X-Prot 1.2.0.00",
"JoWood X-Prot v2",
@@ -168,7 +168,7 @@ namespace MPF.Test.Library
[Fact]
public void SanitizeFoundProtectionsOnlineRegistrationTest()
{
List<string> protections = new List<string>()
List<string> protections = new()
{
"Anything Else Protection",
"Executable-Based Online Registration",
@@ -185,7 +185,7 @@ namespace MPF.Test.Library
[InlineData(3)]
public void SanitizeFoundProtectionStarForceTest(int skip)
{
List<string> protections = new List<string>()
List<string> protections = new()
{
"StarForce 1.20.000.000",
"StarForce 5 [Protected Module]",
@@ -208,7 +208,7 @@ namespace MPF.Test.Library
[Fact]
public void SanitizeFoundProtectionsSysiphusTest()
{
List<string> protections = new List<string>()
List<string> protections = new()
{
"Sysiphus",
"Sysiphus v1.2.0",
@@ -221,7 +221,7 @@ namespace MPF.Test.Library
[Fact]
public void SanitizeFoundProtectionsXCPTest()
{
List<string> protections = new List<string>()
List<string> protections = new()
{
"XCP",
"XCP v1.2.0",

View File

@@ -1,11 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net48;net6.0-windows;net7.0-windows</TargetFrameworks>
<TargetFrameworks>net6.0-windows;net8.0-windows</TargetFrameworks>
<IsPackable>false</IsPackable>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)'!='net48'">
<Nullable>enable</Nullable>
</PropertyGroup>
@@ -14,18 +11,18 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeCoverage" Version="17.7.2" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.2" />
<PackageReference Include="Microsoft.CodeCoverage" Version="17.9.0-preview-23531-01" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0-preview-23531-01" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="SabreTools.RedumpLib" Version="1.1.1" />
<PackageReference Include="xunit" Version="2.5.3" />
<PackageReference Include="SabreTools.RedumpLib" Version="1.2.0" />
<PackageReference Include="xunit" Version="2.6.1" />
<PackageReference Include="xunit.abstractions" Version="2.0.3" />
<PackageReference Include="xunit.analyzers" Version="1.4.0" />
<PackageReference Include="xunit.assert" Version="2.5.3" />
<PackageReference Include="xunit.core" Version="2.5.3" />
<PackageReference Include="xunit.extensibility.core" Version="2.5.3" />
<PackageReference Include="xunit.extensibility.execution" Version="2.5.3" />
<PackageReference Include="xunit.runner.console" Version="2.5.3">
<PackageReference Include="xunit.analyzers" Version="1.5.0" />
<PackageReference Include="xunit.assert" Version="2.6.1" />
<PackageReference Include="xunit.core" Version="2.6.1" />
<PackageReference Include="xunit.extensibility.core" Version="2.6.1" />
<PackageReference Include="xunit.extensibility.execution" Version="2.6.1" />
<PackageReference Include="xunit.runner.console" Version="2.6.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>

View File

@@ -18,7 +18,7 @@ namespace MPF.Test.Modules
[InlineData(RedumpSystem.SonyPlayStation3, MediaType.BluRay, CommandStrings.BluRay)]
[InlineData(RedumpSystem.AppleMacintosh, MediaType.FloppyDisk, CommandStrings.Floppy)]
[InlineData(RedumpSystem.RawThrillsVarious, MediaType.GDROM, null)]
public void ParametersFromSystemAndTypeTest(RedumpSystem? knownSystem, MediaType? mediaType, string expected)
public void ParametersFromSystemAndTypeTest(RedumpSystem? knownSystem, MediaType? mediaType, string? expected)
{
var options = new Options();
var actual = new Parameters(knownSystem, mediaType, "D:\\", "disc.bin", 16, options);
@@ -29,7 +29,7 @@ namespace MPF.Test.Modules
[InlineData(RedumpSystem.AppleMacintosh, MediaType.LaserDisc, null)] // Deliberately unsupported
[InlineData(RedumpSystem.IBMPCcompatible, MediaType.CDROM, new string[] { FlagStrings.C2Opcode, FlagStrings.NoFixSubQSecuROM, FlagStrings.ScanFileProtect })]
[InlineData(RedumpSystem.NintendoGameCube, MediaType.NintendoGameCubeGameDisc, new string[] { FlagStrings.Raw })]
public void ParametersFromOptionsSpecialDefaultTest(RedumpSystem? knownSystem, MediaType? mediaType,string[] expected)
public void ParametersFromOptionsSpecialDefaultTest(RedumpSystem? knownSystem, MediaType? mediaType, string[]? expected)
{
var options = new Options();
var actual = new Parameters(knownSystem, mediaType, "D:\\", "disc.bin", 16, options);
@@ -147,7 +147,7 @@ namespace MPF.Test.Modules
[InlineData("bd D longer\\path_test.iso 16", true)]
[InlineData("stop D", true)]
[InlineData("ls", false)]
public void ValidateParametersTest(string parameters, bool expected)
public void ValidateParametersTest(string? parameters, bool expected)
{
var actual = new Parameters(parameters);
Assert.Equal(expected, actual.IsValid());
@@ -161,11 +161,7 @@ namespace MPF.Test.Modules
[InlineData(MediaType.FloppyDisk, ".img")]
[InlineData(MediaType.Cassette, ".wav")]
[InlineData(MediaType.NONE, null)]
#if NET48
public void MediaTypeToExtensionTest(MediaType? mediaType, string expected)
#else
public void MediaTypeToExtensionTest(MediaType? mediaType, string? expected)
#endif
{
var actual = Converters.Extension(mediaType);
Assert.Equal(expected, actual);
@@ -219,7 +215,7 @@ namespace MPF.Test.Modules
Assert.Equal(expected, actual);
}
#endregion
#endregion
[Fact]
public void DiscImageCreatorAudioParametersTest()

View File

@@ -95,31 +95,15 @@ namespace MPF.Test.RedumpLib
/// Generate a test set of DiscType values
/// </summary>
/// <returns>MemberData-compatible list of DiscType values</returns>
#if NET48
public static List<object[]> GenerateDiscTypeMappingTestData()
#else
public static List<object?[]> GenerateDiscTypeMappingTestData()
#endif
{
#if NET48
var testData = new List<object[]>() { new object[] { null, true } };
#else
var testData = new List<object?[]>() { new object?[] { null, true } };
#endif
foreach (DiscType? discType in Enum.GetValues(typeof(DiscType)))
{
if (_mappableDiscTypes.Contains(discType))
#if NET48
testData.Add(new object[] { discType, false });
#else
testData.Add(new object?[] { discType, false });
#endif
else
#if NET48
testData.Add(new object[] { discType, true });
#else
testData.Add(new object?[] { discType, true });
#endif
}
return testData;
@@ -129,24 +113,12 @@ namespace MPF.Test.RedumpLib
/// Generate a test set of RedumpSystem values
/// </summary>
/// <returns>MemberData-compatible list of RedumpSystem values</returns>
#if NET48
public static List<object[]> GenerateRedumpSystemMappingTestData()
#else
public static List<object?[]> GenerateRedumpSystemMappingTestData()
#endif
{
#if NET48
var testData = new List<object[]>() { new object[] { null } };
#else
var testData = new List<object?[]>() { new object?[] { null } };
#endif
foreach (RedumpSystem? redumpSystem in Enum.GetValues(typeof(RedumpSystem)))
{
#if NET48
testData.Add(new object[] { redumpSystem });
#else
testData.Add(new object?[] { redumpSystem });
#endif
}
return testData;
@@ -156,32 +128,16 @@ namespace MPF.Test.RedumpLib
/// Generate a test set of mappable media types
/// </summary>
/// <returns>MemberData-compatible list of MediaTypes</returns>
#if NET48
public static List<object[]> GenerateMediaTypeMappingTestData()
#else
public static List<object?[]> GenerateMediaTypeMappingTestData()
#endif
{
#if NET48
var testData = new List<object[]>() { new object[] { null, true } };
#else
var testData = new List<object?[]>() { new object?[] { null, true } };
#endif
foreach (MediaType? mediaType in Enum.GetValues(typeof(MediaType)))
{
if (_mappableMediaTypes.Contains(mediaType))
#if NET48
testData.Add(new object[] { mediaType, false });
#else
testData.Add(new object?[] { mediaType, false });
#endif
else
#if NET48
testData.Add(new object[] { mediaType, true });
#else
testData.Add(new object?[] { mediaType, true });
#endif
}
return testData;
@@ -212,24 +168,12 @@ namespace MPF.Test.RedumpLib
/// Generate a test set of DiscCategory values
/// </summary>
/// <returns>MemberData-compatible list of DiscCategory values</returns>
#if NET48
public static List<object[]> GenerateDiscCategoryTestData()
#else
public static List<object?[]> GenerateDiscCategoryTestData()
#endif
{
#if NET48
var testData = new List<object[]>() { new object[] { null, true } };
#else
var testData = new List<object?[]>() { new object?[] { null, true } };
#endif
foreach (DiscCategory? discCategory in Enum.GetValues(typeof(DiscCategory)))
{
#if NET48
testData.Add(new object[] { discCategory, false });
#else
testData.Add(new object?[] { discCategory, false });
#endif
}
return testData;
@@ -260,31 +204,15 @@ namespace MPF.Test.RedumpLib
/// Generate a test set of DiscType values
/// </summary>
/// <returns>MemberData-compatible list of DiscType values</returns>
#if NET48
public static List<object[]> GenerateDiscTypeTestData()
#else
public static List<object?[]> GenerateDiscTypeTestData()
#endif
{
#if NET48
var testData = new List<object[]>() { new object[] { null, true } };
#else
var testData = new List<object?[]>() { new object?[] { null, true } };
#endif
foreach (DiscType? discType in Enum.GetValues(typeof(DiscType)))
{
if (discType == DiscType.NONE)
#if NET48
testData.Add(new object[] { discType, true });
#else
testData.Add(new object?[] { discType, true });
#endif
else
#if NET48
testData.Add(new object[] { discType, false });
#else
testData.Add(new object?[] { discType, false });
#endif
}
return testData;
@@ -413,24 +341,12 @@ namespace MPF.Test.RedumpLib
/// Generate a test set of Language values
/// </summary>
/// <returns>MemberData-compatible list of Language values</returns>
#if NET48
public static List<object[]> GenerateLanguageTestData()
#else
public static List<object?[]> GenerateLanguageTestData()
#endif
{
#if NET48
var testData = new List<object[]>() { new object[] { null, true } };
#else
var testData = new List<object?[]>() { new object?[] { null, true } };
#endif
foreach (Language? language in Enum.GetValues(typeof(Language)))
{
#if NET48
testData.Add(new object[] { language, false });
#else
testData.Add(new object?[] { language, false });
#endif
}
return testData;
@@ -461,24 +377,12 @@ namespace MPF.Test.RedumpLib
/// Generate a test set of LanguageSelection values
/// </summary>
/// <returns>MemberData-compatible list of LanguageSelection values</returns>
#if NET48
public static List<object[]> GenerateLanguageSelectionTestData()
#else
public static List<object?[]> GenerateLanguageSelectionTestData()
#endif
{
#if NET48
var testData = new List<object[]>() { new object[] { null, true } };
#else
var testData = new List<object?[]>() { new object?[] { null, true } };
#endif
foreach (LanguageSelection? languageSelection in Enum.GetValues(typeof(LanguageSelection)))
{
#if NET48
testData.Add(new object[] { languageSelection, false });
#else
testData.Add(new object?[] { languageSelection, false });
#endif
}
return testData;
@@ -526,24 +430,12 @@ namespace MPF.Test.RedumpLib
/// Generate a test set of MediaType values
/// </summary>
/// <returns>MemberData-compatible list of MediaType values</returns>
#if NET48
public static List<object[]> GenerateMediaTypeTestData()
#else
public static List<object?[]> GenerateMediaTypeTestData()
#endif
{
#if NET48
var testData = new List<object[]>() { new object[] { null, true } };
#else
var testData = new List<object?[]>() { new object?[] { null, true } };
#endif
foreach (MediaType? mediaType in Enum.GetValues(typeof(MediaType)))
{
#if NET48
testData.Add(new object[] { mediaType, false });
#else
testData.Add(new object?[] { mediaType, false });
#endif
}
return testData;
@@ -618,24 +510,12 @@ namespace MPF.Test.RedumpLib
/// Generate a test set of Region values
/// </summary>
/// <returns>MemberData-compatible list of Region values</returns>
#if NET48
public static List<object[]> GenerateRegionTestData()
#else
public static List<object?[]> GenerateRegionTestData()
#endif
{
#if NET48
var testData = new List<object[]>() { new object[] { null, true } };
#else
var testData = new List<object?[]>() { new object?[] { null, true } };
#endif
foreach (Region? region in Enum.GetValues(typeof(Region)))
{
#if NET48
testData.Add(new object[] { region, false });
#else
testData.Add(new object?[] { region, false });
#endif
}
return testData;
@@ -683,24 +563,12 @@ namespace MPF.Test.RedumpLib
/// Generate a test set of SiteCode values
/// </summary>
/// <returns>MemberData-compatible list of SiteCode values</returns>
#if NET48
public static List<object[]> GenerateSiteCodeTestData()
#else
public static List<object?[]> GenerateSiteCodeTestData()
#endif
{
#if NET48
var testData = new List<object[]>() { new object[] { null, true } };
#else
var testData = new List<object?[]>() { new object?[] { null, true } };
#endif
foreach (SiteCode? siteCode in Enum.GetValues(typeof(SiteCode)))
{
#if NET48
testData.Add(new object[] { siteCode, false });
#else
testData.Add(new object?[] { siteCode, false });
#endif
}
return testData;
@@ -754,28 +622,16 @@ namespace MPF.Test.RedumpLib
/// Generate a test set of RedumpSystem values
/// </summary>
/// <returns>MemberData-compatible list of RedumpSystem values</returns>
#if NET48
public static List<object[]> GenerateRedumpSystemTestData()
#else
public static List<object?[]> GenerateRedumpSystemTestData()
#endif
{
#if NET48
var testData = new List<object[]>() { new object[] { null, true } };
#else
var testData = new List<object?[]>() { new object?[] { null, true } };
#endif
foreach (RedumpSystem? redumpSystem in Enum.GetValues(typeof(RedumpSystem)))
{
// We want to skip all markers for this
if (redumpSystem.IsMarker())
continue;
#if NET48
testData.Add(new object[] { redumpSystem, false });
#else
testData.Add(new object?[] { redumpSystem, false });
#endif
}
return testData;
@@ -806,31 +662,15 @@ namespace MPF.Test.RedumpLib
/// Generate a test set of SystemCategory values
/// </summary>
/// <returns>MemberData-compatible list of SystemCategory values</returns>
#if NET48
public static List<object[]> GenerateSystemCategoryTestData()
#else
public static List<object?[]> GenerateSystemCategoryTestData()
#endif
{
#if NET48
var testData = new List<object[]>() { new object[] { null, true } };
#else
var testData = new List<object?[]>() { new object?[] { null, true } };
#endif
foreach (SystemCategory? systemCategory in Enum.GetValues(typeof(SystemCategory)))
{
if (systemCategory == SystemCategory.NONE)
#if NET48
testData.Add(new object[] { systemCategory, true });
#else
testData.Add(new object?[] { systemCategory, true });
#endif
else
#if NET48
testData.Add(new object[] { systemCategory, false });
#else
testData.Add(new object?[] { systemCategory, false });
#endif
}
return testData;
@@ -861,24 +701,12 @@ namespace MPF.Test.RedumpLib
/// Generate a test set of YesNo values
/// </summary>
/// <returns>MemberData-compatible list of YesNo values</returns>
#if NET48
public static List<object[]> GenerateYesNoTestData()
#else
public static List<object?[]> GenerateYesNoTestData()
#endif
{
#if NET48
var testData = new List<object[]>() { new object[] { null, false } };
#else
var testData = new List<object?[]>() { new object?[] { null, false } };
#endif
foreach (YesNo? yesNo in Enum.GetValues(typeof(YesNo)))
{
#if NET48
testData.Add(new object[] { yesNo, false });
#else
testData.Add(new object?[] { yesNo, false });
#endif
}
return testData;

View File

@@ -81,20 +81,12 @@ namespace MPF.Test.RedumpLib
EXEDateBuildDate = "19xx-xx-xx",
ErrorsCount = "0",
Comments = "Comment data line 1\r\nComment data line 2",
#if NET48
CommentsSpecialFields = new Dictionary<SiteCode?, string>()
#else
CommentsSpecialFields = new Dictionary<SiteCode, string>()
#endif
{
[SiteCode.ISBN] = "ISBN",
},
Contents = "Special contents 1\r\nSpecial contents 2",
#if NET48
ContentsSpecialFields = new Dictionary<SiteCode?, string>()
#else
ContentsSpecialFields = new Dictionary<SiteCode, string>()
#endif
{
[SiteCode.PlayableDemos] = "Game Demo 1",
},

View File

@@ -1,5 +1,4 @@
using System.Linq;
using MPF.Core.Data;
using MPF.Core.Data;
using SabreTools.RedumpLib.Data;
using Xunit;
@@ -16,7 +15,7 @@ namespace MPF.Test.Data
public void GetAllowedDriveSpeedForMediaTypeTest(MediaType? mediaType, int maxExpected)
{
var actual = Interface.GetSpeedsForMediaType(mediaType);
Assert.Equal(maxExpected, actual.Last());
Assert.Equal(maxExpected, actual[actual.Count - 1]);
}
}
}

View File

@@ -17,6 +17,6 @@ namespace MPF.UI.Core
public static DoubleCollection SpeedsForHDDVDAsCollection { get; } = GetDoubleCollectionFromIntList(HDDVD);
public static DoubleCollection SpeedsForBDAsCollection { get; } = GetDoubleCollectionFromIntList(BD);
private static DoubleCollection GetDoubleCollectionFromIntList(IReadOnlyList<int> list)
=> new DoubleCollection(list.Select(i => Convert.ToDouble(i)).ToList());
=> new(list.Select(i => Convert.ToDouble(i)).ToList());
}
}

View File

@@ -11,54 +11,34 @@ namespace MPF.UI.Core
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
switch (value)
return value switch
{
case DiscCategory discCategory:
return new Element<DiscCategory>(discCategory);
case InternalProgram internalProgram:
return new Element<InternalProgram>(internalProgram);
case MediaType mediaType:
return new Element<MediaType>(mediaType);
case RedumpSystem redumpSystem:
return new RedumpSystemComboBoxItem(redumpSystem);
case Region region:
return new Element<Region>(region);
DiscCategory discCategory => new Element<DiscCategory>(discCategory),
InternalProgram internalProgram => new Element<InternalProgram>(internalProgram),
MediaType mediaType => new Element<MediaType>(mediaType),
RedumpSystem redumpSystem => new RedumpSystemComboBoxItem(redumpSystem),
Region region => new Element<Region>(region),
// Null values are treated as a system value
default:
return new RedumpSystemComboBoxItem((RedumpSystem?)null);
}
_ => new RedumpSystemComboBoxItem((RedumpSystem?)null),
};
}
#if NET48
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
#else
public object? ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
#endif
{
// If it's an IElement but ends up null
#if NET48
if (!(value is IElement element))
#else
if (value is not IElement element)
#endif
return null;
switch (element)
return element switch
{
case Element<DiscCategory> dcElement:
return dcElement.Value;
case Element<InternalProgram> ipElement:
return ipElement.Value;
case Element<MediaType> mtElement:
return mtElement.Value;
case RedumpSystemComboBoxItem rsElement:
return rsElement.Value;
case Element<Region> reValue:
return reValue.Value;
default: return null;
}
Element<DiscCategory> dcElement => dcElement.Value,
Element<InternalProgram> ipElement => ipElement.Value,
Element<MediaType> mtElement => mtElement.Value,
RedumpSystemComboBoxItem rsElement => rsElement.Value,
Element<Region> reValue => reValue.Value,
_ => null,
};
}
}
}

View File

@@ -173,11 +173,7 @@ namespace WPFCustomMessageBox
/// </param>
/// <param name="timeoutResult">If the message box closes automatically due to the <paramref name="timeout"/> being exceeded, this result is returned.</param>
/// <returns>A System.Windows.MessageBoxResult value that specifies which message box button is clicked by the user.</returns>
#if NET48
public static MessageBoxResult Show(Window owner, string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, int? timeout = null, MessageBoxResult timeoutResult = MessageBoxResult.None)
#else
public static MessageBoxResult Show(Window owner, string? messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, int? timeout = null, MessageBoxResult timeoutResult = MessageBoxResult.None)
#endif
{
switch (button)
{
@@ -519,11 +515,7 @@ namespace WPFCustomMessageBox
/// <param name="timeout">The message box will close automatically after given milliseconds</param>
/// <param name="timeoutResult">If the message box closes automatically due to <paramref name="timeout"/> being exceeded, this result is returned.</param>
/// <returns>A System.Windows.MessageBoxResult value that specifies which message box button is clicked by the user.</returns>
#if NET48
private static MessageBoxResult ShowOKMessage(Window owner, string messageBoxText, string caption, string okButtonText, string cancelButtonText, MessageBoxImage? icon, int? timeout = null, MessageBoxResult timeoutResult = MessageBoxResult.None)
#else
private static MessageBoxResult ShowOKMessage(Window? owner, string? messageBoxText, string caption, string? okButtonText, string? cancelButtonText, MessageBoxImage? icon, int? timeout = null, MessageBoxResult timeoutResult = MessageBoxResult.None)
#endif
{
MessageBoxButton buttonLayout = string.IsNullOrEmpty(cancelButtonText) ? MessageBoxButton.OK : MessageBoxButton.OKCancel;
@@ -553,11 +545,7 @@ namespace WPFCustomMessageBox
/// <param name="timeout">The message box will close automatically after given milliseconds</param>
/// <param name="timeoutResult">If the message box closes automatically due to <paramref name="timeout"/> being exceeded, this result is returned.</param>
/// <returns>A System.Windows.MessageBoxResult value that specifies which message box button is clicked by the user.</returns>
#if NET48
private static MessageBoxResult ShowYesNoMessage(Window owner, string messageBoxText, string caption, string yesButtonText, string noButtonText, string cancelButtonText, MessageBoxImage? icon, int? timeout = null, MessageBoxResult timeoutResult = MessageBoxResult.None)
#else
private static MessageBoxResult ShowYesNoMessage(Window? owner, string? messageBoxText, string caption, string? yesButtonText, string? noButtonText, string? cancelButtonText, MessageBoxImage? icon, int? timeout = null, MessageBoxResult timeoutResult = MessageBoxResult.None)
#endif
{
MessageBoxButton buttonLayout = string.IsNullOrEmpty(cancelButtonText) ? MessageBoxButton.YesNo : MessageBoxButton.YesNoCancel;

View File

@@ -12,11 +12,7 @@ namespace WPFCustomMessageBox
{
private readonly bool _removeTitleBarIcon = true;
#if NET48
public string Caption
#else
public string? Caption
#endif
{
get
{
@@ -28,11 +24,7 @@ namespace WPFCustomMessageBox
}
}
#if NET48
public string Message
#else
public string? Message
#endif
{
get
{
@@ -44,11 +36,7 @@ namespace WPFCustomMessageBox
}
}
#if NET48
public string OkButtonText
#else
public string? OkButtonText
#endif
{
get
{
@@ -60,11 +48,7 @@ namespace WPFCustomMessageBox
}
}
#if NET48
public string CancelButtonText
#else
public string? CancelButtonText
#endif
{
get
{
@@ -76,11 +60,7 @@ namespace WPFCustomMessageBox
}
}
#if NET48
public string YesButtonText
#else
public string? YesButtonText
#endif
{
get
{
@@ -92,11 +72,7 @@ namespace WPFCustomMessageBox
}
}
#if NET48
public string NoButtonText
#else
public string? NoButtonText
#endif
{
get
{
@@ -110,11 +86,7 @@ namespace WPFCustomMessageBox
public MessageBoxResult Result { get; set; }
#if NET48
internal CustomMessageBoxWindow(Window owner, string message, string caption = null, MessageBoxButton? button = null, MessageBoxImage? image = null, bool removeTitleBarIcon = true)
#else
internal CustomMessageBoxWindow(Window? owner, string? message, string? caption = null, MessageBoxButton? button = null, MessageBoxImage? image = null, bool removeTitleBarIcon = true)
#endif
{
InitializeComponent();

View File

@@ -60,11 +60,7 @@ namespace WPFCustomMessageBox
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
#if NET48
internal static string TryAddKeyboardAccellerator(this string input)
#else
internal static string? TryAddKeyboardAccellerator(this string? input)
#endif
{
if (input == null)
return input;

View File

@@ -1,17 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<TargetFrameworks>net48;net6.0-windows;net7.0-windows</TargetFrameworks>
<TargetFrameworks>net6.0-windows;net8.0-windows</TargetFrameworks>
<RuntimeIdentifiers>win-x64</RuntimeIdentifiers>
<UseWindowsForms>true</UseWindowsForms>
<UseWPF>true</UseWPF>
<Nullable>enable</Nullable>
<Authors>Matt Nadareski;ReignStumble;Jakz</Authors>
<Copyright>Copyright (c)2019-2023</Copyright>
<VersionPrefix>2.7.5</VersionPrefix>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)'!='net48'">
<Nullable>enable</Nullable>
<VersionPrefix>3.0.0</VersionPrefix>
</PropertyGroup>
<ItemGroup>
@@ -23,12 +20,8 @@
<ProjectReference Include="..\MPF.Core\MPF.Core.csproj" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)'=='net48'">
<Reference Include="PresentationFramework.Aero" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="SabreTools.RedumpLib" Version="1.1.1" />
<PackageReference Include="SabreTools.RedumpLib" Version="1.2.0" />
</ItemGroup>
<ItemGroup>

View File

@@ -13,56 +13,32 @@ namespace MPF.UI.Core
/// <summary>
/// SolidColorBrush used to paint the active window's border.
/// </summary>
#if NET48
public SolidColorBrush ActiveBorderBrush { get; protected set; }
#else
public SolidColorBrush? ActiveBorderBrush { get; protected set; }
#endif
/// <summary>
/// SolidColorBrush that paints the face of a three-dimensional display element.
/// </summary>
#if NET48
public SolidColorBrush ControlBrush { get; protected set; }
#else
public SolidColorBrush? ControlBrush { get; protected set; }
#endif
/// <summary>
/// SolidColorBrush that paints text in a three-dimensional display element.
/// </summary>
#if NET48
public SolidColorBrush ControlTextBrush { get; protected set; }
#else
public SolidColorBrush? ControlTextBrush { get; protected set; }
#endif
/// <summary>
/// SolidColorBrush that paints disabled text.
/// </summary>
#if NET48
public SolidColorBrush GrayTextBrush { get; protected set; }
#else
public SolidColorBrush? GrayTextBrush { get; protected set; }
#endif
/// <summary>
/// SolidColorBrush that paints the background of a window's client area.
/// </summary>
#if NET48
public SolidColorBrush WindowBrush { get; protected set; }
#else
public SolidColorBrush? WindowBrush { get; protected set; }
#endif
/// <summary>
/// SolidColorBrush that paints the text in the client area of a window.
/// </summary>
#if NET48
public SolidColorBrush WindowTextBrush { get; protected set; }
#else
public SolidColorBrush? WindowTextBrush { get; protected set; }
#endif
#endregion
@@ -71,38 +47,22 @@ namespace MPF.UI.Core
/// <summary>
/// Brush for the Button.Disabled.Background resource
/// </summary>
#if NET48
public Brush Button_Disabled_Background { get; protected set; }
#else
public Brush? Button_Disabled_Background { get; protected set; }
#endif
/// <summary>
/// Brush for the Button.MouseOver.Background resource
/// </summary>
#if NET48
public Brush Button_MouseOver_Background { get; protected set; }
#else
public Brush? Button_MouseOver_Background { get; protected set; }
#endif
/// <summary>
/// Brush for the Button.Pressed.Background resource
/// </summary>
#if NET48
public Brush Button_Pressed_Background { get; protected set; }
#else
public Brush? Button_Pressed_Background { get; protected set; }
#endif
/// <summary>
/// Brush for the Button.Static.Background resource
/// </summary>
#if NET48
public Brush Button_Static_Background { get; protected set; }
#else
public Brush? Button_Static_Background { get; protected set; }
#endif
#endregion
@@ -111,110 +71,62 @@ namespace MPF.UI.Core
/// <summary>
/// Brush for the ComboBox.Disabled.Background resource
/// </summary>
#if NET48
public Brush ComboBox_Disabled_Background { get; protected set; }
#else
public Brush? ComboBox_Disabled_Background { get; protected set; }
#endif
/// <summary>
/// Brush for the ComboBox.Disabled.Editable.Background resource
/// </summary>
#if NET48
public Brush ComboBox_Disabled_Editable_Background { get; protected set; }
#else
public Brush? ComboBox_Disabled_Editable_Background { get; protected set; }
#endif
/// <summary>
/// Brush for the ComboBox.Disabled.Editable.Button.Background resource
/// </summary>
#if NET48
public Brush ComboBox_Disabled_Editable_Button_Background { get; protected set; }
#else
public Brush? ComboBox_Disabled_Editable_Button_Background { get; protected set; }
#endif
/// <summary>
/// Brush for the ComboBox.MouseOver.Background resource
/// </summary>
#if NET48
public Brush ComboBox_MouseOver_Background { get; protected set; }
#else
public Brush? ComboBox_MouseOver_Background { get; protected set; }
#endif
/// <summary>
/// Brush for the ComboBox.MouseOver.Editable.Background resource
/// </summary>
#if NET48
public Brush ComboBox_MouseOver_Editable_Background { get; protected set; }
#else
public Brush? ComboBox_MouseOver_Editable_Background { get; protected set; }
#endif
/// <summary>
/// Brush for the ComboBox.MouseOver.Editable.Button.Background resource
/// </summary>
#if NET48
public Brush ComboBox_MouseOver_Editable_Button_Background { get; protected set; }
#else
public Brush? ComboBox_MouseOver_Editable_Button_Background { get; protected set; }
#endif
/// <summary>
/// Brush for the ComboBox.Pressed.Background resource
/// </summary>
#if NET48
public Brush ComboBox_Pressed_Background { get; protected set; }
#else
public Brush? ComboBox_Pressed_Background { get; protected set; }
#endif
/// <summary>
/// Brush for the ComboBox.Pressed.Editable.Background resource
/// </summary>
#if NET48
public Brush ComboBox_Pressed_Editable_Background { get; protected set; }
#else
public Brush? ComboBox_Pressed_Editable_Background { get; protected set; }
#endif
/// <summary>
/// Brush for the ComboBox.Pressed.Editable.Button.Background resource
/// </summary>
#if NET48
public Brush ComboBox_Pressed_Editable_Button_Background { get; protected set; }
#else
public Brush? ComboBox_Pressed_Editable_Button_Background { get; protected set; }
#endif
/// <summary>
/// Brush for the ComboBox.Static.Background resource
/// </summary>
#if NET48
public Brush ComboBox_Static_Background { get; protected set; }
#else
public Brush? ComboBox_Static_Background { get; protected set; }
#endif
/// <summary>
/// Brush for the ComboBox.Static.Editable.Background resource
/// </summary>
#if NET48
public Brush ComboBox_Static_Editable_Background { get; protected set; }
#else
public Brush? ComboBox_Static_Editable_Background { get; protected set; }
#endif
/// <summary>
/// Brush for the ComboBox.Static.Editable.Button.Background resource
/// </summary>
#if NET48
public Brush ComboBox_Static_Editable_Button_Background { get; protected set; }
#else
public Brush? ComboBox_Static_Editable_Button_Background { get; protected set; }
#endif
#endregion
@@ -223,11 +135,7 @@ namespace MPF.UI.Core
/// <summary>
/// Brush for the CustomMessageBox.Static.Background resource
/// </summary>
#if NET48
public Brush CustomMessageBox_Static_Background { get; protected set; }
#else
public Brush? CustomMessageBox_Static_Background { get; protected set; }
#endif
#endregion
@@ -236,20 +144,12 @@ namespace MPF.UI.Core
/// <summary>
/// Brush for the MenuItem.SubMenu.Background resource
/// </summary>
#if NET48
public Brush MenuItem_SubMenu_Background { get; protected set; }
#else
public Brush? MenuItem_SubMenu_Background { get; protected set; }
#endif
/// <summary>
/// Brush for the MenuItem.SubMenu.Border resource
/// </summary>
#if NET48
public Brush MenuItem_SubMenu_Border { get; protected set; }
#else
public Brush? MenuItem_SubMenu_Border { get; protected set; }
#endif
#endregion
@@ -258,11 +158,7 @@ namespace MPF.UI.Core
/// <summary>
/// Brush for the ProgressBar.Background resource
/// </summary>
#if NET48
public Brush ProgressBar_Background { get; protected set; }
#else
public Brush? ProgressBar_Background { get; protected set; }
#endif
#endregion
@@ -271,11 +167,7 @@ namespace MPF.UI.Core
/// <summary>
/// Brush for the ScrollViewer.ScrollBar.Background resource
/// </summary>
#if NET48
public Brush ScrollViewer_ScrollBar_Background { get; protected set; }
#else
public Brush? ScrollViewer_ScrollBar_Background { get; protected set; }
#endif
#endregion
@@ -284,29 +176,17 @@ namespace MPF.UI.Core
/// <summary>
/// Brush for the TabItem.Selected.Background resource
/// </summary>
#if NET48
public Brush TabItem_Selected_Background { get; protected set; }
#else
public Brush? TabItem_Selected_Background { get; protected set; }
#endif
/// <summary>
/// Brush for the TabItem.Static.Background resource
/// </summary>
#if NET48
public Brush TabItem_Static_Background { get; protected set; }
#else
public Brush? TabItem_Static_Background { get; protected set; }
#endif
/// <summary>
/// Brush for the TabItem.Static.Border resource
/// </summary>
#if NET48
public Brush TabItem_Static_Border { get; protected set; }
#else
public Brush? TabItem_Static_Border { get; protected set; }
#endif
#endregion
@@ -315,11 +195,7 @@ namespace MPF.UI.Core
/// <summary>
/// Brush for the TextBox.Static.Background resource
/// </summary>
#if NET48
public Brush TextBox_Static_Background { get; protected set; }
#else
public Brush? TextBox_Static_Background { get; protected set; }
#endif
#endregion

View File

@@ -29,11 +29,7 @@ namespace MPF.UI.Core.UserControls
/// <summary>
/// Cached value of the last line written
/// </summary>
#if NET48
private Run lastLine = null;
#else
private Run? lastLine = null;
#endif
public LogOutput()
{
@@ -168,11 +164,7 @@ namespace MPF.UI.Core.UserControls
{
Dispatcher.Invoke(() =>
{
#if NET48
if (lastLine == null) lastLine = new Run();
#else
lastLine ??= new Run();
#endif
lastLine.Text = logLine.Text;
lastLine.Foreground = logLine.GetForegroundColor();
});

View File

@@ -20,11 +20,7 @@ namespace MPF.UI.Core.Windows
/// <summary>
/// Constructor
/// </summary>
#if NET48
public DiscInformationWindow(Options options, SubmissionInfo submissionInfo)
#else
public DiscInformationWindow(Options options, SubmissionInfo? submissionInfo)
#endif
{
InitializeComponent();
DataContext = new DiscInformationViewModel(options, submissionInfo);
@@ -51,11 +47,7 @@ namespace MPF.UI.Core.Windows
/// <summary>
/// Manipulate fields based on the current disc
/// </summary>
#if NET48
private void ManipulateFields(Options options, SubmissionInfo submissionInfo)
#else
private void ManipulateFields(Options options, SubmissionInfo? submissionInfo)
#endif
{
// Enable tabs in all fields, if required
if (options.EnableTabsInInputFields)
@@ -123,11 +115,7 @@ namespace MPF.UI.Core.Windows
/// </summary>
/// TODO: Figure out how to bind the PartiallyMatchedIDs array to a text box
/// TODO: Convert visibility to a binding
#if NET48
private void HideReadOnlyFields(SubmissionInfo submissionInfo)
#else
private void HideReadOnlyFields(SubmissionInfo? submissionInfo)
#endif
{
// If there's no submission information
if (submissionInfo == null)
@@ -195,11 +183,7 @@ namespace MPF.UI.Core.Windows
/// Update visible fields and sections based on the media type
/// </summary>
/// TODO: See if these can be done by binding
#if NET48
private void UpdateFromDiscType(SubmissionInfo submissionInfo)
#else
private void UpdateFromDiscType(SubmissionInfo? submissionInfo)
#endif
{
// Sony-printed discs have layers in the opposite order
var system = submissionInfo?.CommonDiscInfo?.System;
@@ -346,11 +330,7 @@ namespace MPF.UI.Core.Windows
/// Update visible fields and sections based on the system type
/// </summary>
/// TODO: See if these can be done by binding
#if NET48
private void UpdateFromSystemType(SubmissionInfo submissionInfo)
#else
private void UpdateFromSystemType(SubmissionInfo? submissionInfo)
#endif
{
var system = submissionInfo?.CommonDiscInfo?.System;
switch (system)

View File

@@ -155,44 +155,27 @@ namespace MPF.UI.Core.Windows
public bool? DisplayUserMessage(string title, string message, int optionCount, bool flag)
{
// Set the correct button style
MessageBoxButton button;
switch (optionCount)
var button = optionCount switch
{
case 1:
button = MessageBoxButton.OK;
break;
case 2:
button = MessageBoxButton.YesNo;
break;
case 3:
button = MessageBoxButton.YesNoCancel;
break;
1 => MessageBoxButton.OK,
2 => MessageBoxButton.YesNo,
3 => MessageBoxButton.YesNoCancel,
// This should not happen, but default to "OK"
default:
button = MessageBoxButton.OK;
break;
}
_ => MessageBoxButton.OK,
};
// Set the correct icon
MessageBoxImage image = flag ? MessageBoxImage.Question : MessageBoxImage.Exclamation;
// Display and get the result
MessageBoxResult result = CustomMessageBox.Show(this, message, title, button, image);
switch (result)
return result switch
{
case MessageBoxResult.OK:
case MessageBoxResult.Yes:
return true;
case MessageBoxResult.No:
return false;
case MessageBoxResult.Cancel:
case MessageBoxResult.None:
default:
return null;
}
MessageBoxResult.OK or MessageBoxResult.Yes => true,
MessageBoxResult.No => false,
_ => null,
};
}
/// <summary>
@@ -210,11 +193,7 @@ namespace MPF.UI.Core.Windows
/// </summary>
/// <param name="submissionInfo">SubmissionInfo object to display and possibly change</param>
/// <returns>Dialog open result</returns>
#if NET48
public (bool?, SubmissionInfo) ShowDiscInformationWindow(SubmissionInfo submissionInfo)
#else
public (bool?, SubmissionInfo?) ShowDiscInformationWindow(SubmissionInfo? submissionInfo)
#endif
{
if (MainViewModel.Options.ShowDiscEjectReminder)
CustomMessageBox.Show(this, "It is now safe to eject the disc", "Eject", MessageBoxButton.OK, MessageBoxImage.Information);
@@ -233,27 +212,15 @@ namespace MPF.UI.Core.Windows
// Copy back the submission info changes, if necessary
if (result == true)
#if NET48
submissionInfo = discInformationWindow.DiscInformationViewModel.SubmissionInfo.Clone() as SubmissionInfo;
#else
submissionInfo = (discInformationWindow.DiscInformationViewModel.SubmissionInfo.Clone() as SubmissionInfo)!;
#endif
#if NET48
return (result, submissionInfo);
#else
return (result, submissionInfo!);
#endif
}
/// <summary>
/// Show the Options window
/// </summary>
#if NET48
public void ShowOptionsWindow(string title = null)
#else
public void ShowOptionsWindow(string? title = null)
#endif
{
var optionsWindow = new OptionsWindow(MainViewModel.Options)
{
@@ -291,11 +258,7 @@ namespace MPF.UI.Core.Windows
/// <summary>
/// Handler for OptionsWindow OnUpdated event
/// </summary>
#if NET48
public void OnOptionsUpdated(object sender, EventArgs e)
#else
public void OnOptionsUpdated(object? sender, EventArgs e)
#endif
{
// Get the options window
var optionsWindow = (sender as OptionsWindow);

View File

@@ -58,22 +58,14 @@ namespace MPF.UI.Core.Windows
/// <summary>
/// Browse and set a path based on the invoking button
/// </summary>
#if NET48
private void BrowseForPath(Window parent, System.Windows.Controls.Button button)
#else
private void BrowseForPath(Window parent, System.Windows.Controls.Button? button)
#endif
{
// If the button is null, we can't do anything
if (button == null)
return;
// Strips button prefix to obtain the setting name
#if NET48
string pathSettingName = button.Name.Substring(0, button.Name.IndexOf("Button"));
#else
string pathSettingName = button.Name[..button.Name.IndexOf("Button")];
#endif
// TODO: hack for now, then we'll see
bool shouldBrowseForPath = pathSettingName == "DefaultOutputPath";
@@ -130,30 +122,18 @@ namespace MPF.UI.Core.Windows
/// </summary>
/// <param name="name">Setting name to find</param>
/// <returns>TextBox for that setting</returns>
#if NET48
private static System.Windows.Controls.TextBox TextBoxForPathSetting(Window parent, string name) =>
#else
private static System.Windows.Controls.TextBox? TextBoxForPathSetting(Window parent, string name) =>
#endif
parent.FindName(name + "TextBox") as System.Windows.Controls.TextBox;
/// <summary>
/// Create an open folder dialog box
/// </summary>
#if NET48
private static FolderBrowserDialog CreateFolderBrowserDialog() => new FolderBrowserDialog();
#else
private static FolderBrowserDialog CreateFolderBrowserDialog() => new();
#endif
/// <summary>
/// Create an open file dialog box
/// </summary>
#if NET48
private static OpenFileDialog CreateOpenFileDialog(string initialDirectory)
#else
private static OpenFileDialog CreateOpenFileDialog(string? initialDirectory)
#endif
{
return new OpenFileDialog()
{
@@ -167,17 +147,9 @@ namespace MPF.UI.Core.Windows
/// <summary>
/// Test Redump credentials for validity
/// </summary>
#if NET48
private void ValidateRedumpCredentials()
#else
private async Task ValidateRedumpCredentials()
#endif
{
#if NET48
(bool? success, string message) = OptionsViewModel.TestRedumpLogin(RedumpUsernameTextBox.Text, RedumpPasswordBox.Password);
#else
(bool? success, string? message) = await OptionsViewModel.TestRedumpLogin(RedumpUsernameTextBox.Text, RedumpPasswordBox.Password);
#endif
(bool? success, string? message) = await MPF.Core.UI.ViewModels.OptionsViewModel.TestRedumpLogin(RedumpUsernameTextBox.Text, RedumpPasswordBox.Password);
if (success == true)
CustomMessageBox.Show(this, message, "Success", MessageBoxButton.OK, MessageBoxImage.Information);
@@ -226,11 +198,7 @@ namespace MPF.UI.Core.Windows
/// <summary>
/// Test Redump credentials for validity
/// </summary>
#if NET48
private void OnRedumpTestClick(object sender, EventArgs e) => ValidateRedumpCredentials();
#else
private async void OnRedumpTestClick(object sender, EventArgs e) => await ValidateRedumpCredentials();
#endif
#endregion
}

View File

@@ -1,24 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<TargetFrameworks>net48;net6.0-windows;net7.0-windows</TargetFrameworks>
<TargetFrameworks>net6.0-windows;net8.0-windows</TargetFrameworks>
<RuntimeIdentifiers>win-x64</RuntimeIdentifiers>
<OutputType>WinExe</OutputType>
<UseWindowsForms>true</UseWindowsForms>
<UseWPF>true</UseWPF>
<Nullable>enable</Nullable>
<ApplicationIcon>Images\Icon.ico</ApplicationIcon>
<Title>MPF</Title>
<Description>Frontend for various dumping programs</Description>
<Authors>Matt Nadareski;ReignStumble;Jakz</Authors>
<Copyright>Copyright (c)2019-2023</Copyright>
<VersionPrefix>2.7.5</VersionPrefix>
<VersionPrefix>3.0.0</VersionPrefix>
<InternalsVisibleTo>MPF.Test</InternalsVisibleTo>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)'!='net48'">
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<Resource Include="Images\Icon.ico" />
</ItemGroup>
@@ -28,19 +25,15 @@
<ProjectReference Include="..\MPF.UI.Core\MPF.UI.Core.csproj" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)'=='net48'">
<Reference Include="PresentationFramework.Aero" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="BurnOutSharp" PrivateAssets="build; analyzers" ExcludeAssets="contentFiles" Version="2.9.0" GeneratePathProperty="true">
<PackageReference Include="BinaryObjectScanner" PrivateAssets="build; analyzers" ExcludeAssets="contentFiles" Version="3.0.0" GeneratePathProperty="true">
<IncludeAssets>runtime; compile; build; native; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="SabreTools.RedumpLib" Version="1.1.1" />
<PackageReference Include="SabreTools.RedumpLib" Version="1.2.0" />
</ItemGroup>
<ItemGroup>
<Content Include="$(PkgBurnOutSharp)\content\**" PackagePath="contentFiles\any\any;content" CopyToOutputDirectory="Always" PackageCopyToOutput="true" />
<Content Include="$(PkgBinaryObjectScanner)\content\**" PackagePath="contentFiles\any\any;content" CopyToOutputDirectory="Always" PackageCopyToOutput="true" />
</ItemGroup>
</Project>

View File

@@ -8,66 +8,64 @@ This is a community project, so if you have some time and knowledge to give, we'
## Releases
For those who would rather use the most recent stable build, download the latest release here:
[Releases Page](https://github.com/SabreTools/MPF/releases)
For the most recent stable build, download the latest release here: [Releases Page](https://github.com/SabreTools/MPF/releases)
For those who like to test the newest features, download the latest AppVeyor WIP build here: [AppVeyor](https://ci.appveyor.com/project/mnadareski/MPF/build/artifacts)
For the latest AppVeyor WIP build here: [AppVeyor](https://ci.appveyor.com/project/mnadareski/MPF/build/artifacts)
## Media Preservation Frontend (MPF)
## Media Preservation Frontend UI (MPF)
MPF is the main, UI-centric application of the MPF suite. This program allows users to use Redumper, Aaru, or DiscImageCreator in a more user-friendly way. Each backend dumping program is supported as fully as possible to ensure that all information is captured on output. There are many customization options and quality of life settings that can be access through the Options menu.
### System Requirements
- Windows 8.1 (x64) or newer
- Users who wish to use MPF on Windows 7 need to disable strong name validation due to `Microsoft.Management.Infrastructure` being unsigned. Add the following registry keys (accurate at time of writing):
```
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\StrongName\Verification\*,31bf3856ad364e35]
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\StrongName\Verification\*,31bf3856ad364e35]
```
- Alternatively, look at this [StackOverflow question](https://stackoverflow.com/questions/403731/strong-name-validation-failed) for more information.
- .NET Framework 4.8, .NET 6.0, or .NET 7.0 Runtimes
- As much hard drive space as the amount of discs you will be dumping (20+ GB recommended)
Ensure that your operating system is as up-to-date as possible, since some features may rely on those updates.
### Support Limitations
The main UI has some known limitations that are documented in code and in some prior support tickets:
- Windows-only due to reliance on WPF and Winforms
- MAUI is not a viable alternative due to lack of out-of-box support for Linux
- Avalonia is being heavily considered as an alternative
### Build Instructions
To build for .NET Framework 4.8, .NET 6.0, or .NET 7.0 (all Windows only), ensure that the .NET 7.0 SDK (or later) is installed and included in your PATH. Then, run the following commands from command prompt, Powershell, or Terminal:
```
dotnet build MPF\MPF.csproj --framework [net48|net6.0-windows|net7.0-windows] --runtime win-x64 --self-contained
```
You may also run `publish-win.bat` (on Windows) or `publish-nix.sh` (on Linux) to build and package all variants MPF and MPF.Check at once. The Windows script additionally requires 7-zip commandline, Git for Windows, and .NET Framework 4.8 SDK to be installed and in PATH. The Linux script additionally requires `zip` and Git to be installed and in PATH.
- MAUI is not a viable alternative due to lack of out-of-box support for Linux
- Avalonia is being heavily considered as an alternative
- For those who need .NET Framework 4.8, there is an official fork: [MPF Legacy](https://github.com/Deterous/MPF-Legacy)
## Media Preservation Frontend Checker (MPF.Check)
MPF.Check is a commandline-only program that allows users to generate submission information from their personal rips. This program supports the outputs from Redumper, Aaru, DiscImageCreator, Cleanrip, and UmdImageCreator. Running this program without any parameters will display the help text, including all supported parameters.
### System Requirements
## System Requirements
- Windows 8.1 (x64) or newer, GNU/Linux x64, or OSX x64
- .NET Framework 4.8 (Windows or `mono` only), .NET 6.0, or .NET 7.0 Runtimes
Both MPF UI and MPF.Check have the same system requirements for running, with the exception that MPF UI is Windows-only.
### Build Instructions
- [Supported OS versions for .NET 6](https://github.com/dotnet/core/blob/main/release-notes/6.0/supported-os.md)
- Requires [.NET 6.0 Runtime](https://dotnet.microsoft.com/en-us/download/dotnet/6.0) if built without bundled runtime
- [Supported OS versions for .NET 8](https://github.com/dotnet/core/blob/main/release-notes/8.0/supported-os.md)
- Requires [.NET 8.0 Runtime](https://dotnet.microsoft.com/en-us/download/dotnet/8.0) if built without bundled runtime
To build for .NET Framework 4.8 (Windows only), .NET 6.0, and .NET 7.0 (both all supported OSes), ensure that the .NET 7.0 SDK (or later) is installed and included in your PATH. Then, run the following commands from command prompt, Powershell, Terminal, or shell:
Ensure that your operating system and runtimes are as up-to-date as possible, since some features may rely on those updates.
```
dotnet build MPF.Check\MPF.Check.csproj --framework [net48|net6.0|net7.0] --runtime [win-x64|linux-x64|osx-x64] --self-contained
## Build Instructions
To build for .NET 6.0 or .NET 8.0, ensure that the [.NET 8.0 SDK](https://dotnet.microsoft.com/en-us/download/dotnet/8.0) (or later) is installed and included in your `PATH`. Then, run the following commands from command prompt, Powershell, Terminal, or shell:
**MPF UI (Windows only):**
```bash
dotnet build MPF/MPF.csproj --framework [net6.0-windows|net8.0-windows] --runtime win-x64
```
Choose one of `[win-x64|linux-x64|osx-x64]` depending on the machine you are targeting.
**MPF.Check (Windows, OSX, Linux):**
```bash
dotnet build MPF.Check/MPF.Check.csproj --framework [net6.0|net8.0] --runtime [win-x64|linux-x64|osx-x64]
```
Choose one of `win-x64`, `linux-x64`, or `osx-x64` depending on the machine you are targeting.
### Build Scripts
Windows users may run `publish-win.bat` and Linux users may run `publish-nix.sh` to perform a full release build.
- `publish-win.bat` will build and package all variants of MPF UI and MPF.Check
- The script requires [7-zip commandline](https://www.7-zip.org/download.html) and [Git for Windows](https://git-scm.com/downloads) to be installed and in `PATH`
- `publish-nix.sh` will _only_ build and package all variants of MPF.Check
- The script requires `zip` and `git` to be installed and in `PATH`
## Information
@@ -81,8 +79,7 @@ A list of all changes in each stable release and current WIP builds can now be f
MPF uses some external libraries to assist with additional information gathering after the dumping process.
- **BurnOutSharp** - Protection scanning - [GitHub](https://github.com/mnadareski/BurnOutSharp)
- **UnshieldSharp** - Protection scanning - [GitHub](https://github.com/mnadareski/UnshieldSharp)
- **BinaryObjectScanner** - Protection scanning - [GitHub](https://github.com/SabreTools/BinaryObjectScanner)
- **WPFCustomMessageBox.thabse** - Custom message boxes in UI - [GitHub](https://github.com/thabse/WPFCustomMessageBox)
## Contributors

View File

@@ -1,5 +1,5 @@
# version format
version: 2.7.5-{build}
version: 3.0.0-{build}
# pull request template
pull_requests:
@@ -12,14 +12,6 @@ image: Visual Studio 2022
build_script:
- dotnet restore
# .NET Framework 4.8 Debug
- dotnet publish MPF\MPF.csproj -f net48 -r win7-x64 -c Debug --self-contained true --version-suffix %APPVEYOR_REPO_COMMIT%
- dotnet publish MPF.Check\MPF.Check.csproj -f net48 -r win7-x64 -c Debug --self-contained true --version-suffix %APPVEYOR_REPO_COMMIT%
# .NET Framework 4.8 Release
- dotnet publish MPF\MPF.csproj -f net48 -r win7-x64 -c Release --self-contained true --version-suffix %APPVEYOR_REPO_COMMIT% -p:DebugType=None -p:DebugSymbols=false
- dotnet publish MPF.Check\MPF.Check.csproj -f net48 -r win7-x64 -c Release --self-contained true --version-suffix %APPVEYOR_REPO_COMMIT% -p:DebugType=None -p:DebugSymbols=false
# .NET 6.0 Debug
- dotnet publish MPF\MPF.csproj -f net6.0-windows -r win-x64 -c Debug --self-contained true --version-suffix %APPVEYOR_REPO_COMMIT% -p:PublishSingleFile=true
- dotnet publish MPF.Check\MPF.Check.csproj -f net6.0 -r win-x64 -c Debug --self-contained true --version-suffix %APPVEYOR_REPO_COMMIT% -p:PublishSingleFile=true
@@ -32,44 +24,44 @@ build_script:
- dotnet publish MPF.Check\MPF.Check.csproj -f net6.0 -r linux-x64 -c Release --self-contained true --version-suffix %APPVEYOR_REPO_COMMIT% -p:PublishSingleFile=true -p:DebugType=None -p:DebugSymbols=false
- dotnet publish MPF.Check\MPF.Check.csproj -f net6.0 -r osx-x64 -c Release --self-contained true --version-suffix %APPVEYOR_REPO_COMMIT% -p:PublishSingleFile=true -p:DebugType=None -p:DebugSymbols=false
# .NET 7.0 Debug
- dotnet publish MPF\MPF.csproj -f net7.0-windows -r win-x64 -c Debug --self-contained true --version-suffix %APPVEYOR_REPO_COMMIT% -p:PublishSingleFile=true
- dotnet publish MPF.Check\MPF.Check.csproj -f net7.0 -r win-x64 -c Debug --self-contained true --version-suffix %APPVEYOR_REPO_COMMIT% -p:PublishSingleFile=true
- dotnet publish MPF.Check\MPF.Check.csproj -f net7.0 -r linux-x64 -c Debug --self-contained true --version-suffix %APPVEYOR_REPO_COMMIT% -p:PublishSingleFile=true
- dotnet publish MPF.Check\MPF.Check.csproj -f net7.0 -r osx-x64 -c Debug --self-contained true --version-suffix %APPVEYOR_REPO_COMMIT% -p:PublishSingleFile=true
# .NET 8.0 Debug
- dotnet publish MPF\MPF.csproj -f net8.0-windows -r win-x64 -c Debug --self-contained true --version-suffix %APPVEYOR_REPO_COMMIT% -p:PublishSingleFile=true
- dotnet publish MPF.Check\MPF.Check.csproj -f net8.0 -r win-x64 -c Debug --self-contained true --version-suffix %APPVEYOR_REPO_COMMIT% -p:PublishSingleFile=true
- dotnet publish MPF.Check\MPF.Check.csproj -f net8.0 -r linux-x64 -c Debug --self-contained true --version-suffix %APPVEYOR_REPO_COMMIT% -p:PublishSingleFile=true
- dotnet publish MPF.Check\MPF.Check.csproj -f net8.0 -r osx-x64 -c Debug --self-contained true --version-suffix %APPVEYOR_REPO_COMMIT% -p:PublishSingleFile=true
# .NET 7.0 Release
- dotnet publish MPF\MPF.csproj -f net7.0-windows -r win-x64 -c Release --self-contained true --version-suffix %APPVEYOR_REPO_COMMIT% -p:PublishSingleFile=true -p:DebugType=None -p:DebugSymbols=false
- dotnet publish MPF.Check\MPF.Check.csproj -f net7.0 -r win-x64 -c Release --self-contained true --version-suffix %APPVEYOR_REPO_COMMIT% -p:PublishSingleFile=true -p:DebugType=None -p:DebugSymbols=false
- dotnet publish MPF.Check\MPF.Check.csproj -f net7.0 -r linux-x64 -c Release --self-contained true --version-suffix %APPVEYOR_REPO_COMMIT% -p:PublishSingleFile=true -p:DebugType=None -p:DebugSymbols=false
- dotnet publish MPF.Check\MPF.Check.csproj -f net7.0 -r osx-x64 -c Release --self-contained true --version-suffix %APPVEYOR_REPO_COMMIT% -p:PublishSingleFile=true -p:DebugType=None -p:DebugSymbols=false
# .NET 8.0 Release
- dotnet publish MPF\MPF.csproj -f net8.0-windows -r win-x64 -c Release --self-contained true --version-suffix %APPVEYOR_REPO_COMMIT% -p:PublishSingleFile=true -p:DebugType=None -p:DebugSymbols=false
- dotnet publish MPF.Check\MPF.Check.csproj -f net8.0 -r win-x64 -c Release --self-contained true --version-suffix %APPVEYOR_REPO_COMMIT% -p:PublishSingleFile=true -p:DebugType=None -p:DebugSymbols=false
- dotnet publish MPF.Check\MPF.Check.csproj -f net8.0 -r linux-x64 -c Release --self-contained true --version-suffix %APPVEYOR_REPO_COMMIT% -p:PublishSingleFile=true -p:DebugType=None -p:DebugSymbols=false
- dotnet publish MPF.Check\MPF.Check.csproj -f net8.0 -r osx-x64 -c Release --self-contained true --version-suffix %APPVEYOR_REPO_COMMIT% -p:PublishSingleFile=true -p:DebugType=None -p:DebugSymbols=false
# post-build step
after_build:
# Aaru
- ps: appveyor DownloadFile https://github.com/aaru-dps/Aaru/releases/download/v5.3.2/aaru-5.3.2_windows_x64.zip
- 7z x aaru-5.3.2_windows_x64.zip -oMPF\bin\Debug\net6.0-windows\win-x64\publish\Programs\Aaru *
- 7z x aaru-5.3.2_windows_x64.zip -oMPF\bin\Debug\net8.0-windows\win-x64\publish\Programs\Aaru *
# DiscImageCreator
- ps: appveyor DownloadFile https://github.com/saramibreak/DiscImageCreator/files/11660558/DiscImageCreator_20230606.zip
- 7z e DiscImageCreator_20230606.zip -oMPF\bin\Debug\net6.0-windows\win-x64\publish\Programs\Creator Release_ANSI\*
- 7z e DiscImageCreator_20230606.zip -oMPF\bin\Debug\net8.0-windows\win-x64\publish\Programs\Creator Release_ANSI\*
# Redumper
- ps: appveyor DownloadFile https://github.com/superg/redumper/releases/download/build_247/redumper-2023.11.01_build247-win64.zip
- 7z e redumper-2023.11.01_build247-win64.zip -oMPF\bin\Debug\net6.0-windows\win-x64\publish\Programs\Redumper redumper-2023.11.01_build247-win64\bin\*
- 7z e redumper-2023.11.01_build247-win64.zip -oMPF\bin\Debug\net8.0-windows\win-x64\publish\Programs\Redumper redumper-2023.11.01_build247-win64\bin\*
# Create MPF Debug archives
- cd %APPVEYOR_BUILD_FOLDER%\MPF\bin\Debug\net6.0-windows\win-x64\publish\
- 7z a -tzip %APPVEYOR_BUILD_FOLDER%\MPF_%APPVEYOR_BUILD_NUMBER%_net6.0_win-x64_debug.zip *
- cd %APPVEYOR_BUILD_FOLDER%\MPF\bin\Debug\net8.0-windows\win-x64\publish\
- 7z a -tzip %APPVEYOR_BUILD_FOLDER%\MPF_%APPVEYOR_BUILD_NUMBER%_net8.0_win-x64_debug.zip *
# Create MPF.Check Debug archives
- cd %APPVEYOR_BUILD_FOLDER%\MPF.Check\bin\Debug\net6.0\win-x64\publish\
- 7z a -tzip %APPVEYOR_BUILD_FOLDER%\MPF.Check_%APPVEYOR_BUILD_NUMBER%_net6.0_win-x64_debug.zip *
- cd %APPVEYOR_BUILD_FOLDER%\MPF.Check\bin\Debug\net6.0\linux-x64\publish\
- 7z a -tzip %APPVEYOR_BUILD_FOLDER%\MPF.Check_%APPVEYOR_BUILD_NUMBER%_net6.0_linux-x64_debug.zip *
- cd %APPVEYOR_BUILD_FOLDER%\MPF.Check\bin\Debug\net6.0\osx-x64\publish\
- 7z a -tzip %APPVEYOR_BUILD_FOLDER%\MPF.Check_%APPVEYOR_BUILD_NUMBER%_net6.0_osx-x64_debug.zip *
- cd %APPVEYOR_BUILD_FOLDER%\MPF.Check\bin\Debug\net8.0\win-x64\publish\
- 7z a -tzip %APPVEYOR_BUILD_FOLDER%\MPF.Check_%APPVEYOR_BUILD_NUMBER%_net8.0_win-x64_debug.zip *
- cd %APPVEYOR_BUILD_FOLDER%\MPF.Check\bin\Debug\net8.0\linux-x64\publish\
- 7z a -tzip %APPVEYOR_BUILD_FOLDER%\MPF.Check_%APPVEYOR_BUILD_NUMBER%_net8.0_linux-x64_debug.zip *
- cd %APPVEYOR_BUILD_FOLDER%\MPF.Check\bin\Debug\net8.0\osx-x64\publish\
- 7z a -tzip %APPVEYOR_BUILD_FOLDER%\MPF.Check_%APPVEYOR_BUILD_NUMBER%_net8.0_osx-x64_debug.zip *
# success/failure tracking
on_success:
@@ -81,12 +73,12 @@ on_failure:
# artifact linking
artifacts:
- path: MPF_%APPVEYOR_BUILD_NUMBER%_net6.0_win-x64_debug.zip
name: MPF (.NET 6.0, Debug, Windows x64)
- path: MPF_%APPVEYOR_BUILD_NUMBER%_net8.0_win-x64_debug.zip
name: MPF (.NET 8.0, Debug, Windows x64)
- path: MPF.Check_%APPVEYOR_BUILD_NUMBER%_net6.0_win-x64_debug.zip
name: MPF.Check (.NET 6.0, Debug, Windows x64)
- path: MPF.Check_%APPVEYOR_BUILD_NUMBER%_net6.0_linux-x64_debug.zip
name: MPF.Check (.NET 6.0, Debug, Linux x64)
- path: MPF.Check_%APPVEYOR_BUILD_NUMBER%_net6.0_osx-x64_debug.zip
name: MPF.Check (.NET 6.0, Debug, OSX x64)
- path: MPF.Check_%APPVEYOR_BUILD_NUMBER%_net8.0_win-x64_debug.zip
name: MPF.Check (.NET 8.0, Debug, Windows x64)
- path: MPF.Check_%APPVEYOR_BUILD_NUMBER%_net8.0_linux-x64_debug.zip
name: MPF.Check (.NET 8.0, Debug, Linux x64)
- path: MPF.Check_%APPVEYOR_BUILD_NUMBER%_net8.0_osx-x64_debug.zip
name: MPF.Check (.NET 8.0, Debug, OSX x64)

View File

@@ -1,7 +1,7 @@
#! /bin/bash
# This batch file assumes the following:
# - .NET 7.0 (or newer) SDK is installed and in PATH
# - .NET 8.0 (or newer) SDK is installed and in PATH
# - zip is installed and in PATH
# - Git is installed and in PATH
# - The relevant commandline programs are already downloaded
@@ -37,31 +37,31 @@ dotnet publish MPF.Check/MPF.Check.csproj -f net6.0 -r win-x64 -c Release --self
dotnet publish MPF.Check/MPF.Check.csproj -f net6.0 -r linux-x64 -c Release --self-contained true --version-suffix $COMMIT -p:PublishSingleFile=true -p:PublishTrimmed=true -p:DebugType=None -p:DebugSymbols=false
dotnet publish MPF.Check/MPF.Check.csproj -f net6.0 -r osx-x64 -c Release --self-contained true --version-suffix $COMMIT -p:PublishSingleFile=true -p:PublishTrimmed=true -p:DebugType=None -p:DebugSymbols=false
# .NET 7.0 Debug
echo "Building .NET 7.0 debug"
#dotnet publish MPF/MPF.csproj -f net7.0-windows -r win-x64 -c Debug --self-contained true --version-suffix $COMMIT -p:PublishSingleFile=true
dotnet publish MPF.Check/MPF.Check.csproj -f net7.0 -r win-x64 -c Debug --self-contained true --version-suffix $COMMIT -p:PublishSingleFile=true
dotnet publish MPF.Check/MPF.Check.csproj -f net7.0 -r linux-x64 -c Debug --self-contained true --version-suffix $COMMIT -p:PublishSingleFile=true
dotnet publish MPF.Check/MPF.Check.csproj -f net7.0 -r osx-x64 -c Debug --self-contained true --version-suffix $COMMIT -p:PublishSingleFile=true
# .NET 8.0 Debug
echo "Building .NET 8.0 debug"
#dotnet publish MPF/MPF.csproj -f net8.0-windows -r win-x64 -c Debug --self-contained true --version-suffix $COMMIT -p:PublishSingleFile=true
dotnet publish MPF.Check/MPF.Check.csproj -f net8.0 -r win-x64 -c Debug --self-contained true --version-suffix $COMMIT -p:PublishSingleFile=true
dotnet publish MPF.Check/MPF.Check.csproj -f net8.0 -r linux-x64 -c Debug --self-contained true --version-suffix $COMMIT -p:PublishSingleFile=true
dotnet publish MPF.Check/MPF.Check.csproj -f net8.0 -r osx-x64 -c Debug --self-contained true --version-suffix $COMMIT -p:PublishSingleFile=true
# .NET 7.0 Release
echo "Building .NET 7.0 release"
#dotnet publish MPF/MPF.csproj -f net7.0-windows -r win-x64 -c Release --self-contained true --version-suffix $COMMIT -p:PublishSingleFile=true -p:PublishTrimmed=true -p:DebugType=None -p:DebugSymbols=false
dotnet publish MPF.Check/MPF.Check.csproj -f net7.0 -r win-x64 -c Release --self-contained true --version-suffix $COMMIT -p:PublishSingleFile=true -p:PublishTrimmed=true -p:DebugType=None -p:DebugSymbols=false
dotnet publish MPF.Check/MPF.Check.csproj -f net7.0 -r linux-x64 -c Release --self-contained true --version-suffix $COMMIT -p:PublishSingleFile=true -p:PublishTrimmed=true -p:DebugType=None -p:DebugSymbols=false
dotnet publish MPF.Check/MPF.Check.csproj -f net7.0 -r osx-x64 -c Release --self-contained true --version-suffix $COMMIT -p:PublishSingleFile=true -p:PublishTrimmed=true -p:DebugType=None -p:DebugSymbols=false
# .NET 8.0 Release
echo "Building .NET 8.0 release"
#dotnet publish MPF/MPF.csproj -f net8.0-windows -r win-x64 -c Release --self-contained true --version-suffix $COMMIT -p:PublishSingleFile=true -p:PublishTrimmed=true -p:DebugType=None -p:DebugSymbols=false
dotnet publish MPF.Check/MPF.Check.csproj -f net8.0 -r win-x64 -c Release --self-contained true --version-suffix $COMMIT -p:PublishSingleFile=true -p:PublishTrimmed=true -p:DebugType=None -p:DebugSymbols=false
dotnet publish MPF.Check/MPF.Check.csproj -f net8.0 -r linux-x64 -c Release --self-contained true --version-suffix $COMMIT -p:PublishSingleFile=true -p:PublishTrimmed=true -p:DebugType=None -p:DebugSymbols=false
dotnet publish MPF.Check/MPF.Check.csproj -f net8.0 -r osx-x64 -c Release --self-contained true --version-suffix $COMMIT -p:PublishSingleFile=true -p:PublishTrimmed=true -p:DebugType=None -p:DebugSymbols=false
# Create MPF Debug archives
#cd $BUILD_FOLDER/MPF/bin/Debug/net6.0-windows/win-x64/publish/
#zip -r $BUILD_FOLDER/MPF_net6.0_win-x64_debug.zip .
#cd $BUILD_FOLDER/MPF/bin/Debug/net7.0-windows/win-x64/publish/
#zip -r $BUILD_FOLDER/MPF_net7.0_win-x64_debug.zip .
#cd $BUILD_FOLDER/MPF/bin/Debug/net8.0-windows/win-x64/publish/
#zip -r $BUILD_FOLDER/MPF_net8.0_win-x64_debug.zip .
# Create MPF Release archives
#cd $BUILD_FOLDER/MPF/bin/Release/net6.0-windows/win-x64/publish/
#zip -r $BUILD_FOLDER/MPF_net6.0_win-x64_release.zip .
#cd $BUILD_FOLDER/MPF/bin/Release/net7.0-windows/win-x64/publish/
#zip -r $BUILD_FOLDER/MPF_net7.0_win-x64_release.zip .
#cd $BUILD_FOLDER/MPF/bin/Release/net8.0-windows/win-x64/publish/
#zip -r $BUILD_FOLDER/MPF_net8.0_win-x64_release.zip .
# Create MPF.Check Debug archives
cd $BUILD_FOLDER/MPF.Check/bin/Debug/net6.0/win-x64/publish/
@@ -70,12 +70,12 @@ cd $BUILD_FOLDER/MPF.Check/bin/Debug/net6.0/linux-x64/publish/
zip -r $BUILD_FOLDER/MPF.Check_net6.0_linux-x64_debug.zip .
cd $BUILD_FOLDER/MPF.Check/bin/Debug/net6.0/osx-x64/publish/
zip -r $BUILD_FOLDER/MPF.Check_net6.0_osx-x64_debug.zip .
cd $BUILD_FOLDER/MPF.Check/bin/Debug/net7.0/win-x64/publish/
zip -r $BUILD_FOLDER/MPF.Check_net7.0_win-x64_debug.zip .
cd $BUILD_FOLDER/MPF.Check/bin/Debug/net7.0/linux-x64/publish/
zip -r $BUILD_FOLDER/MPF.Check_net7.0_linux-x64_debug.zip .
cd $BUILD_FOLDER/MPF.Check/bin/Debug/net7.0/osx-x64/publish/
zip -r $BUILD_FOLDER/MPF.Check_net7.0_osx-x64_debug.zip .
cd $BUILD_FOLDER/MPF.Check/bin/Debug/net8.0/win-x64/publish/
zip -r $BUILD_FOLDER/MPF.Check_net8.0_win-x64_debug.zip .
cd $BUILD_FOLDER/MPF.Check/bin/Debug/net8.0/linux-x64/publish/
zip -r $BUILD_FOLDER/MPF.Check_net8.0_linux-x64_debug.zip .
cd $BUILD_FOLDER/MPF.Check/bin/Debug/net8.0/osx-x64/publish/
zip -r $BUILD_FOLDER/MPF.Check_net8.0_osx-x64_debug.zip .
# Create MPF.Check Release archives
cd $BUILD_FOLDER/MPF.Check/bin/Release/net6.0/win-x64/publish/
@@ -84,9 +84,9 @@ cd $BUILD_FOLDER/MPF.Check/bin/Release/net6.0/linux-x64/publish/
zip -r $BUILD_FOLDER/MPF.Check_net6.0_linux-x64_release.zip .
cd $BUILD_FOLDER/MPF.Check/bin/Release/net6.0/osx-x64/publish/
zip -r $BUILD_FOLDER/MPF.Check_net6.0_osx-x64_release.zip .
cd $BUILD_FOLDER/MPF.Check/bin/Release/net7.0/win-x64/publish/
zip -r $BUILD_FOLDER/MPF.Check_net7.0_win-x64_release.zip .
cd $BUILD_FOLDER/MPF.Check/bin/Release/net7.0/linux-x64/publish/
zip -r $BUILD_FOLDER/MPF.Check_net7.0_linux-x64_release.zip .
cd $BUILD_FOLDER/MPF.Check/bin/Release/net7.0/osx-x64/publish/
zip -r $BUILD_FOLDER/MPF.Check_net7.0_osx-x64_release.zip .
cd $BUILD_FOLDER/MPF.Check/bin/Release/net8.0/win-x64/publish/
zip -r $BUILD_FOLDER/MPF.Check_net8.0_win-x64_release.zip .
cd $BUILD_FOLDER/MPF.Check/bin/Release/net8.0/linux-x64/publish/
zip -r $BUILD_FOLDER/MPF.Check_net8.0_linux-x64_release.zip .
cd $BUILD_FOLDER/MPF.Check/bin/Release/net8.0/osx-x64/publish/
zip -r $BUILD_FOLDER/MPF.Check_net8.0_osx-x64_release.zip .

View File

@@ -1,8 +1,7 @@
@echo OFF
REM This batch file assumes the following:
REM - .NET Framework 4.8 SDK is installed and in PATH
REM - .NET 7.0 (or newer) SDK is installed and in PATH
REM - .NET 8.0 (or newer) SDK is installed and in PATH
REM - 7-zip commandline (7z.exe) is installed and in PATH
REM - Git for Windows is installed and in PATH
REM - The relevant commandline programs are already downloaded
@@ -21,16 +20,6 @@ REM Restore Nuget packages for all builds
echo Restoring Nuget packages
dotnet restore
REM .NET Framework 4.8 Debug
echo Building .NET Framework 4.8 debug
dotnet publish MPF\MPF.csproj -f net48 -r win7-x64 -c Debug --self-contained true --version-suffix %COMMIT%
dotnet publish MPF.Check\MPF.Check.csproj -f net48 -r win7-x64 -c Debug --self-contained true --version-suffix %COMMIT%
REM .NET Framework 4.8 Release
echo Building .NET Framework 4.8 release
dotnet publish MPF\MPF.csproj -f net48 -r win7-x64 -c Release --self-contained true --version-suffix %COMMIT% -p:DebugType=None -p:DebugSymbols=false
dotnet publish MPF.Check\MPF.Check.csproj -f net48 -r win7-x64 -c Release --self-contained true --version-suffix %COMMIT% -p:DebugType=None -p:DebugSymbols=false
REM .NET 6.0 Debug
echo Building .NET 6.0 debug
dotnet publish MPF\MPF.csproj -f net6.0-windows -r win-x64 -c Debug --self-contained true --version-suffix %COMMIT% -p:PublishSingleFile=true
@@ -45,64 +34,56 @@ dotnet publish MPF.Check\MPF.Check.csproj -f net6.0 -r win-x64 -c Release --self
dotnet publish MPF.Check\MPF.Check.csproj -f net6.0 -r linux-x64 -c Release --self-contained true --version-suffix %COMMIT% -p:PublishSingleFile=true -p:DebugType=None -p:DebugSymbols=false
dotnet publish MPF.Check\MPF.Check.csproj -f net6.0 -r osx-x64 -c Release --self-contained true --version-suffix %COMMIT% -p:PublishSingleFile=true -p:DebugType=None -p:DebugSymbols=false
REM .NET 7.0 Debug
echo Building .NET 7.0 debug
dotnet publish MPF\MPF.csproj -f net7.0-windows -r win-x64 -c Debug --self-contained true --version-suffix %COMMIT% -p:PublishSingleFile=true
dotnet publish MPF.Check\MPF.Check.csproj -f net7.0 -r win-x64 -c Debug --self-contained true --version-suffix %COMMIT% -p:PublishSingleFile=true
dotnet publish MPF.Check\MPF.Check.csproj -f net7.0 -r linux-x64 -c Debug --self-contained true --version-suffix %COMMIT% -p:PublishSingleFile=true
dotnet publish MPF.Check\MPF.Check.csproj -f net7.0 -r osx-x64 -c Debug --self-contained true --version-suffix %COMMIT% -p:PublishSingleFile=true
REM .NET 8.0 Debug
echo Building .NET 8.0 debug
dotnet publish MPF\MPF.csproj -f net8.0-windows -r win-x64 -c Debug --self-contained true --version-suffix %COMMIT% -p:PublishSingleFile=true
dotnet publish MPF.Check\MPF.Check.csproj -f net8.0 -r win-x64 -c Debug --self-contained true --version-suffix %COMMIT% -p:PublishSingleFile=true
dotnet publish MPF.Check\MPF.Check.csproj -f net8.0 -r linux-x64 -c Debug --self-contained true --version-suffix %COMMIT% -p:PublishSingleFile=true
dotnet publish MPF.Check\MPF.Check.csproj -f net8.0 -r osx-x64 -c Debug --self-contained true --version-suffix %COMMIT% -p:PublishSingleFile=true
REM .NET 7.0 Release
echo Building .NET 7.0 release
dotnet publish MPF\MPF.csproj -f net7.0-windows -r win-x64 -c Release --self-contained true --version-suffix %COMMIT% -p:PublishSingleFile=true -p:DebugType=None -p:DebugSymbols=false
dotnet publish MPF.Check\MPF.Check.csproj -f net7.0 -r win-x64 -c Release --self-contained true --version-suffix %COMMIT% -p:PublishSingleFile=true -p:DebugType=None -p:DebugSymbols=false
dotnet publish MPF.Check\MPF.Check.csproj -f net7.0 -r linux-x64 -c Release --self-contained true --version-suffix %COMMIT% -p:PublishSingleFile=true -p:DebugType=None -p:DebugSymbols=false
dotnet publish MPF.Check\MPF.Check.csproj -f net7.0 -r osx-x64 -c Release --self-contained true --version-suffix %COMMIT% -p:PublishSingleFile=true -p:DebugType=None -p:DebugSymbols=false
REM .NET 8.0 Release
echo Building .NET 8.0 release
dotnet publish MPF\MPF.csproj -f net8.0-windows -r win-x64 -c Release --self-contained true --version-suffix %COMMIT% -p:PublishSingleFile=true -p:DebugType=None -p:DebugSymbols=false
dotnet publish MPF.Check\MPF.Check.csproj -f net8.0 -r win-x64 -c Release --self-contained true --version-suffix %COMMIT% -p:PublishSingleFile=true -p:DebugType=None -p:DebugSymbols=false
dotnet publish MPF.Check\MPF.Check.csproj -f net8.0 -r linux-x64 -c Release --self-contained true --version-suffix %COMMIT% -p:PublishSingleFile=true -p:DebugType=None -p:DebugSymbols=false
dotnet publish MPF.Check\MPF.Check.csproj -f net8.0 -r osx-x64 -c Release --self-contained true --version-suffix %COMMIT% -p:PublishSingleFile=true -p:DebugType=None -p:DebugSymbols=false
REM Create MPF Debug archives
cd %BUILD_FOLDER%\MPF\bin\Debug\net48\win7-x64\publish\
7z a -tzip %BUILD_FOLDER%\MPF_net48_debug.zip *
cd %BUILD_FOLDER%\MPF\bin\Debug\net6.0-windows\win-x64\publish\
7z a -tzip %BUILD_FOLDER%\MPF_net6.0_win-x64_debug.zip *
cd %BUILD_FOLDER%\MPF\bin\Debug\net7.0-windows\win-x64\publish\
7z a -tzip %BUILD_FOLDER%\MPF_net7.0_win-x64_debug.zip *
cd %BUILD_FOLDER%\MPF\bin\Debug\net8.0-windows\win-x64\publish\
7z a -tzip %BUILD_FOLDER%\MPF_net8.0_win-x64_debug.zip *
REM Create MPF Release archives
cd %BUILD_FOLDER%\MPF\bin\Release\net48\win7-x64\publish\
7z a -tzip %BUILD_FOLDER%\MPF_net48_release.zip *
cd %BUILD_FOLDER%\MPF\bin\Release\net6.0-windows\win-x64\publish\
7z a -tzip %BUILD_FOLDER%\MPF_net6.0_win-x64_release.zip *
cd %BUILD_FOLDER%\MPF\bin\Release\net7.0-windows\win-x64\publish\
7z a -tzip %BUILD_FOLDER%\MPF_net7.0_win-x64_release.zip *
cd %BUILD_FOLDER%\MPF\bin\Release\net8.0-windows\win-x64\publish\
7z a -tzip %BUILD_FOLDER%\MPF_net8.0_win-x64_release.zip *
REM Create MPF.Check Debug archives
cd %BUILD_FOLDER%\MPF.Check\bin\Debug\net48\win7-x64\publish\
7z a -tzip %BUILD_FOLDER%\MPF.Check_net48_debug.zip *
cd %BUILD_FOLDER%\MPF.Check\bin\Debug\net6.0\win-x64\publish\
7z a -tzip %BUILD_FOLDER%\MPF.Check_net6.0_win-x64_debug.zip *
cd %BUILD_FOLDER%\MPF.Check\bin\Debug\net6.0\linux-x64\publish\
7z a -tzip %BUILD_FOLDER%\MPF.Check_net6.0_linux-x64_debug.zip *
cd %BUILD_FOLDER%\MPF.Check\bin\Debug\net6.0\osx-x64\publish\
7z a -tzip %BUILD_FOLDER%\MPF.Check_net6.0_osx-x64_debug.zip *
cd %BUILD_FOLDER%\MPF.Check\bin\Debug\net7.0\win-x64\publish\
7z a -tzip %BUILD_FOLDER%\MPF.Check_net7.0_win-x64_debug.zip *
cd %BUILD_FOLDER%\MPF.Check\bin\Debug\net7.0\linux-x64\publish\
7z a -tzip %BUILD_FOLDER%\MPF.Check_net7.0_linux-x64_debug.zip *
cd %BUILD_FOLDER%\MPF.Check\bin\Debug\net7.0\osx-x64\publish\
7z a -tzip %BUILD_FOLDER%\MPF.Check_net7.0_osx-x64_debug.zip *
cd %BUILD_FOLDER%\MPF.Check\bin\Debug\net8.0\win-x64\publish\
7z a -tzip %BUILD_FOLDER%\MPF.Check_net8.0_win-x64_debug.zip *
cd %BUILD_FOLDER%\MPF.Check\bin\Debug\net8.0\linux-x64\publish\
7z a -tzip %BUILD_FOLDER%\MPF.Check_net8.0_linux-x64_debug.zip *
cd %BUILD_FOLDER%\MPF.Check\bin\Debug\net8.0\osx-x64\publish\
7z a -tzip %BUILD_FOLDER%\MPF.Check_net8.0_osx-x64_debug.zip *
REM Create MPF.Check Release archives
cd %BUILD_FOLDER%\MPF.Check\bin\Release\net48\win7-x64\publish\
7z a -tzip %BUILD_FOLDER%\MPF.Check_net48_release.zip *
cd %BUILD_FOLDER%\MPF.Check\bin\Release\net6.0\win-x64\publish\
7z a -tzip %BUILD_FOLDER%\MPF.Check_net6.0_win-x64_release.zip *
cd %BUILD_FOLDER%\MPF.Check\bin\Release\net6.0\linux-x64\publish\
7z a -tzip %BUILD_FOLDER%\MPF.Check_net6.0_linux-x64_release.zip *
cd %BUILD_FOLDER%\MPF.Check\bin\Release\net6.0\osx-x64\publish\
7z a -tzip %BUILD_FOLDER%\MPF.Check_net6.0_osx-x64_release.zip *
cd %BUILD_FOLDER%\MPF.Check\bin\Release\net7.0\win-x64\publish\
7z a -tzip %BUILD_FOLDER%\MPF.Check_net7.0_win-x64_release.zip *
cd %BUILD_FOLDER%\MPF.Check\bin\Release\net7.0\linux-x64\publish\
7z a -tzip %BUILD_FOLDER%\MPF.Check_net7.0_linux-x64_release.zip *
cd %BUILD_FOLDER%\MPF.Check\bin\Release\net7.0\osx-x64\publish\
7z a -tzip %BUILD_FOLDER%\MPF.Check_net7.0_osx-x64_release.zip *
cd %BUILD_FOLDER%\MPF.Check\bin\Release\net8.0\win-x64\publish\
7z a -tzip %BUILD_FOLDER%\MPF.Check_net8.0_win-x64_release.zip *
cd %BUILD_FOLDER%\MPF.Check\bin\Release\net8.0\linux-x64\publish\
7z a -tzip %BUILD_FOLDER%\MPF.Check_net8.0_linux-x64_release.zip *
cd %BUILD_FOLDER%\MPF.Check\bin\Release\net8.0\osx-x64\publish\
7z a -tzip %BUILD_FOLDER%\MPF.Check_net8.0_osx-x64_release.zip *