Compare commits

..

119 Commits
2.5 ... 2.6.2

Author SHA1 Message Date
Matt Nadareski
3dcac28488 Bump version to 2.6.2 2023-07-24 09:40:20 -04:00
Matt Nadareski
4cd7073bf6 Clarify build instructions 2023-07-23 23:51:05 -04:00
Matt Nadareski
1af21e7aba Add build instructions to README 2023-07-23 23:48:04 -04:00
Matt Nadareski
52adcd0b46 Add *nix publish script 2023-07-23 23:44:03 -04:00
Matt Nadareski
8a91593e58 Add Windows publish script 2023-07-23 21:42:10 -04:00
Matt Nadareski
729f8273fc Fix universal hash URL generation 2023-07-23 19:16:57 -04:00
Matt Nadareski
78df6f6583 Fix .NET Framework 4.8 build 2023-07-23 16:48:44 -04:00
Matt Nadareski
dc8dae4df7 Attempt to match universal hash 2023-07-23 16:41:40 -04:00
Matt Nadareski
53db9dbf81 Modify the track count on checking 2023-07-23 15:09:46 -04:00
Matt Nadareski
22755a4af9 Skip extra tracks during checking (fixes #529) 2023-07-22 21:31:20 -04:00
Matt Nadareski
ba28b414ba Normalize old universal hash text (fixes #528) 2023-07-20 20:26:57 -04:00
Matt Nadareski
95d10ecb1e Always show extension for Redumper (fixes #525) 2023-07-20 11:35:15 -04:00
Matt Nadareski
c5ab2c747a Support LibCrypt data from Redumper 2023-07-19 17:07:59 -04:00
Matt Nadareski
476c494f4e Universal hash only for audio discs (fixes #524) 2023-07-19 13:33:14 -04:00
Matt Nadareski
758c49c1cc Ensure custom parameters properly set (fixes #523) 2023-07-19 12:51:22 -04:00
Matt Nadareski
d80ad3b3cf Bump version to 2.6.1 2023-07-19 09:36:34 -04:00
Matt Nadareski
3d06f80703 Fix comment field pulling again 2023-07-19 00:05:33 -04:00
Matt Nadareski
7344460409 Fix comment field pulling again (fixes #522) 2023-07-18 22:40:08 -04:00
Matt Nadareski
19f58d9dde Set extensions for Redumper in UI (fixes #521) 2023-07-18 20:56:08 -04:00
Matt Nadareski
ad9f39f832 Be more explicit about .NET 6 limitation 2023-07-17 13:23:00 -04:00
Matt Nadareski
d51117b058 Be more explicit about .NET 6 limitation (fixes #519) 2023-07-17 13:17:42 -04:00
Matt Nadareski
0d65d5114a Set best compression levels for log files (fixes #518) 2023-07-17 13:13:16 -04:00
Matt Nadareski
30fec3c3d0 Don't pull comment fields that auto-populate (fixes #517) 2023-07-17 10:28:37 -04:00
Matt Nadareski
8eb86fde90 Simplify Redumper error value extraction (fixes #515) 2023-07-14 16:42:47 -04:00
Matt Nadareski
7616c6b2ba Bump version to 2.6 2023-07-14 13:47:00 -04:00
Matt Nadareski
e0742cdfc7 Update Nuget packages to newest stable 2023-07-14 12:07:44 -04:00
Matt Nadareski
a19937d630 Omit pulling universal hash (fixes #513) 2023-07-12 17:29:35 -04:00
Matt Nadareski
fa92402bc5 Ensure we found the tags we're skipping (fixes #512) 2023-07-11 10:57:50 -04:00
Matt Nadareski
cdc3da5839 Reduce pulled information for Xbox and X360 (fixes #512) 2023-07-10 11:15:32 -04:00
Matt Nadareski
3430f8c1db New layerbreak takes precedence 2023-07-10 09:38:52 -04:00
Matt Nadareski
12fd55e76c Parse and format Redumper CD multisession data 2023-07-09 20:55:33 -04:00
Matt Nadareski
0013606d61 Update redumper to build 183 2023-07-09 14:43:47 -04:00
Matt Nadareski
4d520d7d63 Add ordering to disc or book type 2023-07-06 22:50:21 -04:00
Matt Nadareski
7bfe174680 Use HashSet for disc or book type 2023-07-06 15:21:37 -04:00
Matt Nadareski
4951e7bf42 Strip colons from Redumper disc key (fixes #508) 2023-06-27 15:44:55 -04:00
Matt Nadareski
d7d9c468ae UMDs are Sony discs (fixes #507) 2023-06-26 11:46:57 -04:00
Matt Nadareski
32faa33ad3 Update redumper to build 176 2023-06-26 01:06:46 -04:00
Matt Nadareski
8a5475380a Check Redumper dat section for completeness 2023-06-23 11:20:17 -04:00
Matt Nadareski
1dd5542390 Add missing Aaru error log to zip 2023-06-21 16:27:23 -04:00
Matt Nadareski
5156b89eca Normalize multi-instance site tags (fixes #505) 2023-06-19 21:21:20 -04:00
Matt Nadareski
83ea04c880 Normalize Redumper CSS outputs 2023-06-19 21:13:18 -04:00
Matt Nadareski
8695d2981e Fix non-reading loop 2023-06-18 23:18:50 -04:00
Matt Nadareski
e0c299e6f0 Adjust CSS title key parsing 2023-06-18 23:01:17 -04:00
Matt Nadareski
16ec54f389 Add support for redumper CD synonyms 2023-06-18 21:56:49 -04:00
Matt Nadareski
998bf5d5fa Update redumper to build 174 2023-06-18 21:55:57 -04:00
Matt Nadareski
07ec821e9a Hook up CSS output for testing 2023-06-18 21:15:50 -04:00
Matt Nadareski
56cf8f3574 Initial support for Redumper CSS outputs 2023-06-18 21:13:25 -04:00
Matt Nadareski
c6ebfcd6d9 Update redumper to build 173 2023-06-18 21:01:52 -04:00
Matt Nadareski
6ceffce63d Fix previous commit, clean up helpers 2023-06-12 13:42:13 -04:00
Matt Nadareski
f43aafc00d Update Redumper PS1 output parsing 2023-06-12 13:31:49 -04:00
Matt Nadareski
ab598d8377 Fix Redumper DAT/layer parsing 2023-06-11 00:57:42 -04:00
Matt Nadareski
dbd876a1c1 Fix VSCode build 2023-06-11 00:56:54 -04:00
Matt Nadareski
fd102cb56b Fix 2-layer DVD support in Redumper 2023-06-10 20:46:54 -04:00
Matt Nadareski
0afb49b657 Add TODO with notes to Redumper 2023-06-10 18:01:52 -04:00
Matt Nadareski
be980fe0c4 Add placeholder and TODOs for Redumper 2023-06-10 17:49:31 -04:00
Matt Nadareski
08b4e8d602 Support Redumper DVD layerbreak 2023-06-10 17:41:48 -04:00
Matt Nadareski
e483e1cdc6 Unblock Redumper DVD support 2023-06-10 12:03:14 -04:00
Matt Nadareski
5c2dce78e2 Update redumper to build 166 2023-06-09 23:00:20 -04:00
Matt Nadareski
26ea383775 Update to DIC 20230606 2023-06-06 11:13:29 -04:00
Matt Nadareski
64938fd7f1 Fix MCD region(s) parsing 2023-05-30 13:04:33 -04:00
Matt Nadareski
22318ee3c1 Add MCD/SS header support for Redumper (fixes #495)
This also does a replacement for all instances of `?? "";` with `?? string.Empty;`, which is more correct.
2023-05-30 12:58:37 -04:00
Matt Nadareski
b2b54a2706 Update changelog 2023-05-28 16:13:57 -04:00
fuzzball
40f04e0321 Change the fast-forward keyword (#493) 2023-05-28 13:06:49 -07:00
fuzzball
a7638b8063 Get write offset from redumper 119 (#484) 2023-05-28 13:06:20 -07:00
Matt Nadareski
2abcad2a0f Add more safety to DAT generation (fixes #492) 2023-05-28 16:05:00 -04:00
Matt Nadareski
e088b05de4 Update redumper to build 151 2023-05-19 13:10:39 -04:00
Matt Nadareski
a31d894b79 Add executable listing for XSX (fixes #491) 2023-05-10 09:26:50 -04:00
Matt Nadareski
34fae4572d Fix non-zero offset text (fixes #490) 2023-05-09 13:38:22 -04:00
Matt Nadareski
1ecf0ad1fa Fix other media type method 2023-04-26 16:00:20 -04:00
Matt Nadareski
7c7509020f Add PIC identifier to SubmissionInfo (fixes #488) 2023-04-26 10:24:30 -04:00
Matt Nadareski
7c6b118282 Add internal theme support with class (fixes #487) 2023-04-26 09:51:29 -04:00
Matt Nadareski
c154a844e3 Truncate PIC data for PS4/PS5 (fixes #486) 2023-04-26 08:35:36 -04:00
Matt Nadareski
088f1b8545 Add missing BD disc type identifier string 2023-04-26 08:29:56 -04:00
Matt Nadareski
fc3c636bdd Single file packing for .NET 6 again 2023-04-25 09:07:42 -04:00
Matt Nadareski
14c807c882 Fix subdump mkdir path in AV config 2023-04-24 21:52:52 -04:00
Matt Nadareski
d0e9c51786 Fix subdump output path in AV config 2023-04-24 21:42:20 -04:00
Matt Nadareski
b428bc0ba0 Be more specific with runtime identifiers 2023-04-24 21:31:39 -04:00
Matt Nadareski
6dbbb91438 De-indent ringcode data 2023-04-24 14:42:13 -04:00
Matt Nadareski
2066d36424 Ensure blank lines don't interfere 2023-04-24 00:01:07 -04:00
Matt Nadareski
29552cd39d Fix upcoming suppl DAT parsing 2023-04-23 23:59:44 -04:00
Matt Nadareski
640e7091cc Attempt to more accurately parse layerbreaks 2023-04-23 23:38:57 -04:00
Matt Nadareski
af12c18d2e Fix missing size for ISO data 2023-04-23 22:26:24 -04:00
Matt Nadareski
f28cf614c3 Fix info tool hash finding 2023-04-23 10:00:13 -04:00
Matt Nadareski
888cb8ec9f Support single digit subs 2023-04-23 09:45:56 -04:00
Matt Nadareski
04035ac524 Add suppl support to Xbox 2023-04-22 21:51:18 -04:00
Matt Nadareski
600374eb2d Prepare for future DIC changes
This also takes care of additional `sub` files generated for nonstandard tracks, such as Track 00 and Track AA (fixes #483)
2023-04-22 21:19:02 -04:00
Matt Nadareski
6ecb932a82 Start migrating to datafile serialization 2023-04-22 16:48:40 -04:00
Matt Nadareski
4cbc9ac109 Add datafile helper method 2023-04-22 16:25:18 -04:00
Matt Nadareski
5ee0b7345b Add datafile models 2023-04-22 15:11:14 -04:00
Matt Nadareski
cc55330fad Make TOC file optional for CD/GD 2023-04-21 13:19:27 -04:00
Matt Nadareski
6589380fdf Remove path from PS1/PS2 serial (fixes #481) 2023-04-19 11:36:13 -04:00
Matt Nadareski
bd45482bf7 Disable special SmartE handling for DIC 2023-04-17 14:06:27 -04:00
Matt Nadareski
e14c8a8f03 Ensure dumping program box can enable/disable 2023-04-13 12:34:51 -04:00
Matt Nadareski
4ac00e9a1a Comment out . handling for DIC 2023-04-13 12:33:14 -04:00
Matt Nadareski
edf983e304 Update to DIC 20230413 2023-04-13 12:27:46 -04:00
Matt Nadareski
01a69ef9b3 Add dumping program selection to main UI (#479)
* Add dumping program selection to main UI

* Fix program dropdown

* Fix lingering location

* Final changes
2023-04-11 08:15:53 -07:00
Matt Nadareski
a368afc14a UMDs always have "2 layers" (fixes #473) 2023-04-10 10:21:47 -04:00
Matt Nadareski
d83fed16f5 Handle PIC based on disc type 2023-04-10 10:14:44 -04:00
Matt Nadareski
949df08690 Add PIC models for BD (unused) 2023-04-10 10:13:58 -04:00
Matt Nadareski
ab3abb5b3e Re-enable BD33 and BD66 2023-04-10 08:57:51 -04:00
Matt Nadareski
d16e73a530 Add UltraCade 2023-04-09 21:24:47 -04:00
Matt Nadareski
3f8c55ca47 Clarify non-Redump systems 2023-04-09 21:10:08 -04:00
Matt Nadareski
2e9aaa50f9 Update redumper to build 118
This change also does the following:
- Performs some minor cleanup on `OptionsViewModel`
- Add options for enabling verbose and debug by default for Redumper (similar to Aaru)
2023-04-09 20:54:52 -04:00
Matt Nadareski
36951dc5da Resync with Redump 2023-04-08 21:32:20 -04:00
Matt Nadareski
b39c8dd738 Add DIC . notice to README 2023-04-01 21:51:02 -04:00
Matt Nadareski
a1155cf9b7 Update to DIC 20230401 2023-04-01 20:32:42 -04:00
Matt Nadareski
1d151d213e Update redumper to build 115 2023-03-31 10:30:19 -04:00
Matt Nadareski
6dc0c1438a Update changelog 2023-03-31 10:25:09 -04:00
fuzzball
8739569db6 Change the mark for fast-forwarding (#475) 2023-03-31 07:21:36 -07:00
Matt Nadareski
0dcba9ce71 Add Hasbro iON (fixes #471) 2023-03-20 15:59:16 -04:00
Matt Nadareski
8d37b85e12 Update README 2023-03-20 15:47:01 -04:00
Matt Nadareski
43cf8e1a45 Split MMI invocation in drive listing 2023-03-20 15:16:35 -04:00
Matt Nadareski
7317553483 Update redumper to build 113 2023-03-20 10:19:27 -04:00
Matt Nadareski
0b342e265c Add Windows 7 note to README 2023-03-20 10:11:39 -04:00
Matt Nadareski
08359dd45f Update changelog 2023-03-19 14:13:32 -04:00
fuzzball
a24415cae6 Increase the version of AppVeyor (#470) 2023-03-19 11:09:33 -07:00
fuzzball
59f8161308 Pull hardware info from redumper log (#469) 2023-03-19 11:09:12 -07:00
Matt Nadareski
51f955a14c Add warning to login tab 2023-03-13 14:23:54 -04:00
Matt Nadareski
ddebdef00c Update README 2023-03-13 13:25:32 -04:00
54 changed files with 3209 additions and 739 deletions

4
.vscode/launch.json vendored
View File

@@ -10,9 +10,9 @@
"request": "launch",
"preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/MPF/bin/Debug/net6.0-windows/MPF.dll",
"program": "${workspaceFolder}/MPF.Check/bin/Debug/net6.0/MPF.Check.dll",
"args": [],
"cwd": "${workspaceFolder}/MPF",
"cwd": "${workspaceFolder}/MPF.Check",
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
"console": "internalConsole",
"stopAtEntry": false

13
.vscode/tasks.json vendored
View File

@@ -3,25 +3,22 @@
"tasks": [
{
"label": "build",
"command": "dotnet",
"command": "msbuild",
"type": "process",
"args": [
"build",
"${workspaceFolder}/MPF.sln",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
"-property:RuntimeIdentifiers=win7-x64"
],
"problemMatcher": "$msCompile"
},
{
"label": "publish",
"command": "dotnet",
"command": "msbuild",
"type": "process",
"args": [
"publish",
"${workspaceFolder}/MPF/MPF.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
"-target:Publish",
"-property:RuntimeIdentifiers=win7-x64"
],
"problemMatcher": "$msCompile"
},

View File

@@ -1,4 +1,122 @@
### WIP (xxxx-xx-xx)
### 2.6.2 (2023-07-25)
- Ensure custom parameters properly set
- Universal hash only for audio discs
- Support LibCrypt data from Redumper
- Always show extension for Redumper
- Normalize old universal hash text
- Skip extra tracks during checking
- Modify the track count on checking
- Attempt to match universal hash
- Fix .NET Framework 4.8 build
- Fix universal hash URL generation
- Add Windows publish script
- Add *nix publish script
- Add build instructions to README
- Clarify build instructions
### 2.6.1 (2023-07-19)
- Simplify Redumper error value extraction
- Don't pull comment fields that auto-populate
- Set best compression levels for log files
- Be more explicit about .NET 6 limitation
- Set extensions for Redumper in UI
- Fix comment field pulling again
### 2.6 (2023-07-14)
- Update README
- Add warning to login tab
- Pull hardware info from redumper log (fuzz6001)
- Increase the version of AppVeyor (fuzz6001)
- Add Windows 7 note to README
- Update redumper to build 113
- Split MMI invocation in drive listing
- Update README
- Add Hasbro iON
- Get the write offset from the latest redumper (fuzz6001)
- Update redumper to build 115
- Update to DIC 20230401
- Add DIC `.` notice to README
- Resync with Redump
- Update redumper to build 118
- Clarify non-Redump systems
- Add UltraCade
- Re-enable BD33 and BD66
- Add PIC models for BD (unused)
- Handle PIC based on disc type
- UMDs always have "2 layers"
- Add dumping program selection to main UI
- Update to DIC 20230413
- Comment out `.` handling for DIC
- Ensure dumping program box can enable/disable
- Disable special SmartE handling for DIC
- Remove path from PS1/PS2 serial
- Make TOC file optional for CD/GD
- Add datafile models
- Add datafile helper method
- Start migrating to datafile serialization
- Prepare for future DIC changes
- Add suppl support to Xbox
- Support single digit subs
- Fix info tool hash finding
- Fix missing size for ISO data
- Attempt to more accurately parse layerbreaks
- Fix upcoming suppl DAT parsing
- Ensure blank lines don't interfere
- De-indent ringcode data
- Be more specific with runtime identifiers
- Fix subdump output path in AV config
- Fix subdump mkdir path in AV config
- Single file packing for .NET 6 again
- Add missing BD disc type identifier string
- Truncate PIC data for PS4/PS5
- Add internal theme support with class
- Add PIC identifier to SubmissionInfo
- Fix other media type method
- Fix non-zero offset text
- Add executable listing for XSX
- Update redumper to build 151
- Add more safety to DAT generation
- Get write offset from redumper 119 (fuzz6001)
- Update hardware information pull from redumper (fuzz6001)
- Add MCD/SS header support for Redumper
- Fix MCD region(s) parsing
- Update to DIC 20230606
- Update redumper to build 166
- Unblock Redumper DVD support
- Support Redumper DVD layerbreak
- Add placeholder and TODOs for Redumper
- Add TODO with notes to Redumper
- Fix 2-layer DVD support in Redumper
- Fix VSCode build
- Fix Redumper DAT/layer parsing
- Update Redumper PS1 output parsing
- Fix previous commit, clean up helpers
- Update redumper to build 173
- Initial support for Redumper CSS outputs
- Hook up CSS output for testing
- Update redumper to build 174
- Add support for redumper CD synonyms
- Adjust CSS title key parsing
- Fix non-reading loop
- Normalize Redumper CSS outputs
- Normalize multi-instance site tags
- Add missing Aaru error log to zip
- Check Redumper dat section for completeness
- Update redumper to build 176
- UMDs are Sony discs
- Strip colons from Redumper disc key
- Use `HashSet` for disc or book type
- Add ordering to disc or book type
- Update redumper to build 183
- Parse and format Redumper CD multisession data
- New layerbreak takes precedence
- Reduce pulled information for Xbox and X360
- Ensure we found the tags we're skipping
- Omit pulling universal hash
- Update Nuget packages to newest stable
### 2.5 (2023-03-12)

View File

@@ -2,7 +2,7 @@
<PropertyGroup>
<TargetFrameworks>net48;net6.0</TargetFrameworks>
<RuntimeIdentifiers>win7-x64;win-x86;win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
<RuntimeIdentifiers>win7-x64;win8-x64;win81-x64;win10-x64;linux-x64;osx-x64</RuntimeIdentifiers>
<OutputType>Exe</OutputType>
<Title>MPF Check</Title>
<AssemblyName>MPF.Check</AssemblyName>
@@ -10,7 +10,7 @@
<Authors>Matt Nadareski;ReignStumble;Jakz</Authors>
<Copyright>Copyright (c)2019-2023</Copyright>
<RepositoryUrl>https://github.com/SabreTools/MPF</RepositoryUrl>
<Version>2.5</Version>
<Version>2.6.2</Version>
<AssemblyVersion>$(Version)</AssemblyVersion>
<FileVersion>$(Version)</FileVersion>
<IncludeSource>true</IncludeSource>
@@ -28,7 +28,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="BurnOutSharp" PrivateAssets="build; analyzers" ExcludeAssets="contentFiles" Version="2.7.0" GeneratePathProperty="true">
<PackageReference Include="BurnOutSharp" PrivateAssets="build; analyzers" ExcludeAssets="contentFiles" Version="2.8.0" GeneratePathProperty="true">
<IncludeAssets>runtime; compile; build; native; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Unclassified.NetRevisionTask" Version="0.4.3">
@@ -42,6 +42,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MPF.Core\MPF.Core.csproj" />
<ProjectReference Include="..\MPF.Library\MPF.Library.csproj" />
<ProjectReference Include="..\RedumpLib\RedumpLib.csproj" />
</ItemGroup>

View File

@@ -24,7 +24,7 @@ namespace MPF.Check
return;
// Loop through and process options
(Options options, string path, int startIndex) = OptionsLoader.LoadFromArguments(args, startIndex: 2);
(Core.Data.Options options, string path, int startIndex) = OptionsLoader.LoadFromArguments(args, startIndex: 2);
// Make new Progress objects
var resultProgress = new Progress<Result>();
@@ -59,7 +59,7 @@ namespace MPF.Check
if (!string.IsNullOrWhiteSpace(path))
drive = Drive.Create(null, path);
var env = new DumpEnvironment(options, filepath, drive, knownSystem, mediaType, null);
var env = new DumpEnvironment(options, filepath, drive, knownSystem, mediaType, internalProgram: null, parameters: null);
// Finally, attempt to do the output dance
var result = env.VerifyAndSaveDumpOutput(resultProgress, protectionProgress).ConfigureAwait(false).GetAwaiter().GetResult();

View File

@@ -98,7 +98,6 @@ namespace MPF.Core.Converters
if (!LongNameMethods.TryGetValue(sourceType, out MethodInfo method))
{
method = typeof(RedumpLib.Data.Extensions).GetMethod("LongName", new[] { typeof(Nullable<>).MakeGenericType(sourceType) });
if (method == null)
method = typeof(EnumConverter).GetMethod("LongName", new[] { typeof(Nullable<>).MakeGenericType(sourceType) });

View File

@@ -604,14 +604,25 @@ namespace MPF.Core.Data
// TODO: Reduce reliance on `DriveInfo`
// https://github.com/aaru-dps/Aaru/blob/5164a154e2145941472f2ee0aeb2eff3338ecbb3/Aaru.Devices/Windows/ListDevices.cs#L66
// Create an output drive list
List<Drive> drives = new List<Drive>();
// Get all standard supported drive types
try
{
// Get all supported drive types
var drives = DriveInfo.GetDrives()
drives = DriveInfo.GetDrives()
.Where(d => desiredDriveTypes.Contains(d.DriveType))
.Select(d => Create(EnumConverter.ToInternalDriveType(d.DriveType), d.Name))
.ToList();
}
catch
{
return drives;
}
// Find and update all floppy drives
try
{
CimSession session = CimSession.Create(null);
var collection = session.QueryInstances("root\\CIMV2", "WQL", "SELECT * FROM Win32_LogicalDisk");
@@ -625,13 +636,13 @@ namespace MPF.Core.Data
drives.ForEach(d => { if (d.Letter == devId) { d.InternalDriveType = Data.InternalDriveType.Floppy; } });
}
}
return drives;
}
catch
{
return new List<Drive>();
// No-op
}
return drives;
}
#endregion

View File

@@ -306,6 +306,24 @@ namespace MPF.Core.Data
#region Redumper
/// <summary>
/// Enable debug output while dumping by default
/// </summary>
public bool RedumperEnableDebug
{
get { return GetBooleanSetting(_settings, "RedumperEnableDebug", false); }
set { _settings["RedumperEnableDebug"] = value.ToString(); }
}
/// <summary>
/// Enable verbose output while dumping by default
/// </summary>
public bool RedumperEnableVerbose
{
get { return GetBooleanSetting(_settings, "RedumperEnableVerbose", false); }
set { _settings["RedumperEnableVerbose"] = value.ToString(); }
}
/// <summary>
/// Default number of rereads
/// </summary>

View File

@@ -0,0 +1,38 @@
namespace MPF.Core.Data
{
/// <summary>
/// Disc Information and Emergency Brake data shall be read from the PIC zone. DI units that
/// contain physical information shall be returned.Emergency Brake data shall be returned.The
/// information shall be collected from the layer specified in the Layer field of the CDB. If any data
/// can be returned, 4 100 bytes shall be returned.
/// </summary>
/// <see href="https://www.t10.org/ftp/t10/document.05/05-206r0.pdf"/>
/// <see href="https://github.com/aaru-dps/Aaru.Decoders/blob/devel/Bluray/DI.cs"/>
public class PICDiscInformation
{
#region Fields
/// <summary>
/// 2048 bytes for BD-ROM, 3584 bytes for BD-R/RE
/// </summary>
/// <remarks>Big-endian format</remarks>
public ushort DataStructureLength { get; set; }
/// <summary>
/// Should be 0x00
/// </summary>
public byte Reserved0 { get; set; }
/// <summary>
/// Should be 0x00
/// </summary>
public byte Reserved1 { get; set; }
/// <summary>
/// Disc information and emergency brake units
/// </summary>
public PICDiscInformationUnit[] Units { get; set; }
#endregion
}
}

View File

@@ -0,0 +1,114 @@
namespace MPF.Core.Data
{
/// <see href="https://www.t10.org/ftp/t10/document.05/05-206r0.pdf"/>
/// <see href="https://github.com/aaru-dps/Aaru.Decoders/blob/devel/Bluray/DI.cs"/>
public class PICDiscInformationUnit
{
#region Fields
#region Header
/// <summary>
/// Disc Information Identifier "DI"
/// Emergency Brake Identifier "EB"
/// </summary>
public string DiscInformationIdentifier { get; set; }
/// <summary>
/// Disc Information Format
/// </summary>
public byte DiscInformationFormat { get; set; }
/// <summary>
/// Number of DI units in each DI block
/// </summary>
public byte NumberOfUnitsInBlock { get; set; }
/// <summary>
/// Should be 0x00
/// </summary>
public byte Reserved0 { get; set; }
/// <summary>
/// DI unit Sequence Number
/// </summary>
public byte SequenceNumber { get; set; }
/// <summary>
/// Number of bytes in use in this DI unit
/// </summary>
public byte BytesInUse { get; set; }
/// <summary>
/// Should be 0x00
/// </summary>
public byte Reserved1 { get; set; }
#endregion
// TODO: Write models for the dependent contents, if possible
#region Body
/// <summary>
/// Disc Type Identifier
/// = "BDO" for BD-ROM
/// = "BDU" for BD-ROM Ultra
/// = "BDW" for BD-RE
/// = "BDR" for BD-R
/// </summary>
public string DiscTypeIdentifier { get; set; }
/// <summary>
/// Disc Size/Class/Version
/// </summary>
public byte DiscSizeClassVersion { get; set; }
/// <summary>
/// DI Unit Format dependent contents
/// </summary>
/// <remarks>52 bytes for BD-ROM, 100 bytes for BD-R/RE</remarks>
public byte[] FormatDependentContents { get; set; }
#endregion
#region Trailer (BD-R/RE only)
/// <summary>
/// Disc Manufacturer ID
/// </summary>
/// <remarks>6 bytes</remarks>
public byte[] DiscManufacturerID { get; set; }
/// <summary>
/// Media Type ID
/// </summary>
/// <remarks>3 bytes</remarks>
public byte[] MediaTypeID { get; set; }
/// <summary>
/// Time Stamp
/// </summary>
public ushort TimeStamp { get; set; }
/// <summary>
/// Product Revision Number
/// </summary>
public byte ProductRevisionNumber { get; set; }
#endregion
#endregion
#region Constants
public const string DiscTypeIdentifierROM = "BDO";
public const string DiscTypeIdentifierROMUltra = "BDU";
public const string DiscTypeIdentifierReWritable = "BDW";
public const string DiscTypeIdentifierRecordable = "BDR";
#endregion
}
}

View File

@@ -2,11 +2,11 @@
<PropertyGroup>
<TargetFrameworks>net48;net6.0</TargetFrameworks>
<RuntimeIdentifiers>win7-x64;win-x86;win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
<RuntimeIdentifiers>win7-x64;win8-x64;win81-x64;win10-x64;linux-x64;osx-x64</RuntimeIdentifiers>
<Authors>Matt Nadareski;ReignStumble;Jakz</Authors>
<Copyright>Copyright (c)2019-2023</Copyright>
<RepositoryUrl>https://github.com/SabreTools/MPF</RepositoryUrl>
<Version>2.5</Version>
<Version>2.6.2</Version>
<AssemblyVersion>$(Version)</AssemblyVersion>
<FileVersion>$(Version)</FileVersion>
<IncludeSource>true</IncludeSource>
@@ -47,7 +47,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.Management.Infrastructure" Version="2.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="System.Configuration.ConfigurationManager" Version="7.0.0" />
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="6.0.0" />
</ItemGroup>

View File

@@ -72,6 +72,7 @@ namespace MPF.Core.Utilities
case RedumpSystem.SonyPlayStation3:
case RedumpSystem.SonyPlayStation4:
//case RedumpSystem.SonyPlayStation5:
case RedumpSystem.SonyPlayStationPortable:
return true;
default:
return false;
@@ -94,11 +95,13 @@ namespace MPF.Core.Utilities
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:

View File

@@ -2,11 +2,11 @@
<PropertyGroup>
<TargetFrameworks>net48;net6.0</TargetFrameworks>
<RuntimeIdentifiers>win7-x64;win-x86;win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
<RuntimeIdentifiers>win7-x64;win8-x64;win81-x64;win10-x64;linux-x64;osx-x64</RuntimeIdentifiers>
<Authors>Matt Nadareski;ReignStumble;Jakz</Authors>
<Copyright>Copyright (c)2019-2023</Copyright>
<RepositoryUrl>https://github.com/SabreTools/MPF</RepositoryUrl>
<Version>2.5</Version>
<Version>2.6.2</Version>
<AssemblyVersion>$(Version)</AssemblyVersion>
<FileVersion>$(Version)</FileVersion>
<IncludeSource>true</IncludeSource>

View File

@@ -42,10 +42,15 @@ namespace MPF.Library
/// </summary>
public MediaType? Type { get; private set; }
/// <summary>
/// Currently selected dumping program
/// </summary>
public InternalProgram InternalProgram { get; private set; }
/// <summary>
/// Options object representing user-defined options
/// </summary>
public Options Options { get; private set; }
public Core.Data.Options Options { get; private set; }
/// <summary>
/// Parameters object representing what to send to the internal program
@@ -86,12 +91,14 @@ namespace MPF.Library
/// <param name="drive"></param>
/// <param name="system"></param>
/// <param name="type"></param>
/// <param name="internalProgram"></param>
/// <param name="parameters"></param>
public DumpEnvironment(Options options,
public DumpEnvironment(Core.Data.Options options,
string outputPath,
Drive drive,
RedumpSystem? system,
MediaType? type,
InternalProgram? internalProgram,
string parameters)
{
// Set options object
@@ -104,6 +111,7 @@ namespace MPF.Library
this.Drive = drive;
this.System = system ?? options.DefaultSystem;
this.Type = type ?? MediaType.NONE;
this.InternalProgram = internalProgram ?? options.InternalProgram;
// Dumping program
SetParameters(parameters);
@@ -154,7 +162,7 @@ namespace MPF.Library
/// <param name="parameters">String representation of the parameters</param>
public void SetParameters(string parameters)
{
switch (Options.InternalProgram)
switch (this.InternalProgram)
{
// Dumping support
case InternalProgram.Aaru:
@@ -212,7 +220,7 @@ namespace MPF.Library
return null;
// Set the proper parameters
switch (Options.InternalProgram)
switch (this.InternalProgram)
{
case InternalProgram.Aaru:
Parameters = new Modules.Aaru.Parameters(System, Type, Drive.Letter, this.OutputPath, driveSpeed, Options);
@@ -283,10 +291,10 @@ namespace MPF.Library
}
// Execute internal tool
progress?.Report(Result.Success($"Executing {Options.InternalProgram}... {(Options.ToolsInSeparateWindow ? "please wait!" : "see log for output!")}"));
progress?.Report(Result.Success($"Executing {this.InternalProgram}... {(Options.ToolsInSeparateWindow ? "please wait!" : "see log for output!")}"));
Directory.CreateDirectory(Path.GetDirectoryName(this.OutputPath));
await Task.Run(() => Parameters.ExecuteInternalProgram(Options.ToolsInSeparateWindow));
progress?.Report(Result.Success($"{Options.InternalProgram} has finished!"));
progress?.Report(Result.Success($"{this.InternalProgram} has finished!"));
// Execute additional tools
progress?.Report(Result.Success("Running any additional tools... see log for output!"));
@@ -350,7 +358,7 @@ namespace MPF.Library
}
// Reset the drive automatically if configured to
if (Options.InternalProgram == InternalProgram.DiscImageCreator && Options.DICResetDriveAfterDump)
if (this.InternalProgram == InternalProgram.DiscImageCreator && Options.DICResetDriveAfterDump)
{
resultProgress?.Report(Result.Success($"Resetting drive {Drive.Letter}"));
await ResetDrive();

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Drawing.Drawing2D;
using System.IO;
using System.IO.Compression;
using System.Linq;
@@ -40,7 +41,7 @@ namespace MPF.Library
Drive drive,
RedumpSystem? system,
MediaType? mediaType,
Options options,
Core.Data.Options options,
BaseParameters parameters,
IProgress<Result> resultProgress = null,
IProgress<ProtectionProgress> protectionProgress = null)
@@ -199,26 +200,15 @@ namespace MPF.Library
break;
case MediaType.UMD:
// If we have a single-layer disc
if (info.SizeAndChecksums.Layerbreak == default)
{
info.CommonDiscInfo.Layer0MasteringRing = options.AddPlaceholders ? Template.RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Layer0MasteringSID = options.AddPlaceholders ? Template.RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Layer0ToolstampMasteringCode = options.AddPlaceholders ? Template.RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Layer0MouldSID = options.AddPlaceholders ? Template.RequiredIfExistsValue : string.Empty;
}
// If we have a dual-layer disc
else
{
info.CommonDiscInfo.Layer0MasteringRing = options.AddPlaceholders ? Template.RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Layer0MasteringSID = options.AddPlaceholders ? Template.RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Layer0ToolstampMasteringCode = options.AddPlaceholders ? Template.RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Layer0MouldSID = options.AddPlaceholders ? Template.RequiredIfExistsValue : string.Empty;
// Both single- and dual-layer discs have two "layers" for the ring
info.CommonDiscInfo.Layer0MasteringRing = options.AddPlaceholders ? Template.RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Layer0MasteringSID = options.AddPlaceholders ? Template.RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Layer0ToolstampMasteringCode = options.AddPlaceholders ? Template.RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Layer0MouldSID = options.AddPlaceholders ? Template.RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Layer1MasteringRing = options.AddPlaceholders ? Template.RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Layer1MasteringSID = options.AddPlaceholders ? Template.RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Layer1ToolstampMasteringCode = options.AddPlaceholders ? Template.RequiredIfExistsValue : string.Empty;
}
info.CommonDiscInfo.Layer1MasteringRing = options.AddPlaceholders ? Template.RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Layer1MasteringSID = options.AddPlaceholders ? Template.RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Layer1ToolstampMasteringCode = options.AddPlaceholders ? Template.RequiredIfExistsValue : string.Empty;
info.SizeAndChecksums.CRC32 = info.SizeAndChecksums.CRC32 ?? (options.AddPlaceholders ? Template.RequiredValue + " [Not automatically generated for UMD]" : string.Empty);
info.SizeAndChecksums.MD5 = info.SizeAndChecksums.MD5 ?? (options.AddPlaceholders ? Template.RequiredValue + " [Not automatically generated for UMD]" : string.Empty);
@@ -330,6 +320,16 @@ namespace MPF.Library
break;
case RedumpSystem.MicrosoftXboxSeriesXS:
string xboxSeriesXMsxcPath = Path.Combine($"{drive.Letter}:\\", "MSXC");
if (drive != null && Directory.Exists(xboxSeriesXMsxcPath))
{
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.Filename] = string.Join("\n",
Directory.GetFiles(xboxSeriesXMsxcPath, "*", SearchOption.TopDirectoryOnly).Select(Path.GetFileName));
}
break;
case RedumpSystem.NamcoSegaNintendoTriforce:
info.CommonDiscInfo.EXEDateBuildDate = options.AddPlaceholders ? Template.RequiredValue : string.Empty;
break;
@@ -467,7 +467,7 @@ namespace MPF.Library
/// <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>
private static async Task<(string, Dictionary<string, List<string>>)> GetCopyProtection(Drive drive, Options options, IProgress<ProtectionProgress> progress = null)
private static async Task<(string, Dictionary<string, List<string>>)> GetCopyProtection(Drive drive, Core.Data.Options options, IProgress<ProtectionProgress> progress = null)
{
if (options.ScanForProtection && drive != null)
{
@@ -616,7 +616,11 @@ namespace MPF.Library
foreach (string file in files)
{
string entryName = file.Substring(outputDirectory.Length).TrimStart(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
zf.CreateEntryFromFile(file, entryName);
#if NET48 || NETSTANDARD2_1
zf.CreateEntryFromFile(file, entryName, CompressionLevel.Optimal);
#else
zf.CreateEntryFromFile(file, entryName, CompressionLevel.SmallestSize);
#endif
// If the file is MPF-specific, don't delete
if (mpfFiles.Contains(file))
@@ -647,7 +651,7 @@ namespace MPF.Library
/// <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>
public static (List<string>, string) FormatOutputData(SubmissionInfo info, Options options)
public static (List<string>, string) FormatOutputData(SubmissionInfo info, Core.Data.Options options)
{
// Check to see if the inputs are valid
if (info == null)
@@ -668,6 +672,7 @@ namespace MPF.Library
AddIfExists(output, Template.SystemField, info.CommonDiscInfo.System.LongName(), 1);
AddIfExists(output, Template.MediaTypeField, GetFixedMediaType(
info.CommonDiscInfo.Media.ToMediaType(),
info.SizeAndChecksums.PICIdentifier,
info.SizeAndChecksums.Size,
info.SizeAndChecksums.Layerbreak,
info.SizeAndChecksums.Layerbreak2,
@@ -682,81 +687,82 @@ namespace MPF.Library
AddIfExists(output, Template.DiscSerialField, info.CommonDiscInfo.Serial, 1);
// All ringcode information goes in an indented area
output.Add(""); output.Add("\tRingcode Information:");
output.Add(""); output.Add("\tRingcode Information:"); output.Add("");
// If we have a triple-layer disc
if (info.SizeAndChecksums.Layerbreak3 != default)
{
AddIfExists(output, (reverseOrder ? "Layer 0 (Outer) " : "Layer 0 (Inner) ") + Template.MasteringRingField, info.CommonDiscInfo.Layer0MasteringRing, 2);
AddIfExists(output, (reverseOrder ? "Layer 0 (Outer) " : "Layer 0 (Inner) ") + Template.MasteringSIDField, info.CommonDiscInfo.Layer0MasteringSID, 2);
AddIfExists(output, (reverseOrder ? "Layer 0 (Outer) " : "Layer 0 (Inner) ") + Template.ToolstampField, info.CommonDiscInfo.Layer0ToolstampMasteringCode, 2);
AddIfExists(output, "Data Side " + Template.MouldSIDField, info.CommonDiscInfo.Layer0MouldSID, 2);
AddIfExists(output, "Data Side " + Template.AdditionalMouldField, info.CommonDiscInfo.Layer0AdditionalMould, 2);
AddIfExists(output, (reverseOrder ? "Layer 0 (Outer) " : "Layer 0 (Inner) ") + Template.MasteringRingField, info.CommonDiscInfo.Layer0MasteringRing, 0);
AddIfExists(output, (reverseOrder ? "Layer 0 (Outer) " : "Layer 0 (Inner) ") + Template.MasteringSIDField, info.CommonDiscInfo.Layer0MasteringSID, 0);
AddIfExists(output, (reverseOrder ? "Layer 0 (Outer) " : "Layer 0 (Inner) ") + Template.ToolstampField, info.CommonDiscInfo.Layer0ToolstampMasteringCode, 0);
AddIfExists(output, "Data Side " + Template.MouldSIDField, info.CommonDiscInfo.Layer0MouldSID, 0);
AddIfExists(output, "Data Side " + Template.AdditionalMouldField, info.CommonDiscInfo.Layer0AdditionalMould, 0);
AddIfExists(output, "Layer 1 " + Template.MasteringRingField, info.CommonDiscInfo.Layer1MasteringRing, 2);
AddIfExists(output, "Layer 1 " + Template.MasteringSIDField, info.CommonDiscInfo.Layer1MasteringSID, 2);
AddIfExists(output, "Layer 1 " + Template.ToolstampField, info.CommonDiscInfo.Layer1ToolstampMasteringCode, 2);
AddIfExists(output, "Label Side " + Template.MouldSIDField, info.CommonDiscInfo.Layer1MouldSID, 2);
AddIfExists(output, "Label Side " + Template.AdditionalMouldField, info.CommonDiscInfo.Layer1AdditionalMould, 2);
AddIfExists(output, "Layer 1 " + Template.MasteringRingField, info.CommonDiscInfo.Layer1MasteringRing, 0);
AddIfExists(output, "Layer 1 " + Template.MasteringSIDField, info.CommonDiscInfo.Layer1MasteringSID, 0);
AddIfExists(output, "Layer 1 " + Template.ToolstampField, info.CommonDiscInfo.Layer1ToolstampMasteringCode, 0);
AddIfExists(output, "Label Side " + Template.MouldSIDField, info.CommonDiscInfo.Layer1MouldSID, 0);
AddIfExists(output, "Label Side " + Template.AdditionalMouldField, info.CommonDiscInfo.Layer1AdditionalMould, 0);
AddIfExists(output, "Layer 2 " + Template.MasteringRingField, info.CommonDiscInfo.Layer2MasteringRing, 2);
AddIfExists(output, "Layer 2 " + Template.MasteringSIDField, info.CommonDiscInfo.Layer2MasteringSID, 2);
AddIfExists(output, "Layer 2 " + Template.ToolstampField, info.CommonDiscInfo.Layer2ToolstampMasteringCode, 2);
AddIfExists(output, "Layer 2 " + Template.MasteringRingField, info.CommonDiscInfo.Layer2MasteringRing, 0);
AddIfExists(output, "Layer 2 " + Template.MasteringSIDField, info.CommonDiscInfo.Layer2MasteringSID, 0);
AddIfExists(output, "Layer 2 " + Template.ToolstampField, info.CommonDiscInfo.Layer2ToolstampMasteringCode, 0);
AddIfExists(output, (reverseOrder ? "Layer 3 (Inner) " : "Layer 3 (Outer) ") + Template.MasteringRingField, info.CommonDiscInfo.Layer3MasteringRing, 2);
AddIfExists(output, (reverseOrder ? "Layer 3 (Inner) " : "Layer 3 (Outer) ") + Template.MasteringSIDField, info.CommonDiscInfo.Layer3MasteringSID, 2);
AddIfExists(output, (reverseOrder ? "Layer 3 (Inner) " : "Layer 3 (Outer) ") + Template.ToolstampField, info.CommonDiscInfo.Layer3ToolstampMasteringCode, 2);
AddIfExists(output, (reverseOrder ? "Layer 3 (Inner) " : "Layer 3 (Outer) ") + Template.MasteringRingField, info.CommonDiscInfo.Layer3MasteringRing, 0);
AddIfExists(output, (reverseOrder ? "Layer 3 (Inner) " : "Layer 3 (Outer) ") + Template.MasteringSIDField, info.CommonDiscInfo.Layer3MasteringSID, 0);
AddIfExists(output, (reverseOrder ? "Layer 3 (Inner) " : "Layer 3 (Outer) ") + Template.ToolstampField, info.CommonDiscInfo.Layer3ToolstampMasteringCode, 0);
}
// If we have a triple-layer disc
else if (info.SizeAndChecksums.Layerbreak2 != default)
{
AddIfExists(output, (reverseOrder ? "Layer 0 (Outer) " : "Layer 0 (Inner) ") + Template.MasteringRingField, info.CommonDiscInfo.Layer0MasteringRing, 2);
AddIfExists(output, (reverseOrder ? "Layer 0 (Outer) " : "Layer 0 (Inner) ") + Template.MasteringSIDField, info.CommonDiscInfo.Layer0MasteringSID, 2);
AddIfExists(output, (reverseOrder ? "Layer 0 (Outer) " : "Layer 0 (Inner) ") + Template.ToolstampField, info.CommonDiscInfo.Layer0ToolstampMasteringCode, 2);
AddIfExists(output, "Data Side " + Template.MouldSIDField, info.CommonDiscInfo.Layer0MouldSID, 2);
AddIfExists(output, "Data Side " + Template.AdditionalMouldField, info.CommonDiscInfo.Layer0AdditionalMould, 2);
AddIfExists(output, (reverseOrder ? "Layer 0 (Outer) " : "Layer 0 (Inner) ") + Template.MasteringRingField, info.CommonDiscInfo.Layer0MasteringRing, 0);
AddIfExists(output, (reverseOrder ? "Layer 0 (Outer) " : "Layer 0 (Inner) ") + Template.MasteringSIDField, info.CommonDiscInfo.Layer0MasteringSID, 0);
AddIfExists(output, (reverseOrder ? "Layer 0 (Outer) " : "Layer 0 (Inner) ") + Template.ToolstampField, info.CommonDiscInfo.Layer0ToolstampMasteringCode, 0);
AddIfExists(output, "Data Side " + Template.MouldSIDField, info.CommonDiscInfo.Layer0MouldSID, 0);
AddIfExists(output, "Data Side " + Template.AdditionalMouldField, info.CommonDiscInfo.Layer0AdditionalMould, 0);
AddIfExists(output, "Layer 1 " + Template.MasteringRingField, info.CommonDiscInfo.Layer1MasteringRing, 2);
AddIfExists(output, "Layer 1 " + Template.MasteringSIDField, info.CommonDiscInfo.Layer1MasteringSID, 2);
AddIfExists(output, "Layer 1 " + Template.ToolstampField, info.CommonDiscInfo.Layer1ToolstampMasteringCode, 2);
AddIfExists(output, "Label Side " + Template.MouldSIDField, info.CommonDiscInfo.Layer1MouldSID, 2);
AddIfExists(output, "Label Side " + Template.AdditionalMouldField, info.CommonDiscInfo.Layer1AdditionalMould, 2);
AddIfExists(output, "Layer 1 " + Template.MasteringRingField, info.CommonDiscInfo.Layer1MasteringRing, 0);
AddIfExists(output, "Layer 1 " + Template.MasteringSIDField, info.CommonDiscInfo.Layer1MasteringSID, 0);
AddIfExists(output, "Layer 1 " + Template.ToolstampField, info.CommonDiscInfo.Layer1ToolstampMasteringCode, 0);
AddIfExists(output, "Label Side " + Template.MouldSIDField, info.CommonDiscInfo.Layer1MouldSID, 0);
AddIfExists(output, "Label Side " + Template.AdditionalMouldField, info.CommonDiscInfo.Layer1AdditionalMould, 0);
AddIfExists(output, (reverseOrder ? "Layer 2 (Inner) " : "Layer 2 (Outer) ") + Template.MasteringRingField, info.CommonDiscInfo.Layer2MasteringRing, 2);
AddIfExists(output, (reverseOrder ? "Layer 2 (Inner) " : "Layer 2 (Outer) ") + Template.MasteringSIDField, info.CommonDiscInfo.Layer2MasteringSID, 2);
AddIfExists(output, (reverseOrder ? "Layer 2 (Inner) " : "Layer 2 (Outer) ") + Template.ToolstampField, info.CommonDiscInfo.Layer2ToolstampMasteringCode, 2);
AddIfExists(output, (reverseOrder ? "Layer 2 (Inner) " : "Layer 2 (Outer) ") + Template.MasteringRingField, info.CommonDiscInfo.Layer2MasteringRing, 0);
AddIfExists(output, (reverseOrder ? "Layer 2 (Inner) " : "Layer 2 (Outer) ") + Template.MasteringSIDField, info.CommonDiscInfo.Layer2MasteringSID, 0);
AddIfExists(output, (reverseOrder ? "Layer 2 (Inner) " : "Layer 2 (Outer) ") + Template.ToolstampField, info.CommonDiscInfo.Layer2ToolstampMasteringCode, 0);
}
// If we have a dual-layer disc
else if (info.SizeAndChecksums.Layerbreak != default)
{
AddIfExists(output, (reverseOrder ? "Layer 0 (Outer) " : "Layer 0 (Inner) ") + Template.MasteringRingField, info.CommonDiscInfo.Layer0MasteringRing, 2);
AddIfExists(output, (reverseOrder ? "Layer 0 (Outer) " : "Layer 0 (Inner) ") + Template.MasteringSIDField, info.CommonDiscInfo.Layer0MasteringSID, 2);
AddIfExists(output, (reverseOrder ? "Layer 0 (Outer) " : "Layer 0 (Inner) ") + Template.ToolstampField, info.CommonDiscInfo.Layer0ToolstampMasteringCode, 2);
AddIfExists(output, "Data Side " + Template.MouldSIDField, info.CommonDiscInfo.Layer0MouldSID, 2);
AddIfExists(output, "Data Side " + Template.AdditionalMouldField, info.CommonDiscInfo.Layer0AdditionalMould, 2);
AddIfExists(output, (reverseOrder ? "Layer 0 (Outer) " : "Layer 0 (Inner) ") + Template.MasteringRingField, info.CommonDiscInfo.Layer0MasteringRing, 0);
AddIfExists(output, (reverseOrder ? "Layer 0 (Outer) " : "Layer 0 (Inner) ") + Template.MasteringSIDField, info.CommonDiscInfo.Layer0MasteringSID, 0);
AddIfExists(output, (reverseOrder ? "Layer 0 (Outer) " : "Layer 0 (Inner) ") + Template.ToolstampField, info.CommonDiscInfo.Layer0ToolstampMasteringCode, 0);
AddIfExists(output, "Data Side " + Template.MouldSIDField, info.CommonDiscInfo.Layer0MouldSID, 0);
AddIfExists(output, "Data Side " + Template.AdditionalMouldField, info.CommonDiscInfo.Layer0AdditionalMould, 0);
AddIfExists(output, (reverseOrder ? "Layer 1 (Inner) " : "Layer 1 (Outer) ") + Template.MasteringRingField, info.CommonDiscInfo.Layer1MasteringRing, 2);
AddIfExists(output, (reverseOrder ? "Layer 1 (Inner) " : "Layer 1 (Outer) ") + Template.MasteringSIDField, info.CommonDiscInfo.Layer1MasteringSID, 2);
AddIfExists(output, (reverseOrder ? "Layer 1 (Inner) " : "Layer 1 (Outer) ") + Template.ToolstampField, info.CommonDiscInfo.Layer1ToolstampMasteringCode, 2);
AddIfExists(output, "Label Side " + Template.MouldSIDField, info.CommonDiscInfo.Layer1MouldSID, 2);
AddIfExists(output, "Label Side " + Template.AdditionalMouldField, info.CommonDiscInfo.Layer1AdditionalMould, 2);
AddIfExists(output, (reverseOrder ? "Layer 1 (Inner) " : "Layer 1 (Outer) ") + Template.MasteringRingField, info.CommonDiscInfo.Layer1MasteringRing, 0);
AddIfExists(output, (reverseOrder ? "Layer 1 (Inner) " : "Layer 1 (Outer) ") + Template.MasteringSIDField, info.CommonDiscInfo.Layer1MasteringSID, 0);
AddIfExists(output, (reverseOrder ? "Layer 1 (Inner) " : "Layer 1 (Outer) ") + Template.ToolstampField, info.CommonDiscInfo.Layer1ToolstampMasteringCode, 0);
AddIfExists(output, "Label Side " + Template.MouldSIDField, info.CommonDiscInfo.Layer1MouldSID, 0);
AddIfExists(output, "Label Side " + Template.AdditionalMouldField, info.CommonDiscInfo.Layer1AdditionalMould, 0);
}
// If we have a single-layer disc
else
{
AddIfExists(output, "Data Side " + Template.MasteringRingField, info.CommonDiscInfo.Layer0MasteringRing, 2);
AddIfExists(output, "Data Side " + Template.MasteringSIDField, info.CommonDiscInfo.Layer0MasteringSID, 2);
AddIfExists(output, "Data Side " + Template.ToolstampField, info.CommonDiscInfo.Layer0ToolstampMasteringCode, 2);
AddIfExists(output, "Data Side " + Template.MouldSIDField, info.CommonDiscInfo.Layer0MouldSID, 2);
AddIfExists(output, "Data Side " + Template.AdditionalMouldField, info.CommonDiscInfo.Layer0AdditionalMould, 2);
AddIfExists(output, "Data Side " + Template.MasteringRingField, info.CommonDiscInfo.Layer0MasteringRing, 0);
AddIfExists(output, "Data Side " + Template.MasteringSIDField, info.CommonDiscInfo.Layer0MasteringSID, 0);
AddIfExists(output, "Data Side " + Template.ToolstampField, info.CommonDiscInfo.Layer0ToolstampMasteringCode, 0);
AddIfExists(output, "Data Side " + Template.MouldSIDField, info.CommonDiscInfo.Layer0MouldSID, 0);
AddIfExists(output, "Data Side " + Template.AdditionalMouldField, info.CommonDiscInfo.Layer0AdditionalMould, 0);
AddIfExists(output, "Label Side " + Template.MasteringRingField, info.CommonDiscInfo.Layer1MasteringRing, 2);
AddIfExists(output, "Label Side " + Template.MasteringSIDField, info.CommonDiscInfo.Layer1MasteringSID, 2);
AddIfExists(output, "Label Side " + Template.ToolstampField, info.CommonDiscInfo.Layer1ToolstampMasteringCode, 2);
AddIfExists(output, "Label Side " + Template.MouldSIDField, info.CommonDiscInfo.Layer1MouldSID, 2);
AddIfExists(output, "Label Side " + Template.AdditionalMouldField, info.CommonDiscInfo.Layer1AdditionalMould, 2);
AddIfExists(output, "Label Side " + Template.MasteringRingField, info.CommonDiscInfo.Layer1MasteringRing, 0);
AddIfExists(output, "Label Side " + Template.MasteringSIDField, info.CommonDiscInfo.Layer1MasteringSID, 0);
AddIfExists(output, "Label Side " + Template.ToolstampField, info.CommonDiscInfo.Layer1ToolstampMasteringCode, 0);
AddIfExists(output, "Label Side " + Template.MouldSIDField, info.CommonDiscInfo.Layer1MouldSID, 0);
AddIfExists(output, "Label Side " + Template.AdditionalMouldField, info.CommonDiscInfo.Layer1AdditionalMould, 0);
}
output.Add("");
AddIfExists(output, Template.BarcodeField, info.CommonDiscInfo.Barcode, 1);
AddIfExists(output, Template.EXEDateBuildDate, info.CommonDiscInfo.EXEDateBuildDate, 1);
AddIfExists(output, Template.ErrorCountField, info.CommonDiscInfo.ErrorsCount, 1);
@@ -883,12 +889,14 @@ namespace MPF.Library
/// Get the adjusted name of the media based on layers, if applicable
/// </summary>
/// <param name="mediaType">MediaType to get the proper name for</param>
/// <param name="picIdentifier">PIC identifier string (BD only)</param>
/// <param name="size">Size of the current media</param>
/// <param name="layerbreak">First layerbreak value, as applicable</param>
/// <param name="layerbreak2">Second layerbreak value, as applicable</param>
/// <param name="layerbreak3">Third layerbreak value, as applicable</param>
/// <returns>String representation of the media, including layer specification</returns>
public static string GetFixedMediaType(MediaType? mediaType, long size, long layerbreak, long layerbreak2, long layerbreak3)
/// TODO: Figure out why we have this and NormalizeDiscType as well
public static string GetFixedMediaType(MediaType? mediaType, string picIdentifier, long size, long layerbreak, long layerbreak2, long layerbreak3)
{
switch (mediaType)
{
@@ -903,12 +911,16 @@ namespace MPF.Library
return $"{mediaType.LongName()}-128";
else if (layerbreak2 != default)
return $"{mediaType.LongName()}-100";
//else if (layerbreak != default && size > 53_687_063_712)
// return $"{mediaType.LongName()}-66";
else if (layerbreak != default && picIdentifier == PICDiscInformationUnit.DiscTypeIdentifierROMUltra)
return $"{mediaType.LongName()}-66";
else if (layerbreak != default && size > 53_687_063_712)
return $"{mediaType.LongName()}-66";
else if (layerbreak != default)
return $"{mediaType.LongName()}-50";
//else if (size > 26_843_531_856)
// return $"{mediaType.LongName()}-33";
else if (picIdentifier == PICDiscInformationUnit.DiscTypeIdentifierROMUltra)
return $"{mediaType.LongName()}-33";
else if (size > 26_843_531_856)
return $"{mediaType.LongName()}-33";
else
return $"{mediaType.LongName()}-25";
@@ -1604,21 +1616,25 @@ namespace MPF.Library
switch (info.CommonDiscInfo.Media)
{
case DiscType.BD25:
//case DiscType.BD33:
case DiscType.BD33:
case DiscType.BD50:
//case DiscType.BD66:
case DiscType.BD66:
case DiscType.BD100:
case DiscType.BD128:
if (info.SizeAndChecksums.Layerbreak3 != default)
info.CommonDiscInfo.Media = DiscType.BD128;
else if (info.SizeAndChecksums.Layerbreak2 != default)
info.CommonDiscInfo.Media = DiscType.BD100;
//else if (info.SizeAndChecksums.Layerbreak != default && info.SizeAndChecksums.Size > 53_687_063_712)
// info.CommonDiscInfo.Media = DiscType.BD66;
else if (info.SizeAndChecksums.Layerbreak != default && info.SizeAndChecksums.PICIdentifier == PICDiscInformationUnit.DiscTypeIdentifierROMUltra)
info.CommonDiscInfo.Media = DiscType.BD66;
else if (info.SizeAndChecksums.Layerbreak != default && info.SizeAndChecksums.Size > 50_050_629_632)
info.CommonDiscInfo.Media = DiscType.BD66;
else if (info.SizeAndChecksums.Layerbreak != default)
info.CommonDiscInfo.Media = DiscType.BD50;
//else if (info.SizeAndChecksums.Size > 26_843_531_856)
// info.CommonDiscInfo.Media = DiscType.BD33;
else if (info.SizeAndChecksums.PICIdentifier == PICDiscInformationUnit.DiscTypeIdentifierROMUltra)
info.CommonDiscInfo.Media = DiscType.BD33;
else if (info.SizeAndChecksums.Size > 25_025_314_816)
info.CommonDiscInfo.Media = DiscType.BD33;
else
info.CommonDiscInfo.Media = DiscType.BD25;
break;
@@ -2037,18 +2053,55 @@ namespace MPF.Library
if (!commentLine.Contains(siteCode.ShortName()))
continue;
// Mark as having found a tag
foundTag = true;
// Cache the current site code
lastSiteCode = siteCode;
// A subset of tags can be multiline
addToLast = IsMultiLine(siteCode);
// Skip certain site codes because of data issues
switch (siteCode)
{
// Multiple
case SiteCode.InternalSerialName:
case SiteCode.Multisession:
case SiteCode.VolumeLabel:
continue;
// Audio CD
case SiteCode.RingNonZeroDataStart:
case SiteCode.UniversalHash:
continue;
// Microsoft Xbox and Xbox 360
case SiteCode.DMIHash:
case SiteCode.PFIHash:
case SiteCode.SSHash:
case SiteCode.SSVersion:
case SiteCode.XMID:
case SiteCode.XeMID:
continue;
// Microsoft Xbox One and Series X/S
case SiteCode.Filename:
continue;
// Nintendo Gamecube
case SiteCode.InternalName:
continue;
}
// If we don't already have this site code, add it to the dictionary
if (!info.CommonDiscInfo.CommentsSpecialFields.ContainsKey(siteCode))
info.CommonDiscInfo.CommentsSpecialFields[siteCode] = $"(VERIFY THIS) {commentLine.Replace(siteCode.ShortName(), string.Empty).Trim()}";
// A subset of tags can be multiline
addToLast = IsMultiLine(siteCode);
// Otherwise, append the value to the existing key
else
info.CommonDiscInfo.CommentsSpecialFields[siteCode] += $", {commentLine.Replace(siteCode.ShortName(), string.Empty).Trim()}";
// Mark as having found a tag
foundTag = true;
break;
}
@@ -2183,9 +2236,9 @@ namespace MPF.Library
/// <param name="info">Existing SubmissionInfo object to fill</param>
/// <param name="resultProgress">Optional result progress callback</param>
#if NET48 || NETSTANDARD2_1
private static bool FillFromRedump(Options options, SubmissionInfo info, IProgress<Result> resultProgress = null)
private static bool FillFromRedump(Core.Data.Options options, SubmissionInfo info, IProgress<Result> resultProgress = null)
#else
private async static Task<bool> FillFromRedump(Options options, SubmissionInfo info, IProgress<Result> resultProgress = null)
private async static Task<bool> FillFromRedump(Core.Data.Options options, SubmissionInfo info, IProgress<Result> resultProgress = null)
#endif
{
// Set the current dumper based on username
@@ -2221,9 +2274,29 @@ namespace MPF.Library
// Loop through all of the hashdata to find matching IDs
resultProgress?.Report(Result.Success("Finding disc matches on Redump..."));
string[] splitData = info.TracksAndWriteOffsets.ClrMameProData.Split('\n');
string[] splitData = info.TracksAndWriteOffsets.ClrMameProData.TrimEnd('\n').Split('\n');
int trackCount = splitData.Length;
foreach (string hashData in splitData)
{
// Catch any errant blank lines
if (string.IsNullOrWhiteSpace(hashData))
{
trackCount--;
resultProgress?.Report(Result.Success("Blank line found, skipping!"));
continue;
}
// If the line ends in a known extra track names, skip them for checking
if (hashData.Contains("(Track 0).bin")
|| hashData.Contains("(Track 00).bin")
|| hashData.Contains("(Track A).bin")
|| hashData.Contains("(Track AA).bin"))
{
trackCount--;
resultProgress?.Report(Result.Success("Extra track found, skipping!"));
continue;
}
#if NET48 || NETSTANDARD2_1
(bool singleFound, List<int> foundIds) = ValidateSingleTrack(wc, info, hashData, resultProgress);
#else
@@ -2248,6 +2321,30 @@ namespace MPF.Library
}
}
// If we don't have any matches but we have a universal hash
if (!info.PartiallyMatchedIDs.Any() && info.CommonDiscInfo.CommentsSpecialFields.ContainsKey(SiteCode.UniversalHash))
{
#if NET48 || NETSTANDARD2_1
(bool singleFound, List<int> foundIds) = ValidateUniversalHash(wc, info, resultProgress);
#else
(bool singleFound, List<int> foundIds) = await ValidateUniversalHash(wc, info, resultProgress);
#endif
// Ensure that the hash is found
allFound = singleFound;
// If we found a track, only keep track of distinct found tracks
if (singleFound && foundIds != null)
{
fullyMatchedIDs = foundIds;
}
// If no tracks were found, remove all fully matched IDs found so far
else
{
fullyMatchedIDs = new List<int>();
}
}
// Make sure we only have unique IDs
info.PartiallyMatchedIDs = info.PartiallyMatchedIDs
.Distinct()
@@ -2268,10 +2365,10 @@ namespace MPF.Library
{
// Skip if the track count doesn't match
#if NET48 || NETSTANDARD2_1
if (!ValidateTrackCount(wc, fullyMatchedIDs[i], splitData.Length))
if (!ValidateTrackCount(wc, fullyMatchedIDs[i], trackCount))
continue;
#else
if (!await ValidateTrackCount(wc, fullyMatchedIDs[i], splitData.Length))
if (!await ValidateTrackCount(wc, fullyMatchedIDs[i], trackCount))
continue;
#endif
@@ -2324,8 +2421,11 @@ namespace MPF.Library
text = text.Replace("PFI:", ((SiteCode?)SiteCode.PFIHash).ShortName());
text = text.Replace("SS:", ((SiteCode?)SiteCode.SSHash).ShortName());
text = text.Replace("SSv1:", ((SiteCode?)SiteCode.SSHash).ShortName());
text = text.Replace("<b>SSv1</b>:", ((SiteCode?)SiteCode.SSHash).ShortName());
text = text.Replace("SSv2:", ((SiteCode?)SiteCode.SSHash).ShortName());
text = text.Replace("<b>SSv2</b>:", ((SiteCode?)SiteCode.SSHash).ShortName());
text = text.Replace("SS version:", ((SiteCode?)SiteCode.SSVersion).ShortName());
text = text.Replace("Universal Hash (SHA-1):", ((SiteCode?)SiteCode.UniversalHash).ShortName());
text = text.Replace("XeMID:", ((SiteCode?)SiteCode.XeMID).ShortName());
text = text.Replace("XMID:", ((SiteCode?)SiteCode.XMID).ShortName());
@@ -2337,11 +2437,12 @@ namespace MPF.Library
/// </summary>
/// <param name="wc">RedumpWebClient for making the connection</param>
/// <param name="query">Query string to attempt to search for</param>
/// <param name="filterForwardSlashes">True to filter forward slashes, false otherwise</param>
/// <returns>All disc IDs for the given query, null on error</returns>
#if NET48 || NETSTANDARD2_1
private static List<int> ListSearchResults(RedumpWebClient wc, string query)
private static List<int> ListSearchResults(RedumpWebClient wc, string query, bool filterForwardSlashes = true)
#else
private async static Task<List<int>> ListSearchResults(RedumpHttpClient wc, string query)
private async static Task<List<int>> ListSearchResults(RedumpHttpClient wc, string query, bool filterForwardSlashes = true)
#endif
{
List<int> ids = new List<int>();
@@ -2351,7 +2452,8 @@ namespace MPF.Library
// Special characters become dashes
query = query.Replace(' ', '-');
query = query.Replace('/', '-');
if (filterForwardSlashes)
query = query.Replace('/', '-');
query = query.Replace('\\', '/');
// Lowercase is defined per language
@@ -2430,6 +2532,57 @@ namespace MPF.Library
return (true, newIds);
}
/// <summary>
/// Validate a universal hash against Redump, if possible
/// </summary>
/// <param name="wc">RedumpWebClient for making the connection</param>
/// <param name="info">Existing SubmissionInfo object to fill</param>
/// <param name="resultProgress">Optional result progress callback</param>
/// <returns>True if the track was found, false otherwise; List of found values, if possible</returns>
#if NET48 || NETSTANDARD2_1
private static (bool, List<int>) ValidateUniversalHash(RedumpWebClient wc, SubmissionInfo info, IProgress<Result> resultProgress = null)
#else
private async static Task<(bool, List<int>)> ValidateUniversalHash(RedumpHttpClient wc, SubmissionInfo info, IProgress<Result> resultProgress = null)
#endif
{
// If we don't have a universal hash
string universalHash = info.CommonDiscInfo.CommentsSpecialFields[SiteCode.UniversalHash];
if (string.IsNullOrEmpty(universalHash))
{
resultProgress?.Report(Result.Failure("Universal hash was missing"));
return (false, null);
}
// Format the universal hash for finding within the comments
universalHash = $"{universalHash.Substring(0, universalHash.Length - 1)}/comments/only";
// Get all matching IDs for the hash
#if NET48 || NETSTANDARD2_1
List<int> newIds = ListSearchResults(wc, universalHash, filterForwardSlashes: false);
#else
List<int> newIds = await ListSearchResults(wc, universalHash, filterForwardSlashes: false);
#endif
// If we got null back, there was an error
if (newIds == null)
{
resultProgress?.Report(Result.Failure("There was an unknown error retrieving information from Redump"));
return (false, null);
}
// If no IDs match any track, just return
if (!newIds.Any())
return (false, null);
// Join the list of found IDs to the existing list, if possible
if (info.PartiallyMatchedIDs.Any())
info.PartiallyMatchedIDs.AddRange(newIds);
else
info.PartiallyMatchedIDs = newIds;
return (true, newIds);
}
/// <summary>
/// Validate that the current track count and remote track count match
/// </summary>

View File

@@ -2,12 +2,12 @@
<PropertyGroup>
<TargetFrameworks>net48;net6.0</TargetFrameworks>
<RuntimeIdentifiers>win7-x64;win-x86;win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
<RuntimeIdentifiers>win7-x64;win8-x64;win81-x64;win10-x64;linux-x64;osx-x64</RuntimeIdentifiers>
<AssemblyName>MPF.Library</AssemblyName>
<Authors>Matt Nadareski;ReignStumble;Jakz</Authors>
<Copyright>Copyright (c)2019-2023</Copyright>
<RepositoryUrl>https://github.com/SabreTools/MPF</RepositoryUrl>
<Version>2.5</Version>
<Version>2.6.2</Version>
<AssemblyVersion>$(Version)</AssemblyVersion>
<FileVersion>$(Version)</FileVersion>
<IncludeSource>true</IncludeSource>
@@ -28,10 +28,10 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="BurnOutSharp" PrivateAssets="build; analyzers" ExcludeAssets="contentFiles" Version="2.7.0" GeneratePathProperty="true">
<PackageReference Include="BurnOutSharp" PrivateAssets="build; analyzers" ExcludeAssets="contentFiles" Version="2.8.0" GeneratePathProperty="true">
<IncludeAssets>runtime; compile; build; native; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="System.IO.Compression" Version="4.3.0" />
<PackageReference Include="System.IO.Compression.ZipFile" Version="4.3.0" />
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="6.0.0" />

View File

@@ -4,9 +4,8 @@ using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using BinaryObjectScanner.Protection;
using BurnOutSharp;
using BurnOutSharp.ProtectionType;
using MPF.Core.Data;
using psxt001z;
namespace MPF.Library
@@ -20,7 +19,7 @@ namespace MPF.Library
/// <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>
public static async Task<(Dictionary<string, List<string>>, string)> RunProtectionScanOnPath(string path, Options options, IProgress<ProtectionProgress> progress = null)
public static async Task<(Dictionary<string, List<string>>, string)> RunProtectionScanOnPath(string path, Core.Data.Options options, IProgress<ProtectionProgress> progress = null)
{
try
{
@@ -29,6 +28,7 @@ namespace MPF.Library
var scanner = new Scanner(
options.ScanArchivesForProtection,
scanContents: true, // Hardcoded value to avoid issues
scanGameEngines: false, // Hardcoded value to avoid issues
options.ScanPackersForProtection,
scanPaths: true, // Hardcoded value to avoid issues
options.IncludeDebugProtectionInformation,

View File

@@ -225,14 +225,16 @@ namespace MPF.Modules.Aaru
info.DumpingInfo.ReportedDiscType = fullDiscType;
}
// Get the Datafile information
Datafile datafile = GenerateDatafile(sidecar, basePath);
// Fill in the hash data
info.TracksAndWriteOffsets.ClrMameProData = GenerateDatfile(sidecar, basePath);
info.TracksAndWriteOffsets.ClrMameProData = GenerateDatfile(datafile);
switch (this.Type)
{
// TODO: Can this do GD-ROM?
case MediaType.CDROM:
// TODO: Re-enable once PVD generation / finding is fixed
// Generate / obtain the PVD
//info.Extras.PVD = GeneratePVD(sidecar) ?? "Disc has no PVD";
@@ -243,9 +245,9 @@ namespace MPF.Modules.Aaru
info.CommonDiscInfo.ErrorsCount = (errorCount == -1 ? "Error retrieving error count" : errorCount.ToString());
info.TracksAndWriteOffsets.Cuesheet = GenerateCuesheet(sidecar, basePath) ?? "";
info.TracksAndWriteOffsets.Cuesheet = GenerateCuesheet(sidecar, basePath) ?? string.Empty;
string cdWriteOffset = GetWriteOffset(sidecar) ?? "";
string cdWriteOffset = GetWriteOffset(sidecar) ?? string.Empty;
info.CommonDiscInfo.RingWriteOffset = cdWriteOffset;
info.TracksAndWriteOffsets.OtherWriteOffsets = cdWriteOffset;
break;
@@ -254,7 +256,7 @@ namespace MPF.Modules.Aaru
case MediaType.HDDVD:
case MediaType.BluRay:
// Get the individual hash data, as per internal
if (GetISOHashValues(info.TracksAndWriteOffsets.ClrMameProData, out long size, out string crc32, out string md5, out string sha1))
if (GetISOHashValues(datafile, out long size, out string crc32, out string md5, out string sha1))
{
info.SizeAndChecksums.Size = size;
info.SizeAndChecksums.CRC32 = crc32;
@@ -269,7 +271,7 @@ namespace MPF.Modules.Aaru
// Deal with the layerbreak
string layerbreak = null;
if (this.Type == MediaType.DVD)
layerbreak = GetLayerbreak(sidecar) ?? "";
layerbreak = GetLayerbreak(sidecar) ?? string.Empty;
else if (this.Type == MediaType.BluRay)
layerbreak = info.SizeAndChecksums.Size > 25_025_314_816 ? "25025314816" : null;
@@ -301,7 +303,7 @@ namespace MPF.Modules.Aaru
case RedumpSystem.DVDAudio:
case RedumpSystem.DVDVideo:
info.CopyProtection.Protection = GetDVDProtection(sidecar) ?? "";
info.CopyProtection.Protection = GetDVDProtection(sidecar) ?? string.Empty;
break;
case RedumpSystem.KonamiPython2:
@@ -313,7 +315,7 @@ namespace MPF.Modules.Aaru
info.CommonDiscInfo.EXEDateBuildDate = pythonTwoDate;
}
info.VersionAndEditions.Version = GetPlayStation2Version(drive?.Letter) ?? "";
info.VersionAndEditions.Version = GetPlayStation2Version(drive?.Letter) ?? string.Empty;
break;
case RedumpSystem.MicrosoftXbox:
@@ -323,13 +325,13 @@ namespace MPF.Modules.Aaru
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.PFIHash] = xgd1PFIHash;
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.SSHash] = xgd1SSHash;
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.SSVersion] = xgd1SSVer;
info.Extras.SecuritySectorRanges = ss ?? "";
info.Extras.SecuritySectorRanges = ss ?? string.Empty;
}
if (GetXboxDMIInfo(sidecar, out string serial, out string version, out Region? region))
{
info.CommonDiscInfo.Serial = serial ?? "";
info.VersionAndEditions.Version = version ?? "";
info.CommonDiscInfo.Serial = serial ?? string.Empty;
info.VersionAndEditions.Version = version ?? string.Empty;
info.CommonDiscInfo.Region = region;
}
@@ -342,13 +344,13 @@ namespace MPF.Modules.Aaru
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.PFIHash] = xgd23PFIHash;
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.SSHash] = xgd23SSHash;
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.SSVersion] = xgd23SSVer;
info.Extras.SecuritySectorRanges = ss360 ?? "";
info.Extras.SecuritySectorRanges = ss360 ?? string.Empty;
}
if (GetXbox360DMIInfo(sidecar, out string serial360, out string version360, out Region? region360))
{
info.CommonDiscInfo.Serial = serial360 ?? "";
info.VersionAndEditions.Version = version360 ?? "";
info.CommonDiscInfo.Serial = serial360 ?? string.Empty;
info.VersionAndEditions.Version = version360 ?? string.Empty;
info.CommonDiscInfo.Region = region360;
}
break;
@@ -373,22 +375,22 @@ namespace MPF.Modules.Aaru
info.CommonDiscInfo.EXEDateBuildDate = playstationTwoDate;
}
info.VersionAndEditions.Version = GetPlayStation2Version(drive?.Letter) ?? "";
info.VersionAndEditions.Version = GetPlayStation2Version(drive?.Letter) ?? string.Empty;
break;
case RedumpSystem.SonyPlayStation3:
info.VersionAndEditions.Version = GetPlayStation3Version(drive?.Letter) ?? "";
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.InternalSerialName] = GetPlayStation3Serial(drive?.Letter) ?? "";
info.VersionAndEditions.Version = GetPlayStation3Version(drive?.Letter) ?? string.Empty;
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.InternalSerialName] = GetPlayStation3Serial(drive?.Letter) ?? string.Empty;
break;
case RedumpSystem.SonyPlayStation4:
info.VersionAndEditions.Version = GetPlayStation4Version(drive?.Letter) ?? "";
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.InternalSerialName] = GetPlayStation4Serial(drive?.Letter) ?? "";
info.VersionAndEditions.Version = GetPlayStation4Version(drive?.Letter) ?? string.Empty;
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.InternalSerialName] = GetPlayStation4Serial(drive?.Letter) ?? string.Empty;
break;
case RedumpSystem.SonyPlayStation5:
info.VersionAndEditions.Version = GetPlayStation5Version(drive?.Letter) ?? "";
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.InternalSerialName] = GetPlayStation5Serial(drive?.Letter) ?? "";
info.VersionAndEditions.Version = GetPlayStation5Version(drive?.Letter) ?? string.Empty;
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.InternalSerialName] = GetPlayStation5Serial(drive?.Letter) ?? string.Empty;
break;
}
@@ -1435,6 +1437,8 @@ namespace MPF.Modules.Aaru
case MediaType.CDROM:
if (File.Exists($"{basePath}.cicm.xml"))
logFiles.Add($"{basePath}.cicm.xml");
if (File.Exists($"{basePath}.error.log"))
logFiles.Add($"{basePath}.error.log");
if (File.Exists($"{basePath}.ibg"))
logFiles.Add($"{basePath}.ibg");
if (File.Exists($"{basePath}.log"))
@@ -1453,6 +1457,8 @@ namespace MPF.Modules.Aaru
case MediaType.BluRay:
if (File.Exists($"{basePath}.cicm.xml"))
logFiles.Add($"{basePath}.cicm.xml");
if (File.Exists($"{basePath}.error.log"))
logFiles.Add($"{basePath}.error.log");
if (File.Exists($"{basePath}.ibg"))
logFiles.Add($"{basePath}.ibg");
if (File.Exists($"{basePath}.log"))
@@ -2642,6 +2648,119 @@ namespace MPF.Modules.Aaru
return datfile;
}
/// <summary>
/// Generate a CMP XML datfile string based on CICM sidecar data
/// </summary>
/// <param name="cicmSidecar">CICM Sidecar data generated by Aaru</param>
/// <param name="basePath">Base path for determining file names</param>
/// <returns>Datafile containing the hash information, null on error</returns>
private static Datafile GenerateDatafile(CICMMetadataType cicmSidecar, string basePath)
{
// If the object is null, we can't get information from it
if (cicmSidecar == null)
return null;
// Required variables
Datafile datafile = new Datafile();
List<Rom> roms = new List<Rom>();
// Process OpticalDisc, if possible
if (cicmSidecar.OpticalDisc != null && cicmSidecar.OpticalDisc.Length > 0)
{
// Loop through each OpticalDisc in the metadata
foreach (OpticalDiscType opticalDisc in cicmSidecar.OpticalDisc)
{
// Only capture the first total track count
uint totalTracks = 0;
if (opticalDisc.Tracks != null && opticalDisc.Tracks.Length > 0)
totalTracks = opticalDisc.Tracks[0];
// If there are no tracks, we can't get a datfile
if (opticalDisc.Track == null || opticalDisc.Track.Length == 0)
continue;
// Loop through each track
foreach (TrackType track in opticalDisc.Track)
{
uint trackNumber = track.Sequence?.TrackNumber ?? 0;
ulong size = track.Size;
string crc32 = string.Empty;
string md5 = string.Empty;
string sha1 = string.Empty;
// If we don't have any checksums, we can't get a DAT for this track
if (track.Checksums == null || track.Checksums.Length == 0)
continue;
// Extract only relevant checksums
foreach (ChecksumType checksum in track.Checksums)
{
switch (checksum.type)
{
case ChecksumTypeType.crc32:
crc32 = checksum.Value;
break;
case ChecksumTypeType.md5:
md5 = checksum.Value;
break;
case ChecksumTypeType.sha1:
sha1 = checksum.Value;
break;
}
}
// Build the track datfile data and append
string trackName = GenerateTrackName(basePath, (int)totalTracks, (int)trackNumber, opticalDisc.DiscType);
roms.Add(new Rom { Name = trackName, Size = size.ToString(), Crc = crc32, Md5 = md5, Sha1 = sha1 });
}
}
}
// Process BlockMedia, if possible
if (cicmSidecar.BlockMedia != null && cicmSidecar.BlockMedia.Length > 0)
{
// Loop through each BlockMedia in the metadata
foreach (BlockMediaType blockMedia in cicmSidecar.BlockMedia)
{
ulong size = blockMedia.Size;
string crc32 = string.Empty;
string md5 = string.Empty;
string sha1 = string.Empty;
// If we don't have any checksums, we can't get a DAT for this track
if (blockMedia.Checksums == null || blockMedia.Checksums.Length == 0)
continue;
// Extract only relevant checksums
foreach (ChecksumType checksum in blockMedia.Checksums)
{
switch (checksum.type)
{
case ChecksumTypeType.crc32:
crc32 = checksum.Value;
break;
case ChecksumTypeType.md5:
md5 = checksum.Value;
break;
case ChecksumTypeType.sha1:
sha1 = checksum.Value;
break;
}
}
// Build the track datfile data and append
string trackName = $"{basePath}.bin";
roms.Add(new Rom { Name = trackName, Size = size.ToString(), Crc = crc32, Md5 = md5, Sha1 = sha1 });
}
}
// Assign the roms to a new game
datafile.Games = new Game[1];
datafile.Games[0] = new Game { Roms = roms.ToArray() };
return datafile;
}
/// <summary>
/// Generate a track name based on current path and tracks
/// </summary>

View File

@@ -6,6 +6,9 @@ using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Xml.Schema;
using System.Xml;
using System.Xml.Serialization;
using MPF.Core.Data;
using MPF.Core.Hashing;
using MPF.Core.Utilities;
@@ -1080,6 +1083,155 @@ namespace MPF.Modules
#region Common Information Extraction
/// <summary>
/// Generate the proper datfile from the input Datafile, if possible
/// </summary>
/// <param name="datafile">.dat file location</param>
/// <returns>Relevant pieces of the datfile, null on error</returns>
protected static string GenerateDatfile(Datafile datafile)
{
// If we don't have a valid datafile, we can't do anything
if (datafile?.Games == null || datafile.Games.Length == 0 || datafile.Games[0]?.Roms == null || datafile.Games[0].Roms.Length == 0)
return null;
// Otherwise, reconstruct the hash data with only the required info
try
{
var roms = datafile.Games[0].Roms;
string datString = string.Empty;
for (int i = 0; i < roms.Length; i++)
{
var rom = roms[i];
datString += $"<rom name=\"{rom.Name}\" size=\"{rom.Size}\" crc=\"{rom.Crc}\" md5=\"{rom.Md5}\" sha1=\"{rom.Sha1}\" />\n";
}
datString.TrimEnd('\n');
return datString;
}
catch
{
// We don't care what the exception is right now
return null;
}
}
/// <summary>
/// Get Datafile from a standard DAT
/// </summary>
/// <param name="dat">Path to the DAT file to parse</param>
/// <returns>Filled Datafile on success, null on error</returns>
protected static Datafile GetDatafile(string dat)
{
// If there's no path, we can't read the file
if (string.IsNullOrWhiteSpace(dat))
return null;
// If the file doesn't exist, we can't read it
if (!File.Exists(dat))
return null;
try
{
// Open and read in the XML file
XmlReader xtr = XmlReader.Create(dat, new XmlReaderSettings
{
CheckCharacters = false,
DtdProcessing = DtdProcessing.Ignore,
IgnoreComments = true,
IgnoreWhitespace = true,
ValidationFlags = XmlSchemaValidationFlags.None,
ValidationType = ValidationType.None,
});
// If the reader is null for some reason, we can't do anything
if (xtr == null)
return null;
XmlSerializer serializer = new XmlSerializer(typeof(Datafile));
Datafile obj = serializer.Deserialize(xtr) as Datafile;
return obj;
}
catch
{
// We don't care what the exception is right now
return null;
}
}
/// <summary>
/// Gets disc information from a PIC file
/// </summary>
/// <param name="pic">Path to a PIC.bin file</param>
/// <returns>Filled PICDiscInformation on success, null on error</returns>
/// <remarks>This omits the emergency brake information, if it exists</remarks>
protected static PICDiscInformation GetDiscInformation(string pic)
{
try
{
using (BinaryReader br = new BinaryReader(File.OpenRead(pic)))
{
var di = new PICDiscInformation();
// Read the initial disc information
di.DataStructureLength = br.ReadUInt16BigEndian();
di.Reserved0 = br.ReadByte();
di.Reserved1 = br.ReadByte();
// Create a list for the units
var diUnits = new List<PICDiscInformationUnit>();
// Loop and read all available units
for (int i = 0; i < 32; i++)
{
var unit = new PICDiscInformationUnit();
// We only accept Disc Information units, not Emergency Brake or other
unit.DiscInformationIdentifier = Encoding.ASCII.GetString(br.ReadBytes(2));
if (unit.DiscInformationIdentifier != "DI")
break;
unit.DiscInformationFormat = br.ReadByte();
unit.NumberOfUnitsInBlock = br.ReadByte();
unit.Reserved0 = br.ReadByte();
unit.SequenceNumber = br.ReadByte();
unit.BytesInUse = br.ReadByte();
unit.Reserved1 = br.ReadByte();
unit.DiscTypeIdentifier = Encoding.ASCII.GetString(br.ReadBytes(3));
unit.DiscSizeClassVersion = br.ReadByte();
switch (unit.DiscTypeIdentifier)
{
case PICDiscInformationUnit.DiscTypeIdentifierROM:
case PICDiscInformationUnit.DiscTypeIdentifierROMUltra:
unit.FormatDependentContents = br.ReadBytes(52);
break;
case PICDiscInformationUnit.DiscTypeIdentifierReWritable:
case PICDiscInformationUnit.DiscTypeIdentifierRecordable:
unit.FormatDependentContents = br.ReadBytes(100);
unit.DiscManufacturerID = br.ReadBytes(6);
unit.MediaTypeID = br.ReadBytes(3);
unit.TimeStamp = br.ReadUInt16();
unit.ProductRevisionNumber = br.ReadByte();
break;
}
diUnits.Add(unit);
}
// Assign the units and return
di.Units = diUnits.ToArray();
return di;
}
}
catch
{
// We don't care what the error was
return null;
}
}
/// <summary>
/// Get hashes from an input file path
/// </summary>
@@ -1199,6 +1351,8 @@ namespace MPF.Modules
if (string.IsNullOrWhiteSpace(hashData))
return false;
// TODO: Use deserialization to Rom instead of Regex
Regex hashreg = new Regex(@"<rom name="".*?"" size=""(.*?)"" crc=""(.*?)"" md5=""(.*?)"" sha1=""(.*?)""");
Match m = hashreg.Match(hashData);
if (m.Success)
@@ -1215,6 +1369,92 @@ namespace MPF.Modules
}
}
/// <summary>
/// Get the split values for ISO-based media
/// </summary>
/// <param name="datafile">Datafile represenging the hash data</param>
/// <returns>True if extraction was successful, false otherwise</returns>
protected static bool GetISOHashValues(Datafile datafile, out long size, out string crc32, out string md5, out string sha1)
{
size = -1; crc32 = null; md5 = null; sha1 = null;
if (datafile?.Games == null || datafile.Games.Length == 0 || datafile.Games[0].Roms.Length == 0)
return false;
var rom = datafile.Games[0].Roms[0];
Int64.TryParse(rom.Size, out size);
crc32 = rom.Crc;
md5 = rom.Md5;
sha1 = rom.Sha1;
return true;
}
/// <summary>
/// Get the layerbreak info associated from the disc information
/// </summary>
/// <param name="di">Disc information containing unformatted data</param>
/// <returns>True if layerbreak info was set, false otherwise</returns>
protected static bool GetLayerbreaks(PICDiscInformation di, out long? layerbreak1, out long? layerbreak2, out long? layerbreak3)
{
// Set the default values
layerbreak1 = null; layerbreak2 = null; layerbreak3 = null;
// If we don't have valid disc information, we can't do anything
if (di?.Units == null || di.Units.Length <= 1)
return false;
int ReadFromArrayBigEndian(byte[] bytes, int offset)
{
var span = new ReadOnlySpan<byte>(bytes, offset, 0x04);
byte[] rev = span.ToArray();
Array.Reverse(rev);
return BitConverter.ToInt32(rev, 0);
}
// Layerbreak 1 (2+ layers)
if (di.Units.Length >= 2)
{
long offset = ReadFromArrayBigEndian(di.Units[0].FormatDependentContents, 0x0C);
long value = ReadFromArrayBigEndian(di.Units[0].FormatDependentContents, 0x10);
layerbreak1 = value - offset + 2;
}
// Layerbreak 2 (3+ layers)
if (di.Units.Length >= 3)
{
long offset = ReadFromArrayBigEndian(di.Units[1].FormatDependentContents, 0x0C);
long value = ReadFromArrayBigEndian(di.Units[1].FormatDependentContents, 0x10);
layerbreak2 = layerbreak1 + value - offset + 2;
}
// Layerbreak 3 (4 layers)
if (di.Units.Length >= 4)
{
long offset = ReadFromArrayBigEndian(di.Units[2].FormatDependentContents, 0x0C);
long value = ReadFromArrayBigEndian(di.Units[2].FormatDependentContents, 0x10);
layerbreak3 = layerbreak2 + value - offset + 2;
}
return true;
}
/// <summary>
/// Get the PIC identifier from the first disc information unit, if possible
/// </summary>
/// <param name="di">Disc information containing the data</param>
/// <returns>String representing the PIC identifier, null on error</returns>
protected static string GetPICIdentifier(PICDiscInformation di)
{
// If we don't have valid disc information, we can't do anything
if (di?.Units == null || di.Units.Length <= 1)
return null;
// We assume the identifier is consistent across all units
return di.Units[0].DiscTypeIdentifier;
}
/// <summary>
/// Get the EXE date from a PlayStation disc, if possible
/// </summary>
@@ -1271,6 +1511,9 @@ namespace MPF.Modules
serial = exeName
.Replace('_', '-')
.Replace(".", string.Empty);
// Some games may have the EXE in a subfolder
serial = Path.GetFileName(serial);
}
}

View File

@@ -63,10 +63,10 @@ namespace MPF.Modules.CleanRip
{
// TODO: Determine if there's a CleanRip version anywhere
info.DumpingInfo.DumpingProgram = EnumConverter.LongName(this.InternalProgram);
info.TracksAndWriteOffsets.ClrMameProData = GetCleanripDatfile(basePath + ".iso", basePath + "-dumpinfo.txt");
Datafile datafile = GenerateCleanripDatafile(basePath + ".iso", basePath + "-dumpinfo.txt");
// Get the individual hash data, as per internal
if (GetISOHashValues(info.TracksAndWriteOffsets.ClrMameProData, out long size, out string crc32, out string md5, out string sha1))
if (GetISOHashValues(datafile, out long size, out string crc32, out string md5, out string sha1))
{
info.SizeAndChecksums.Size = size;
info.SizeAndChecksums.CRC32 = crc32;
@@ -131,6 +131,65 @@ namespace MPF.Modules.CleanRip
#region Information Extraction Methods
/// <summary>
/// Get a formatted datfile from the cleanrip output, if possible
/// </summary>
/// <param name="iso">Path to ISO file</param>
/// <param name="dumpinfo">Path to discinfo file</param>
/// <returns></returns>
private static Datafile GenerateCleanripDatafile(string iso, string dumpinfo)
{
// If the file doesn't exist, we can't get info from it
if (!File.Exists(dumpinfo))
return null;
using (StreamReader sr = File.OpenText(dumpinfo))
{
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"))
return null;
// Read all lines and gather dat information
while (!sr.EndOfStream)
{
string line = sr.ReadLine().Trim();
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);
}
return new Datafile
{
Games = new Game[]
{
new Game
{
Roms = new Rom[]
{
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;
}
}
}
/// <summary>
/// Get the hex contents of the BCA file
/// </summary>

View File

@@ -100,7 +100,7 @@ namespace MPF.Modules.DD
info.CommonDiscInfo.EXEDateBuildDate = pythonTwoDate;
}
info.VersionAndEditions.Version = GetPlayStation2Version(drive?.Letter) ?? "";
info.VersionAndEditions.Version = GetPlayStation2Version(drive?.Letter) ?? string.Empty;
break;
case RedumpSystem.SonyPlayStation:
@@ -123,22 +123,22 @@ namespace MPF.Modules.DD
info.CommonDiscInfo.EXEDateBuildDate = playstationTwoDate;
}
info.VersionAndEditions.Version = GetPlayStation2Version(drive?.Letter) ?? "";
info.VersionAndEditions.Version = GetPlayStation2Version(drive?.Letter) ?? string.Empty;
break;
case RedumpSystem.SonyPlayStation3:
info.VersionAndEditions.Version = GetPlayStation3Version(drive?.Letter) ?? "";
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.InternalSerialName] = GetPlayStation3Serial(drive?.Letter) ?? "";
info.VersionAndEditions.Version = GetPlayStation3Version(drive?.Letter) ?? string.Empty;
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.InternalSerialName] = GetPlayStation3Serial(drive?.Letter) ?? string.Empty;
break;
case RedumpSystem.SonyPlayStation4:
info.VersionAndEditions.Version = GetPlayStation4Version(drive?.Letter) ?? "";
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.InternalSerialName] = GetPlayStation4Serial(drive?.Letter) ?? "";
info.VersionAndEditions.Version = GetPlayStation4Version(drive?.Letter) ?? string.Empty;
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.InternalSerialName] = GetPlayStation4Serial(drive?.Letter) ?? string.Empty;
break;
case RedumpSystem.SonyPlayStation5:
info.VersionAndEditions.Version = GetPlayStation5Version(drive?.Letter) ?? "";
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.InternalSerialName] = GetPlayStation5Serial(drive?.Letter) ?? "";
info.VersionAndEditions.Version = GetPlayStation5Version(drive?.Letter) ?? string.Empty;
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.InternalSerialName] = GetPlayStation5Serial(drive?.Letter) ?? string.Empty;
break;
}
}

73
MPF.Modules/Datafile.cs Normal file
View File

@@ -0,0 +1,73 @@
using System.Xml.Serialization;
namespace MPF.Modules
{
[XmlRoot("datafile")]
public class Datafile
{
[XmlElement("header")]
public Header Header;
[XmlElement("game")]
public Game[] Games;
}
public class Header
{
[XmlElement("name")]
public string Name;
[XmlElement("description")]
public string Description;
[XmlElement("version")]
public string Version;
[XmlElement("date")]
public string Date;
[XmlElement("author")]
public string Author;
[XmlElement("homepage")]
public string Homepage;
[XmlElement("url")]
public string Url;
}
public class Game
{
[XmlAttribute("name")]
public string Name;
[XmlElement("category")]
public string Category;
[XmlElement("description")]
public string Description;
[XmlElement("rom")]
public Rom[] Roms;
}
public class Rom
{
[XmlAttribute("name")]
public string Name;
[XmlAttribute("size")]
public string Size;
[XmlAttribute("crc")]
public string Crc;
[XmlAttribute("md5")]
public string Md5;
[XmlAttribute("sha1")]
public string Sha1;
// TODO: Add extended hashes here
}
}

View File

@@ -26,6 +26,7 @@ namespace MPF.Modules.DiscImageCreator
public const string Sub = "sub";
public const string Swap = "swap";
public const string Tape = "tape";
public const string Version = "/v";
public const string XBOX = "xbox";
public const string XBOXSwap = "xboxswap";
public const string XGD2Swap = "xgd2swap";
@@ -51,7 +52,6 @@ namespace MPF.Modules.DiscImageCreator
public const string Fix = "/fix";
public const string ForceUnitAccess = "/f";
public const string MultiSectorRead = "/mr";
public const string MultiSession = "/ms";
public const string NoFixSubP = "/np";
public const string NoFixSubQ = "/nq";
public const string NoFixSubQLibCrypt = "/nl";
@@ -59,6 +59,7 @@ namespace MPF.Modules.DiscImageCreator
public const string NoFixSubQSecuROM = "/ns";
public const string NoSkipSS = "/nss";
public const string PadSector = "/ps";
public const string Range = "/ra";
public const string Raw = "/raw";
public const string Resume = "/re";
public const string Reverse = "/r";
@@ -69,7 +70,6 @@ namespace MPF.Modules.DiscImageCreator
public const string SkipSector = "/sk";
public const string SubchannelReadLevel = "/s";
public const string UseAnchorVolumeDescriptorPointer = "/avdp";
public const string VerifyAudio = "/vrfy";
public const string VideoNow = "/vn";
public const string VideoNowColor = "/vnc";
public const string VideoNowXP = "/vnx";

View File

@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using MPF.Core.Converters;
using MPF.Core.Data;
@@ -92,11 +93,12 @@ namespace MPF.Modules.DiscImageCreator
/// <summary>
/// C2 reread options for dumping [CD only]
/// [0] - Reread value (default 4000)
/// [1] - 0 reread issue sector (default), 1 reread all
/// [2] - First LBA to reread (default 0)
/// [3] - Last LBA to reread (default EOS)
/// [1] - C2 offset (default: 0)
/// [2] - 0 reread issue sector (default), 1 reread all
/// [3] - First LBA to reread (default 0)
/// [4] - Last LBA to reread (default EOS)
/// </summary>
public int?[] C2OpcodeValue { get; set; } = new int?[4];
public int?[] C2OpcodeValue { get; set; } = new int?[5];
/// <summary>
/// C2 reread options for dumping [DVD/HD-DVD/BD only] (default 10)
@@ -126,7 +128,7 @@ namespace MPF.Modules.DiscImageCreator
/// <summary>
/// Set the pad sector flag value (default 0)
/// </summary>
public int? PadSectorValue { get; set; }
public byte? PadSectorValue { get; set; }
/// <summary>
/// Set the reverse End LBA value (required for DVD)
@@ -154,12 +156,6 @@ namespace MPF.Modules.DiscImageCreator
/// </summary>
public int? SubchannelReadLevelValue { get; set; }
/// <summary>
/// Set verify audio level for the dump
/// Possible values: 0 no offset (default), 1 with offset, 2 without dumping
/// </summary>
public int? VerifyAudioValue { get; set; }
/// <summary>
/// Set number of empty bytes to insert at the head of first track for VideoNow (default 0)
/// </summary>
@@ -258,8 +254,6 @@ namespace MPF.Modules.DiscImageCreator
missingFiles.Add($"{basePath}.dat");
if (!File.Exists($"{basePath}.sub") && !File.Exists($"{basePath}.subtmp"))
missingFiles.Add($"{basePath}.sub");
if (!File.Exists($"{basePath}.toc"))
missingFiles.Add($"{basePath}.toc");
if (!File.Exists($"{basePath}_disc.txt"))
missingFiles.Add($"{basePath}_disc.txt");
if (!File.Exists($"{basePath}_drive.txt"))
@@ -305,6 +299,14 @@ namespace MPF.Modules.DiscImageCreator
// Not guaranteed output
if (!File.Exists($"{basePath}_subIntention.txt"))
missingFiles.Add($"{basePath}_subIntention.txt");
// Not guaranteed output
if (File.Exists($"{basePath}_suppl.dat"))
missingFiles.Add($"{basePath}_suppl.dat");
// Not guaranteed output (at least PCE)
if (!File.Exists($"{basePath}.toc"))
missingFiles.Add($"{basePath}.toc");
}
break;
@@ -340,6 +342,14 @@ namespace MPF.Modules.DiscImageCreator
// Not guaranteed output
if (File.Exists($"{basePath}_CSSKey.txt"))
missingFiles.Add($"{basePath}_CSSKey.txt");
// Only output for some parameters
if (File.Exists($"{basePath}.raw"))
missingFiles.Add($"{basePath}.raw");
// Not guaranteed output
if (File.Exists($"{basePath}_suppl.dat"))
missingFiles.Add($"{basePath}_suppl.dat");
}
break;
@@ -394,8 +404,11 @@ namespace MPF.Modules.DiscImageCreator
if (GetDiscType($"{basePath}_disc.txt", out string discTypeOrBookType))
info.DumpingInfo.ReportedDiscType = discTypeOrBookType;
// Get the Datafile information
Datafile datafile = GetDatafile($"{basePath}.dat");
// Fill in the hash data
info.TracksAndWriteOffsets.ClrMameProData = GetDatfile($"{basePath}.dat");
info.TracksAndWriteOffsets.ClrMameProData = GenerateDatfile(datafile);
// Extract info based generically on MediaType
switch (this.Type)
@@ -420,23 +433,24 @@ namespace MPF.Modules.DiscImageCreator
info.CommonDiscInfo.ErrorsCount = (errorCount == -1 ? "Error retrieving error count" : errorCount.ToString());
}
info.TracksAndWriteOffsets.Cuesheet = GetFullFile($"{basePath}.cue") ?? "";
info.TracksAndWriteOffsets.Cuesheet = GetFullFile($"{basePath}.cue") ?? string.Empty;
//var cueSheet = new CueSheet($"{basePath}.cue"); // TODO: Do something with this
// Attempt to get the write offset
string cdWriteOffset = GetWriteOffset($"{basePath}_disc.txt") ?? "";
string cdWriteOffset = GetWriteOffset($"{basePath}_disc.txt") ?? string.Empty;
info.CommonDiscInfo.RingWriteOffset = cdWriteOffset;
info.TracksAndWriteOffsets.OtherWriteOffsets = cdWriteOffset;
// Attempt to get multisession data
string cdMultiSessionInfo = GetMultisessionInformation($"{basePath}_disc.txt");
if (!string.IsNullOrWhiteSpace(cdMultiSessionInfo))
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.Multisession] = cdMultiSessionInfo;
string cdMultiSessionInfo = GetMultisessionInformation($"{basePath}_disc.txt") ?? string.Empty;
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.Multisession] = cdMultiSessionInfo;
// Attempt to get the universal hash
string universalHash = GetUniversalHash($"{basePath}_disc.txt") ?? "";
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.UniversalHash] = universalHash;
// Attempt to get the universal hash, if it's an audio disc
if (this.System.IsAudio())
{
string universalHash = GetUniversalHash($"{basePath}_disc.txt") ?? string.Empty;
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.UniversalHash] = universalHash;
}
break;
@@ -444,7 +458,7 @@ namespace MPF.Modules.DiscImageCreator
case MediaType.HDDVD:
case MediaType.BluRay:
// Get the individual hash data, as per internal
if (GetISOHashValues(info.TracksAndWriteOffsets.ClrMameProData, out long size, out string crc32, out string md5, out string sha1))
if (GetISOHashValues(datafile, out long size, out string crc32, out string md5, out string sha1))
{
info.SizeAndChecksums.Size = size;
info.SizeAndChecksums.CRC32 = crc32;
@@ -455,12 +469,14 @@ namespace MPF.Modules.DiscImageCreator
// Deal with the layerbreaks
if (this.Type == MediaType.DVD)
{
string layerbreak = GetLayerbreak($"{basePath}_disc.txt", System.IsXGD()) ?? "";
string layerbreak = GetLayerbreak($"{basePath}_disc.txt", System.IsXGD()) ?? string.Empty;
info.SizeAndChecksums.Layerbreak = !string.IsNullOrEmpty(layerbreak) ? Int64.Parse(layerbreak) : default;
}
else if (this.Type == MediaType.BluRay)
{
if (GetLayerbreak($"{basePath}_PIC.bin", out long? layerbreak1, out long? layerbreak2, out long? layerbreak3))
var di = GetDiscInformation($"{basePath}_PIC.bin");
info.SizeAndChecksums.PICIdentifier = GetPICIdentifier(di);
if (GetLayerbreaks(di, out long? layerbreak1, out long? layerbreak2, out long? layerbreak3))
{
if (layerbreak1 != null && layerbreak1 * 2048 < info.SizeAndChecksums.Size)
info.SizeAndChecksums.Layerbreak = layerbreak1.Value;
@@ -475,7 +491,7 @@ namespace MPF.Modules.DiscImageCreator
// Read the PVD
if (!options.EnableRedumpCompatibility || System != RedumpSystem.MicrosoftXbox)
info.Extras.PVD = GetPVD($"{basePath}_mainInfo.txt") ?? "";
info.Extras.PVD = GetPVD($"{basePath}_mainInfo.txt") ?? string.Empty;
// Bluray-specific options
if (this.Type == MediaType.BluRay)
@@ -484,11 +500,13 @@ namespace MPF.Modules.DiscImageCreator
switch (this.System)
{
case RedumpSystem.SonyPlayStation3:
case RedumpSystem.SonyPlayStation4:
case RedumpSystem.SonyPlayStation5:
trimLength = 264;
break;
}
info.Extras.PIC = GetPIC($"{basePath}_PIC.bin", trimLength) ?? "";
info.Extras.PIC = GetPIC($"{basePath}_PIC.bin", trimLength) ?? string.Empty;
}
break;
@@ -506,14 +524,14 @@ namespace MPF.Modules.DiscImageCreator
{
FileInfo fi = new FileInfo($"{basePath}_subIntention.txt");
if (fi.Length > 0)
info.CopyProtection.SecuROMData = GetFullFile($"{basePath}_subIntention.txt") ?? "";
info.CopyProtection.SecuROMData = GetFullFile($"{basePath}_subIntention.txt") ?? string.Empty;
}
break;
case RedumpSystem.DVDAudio:
case RedumpSystem.DVDVideo:
info.CopyProtection.Protection = GetDVDProtection($"{basePath}_CSSKey.txt", $"{basePath}_disc.txt") ?? "";
info.CopyProtection.Protection = GetDVDProtection($"{basePath}_CSSKey.txt", $"{basePath}_disc.txt") ?? string.Empty;
break;
case RedumpSystem.KonamiPython2:
@@ -525,7 +543,7 @@ namespace MPF.Modules.DiscImageCreator
info.CommonDiscInfo.EXEDateBuildDate = pythonTwoDate;
}
info.VersionAndEditions.Version = GetPlayStation2Version(drive?.Letter) ?? "";
info.VersionAndEditions.Version = GetPlayStation2Version(drive?.Letter) ?? string.Empty;
break;
case RedumpSystem.MicrosoftXbox:
@@ -534,19 +552,39 @@ namespace MPF.Modules.DiscImageCreator
if (xgd1Info?.Initialized == true)
{
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.XMID] = xgd1Info.XMID;
info.CommonDiscInfo.Serial = xgd1Info.GetSerial() ?? "";
info.CommonDiscInfo.Serial = xgd1Info.GetSerial() ?? string.Empty;
if (!options.EnableRedumpCompatibility)
info.VersionAndEditions.Version = xgd1Info.GetVersion() ?? "";
info.VersionAndEditions.Version = xgd1Info.GetVersion() ?? string.Empty;
info.CommonDiscInfo.Region = xgd1Info.InternalRegion;
}
if (GetXGDAuxInfo($"{basePath}_disc.txt", out string xgd1DMIHash, out string xgd1PFIHash, out string xgd1SSHash, out string xgd1SS, out string xgd1SSVer))
// If we have the new, external DAT
if (File.Exists($"{basePath}_suppl.dat"))
{
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.DMIHash] = xgd1DMIHash;
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.PFIHash] = xgd1PFIHash;
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.SSHash] = xgd1SSHash;
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.SSVersion] = xgd1SSVer;
info.Extras.SecuritySectorRanges = xgd1SS ?? "";
Datafile suppl = GetDatafile($"{basePath}_suppl.dat");
if (GetXGDAuxHashInfo(suppl, out string xgd1DMIHash, out string xgd1PFIHash, out string xgd1SSHash))
{
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.DMIHash] = xgd1DMIHash;
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.PFIHash] = xgd1PFIHash;
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.SSHash] = xgd1SSHash;
}
if (GetXGDAuxSSInfo($"{basePath}_disc.txt", out string xgd1SS, out string xgd1SSVer))
{
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.SSVersion] = xgd1SSVer;
info.Extras.SecuritySectorRanges = xgd1SS ?? string.Empty;
}
}
else
{
if (GetXGDAuxInfo($"{basePath}_disc.txt", out string xgd1DMIHash, out string xgd1PFIHash, out string xgd1SSHash, out string xgd1SS, out string xgd1SSVer))
{
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.DMIHash] = xgd1DMIHash;
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.PFIHash] = xgd1PFIHash;
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.SSHash] = xgd1SSHash;
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.SSVersion] = xgd1SSVer;
info.Extras.SecuritySectorRanges = xgd1SS ?? string.Empty;
}
}
break;
@@ -557,19 +595,39 @@ namespace MPF.Modules.DiscImageCreator
if (xgd23Info?.Initialized == true)
{
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.XeMID] = xgd23Info.XMID;
info.CommonDiscInfo.Serial = xgd23Info.GetSerial() ?? "";
info.CommonDiscInfo.Serial = xgd23Info.GetSerial() ?? string.Empty;
if (!options.EnableRedumpCompatibility)
info.VersionAndEditions.Version = xgd23Info.GetVersion() ?? "";
info.VersionAndEditions.Version = xgd23Info.GetVersion() ?? string.Empty;
info.CommonDiscInfo.Region = xgd23Info.InternalRegion;
}
if (GetXGDAuxInfo($"{basePath}_disc.txt", out string xgd23DMIHash, out string xgd23PFIHash, out string xgd23SSHash, out string xgd23SS, out string xgd23SSVer))
// If we have the new, external DAT
if (File.Exists($"{basePath}_suppl.dat"))
{
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.DMIHash] = xgd23DMIHash;
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.PFIHash] = xgd23PFIHash;
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.SSHash] = xgd23SSHash;
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.SSVersion] = xgd23SSVer;
info.Extras.SecuritySectorRanges = xgd23SS ?? "";
Datafile suppl = GetDatafile($"{basePath}_suppl.dat");
if (GetXGDAuxHashInfo(suppl, out string xgd23DMIHash, out string xgd23PFIHash, out string xgd23SSHash))
{
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.DMIHash] = xgd23DMIHash;
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.PFIHash] = xgd23PFIHash;
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.SSHash] = xgd23SSHash;
}
if (GetXGDAuxSSInfo($"{basePath}_disc.txt", out string xgd23SS, out string xgd23SSVer))
{
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.SSVersion] = xgd23SSVer;
info.Extras.SecuritySectorRanges = xgd23SS ?? string.Empty;
}
}
else
{
if (GetXGDAuxInfo($"{basePath}_disc.txt", out string xgd23DMIHash, out string xgd23PFIHash, out string xgd23SSHash, out string xgd23SS, out string xgd23SSVer))
{
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.DMIHash] = xgd23DMIHash;
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.PFIHash] = xgd23PFIHash;
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.SSHash] = xgd23SSHash;
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.SSVersion] = xgd23SSVer;
info.Extras.SecuritySectorRanges = xgd23SS ?? string.Empty;
}
}
break;
@@ -577,7 +635,7 @@ namespace MPF.Modules.DiscImageCreator
case RedumpSystem.NamcoSegaNintendoTriforce:
if (this.Type == MediaType.CDROM)
{
info.Extras.Header = GetSegaHeader($"{basePath}_mainInfo.txt") ?? "";
info.Extras.Header = GetSegaHeader($"{basePath}_mainInfo.txt") ?? string.Empty;
// Take only the first 16 lines for GD-ROM
if (!string.IsNullOrEmpty(info.Extras.Header))
@@ -587,15 +645,15 @@ namespace MPF.Modules.DiscImageCreator
{
// Ensure internal serial is pulled from local data
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.InternalSerialName] = gdSerial ?? string.Empty;
info.VersionAndEditions.Version = gdVersion ?? "";
info.CommonDiscInfo.EXEDateBuildDate = gdDate ?? "";
info.VersionAndEditions.Version = gdVersion ?? string.Empty;
info.CommonDiscInfo.EXEDateBuildDate = gdDate ?? string.Empty;
}
}
break;
case RedumpSystem.SegaMegaCDSegaCD:
info.Extras.Header = GetSegaHeader($"{basePath}_mainInfo.txt") ?? "";
info.Extras.Header = GetSegaHeader($"{basePath}_mainInfo.txt") ?? string.Empty;
// Take only the last 16 lines for Sega CD
if (!string.IsNullOrEmpty(info.Extras.Header))
@@ -605,7 +663,7 @@ namespace MPF.Modules.DiscImageCreator
{
// Ensure internal serial is pulled from local data
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.InternalSerialName] = scdSerial ?? string.Empty;
info.CommonDiscInfo.EXEDateBuildDate = fixedDate ?? "";
info.CommonDiscInfo.EXEDateBuildDate = fixedDate ?? string.Empty;
}
break;
@@ -613,7 +671,7 @@ namespace MPF.Modules.DiscImageCreator
case RedumpSystem.SegaChihiro:
if (this.Type == MediaType.CDROM)
{
info.Extras.Header = GetSegaHeader($"{basePath}_mainInfo.txt") ?? "";
info.Extras.Header = GetSegaHeader($"{basePath}_mainInfo.txt") ?? string.Empty;
// Take only the first 16 lines for GD-ROM
if (!string.IsNullOrEmpty(info.Extras.Header))
@@ -623,8 +681,8 @@ namespace MPF.Modules.DiscImageCreator
{
// Ensure internal serial is pulled from local data
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.InternalSerialName] = gdSerial ?? string.Empty;
info.VersionAndEditions.Version = gdVersion ?? "";
info.CommonDiscInfo.EXEDateBuildDate = gdDate ?? "";
info.VersionAndEditions.Version = gdVersion ?? string.Empty;
info.CommonDiscInfo.EXEDateBuildDate = gdDate ?? string.Empty;
}
}
@@ -633,7 +691,7 @@ namespace MPF.Modules.DiscImageCreator
case RedumpSystem.SegaDreamcast:
if (this.Type == MediaType.CDROM)
{
info.Extras.Header = GetSegaHeader($"{basePath}_mainInfo.txt") ?? "";
info.Extras.Header = GetSegaHeader($"{basePath}_mainInfo.txt") ?? string.Empty;
// Take only the first 16 lines for GD-ROM
if (!string.IsNullOrEmpty(info.Extras.Header))
@@ -643,8 +701,8 @@ namespace MPF.Modules.DiscImageCreator
{
// Ensure internal serial is pulled from local data
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.InternalSerialName] = gdSerial ?? string.Empty;
info.VersionAndEditions.Version = gdVersion ?? "";
info.CommonDiscInfo.EXEDateBuildDate = gdDate ?? "";
info.VersionAndEditions.Version = gdVersion ?? string.Empty;
info.CommonDiscInfo.EXEDateBuildDate = gdDate ?? string.Empty;
}
}
@@ -653,7 +711,7 @@ namespace MPF.Modules.DiscImageCreator
case RedumpSystem.SegaNaomi:
if (this.Type == MediaType.CDROM)
{
info.Extras.Header = GetSegaHeader($"{basePath}_mainInfo.txt") ?? "";
info.Extras.Header = GetSegaHeader($"{basePath}_mainInfo.txt") ?? string.Empty;
// Take only the first 16 lines for GD-ROM
if (!string.IsNullOrEmpty(info.Extras.Header))
@@ -663,8 +721,8 @@ namespace MPF.Modules.DiscImageCreator
{
// Ensure internal serial is pulled from local data
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.InternalSerialName] = gdSerial ?? string.Empty;
info.VersionAndEditions.Version = gdVersion ?? "";
info.CommonDiscInfo.EXEDateBuildDate = gdDate ?? "";
info.VersionAndEditions.Version = gdVersion ?? string.Empty;
info.CommonDiscInfo.EXEDateBuildDate = gdDate ?? string.Empty;
}
}
@@ -673,7 +731,7 @@ namespace MPF.Modules.DiscImageCreator
case RedumpSystem.SegaNaomi2:
if (this.Type == MediaType.CDROM)
{
info.Extras.Header = GetSegaHeader($"{basePath}_mainInfo.txt") ?? "";
info.Extras.Header = GetSegaHeader($"{basePath}_mainInfo.txt") ?? string.Empty;
// Take only the first 16 lines for GD-ROM
if (!string.IsNullOrEmpty(info.Extras.Header))
@@ -683,15 +741,15 @@ namespace MPF.Modules.DiscImageCreator
{
// Ensure internal serial is pulled from local data
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.InternalSerialName] = gdSerial ?? string.Empty;
info.VersionAndEditions.Version = gdVersion ?? "";
info.CommonDiscInfo.EXEDateBuildDate = gdDate ?? "";
info.VersionAndEditions.Version = gdVersion ?? string.Empty;
info.CommonDiscInfo.EXEDateBuildDate = gdDate ?? string.Empty;
}
}
break;
case RedumpSystem.SegaSaturn:
info.Extras.Header = GetSegaHeader($"{basePath}_mainInfo.txt") ?? "";
info.Extras.Header = GetSegaHeader($"{basePath}_mainInfo.txt") ?? string.Empty;
// Take only the first 16 lines for Saturn
if (!string.IsNullOrEmpty(info.Extras.Header))
@@ -701,8 +759,8 @@ namespace MPF.Modules.DiscImageCreator
{
// Ensure internal serial is pulled from local data
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.InternalSerialName] = saturnSerial ?? string.Empty;
info.VersionAndEditions.Version = saturnVersion ?? "";
info.CommonDiscInfo.EXEDateBuildDate = buildDate ?? "";
info.VersionAndEditions.Version = saturnVersion ?? string.Empty;
info.CommonDiscInfo.EXEDateBuildDate = buildDate ?? string.Empty;
}
break;
@@ -722,14 +780,8 @@ namespace MPF.Modules.DiscImageCreator
else if (File.Exists($"{basePath}.img_EccEdc.txt"))
psEdcStatus = GetPlayStationEDCStatus($"{basePath}.img_EccEdc.txt");
if (psEdcStatus == true)
info.EDC.EDC = YesNo.Yes;
else if (psEdcStatus == false)
info.EDC.EDC = YesNo.No;
else
info.EDC.EDC = YesNo.NULL;
info.CopyProtection.AntiModchip = GetPlayStationAntiModchipDetected($"{basePath}_disc.txt") ? YesNo.Yes : YesNo.No;
info.EDC.EDC = psEdcStatus.ToYesNo();
info.CopyProtection.AntiModchip = GetPlayStationAntiModchipDetected($"{basePath}_disc.txt").ToYesNo();
break;
case RedumpSystem.SonyPlayStation2:
@@ -741,22 +793,22 @@ namespace MPF.Modules.DiscImageCreator
info.CommonDiscInfo.EXEDateBuildDate = playstationTwoDate;
}
info.VersionAndEditions.Version = GetPlayStation2Version(drive?.Letter) ?? "";
info.VersionAndEditions.Version = GetPlayStation2Version(drive?.Letter) ?? string.Empty;
break;
case RedumpSystem.SonyPlayStation3:
info.VersionAndEditions.Version = GetPlayStation3Version(drive?.Letter) ?? "";
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.InternalSerialName] = GetPlayStation3Serial(drive?.Letter) ?? "";
info.VersionAndEditions.Version = GetPlayStation3Version(drive?.Letter) ?? string.Empty;
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.InternalSerialName] = GetPlayStation3Serial(drive?.Letter) ?? string.Empty;
break;
case RedumpSystem.SonyPlayStation4:
info.VersionAndEditions.Version = GetPlayStation4Version(drive?.Letter) ?? "";
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.InternalSerialName] = GetPlayStation4Serial(drive?.Letter) ?? "";
info.VersionAndEditions.Version = GetPlayStation4Version(drive?.Letter) ?? string.Empty;
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.InternalSerialName] = GetPlayStation4Serial(drive?.Letter) ?? string.Empty;
break;
case RedumpSystem.SonyPlayStation5:
info.VersionAndEditions.Version = GetPlayStation5Version(drive?.Letter) ?? "";
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.InternalSerialName] = GetPlayStation5Serial(drive?.Letter) ?? "";
info.VersionAndEditions.Version = GetPlayStation5Version(drive?.Letter) ?? string.Empty;
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.InternalSerialName] = GetPlayStation5Serial(drive?.Letter) ?? string.Empty;
break;
}
@@ -977,19 +1029,23 @@ namespace MPF.Modules.DiscImageCreator
}
if (C2OpcodeValue[1] != null)
{
if (C2OpcodeValue[1] == 0)
parameters.Add(C2OpcodeValue[1].ToString());
}
if (C2OpcodeValue[2] != null)
{
if (C2OpcodeValue[2] == 0)
{
parameters.Add(C2OpcodeValue[1].ToString());
parameters.Add(C2OpcodeValue[2].ToString());
}
else if (C2OpcodeValue[1] == 1)
else if (C2OpcodeValue[2] == 1)
{
parameters.Add(C2OpcodeValue[1].ToString());
if (C2OpcodeValue[2] != null && C2OpcodeValue[3] != null)
parameters.Add(C2OpcodeValue[2].ToString());
if (C2OpcodeValue[3] != null && C2OpcodeValue[4] != null)
{
if (C2OpcodeValue[2] > 0 && C2OpcodeValue[3] > 0)
if (C2OpcodeValue[3] > 0 && C2OpcodeValue[4] > 0)
{
parameters.Add(C2OpcodeValue[2].ToString());
parameters.Add(C2OpcodeValue[3].ToString());
parameters.Add(C2OpcodeValue[4].ToString());
}
else
{
@@ -1086,13 +1142,6 @@ namespace MPF.Modules.DiscImageCreator
}
}
// Multi-Session
if (IsFlagSupported(FlagStrings.MultiSession))
{
if (this[FlagStrings.MultiSession] == true)
parameters.Add(FlagStrings.MultiSession);
}
// Not fix SubP
if (IsFlagSupported(FlagStrings.NoFixSubP))
{
@@ -1150,6 +1199,13 @@ namespace MPF.Modules.DiscImageCreator
}
}
// Range
if (IsFlagSupported(FlagStrings.Range))
{
if (this[FlagStrings.Range] == true)
parameters.Add(FlagStrings.Range);
}
// Raw read (2064 byte/sector)
if (IsFlagSupported(FlagStrings.Raw))
{
@@ -1263,22 +1319,6 @@ namespace MPF.Modules.DiscImageCreator
parameters.Add(FlagStrings.UseAnchorVolumeDescriptorPointer);
}
// Verify Audio
if (IsFlagSupported(FlagStrings.VerifyAudio))
{
if (this[FlagStrings.VerifyAudio] == true)
{
parameters.Add(FlagStrings.VerifyAudio);
if (VerifyAudioValue != null)
{
if (VerifyAudioValue >= 0 && VerifyAudioValue <= 2)
parameters.Add(VerifyAudioValue.ToString());
else
return null;
}
}
}
// VideoNow
if (IsFlagSupported(FlagStrings.VideoNow))
{
@@ -1325,7 +1365,6 @@ namespace MPF.Modules.DiscImageCreator
FlagStrings.DatExpand,
FlagStrings.DisableBeep,
FlagStrings.ForceUnitAccess,
FlagStrings.MultiSession,
FlagStrings.NoFixSubP,
FlagStrings.NoFixSubQ,
FlagStrings.NoFixSubRtoW,
@@ -1363,7 +1402,6 @@ namespace MPF.Modules.DiscImageCreator
FlagStrings.ExtractMicroSoftCabFile,
FlagStrings.ForceUnitAccess,
FlagStrings.MultiSectorRead,
FlagStrings.MultiSession,
FlagStrings.NoFixSubP,
FlagStrings.NoFixSubQ,
FlagStrings.NoFixSubQLibCrypt,
@@ -1374,7 +1412,6 @@ namespace MPF.Modules.DiscImageCreator
FlagStrings.ScanSectorProtect,
FlagStrings.SeventyFour,
FlagStrings.SubchannelReadLevel,
FlagStrings.VerifyAudio,
FlagStrings.VideoNow,
FlagStrings.VideoNowColor,
FlagStrings.VideoNowXP,
@@ -1388,7 +1425,6 @@ namespace MPF.Modules.DiscImageCreator
FlagStrings.DatExpand,
FlagStrings.DisableBeep,
FlagStrings.ForceUnitAccess,
FlagStrings.MultiSession,
FlagStrings.NoFixSubP,
FlagStrings.NoFixSubQ,
FlagStrings.NoFixSubRtoW,
@@ -1409,6 +1445,7 @@ namespace MPF.Modules.DiscImageCreator
FlagStrings.Fix,
FlagStrings.ForceUnitAccess,
FlagStrings.PadSector,
FlagStrings.Range,
FlagStrings.Raw,
FlagStrings.Resume,
FlagStrings.Reverse,
@@ -1488,7 +1525,6 @@ namespace MPF.Modules.DiscImageCreator
FlagStrings.DatExpand,
FlagStrings.DisableBeep,
FlagStrings.ForceUnitAccess,
FlagStrings.MultiSession,
FlagStrings.NoFixSubP,
FlagStrings.NoFixSubQ,
FlagStrings.NoFixSubQLibCrypt,
@@ -1508,6 +1544,10 @@ namespace MPF.Modules.DiscImageCreator
{
},
[CommandStrings.Version] = new List<string>()
{
},
[CommandStrings.XBOX] = new List<string>()
{
FlagStrings.DatExpand,
@@ -1570,6 +1610,16 @@ namespace MPF.Modules.DiscImageCreator
logFiles.Add($"{basePath}.dat");
if (File.Exists($"{basePath}.sub"))
logFiles.Add($"{basePath}.sub");
if (File.Exists($"{basePath} (Track 0).sub"))
logFiles.Add($"{basePath} (Track 0).sub");
if (File.Exists($"{basePath} (Track 00).sub"))
logFiles.Add($"{basePath} (Track 00).sub");
if (File.Exists($"{basePath} (Track 1)(-LBA).sub"))
logFiles.Add($"{basePath} (Track 1)(-LBA).sub");
if (File.Exists($"{basePath} (Track 01)(-LBA).sub"))
logFiles.Add($"{basePath} (Track 01)(-LBA).sub");
if (File.Exists($"{basePath} (Track AA).sub"))
logFiles.Add($"{basePath} (Track AA).sub");
if (File.Exists($"{basePath}.subtmp"))
logFiles.Add($"{basePath}.subtmp");
if (File.Exists($"{basePath}.toc"))
@@ -1598,6 +1648,8 @@ namespace MPF.Modules.DiscImageCreator
logFiles.Add($"{basePath}_subIntention.txt");
if (File.Exists($"{basePath}_subReadable.txt"))
logFiles.Add($"{basePath}_subReadable.txt");
if (File.Exists($"{basePath}_suppl.dat"))
logFiles.Add($"{basePath}_suppl.dat");
if (File.Exists($"{basePath}_volDesc.txt"))
logFiles.Add($"{basePath}_volDesc.txt");
@@ -1626,6 +1678,8 @@ namespace MPF.Modules.DiscImageCreator
logFiles.Add($"{basePath}_mainError.txt");
if (File.Exists($"{basePath}_mainInfo.txt"))
logFiles.Add($"{basePath}_mainInfo.txt");
if (File.Exists($"{basePath}_suppl.dat"))
logFiles.Add($"{basePath}_suppl.dat");
if (File.Exists($"{basePath}_volDesc.txt"))
logFiles.Add($"{basePath}_volDesc.txt");
@@ -1705,7 +1759,7 @@ namespace MPF.Modules.DiscImageCreator
AddOffsetValue = null;
BEOpcodeValue = null;
C2OpcodeValue = new int?[4];
C2OpcodeValue = new int?[5];
DVDRereadValue = null;
FixValue = null;
ForceUnitAccessValue = null;
@@ -2196,6 +2250,12 @@ namespace MPF.Modules.DiscImageCreator
break;
case CommandStrings.Version:
if (parts.Count != 1)
return false;
break;
case CommandStrings.XBOX:
if (parts.Count < 4)
return false;
@@ -2256,6 +2316,7 @@ namespace MPF.Modules.DiscImageCreator
for (int i = index; i < parts.Count; i++)
{
// Flag read-out values
byte? byteValue = null;
int? intValue = null;
string stringValue = null;
@@ -2284,7 +2345,7 @@ namespace MPF.Modules.DiscImageCreator
if (parts[i] == FlagStrings.C2Opcode && IsFlagSupported(FlagStrings.C2Opcode))
{
this[FlagStrings.C2Opcode] = true;
for (int j = 0; j < 4; j++)
for (int j = 0; j < 5; j++)
{
if (!DoesExist(parts, i + 1))
{
@@ -2341,9 +2402,6 @@ namespace MPF.Modules.DiscImageCreator
if (intValue != null && intValue != Int32.MinValue && intValue >= 0)
MultiSectorReadValue = intValue;
// Multi-Session
ProcessFlagParameter(parts, FlagStrings.MultiSession, ref i);
// NoFixSubP
ProcessFlagParameter(parts, FlagStrings.NoFixSubP, ref i);
@@ -2365,9 +2423,9 @@ namespace MPF.Modules.DiscImageCreator
NoSkipSecuritySectorValue = intValue;
// PadSector
intValue = ProcessInt32Parameter(parts, FlagStrings.PadSector, ref i, missingAllowed: true);
if (intValue != null && intValue != Int32.MinValue && intValue >= 0)
PadSectorValue = intValue;
byteValue = ProcessUInt8Parameter(parts, FlagStrings.PadSector, ref i, missingAllowed: true);
if (byteValue != null)
PadSectorValue = byteValue;
// Raw
ProcessFlagParameter(parts, FlagStrings.Raw, ref i);
@@ -2446,11 +2504,6 @@ namespace MPF.Modules.DiscImageCreator
// SeventyFour
ProcessFlagParameter(parts, FlagStrings.UseAnchorVolumeDescriptorPointer, ref i);
// VerifyAudio
intValue = ProcessInt32Parameter(parts, FlagStrings.VerifyAudio, ref i, missingAllowed: true);
if (intValue != null && intValue != Int32.MinValue && intValue >= 0 && intValue <= 2)
VerifyAudioValue = intValue;
// VideoNow
intValue = ProcessInt32Parameter(parts, FlagStrings.VideoNow, ref i, missingAllowed: true);
if (intValue != null && intValue != Int32.MinValue && intValue >= 0)
@@ -2565,50 +2618,6 @@ namespace MPF.Modules.DiscImageCreator
#region Information Extraction Methods
/// <summary>
/// Get the proper datfile from the input file, if possible
/// </summary>
/// <param name="dat">.dat file location</param>
/// <returns>Relevant pieces of the datfile, null on error</returns>
private static string GetDatfile(string dat)
{
// If the file doesn't exist, we can't get info from it
if (!File.Exists(dat))
return null;
using (StreamReader sr = File.OpenText(dat))
{
try
{
// Make sure this file is a .dat
if (sr.ReadLine() != "<?xml version=\"1.0\" encoding=\"UTF-8\"?>")
return null;
if (sr.ReadLine() != "<!DOCTYPE datafile PUBLIC \"-//Logiqx//DTD ROM Management Datafile//EN\" \"http://www.logiqx.com/Dats/datafile.dtd\">")
return null;
// Fast forward to the rom lines
while (!sr.ReadLine().TrimStart().StartsWith("<game")) ;
sr.ReadLine(); // <category>Games</category>
sr.ReadLine(); // <description>Plextor</description>
// Now that we're at the relevant entries, read each line in and concatenate
string datString = "", line = sr.ReadLine().Trim();
while (line.StartsWith("<rom"))
{
datString += line + "\n";
line = sr.ReadLine().Trim();
}
return datString.TrimEnd('\n');
}
catch
{
// We don't care what the exception is right now
return null;
}
}
}
/// <summary>
/// Get reported disc type information, if possible
/// </summary>
@@ -2627,6 +2636,9 @@ namespace MPF.Modules.DiscImageCreator
{
try
{
// Create a hashset to contain all of the found values
var discTypeOrBookTypeSet = new HashSet<string>();
string line = sr.ReadLine();
while (line != null)
{
@@ -2637,44 +2649,41 @@ namespace MPF.Modules.DiscImageCreator
if (line.StartsWith("DiscType:"))
{
// DiscType: <discType>
if (string.IsNullOrEmpty(discTypeOrBookType))
discTypeOrBookType = line.Substring("DiscType: ".Length);
else
discTypeOrBookType += $", {line.Substring("DiscType: ".Length)}";
string identifier = line.Substring("DiscType: ".Length);
discTypeOrBookTypeSet.Add(identifier);
}
else if (line.StartsWith("DiscTypeIdentifier:"))
{
// DiscType: <discType>
if (string.IsNullOrEmpty(discTypeOrBookType))
discTypeOrBookType = line.Substring("DiscTypeIdentifier: ".Length);
else
discTypeOrBookType += $", {line.Substring("DiscTypeIdentifier: ".Length)}";
// DiscTypeIdentifier: <discType>
string identifier = line.Substring("DiscTypeIdentifier: ".Length);
discTypeOrBookTypeSet.Add(identifier);
}
else if (line.StartsWith("DiscTypeSpecific:"))
{
// DiscType: <discType>
if (string.IsNullOrEmpty(discTypeOrBookType))
discTypeOrBookType = line.Substring("DiscTypeSpecific: ".Length);
else
discTypeOrBookType += $", {line.Substring("DiscTypeSpecific: ".Length)}";
// DiscTypeSpecific: <discType>
string identifier = line.Substring("DiscTypeSpecific: ".Length);
discTypeOrBookTypeSet.Add(identifier);
}
else if (line.StartsWith("BookType:"))
{
// BookType: <discType>
if (string.IsNullOrEmpty(discTypeOrBookType))
discTypeOrBookType = line.Substring("BookType: ".Length);
else
discTypeOrBookType += $", {line.Substring("BookType: ".Length)}";
string identifier = line.Substring("BookType: ".Length);
discTypeOrBookTypeSet.Add(identifier);
}
line = sr.ReadLine();
}
// Create the output string
if (discTypeOrBookTypeSet.Any())
discTypeOrBookType = string.Join(", ", discTypeOrBookTypeSet.OrderBy(s => s));
return true;
}
catch
{
// We don't care what the exception is right now
discTypeOrBookType = null;
return false;
}
}
@@ -2985,62 +2994,6 @@ namespace MPF.Modules.DiscImageCreator
}
}
/// <summary>
/// Get the layerbreak info associated with the dump
/// </summary>
/// <param name="picPath">Path to the PIC.bin file associated with the dump</param>
/// <returns>True if layerbreak info was set, false otherwise</returns>
/// <remarks>https://stackoverflow.com/questions/9932096/add-separator-to-string-at-every-n-characters</remarks>
private static bool GetLayerbreak(string picPath, out long? layerbreak1, out long? layerbreak2, out long? layerbreak3)
{
// Set the default values
layerbreak1 = null; layerbreak2 = null; layerbreak3 = null;
// If the file doesn't exist, we can't get the info
if (!File.Exists(picPath))
return false;
try
{
using (BinaryReader br = new BinaryReader(File.OpenRead(picPath)))
{
// Layerbreak 1
br.BaseStream.Seek(0x1C, SeekOrigin.Begin);
long layerbreak1Offset = br.ReadInt32BigEndian();
long layerbreak1Value = br.ReadInt32BigEndian();
if (layerbreak1Value == 0)
return false;
layerbreak1 = layerbreak1Value - layerbreak1Offset + 2;
// Layerbreak 2
br.BaseStream.Seek(0x5C, SeekOrigin.Begin);
long layerbreak2Offset = br.ReadInt32BigEndian();
long layerbreak2Value = br.ReadInt32BigEndian();
if (layerbreak2Value == 0)
return true;
layerbreak2 = layerbreak1 + layerbreak2Value - layerbreak2Offset + 2;
// Layerbreak 3
br.BaseStream.Seek(0x9C, SeekOrigin.Begin);
long layerbreak3Offset = br.ReadInt32BigEndian();
long layerbreak3Value = br.ReadInt32BigEndian();
if (layerbreak3Value == 0)
return true;
layerbreak3 = layerbreak2 + layerbreak3Value - layerbreak3Offset + 2;
return true;
}
}
catch
{
// We don't care what the error was
return false;
}
}
/// <summary>
/// Get multisession information from the input file, if possible
/// </summary>
@@ -3191,11 +3144,11 @@ namespace MPF.Modules.DiscImageCreator
/// </summary>
/// <param name="disc">_disc.txt file location</param>
/// <returns>Anti-modchip existence if possible, false on error</returns>
private static bool GetPlayStationAntiModchipDetected(string disc)
private static bool? GetPlayStationAntiModchipDetected(string disc)
{
// If the file doesn't exist, we can't get info from it
if (!File.Exists(disc))
return false;
return null;
using (StreamReader sr = File.OpenText(disc))
{
@@ -3218,7 +3171,7 @@ namespace MPF.Modules.DiscImageCreator
catch
{
// We don't care what the exception is right now
return false;
return null;
}
}
}
@@ -3579,6 +3532,33 @@ namespace MPF.Modules.DiscImageCreator
}
}
/// <summary>
/// Get the XGD auxiliary hash info from the outputted files, if possible
/// </summary>
/// <param name="suppl">Datafile representing the supplementary hashes</param>
/// <param name="dmihash">Extracted DMI.bin CRC32 hash (upper-cased)</param>
/// <param name="pfihash">Extracted PFI.bin CRC32 hash (upper-cased)</param>
/// <param name="sshash">Extracted SS.bin CRC32 hash (upper-cased)</param>
/// <returns>True on successful extraction of info, false otherwise</returns>
/// <remarks>Currently only the CRC32 values are returned for each, this may change in the future</remarks>
private static bool GetXGDAuxHashInfo(Datafile suppl, out string dmihash, out string pfihash, out string sshash)
{
// Assign values to all outputs first
dmihash = null; pfihash = null; sshash = null;
// If we don't have a valid datafile, we can't do anything
if (suppl == null || suppl.Games.Length == 0 || suppl.Games[0].Roms.Length == 0)
return false;
// Try to extract the hash information
var roms = suppl.Games[0].Roms;
dmihash = roms.FirstOrDefault(r => r.Name.EndsWith("DMI.bin"))?.Crc?.ToUpperInvariant();
pfihash = roms.FirstOrDefault(r => r.Name.EndsWith("PFI.bin"))?.Crc?.ToUpperInvariant();
sshash = roms.FirstOrDefault(r => r.Name.EndsWith("SS.bin"))?.Crc?.ToUpperInvariant();
return true;
}
/// <summary>
/// Get the XGD auxiliary info from the outputted files, if possible
/// </summary>
@@ -3662,6 +3642,72 @@ namespace MPF.Modules.DiscImageCreator
}
}
/// <summary>
/// Get the XGD auxiliary security sector info from the outputted files, if possible
/// </summary>
/// <param name="disc">_disc.txt file location</param>
/// <param name="ss">Extracted security sector data</param>
/// <param name="ssver">Extracted security sector version</param>
/// <returns>True on successful extraction of info, false otherwise</returns>
private static bool GetXGDAuxSSInfo(string disc, out string ss, out string ssver)
{
ss = null; ssver = null;
// If the file doesn't exist, we can't get info from it
if (!File.Exists(disc))
return false;
// This flag is needed because recent versions of DIC include security data twice
bool foundSecuritySectors = false;
using (StreamReader sr = File.OpenText(disc))
{
try
{
while (!sr.EndOfStream)
{
string line = sr.ReadLine().Trim();
// Security Sector version
if (line.StartsWith("Version of challenge table"))
{
ssver = line.Split(' ')[4]; // "Version of challenge table: <VER>"
}
// Security Sector ranges
else if (line.StartsWith("Number of security sector ranges:") && !foundSecuritySectors)
{
// Set the flag so we don't read duplicate data
foundSecuritySectors = true;
Regex layerRegex = new Regex(@"Layer [01].*, startLBA-endLBA:\s*(\d+)-\s*(\d+)");
line = sr.ReadLine().Trim();
while (!line.StartsWith("========== TotalLength ==========")
&& !line.StartsWith("========== Unlock 2 state(wxripper) =========="))
{
// If we have a recognized line format, parse it
if (line.StartsWith("Layer "))
{
var match = layerRegex.Match(line);
ss += $"{match.Groups[1]}-{match.Groups[2]}\n";
}
line = sr.ReadLine().Trim();
}
}
}
return true;
}
catch
{
// We don't care what the exception is right now
return false;
}
}
}
/// <summary>
/// Get the XGD1 Master ID (XMID) information
/// </summary>

View File

@@ -2,11 +2,11 @@
<PropertyGroup>
<TargetFrameworks>net48;net6.0</TargetFrameworks>
<RuntimeIdentifiers>win7-x64;win-x86;win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
<RuntimeIdentifiers>win7-x64;win8-x64;win81-x64;win10-x64;linux-x64;osx-x64</RuntimeIdentifiers>
<Authors>Matt Nadareski;ReignStumble;Jakz</Authors>
<Copyright>Copyright (c)2019-2023</Copyright>
<RepositoryUrl>https://github.com/SabreTools/MPF</RepositoryUrl>
<Version>2.5</Version>
<Version>2.6.2</Version>
<AssemblyVersion>$(Version)</AssemblyVersion>
<FileVersion>$(Version)</FileVersion>
<IncludeSource>true</IncludeSource>

View File

@@ -7,12 +7,16 @@ namespace MPF.Modules.Redumper
{
public const string NONE = "";
public const string CD = "cd";
public const string DVD = "dvd"; // Synonym for CD
public const string BluRay = "bd"; // Synonym for CD
public const string SACD = "sacd"; // Synonym for CD
public const string Dump = "dump";
public const string Info = "info";
public const string Protection = "protection";
public const string Refine = "refine";
//public const string Rings = "rings";
public const string Split = "split";
public const string Verify = "verify";
public const string DVDKey = "dvdkey";
}
/// <summary>
@@ -24,6 +28,7 @@ namespace MPF.Modules.Redumper
public const string HelpLong = "--help";
public const string HelpShort = "-h";
public const string Verbose = "--verbose";
public const string Debug = "--debug";
public const string Drive = "--drive";
public const string Speed = "--speed";
public const string Retries = "--retries";
@@ -40,13 +45,15 @@ namespace MPF.Modules.Redumper
public const string DriveSectorOrder = "--drive-sector-order";
// Drive Specific
public const string PlextorSkipLeadin = "--plextor-skip-leadin";
public const string PlextorLeadinSkip = "--plextor-leadin-skip";
public const string PlextorLeadinRetries = "--plextor-leadin-retries";
public const string AsusSkipLeadout = "--asus-skip-leadout";
// Offset
public const string ForceOffset = "--force-offset";
public const string AudioSilenceThreshold = "--audio-silence-threshold";
public const string CorrectOffsetShift = "--correct-offset-shift";
public const string OffsetShiftRelocate = "--offset-shift-relocate";
// Split
public const string ForceSplit = "--force-split";
@@ -54,12 +61,12 @@ namespace MPF.Modules.Redumper
public const string ForceQTOC = "--force-qtoc";
public const string SkipFill = "--skip-fill";
public const string ISO9660Trim = "--iso9660-trim";
public const string CDiReadyNormalize = "--cdi-ready-normalize";
// Miscellaneous
public const string LBAStart = "--lba-start";
public const string LBAEnd = "--lba-end";
public const string RefineSubchannel = "--refine-subchannel";
public const string Skip = "--skip";
public const string DumpReadSize = "--dump-read-size";
}
}

View File

@@ -13,8 +13,18 @@ namespace MPF.Modules.Redumper
/// <returns>Valid extension (with leading '.'), null on error</returns>
public static string Extension(MediaType? type)
{
// TODO: Determine what extensions are used for each supported type
return ".bin";
switch (type)
{
case MediaType.CDROM:
return ".bin";
case MediaType.DVD:
case MediaType.HDDVD:
case MediaType.BluRay:
return ".iso";
case MediaType.NONE:
default:
return null;
}
}
#endregion

File diff suppressed because it is too large Load Diff

View File

@@ -72,7 +72,7 @@ namespace MPF.Modules.UmdImageCreator
switch (this.Type)
{
case MediaType.UMD:
info.Extras.PVD = GetPVD(basePath + "_mainInfo.txt") ?? "";
info.Extras.PVD = GetPVD(basePath + "_mainInfo.txt") ?? string.Empty;
if (GetFileHashes(basePath + ".iso", out long filesize, out string crc32, out string md5, out string sha1))
{
@@ -84,9 +84,9 @@ namespace MPF.Modules.UmdImageCreator
if (GetUMDAuxInfo(basePath + "_disc.txt", out string title, out DiscCategory? umdcat, out string umdversion, out string umdlayer, out long umdsize))
{
info.CommonDiscInfo.Title = title ?? "";
info.CommonDiscInfo.Title = title ?? string.Empty;
info.CommonDiscInfo.Category = umdcat ?? DiscCategory.Games;
info.VersionAndEditions.Version = umdversion ?? "";
info.VersionAndEditions.Version = umdversion ?? string.Empty;
info.SizeAndChecksums.Size = umdsize;
if (!string.IsNullOrWhiteSpace(umdlayer))

View File

@@ -31,6 +31,7 @@ namespace MPF.Test.Core.Utilities
RedumpSystem.AtariJaguarCDInteractiveMultimediaSystem,
RedumpSystem.AudioCD,
RedumpSystem.DVDAudio,
RedumpSystem.HasbroiONEducationalGamingSystem,
RedumpSystem.HasbroVideoNow,
RedumpSystem.HasbroVideoNowColor,
RedumpSystem.HasbroVideoNowJr,
@@ -58,6 +59,7 @@ namespace MPF.Test.Core.Utilities
RedumpSystem.SonyPlayStation2,
RedumpSystem.SonyPlayStation3,
RedumpSystem.SonyPlayStation4,
RedumpSystem.SonyPlayStationPortable,
};
/// <summary>

View File

@@ -24,7 +24,7 @@ namespace MPF.Test.Library
? Drive.Create(InternalDriveType.Floppy, letter.ToString())
: Drive.Create(InternalDriveType.Optical, letter.ToString());
var env = new DumpEnvironment(options, string.Empty, drive, RedumpSystem.IBMPCcompatible, mediaType, parameters);
var env = new DumpEnvironment(options, string.Empty, drive, RedumpSystem.IBMPCcompatible, mediaType, null, parameters);
bool actual = env.ParametersValid();
Assert.Equal(expected, actual);

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.IO;
using MPF.Library;
using RedumpLib.Data;
using Xunit;
@@ -25,9 +26,9 @@ namespace MPF.Test.Library
[InlineData(MediaType.DVD, 12345, 1, 2, 3, "DVD-ROM-9")]
[InlineData(MediaType.BluRay, 0, 0, 0, 0, "BD-ROM-25")]
[InlineData(MediaType.BluRay, 12345, 0, 0, 0, "BD-ROM-25")]
//[InlineData(MediaType.BluRay, 26_843_531_857, 0, 0, 0, "BD-ROM-33")]
[InlineData(MediaType.BluRay, 26_843_531_857, 0, 0, 0, "BD-ROM-33")]
[InlineData(MediaType.BluRay, 12345, 1, 0, 0, "BD-ROM-50")]
//[InlineData(MediaType.BluRay, 53_687_063_713, 1, 0, 0, "BD-ROM-66")]
[InlineData(MediaType.BluRay, 53_687_063_713, 1, 0, 0, "BD-ROM-66")]
[InlineData(MediaType.BluRay, 12345, 1, 2, 0, "BD-ROM-100")]
[InlineData(MediaType.BluRay, 12345, 1, 2, 3, "BD-ROM-128")]
[InlineData(MediaType.UMD, 0, 0, 0, 0, "UMD-SL")]
@@ -43,7 +44,8 @@ namespace MPF.Test.Library
long layerbreak3,
string expected)
{
string actual = InfoTool.GetFixedMediaType(mediaType, size, layerbreak, layerbreak2, layerbreak3);
// TODO: Add tests around BDU
string actual = InfoTool.GetFixedMediaType(mediaType, null, size, layerbreak, layerbreak2, layerbreak3);
Assert.Equal(expected, actual);
}
@@ -58,6 +60,9 @@ namespace MPF.Test.Library
[InlineData("superhero\\blah&foo.bin", "superhero\\blah&foo.bin")]
public void NormalizeOutputPathsTest(string outputPath, string expectedPath)
{
if (!string.IsNullOrWhiteSpace(expectedPath))
expectedPath = Path.GetFullPath(expectedPath);
string actualPath = InfoTool.NormalizeOutputPaths(outputPath);
Assert.Equal(expectedPath, actualPath);
}

View File

@@ -34,21 +34,21 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeCoverage" Version="17.4.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.4.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="Microsoft.CodeCoverage" Version="17.6.3" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.3" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="xunit" Version="2.5.0" />
<PackageReference Include="xunit.abstractions" Version="2.0.3" />
<PackageReference Include="xunit.analyzers" Version="1.1.0" />
<PackageReference Include="xunit.assert" Version="2.4.2" />
<PackageReference Include="xunit.core" Version="2.4.2" />
<PackageReference Include="xunit.extensibility.core" Version="2.4.2" />
<PackageReference Include="xunit.extensibility.execution" Version="2.4.2" />
<PackageReference Include="xunit.runner.console" Version="2.4.2">
<PackageReference Include="xunit.analyzers" Version="1.2.0" />
<PackageReference Include="xunit.assert" Version="2.5.0" />
<PackageReference Include="xunit.core" Version="2.5.0" />
<PackageReference Include="xunit.extensibility.core" Version="2.5.0" />
<PackageReference Include="xunit.extensibility.execution" Version="2.5.0" />
<PackageReference Include="xunit.runner.console" Version="2.5.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>

View File

@@ -18,9 +18,9 @@ namespace MPF.Test.RedumpLib
private static readonly DiscType?[] _mappableDiscTypes = new DiscType?[]
{
DiscType.BD25,
//DiscType.BD33,
DiscType.BD33,
DiscType.BD50,
//DiscType.BD66,
DiscType.BD66,
DiscType.BD100,
DiscType.BD128,
DiscType.CD,

View File

@@ -2,14 +2,14 @@
<PropertyGroup>
<TargetFrameworks>net48;net6.0-windows</TargetFrameworks>
<RuntimeIdentifiers>win7-x64;win-x86;win-x64</RuntimeIdentifiers>
<RuntimeIdentifiers>win7-x64;win8-x64;win81-x64;win10-x64</RuntimeIdentifiers>
<UseWindowsForms>true</UseWindowsForms>
<UseWPF>true</UseWPF>
<Title>MPF.UI.Core</Title>
<AssemblyName>MPF.UI.Core</AssemblyName>
<Authors>Matt Nadareski;ReignStumble;Jakz</Authors>
<Copyright>Copyright (c)2019-2023</Copyright>
<Version>2.5</Version>
<Version>2.6.2</Version>
<AssemblyVersion>$(Version)</AssemblyVersion>
<FileVersion>$(Version)</FileVersion>
<IncludeSource>true</IncludeSource>

400
MPF.UI.Core/Theme.cs Normal file
View File

@@ -0,0 +1,400 @@
using System.Windows;
using System.Windows.Media;
namespace MPF.UI.Core
{
/// <summary>
/// Represents all required mapping values for the UI
/// </summary>
public class Theme
{
#region Application-Wide
/// <summary>
/// SolidColorBrush used to paint the active window's border.
/// </summary>
public SolidColorBrush ActiveBorderBrush { get; set; }
/// <summary>
/// SolidColorBrush that paints the face of a three-dimensional display element.
/// </summary>
public SolidColorBrush ControlBrush { get; set; }
/// <summary>
/// SolidColorBrush that paints text in a three-dimensional display element.
/// </summary>
public SolidColorBrush ControlTextBrush { get; set; }
/// <summary>
/// SolidColorBrush that paints disabled text.
/// </summary>
public SolidColorBrush GrayTextBrush { get; set; }
/// <summary>
/// SolidColorBrush that paints the background of a window's client area.
/// </summary>
public SolidColorBrush WindowBrush { get; set; }
/// <summary>
/// SolidColorBrush that paints the text in the client area of a window.
/// </summary>
public SolidColorBrush WindowTextBrush { get; set; }
#endregion
#region Button
/// <summary>
/// Brush for the Button.Disabled.Background resource
/// </summary>
public Brush Button_Disabled_Background { get; set; }
/// <summary>
/// Brush for the Button.MouseOver.Background resource
/// </summary>
public Brush Button_MouseOver_Background { get; set; }
/// <summary>
/// Brush for the Button.Pressed.Background resource
/// </summary>
public Brush Button_Pressed_Background { get; set; }
/// <summary>
/// Brush for the Button.Static.Background resource
/// </summary>
public Brush Button_Static_Background { get; set; }
#endregion
#region ComboBox
/// <summary>
/// Brush for the ComboBox.Disabled.Background resource
/// </summary>
public Brush ComboBox_Disabled_Background { get; set; }
/// <summary>
/// Brush for the ComboBox.Disabled.Editable.Background resource
/// </summary>
public Brush ComboBox_Disabled_Editable_Background { get; set; }
/// <summary>
/// Brush for the ComboBox.Disabled.Editable.Button.Background resource
/// </summary>
public Brush ComboBox_Disabled_Editable_Button_Background { get; set; }
/// <summary>
/// Brush for the ComboBox.MouseOver.Background resource
/// </summary>
public Brush ComboBox_MouseOver_Background { get; set; }
/// <summary>
/// Brush for the ComboBox.MouseOver.Editable.Background resource
/// </summary>
public Brush ComboBox_MouseOver_Editable_Background { get; set; }
/// <summary>
/// Brush for the ComboBox.MouseOver.Editable.Button.Background resource
/// </summary>
public Brush ComboBox_MouseOver_Editable_Button_Background { get; set; }
/// <summary>
/// Brush for the ComboBox.Pressed.Background resource
/// </summary>
public Brush ComboBox_Pressed_Background { get; set; }
/// <summary>
/// Brush for the ComboBox.Pressed.Editable.Background resource
/// </summary>
public Brush ComboBox_Pressed_Editable_Background { get; set; }
/// <summary>
/// Brush for the ComboBox.Pressed.Editable.Button.Background resource
/// </summary>
public Brush ComboBox_Pressed_Editable_Button_Background { get; set; }
/// <summary>
/// Brush for the ComboBox.Static.Background resource
/// </summary>
public Brush ComboBox_Static_Background { get; set; }
/// <summary>
/// Brush for the ComboBox.Static.Editable.Background resource
/// </summary>
public Brush ComboBox_Static_Editable_Background { get; set; }
/// <summary>
/// Brush for the ComboBox.Static.Editable.Button.Background resource
/// </summary>
public Brush ComboBox_Static_Editable_Button_Background { get; set; }
#endregion
#region CustomMessageBox
/// <summary>
/// Brush for the CustomMessageBox.Static.Background resource
/// </summary>
public Brush CustomMessageBox_Static_Background { get; set; }
#endregion
#region MenuItem
/// <summary>
/// Brush for the MenuItem.SubMenu.Background resource
/// </summary>
public Brush MenuItem_SubMenu_Background { get; set; }
/// <summary>
/// Brush for the MenuItem.SubMenu.Border resource
/// </summary>
public Brush MenuItem_SubMenu_Border { get; set; }
#endregion
#region ProgressBar
/// <summary>
/// Brush for the ProgressBar.Background resource
/// </summary>
public Brush ProgressBar_Background { get; set; }
#endregion
#region ScrollViewer
/// <summary>
/// Brush for the ScrollViewer.ScrollBar.Background resource
/// </summary>
public Brush ScrollViewer_ScrollBar_Background { get; set; }
#endregion
#region TabItem
/// <summary>
/// Brush for the TabItem.Selected.Background resource
/// </summary>
public Brush TabItem_Selected_Background { get; set; }
/// <summary>
/// Brush for the TabItem.Static.Background resource
/// </summary>
public Brush TabItem_Static_Background { get; set; }
/// <summary>
/// Brush for the TabItem.Static.Border resource
/// </summary>
public Brush TabItem_Static_Border { get; set; }
#endregion
#region TextBox
/// <summary>
/// Brush for the TextBox.Static.Background resource
/// </summary>
public Brush TextBox_Static_Background { get; set; }
#endregion
/// <summary>
/// Apply the theme to the current application
/// </summary>
public void Apply()
{
// Handle application-wide resources
Application.Current.Resources[SystemColors.ActiveBorderBrushKey] = this.ActiveBorderBrush;
Application.Current.Resources[SystemColors.ControlBrushKey] = this.ControlBrush;
Application.Current.Resources[SystemColors.ControlTextBrushKey] = this.ControlTextBrush;
Application.Current.Resources[SystemColors.GrayTextBrushKey] = this.GrayTextBrush;
Application.Current.Resources[SystemColors.WindowBrushKey] = this.WindowBrush;
Application.Current.Resources[SystemColors.WindowTextBrushKey] = this.WindowTextBrush;
// Handle Button-specific resources
Application.Current.Resources["Button.Disabled.Background"] = this.Button_Disabled_Background;
Application.Current.Resources["Button.MouseOver.Background"] = this.Button_MouseOver_Background;
Application.Current.Resources["Button.Pressed.Background"] = this.Button_Pressed_Background;
Application.Current.Resources["Button.Static.Background"] = this.Button_Static_Background;
// Handle ComboBox-specific resources
Application.Current.Resources["ComboBox.Disabled.Background"] = this.ComboBox_Disabled_Background;
Application.Current.Resources["ComboBox.Disabled.Editable.Background"] = this.ComboBox_Disabled_Editable_Background;
Application.Current.Resources["ComboBox.Disabled.Editable.Button.Background"] = this.ComboBox_Disabled_Editable_Button_Background;
Application.Current.Resources["ComboBox.MouseOver.Background"] = this.ComboBox_MouseOver_Background;
Application.Current.Resources["ComboBox.MouseOver.Editable.Background"] = this.ComboBox_MouseOver_Editable_Background;
Application.Current.Resources["ComboBox.MouseOver.Editable.Button.Background"] = this.ComboBox_MouseOver_Editable_Button_Background;
Application.Current.Resources["ComboBox.Pressed.Background"] = this.ComboBox_Pressed_Background;
Application.Current.Resources["ComboBox.Pressed.Editable.Background"] = this.ComboBox_Pressed_Editable_Background;
Application.Current.Resources["ComboBox.Pressed.Editable.Button.Background"] = this.ComboBox_Pressed_Editable_Button_Background;
Application.Current.Resources["ComboBox.Static.Background"] = this.ComboBox_Static_Background;
Application.Current.Resources["ComboBox.Static.Editable.Background"] = this.ComboBox_Static_Editable_Background;
Application.Current.Resources["ComboBox.Static.Editable.Button.Background"] = this.ComboBox_Static_Editable_Button_Background;
// Handle CustomMessageBox-specific resources
Application.Current.Resources["CustomMessageBox.Static.Background"] = this.CustomMessageBox_Static_Background;
// Handle MenuItem-specific resources
Application.Current.Resources["MenuItem.SubMenu.Background"] = this.MenuItem_SubMenu_Background;
Application.Current.Resources["MenuItem.SubMenu.Border"] = this.MenuItem_SubMenu_Border;
// Handle ProgressBar-specific resources
Application.Current.Resources["ProgressBar.Background"] = this.ProgressBar_Background;
// Handle ScrollViewer-specific resources
Application.Current.Resources["ScrollViewer.ScrollBar.Background"] = this.ScrollViewer_ScrollBar_Background;
// Handle TabItem-specific resources
Application.Current.Resources["TabItem.Selected.Background"] = this.TabItem_Selected_Background;
Application.Current.Resources["TabItem.Static.Background"] = this.TabItem_Static_Background;
Application.Current.Resources["TabItem.Static.Border"] = this.TabItem_Static_Border;
// Handle TextBox-specific resources
Application.Current.Resources["TextBox.Static.Background"] = this.TextBox_Static_Background;
}
}
/// <summary>
/// Default light-mode theme
/// </summary>
public class LightModeTheme : Theme
{
public LightModeTheme()
{
// Handle application-wide resources
this.ActiveBorderBrush = null;
this.ControlBrush = null;
this.ControlTextBrush = null;
this.GrayTextBrush = null;
this.WindowBrush = null;
this.WindowTextBrush = null;
// Handle Button-specific resources
this.Button_Disabled_Background = new SolidColorBrush(Color.FromArgb(0xFF, 0xF4, 0xF4, 0xF4));
this.Button_MouseOver_Background = new SolidColorBrush(Color.FromArgb(0xFF, 0xBE, 0xE6, 0xFD));
this.Button_Pressed_Background = new SolidColorBrush(Color.FromArgb(0xFF, 0xC4, 0xE5, 0xF6));
this.Button_Static_Background = new SolidColorBrush(Color.FromArgb(0xFF, 0xDD, 0xDD, 0xDD));
// Handle ComboBox-specific resources
this.ComboBox_Disabled_Background = new SolidColorBrush(Color.FromArgb(0xFF, 0xF0, 0xF0, 0xF0));
this.ComboBox_Disabled_Editable_Background = new SolidColorBrush(Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF));
this.ComboBox_Disabled_Editable_Button_Background = Brushes.Transparent;
this.ComboBox_MouseOver_Background = new LinearGradientBrush(
Color.FromArgb(0xFF, 0xEC, 0xF4, 0xFC),
Color.FromArgb(0xFF, 0xDC, 0xEC, 0xFC),
new Point(0, 0),
new Point(0, 1));
this.ComboBox_MouseOver_Editable_Background = new SolidColorBrush(Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF));
this.ComboBox_MouseOver_Editable_Button_Background = new LinearGradientBrush(
Color.FromArgb(0xFF, 0xEB, 0xF4, 0xFC),
Color.FromArgb(0xFF, 0xDC, 0xEC, 0xFC),
new Point(0, 0),
new Point(0, 1));
this.ComboBox_Pressed_Background = new LinearGradientBrush(
Color.FromArgb(0xFF, 0xDA, 0xEC, 0xFC),
Color.FromArgb(0xFF, 0xC4, 0xE0, 0xFC),
new Point(0, 0),
new Point(0, 1));
this.ComboBox_Pressed_Editable_Background = new SolidColorBrush(Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF));
this.ComboBox_Pressed_Editable_Button_Background = new LinearGradientBrush(
Color.FromArgb(0xFF, 0xDA, 0xEB, 0xFC),
Color.FromArgb(0xFF, 0xC4, 0xE0, 0xFC),
new Point(0, 0),
new Point(0, 1));
this.ComboBox_Static_Background = new LinearGradientBrush(
Color.FromArgb(0xFF, 0xF0, 0xF0, 0xF0),
Color.FromArgb(0xFF, 0xE5, 0xE5, 0xE5),
new Point(0, 0),
new Point(0, 1));
this.ComboBox_Static_Editable_Background = new SolidColorBrush(Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF));
this.ComboBox_Static_Editable_Button_Background = Brushes.Transparent;
// Handle CustomMessageBox-specific resources
this.CustomMessageBox_Static_Background = null;
// Handle MenuItem-specific resources
this.MenuItem_SubMenu_Background = new SolidColorBrush(Color.FromArgb(0xFF, 0xF0, 0xF0, 0xF0));
this.MenuItem_SubMenu_Border = Brushes.DarkGray;
// Handle ProgressBar-specific resources
this.ProgressBar_Background = new SolidColorBrush(Color.FromArgb(0xFF, 0xE6, 0xE6, 0xE6));
// Handle ScrollViewer-specific resources
this.ScrollViewer_ScrollBar_Background = Brushes.LightGray;
// Handle TabItem-specific resources
this.TabItem_Selected_Background = new SolidColorBrush(Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF));
this.TabItem_Static_Background = new LinearGradientBrush(
Color.FromArgb(0xFF, 0xF0, 0xF0, 0xF0),
Color.FromArgb(0xFF, 0xE5, 0xE5, 0xE5),
new Point(0, 0),
new Point(0, 1));
this.TabItem_Static_Border = Brushes.DarkGray;
// Handle TextBox-specific resources
this.TextBox_Static_Background = new SolidColorBrush(Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF));
}
}
/// <summary>
/// Default dark-mode theme
/// </summary>
public class DarkModeTheme : Theme
{
public DarkModeTheme()
{
// Setup needed brushes
var darkModeBrush = new SolidColorBrush { Color = Color.FromArgb(0xff, 0x20, 0x20, 0x20) };
// Handle application-wide resources
this.ActiveBorderBrush = Brushes.Black;
this.ControlBrush = darkModeBrush;
this.ControlTextBrush = Brushes.White;
this.GrayTextBrush = Brushes.DarkGray;
this.WindowBrush = darkModeBrush;
this.WindowTextBrush = Brushes.White;
// Handle Button-specific resources
this.Button_Disabled_Background = darkModeBrush;
this.Button_MouseOver_Background = darkModeBrush;
this.Button_Pressed_Background = darkModeBrush;
this.Button_Static_Background = darkModeBrush;
// Handle ComboBox-specific resources
this.ComboBox_Disabled_Background = darkModeBrush;
this.ComboBox_Disabled_Editable_Background = darkModeBrush;
this.ComboBox_Disabled_Editable_Button_Background = darkModeBrush;
this.ComboBox_MouseOver_Background = darkModeBrush;
this.ComboBox_MouseOver_Editable_Background = darkModeBrush;
this.ComboBox_MouseOver_Editable_Button_Background = darkModeBrush;
this.ComboBox_Pressed_Background = darkModeBrush;
this.ComboBox_Pressed_Editable_Background = darkModeBrush;
this.ComboBox_Pressed_Editable_Button_Background = darkModeBrush;
this.ComboBox_Static_Background = darkModeBrush;
this.ComboBox_Static_Editable_Background = darkModeBrush;
this.ComboBox_Static_Editable_Button_Background = darkModeBrush;
// Handle CustomMessageBox-specific resources
this.CustomMessageBox_Static_Background = darkModeBrush;
// Handle MenuItem-specific resources
this.MenuItem_SubMenu_Background = darkModeBrush;
this.MenuItem_SubMenu_Border = Brushes.DarkGray;
// Handle ProgressBar-specific resources
this.ProgressBar_Background = darkModeBrush;
// Handle ScrollViewer-specific resources
this.ScrollViewer_ScrollBar_Background = darkModeBrush;
// Handle TabItem-specific resources
this.TabItem_Selected_Background = darkModeBrush;
this.TabItem_Static_Background = darkModeBrush;
this.TabItem_Static_Border = Brushes.DarkGray;
// Handle TextBox-specific resources
this.TextBox_Static_Background = darkModeBrush;
}
}
}

View File

@@ -671,9 +671,9 @@ namespace MPF.UI.Core.ViewModels
case DiscType.HDDVDSL:
case DiscType.HDDVDDL:
case DiscType.BD25:
//case DiscType.BD33:
case DiscType.BD33:
case DiscType.BD50:
//case DiscType.BD66:
case DiscType.BD66:
case DiscType.BD100:
case DiscType.BD128:
case DiscType.NintendoGameCubeGameDisc:

View File

@@ -369,7 +369,7 @@
<controls:UserInput x:Name="PVD" Label="PVD" IsReadOnly="True"
Text="{Binding SubmissionInfo.Extras.PVD, Mode=TwoWay}" TextHeight="75" TextWrapping="NoWrap"
VerticalContentAlignmentValue="Top" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"/>
<controls:UserInput x:Name="RingNonZeroDataStart" Label="Universal Hash (SHA-1)" IsReadOnly="True"/>
<controls:UserInput x:Name="RingNonZeroDataStart" Label="Ring Non-Zero Data Start" IsReadOnly="True"/>
<controls:UserInput x:Name="SecuROMData" Label="SecuROM Data" IsReadOnly="True"
Text="{Binding SubmissionInfo.CopyProtection.SecuROMData, Mode=TwoWay}" TextHeight="75" TextWrapping="NoWrap"
VerticalContentAlignmentValue="Top" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"/>

View File

@@ -18,7 +18,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
.github\ISSUE_TEMPLATE\feature-request.md = .github\ISSUE_TEMPLATE\feature-request.md
.github\ISSUE_TEMPLATE\informational.md = .github\ISSUE_TEMPLATE\informational.md
.github\ISSUE_TEMPLATE\issue-report.md = .github\ISSUE_TEMPLATE\issue-report.md
publish-nix.sh = publish-nix.sh
README.md = README.md
publish-win.bat = publish-win.bat
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RedumpLib", "RedumpLib\RedumpLib.csproj", "{13574913-A426-4644-9955-F49AD0876E5F}"

View File

@@ -2,7 +2,7 @@
<PropertyGroup>
<TargetFrameworks>net48;net6.0-windows</TargetFrameworks>
<RuntimeIdentifiers>win7-x64;win-x86;win-x64</RuntimeIdentifiers>
<RuntimeIdentifiers>win7-x64;win8-x64;win81-x64;win10-x64</RuntimeIdentifiers>
<OutputType>WinExe</OutputType>
<UseWindowsForms>true</UseWindowsForms>
<UseWPF>true</UseWPF>
@@ -13,7 +13,7 @@
<Authors>Matt Nadareski;ReignStumble;Jakz</Authors>
<Copyright>Copyright (c)2019-2023</Copyright>
<RepositoryUrl>https://github.com/SabreTools/MPF</RepositoryUrl>
<Version>2.5</Version>
<Version>2.6.2</Version>
<AssemblyVersion>$(Version)</AssemblyVersion>
<FileVersion>$(Version)</FileVersion>
<IncludeSource>true</IncludeSource>
@@ -27,7 +27,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="BurnOutSharp" PrivateAssets="build; analyzers" ExcludeAssets="contentFiles" Version="2.7.0" GeneratePathProperty="true">
<PackageReference Include="BurnOutSharp" PrivateAssets="build; analyzers" ExcludeAssets="contentFiles" Version="2.8.0" GeneratePathProperty="true">
<IncludeAssets>runtime; compile; build; native; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="System.Configuration.ConfigurationManager" Version="7.0.0" />

View File

@@ -15,6 +15,7 @@ using MPF.UI.Core.Windows;
using RedumpLib.Data;
using WPFCustomMessageBox;
using WinForms = System.Windows.Forms;
using MPF.UI.Core;
namespace MPF.UI.ViewModels
{
@@ -51,6 +52,11 @@ namespace MPF.UI.ViewModels
/// </summary>
public List<RedumpSystemComboBoxItem> Systems { get; set; } = RedumpSystemComboBoxItem.GenerateElements().ToList();
/// <summary>
/// List of available internal programs
/// </summary>
public List<Element<InternalProgram>> InternalPrograms { get; set; } = new List<Element<InternalProgram>>();
#endregion
#region Private Event Flags
@@ -161,7 +167,7 @@ namespace MPF.UI.ViewModels
/// <summary>
/// Populate media type according to system type
/// </summary>
public void PopulateMediaType()
private void PopulateMediaType()
{
RedumpSystem? currentSystem = App.Instance.SystemTypeComboBox.SelectedItem as RedumpSystemComboBoxItem;
@@ -186,6 +192,27 @@ namespace MPF.UI.ViewModels
App.Instance.UpdateLayout();
}
/// <summary>
/// Populate media type according to system type
/// </summary>
private void PopulateInternalPrograms()
{
// Get the current internal program
InternalProgram internalProgram = App.Options.InternalProgram;
// Create a static list of supported programs, not everything
var internalPrograms = new List<InternalProgram> { InternalProgram.DiscImageCreator, InternalProgram.Aaru, InternalProgram.Redumper, InternalProgram.DD };
InternalPrograms = internalPrograms.Select(ip => new Element<InternalProgram>(ip)).ToList();
App.Instance.DumpingProgramComboBox.ItemsSource = InternalPrograms;
// Select the current default dumping program
int currentIndex = InternalPrograms.FindIndex(m => m == internalProgram);
App.Instance.DumpingProgramComboBox.SelectedIndex = (currentIndex > -1 ? currentIndex : 0);
// Ensure the UI gets updated
App.Instance.UpdateLayout();
}
#endregion
#region UI Commands
@@ -500,7 +527,7 @@ namespace MPF.UI.ViewModels
{
if (optionsWindow?.OptionsViewModel.SavedSettings == true)
{
App.Options = optionsWindow.OptionsViewModel.Options.Clone() as Options;
App.Options = optionsWindow.OptionsViewModel.Options.Clone() as MPF.Core.Data.Options;
InitializeUIValues(removeEventHandlers: true, rescanDrives: true);
}
}
@@ -532,7 +559,7 @@ namespace MPF.UI.ViewModels
if (App.Options.EnableDarkMode)
EnableDarkMode();
else
DisableDarkMode();
EnableLightMode();
// Force the UI to reload after applying the theme
App.Instance.UpdateLayout();
@@ -557,6 +584,9 @@ namespace MPF.UI.ViewModels
CacheCurrentDiscType();
SetCurrentDiscType();
// Set the dumping program
await App.Instance.Dispatcher.InvokeAsync(PopulateInternalPrograms);
// Set the initial environment and UI values
SetSupportedDriveSpeed();
Env = DetermineEnvironment();
@@ -632,6 +662,7 @@ namespace MPF.UI.ViewModels
App.Instance.MediaTypeComboBox.SelectionChanged += MediaTypeComboBoxSelectionChanged;
App.Instance.DriveLetterComboBox.SelectionChanged += DriveLetterComboBoxSelectionChanged;
App.Instance.DriveSpeedComboBox.SelectionChanged += DriveSpeedComboBoxSelectionChanged;
App.Instance.DumpingProgramComboBox.SelectionChanged += DumpingProgramComboBoxSelectionChanged;
// User Area TextChanged
App.Instance.OutputPathTextBox.TextChanged += OutputPathTextBoxTextChanged;
@@ -665,6 +696,7 @@ namespace MPF.UI.ViewModels
App.Instance.OutputPathBrowseButton.IsEnabled = false;
App.Instance.DriveLetterComboBox.IsEnabled = false;
App.Instance.DriveSpeedComboBox.IsEnabled = false;
App.Instance.DumpingProgramComboBox.IsEnabled = false;
App.Instance.EnableParametersCheckBox.IsEnabled = false;
App.Instance.StartStopButton.Content = Interface.StopDumping;
App.Instance.MediaScanButton.IsEnabled = false;
@@ -684,6 +716,7 @@ namespace MPF.UI.ViewModels
App.Instance.OutputPathBrowseButton.IsEnabled = true;
App.Instance.DriveLetterComboBox.IsEnabled = true;
App.Instance.DriveSpeedComboBox.IsEnabled = true;
App.Instance.DumpingProgramComboBox.IsEnabled = true;
App.Instance.EnableParametersCheckBox.IsEnabled = true;
App.Instance.StartStopButton.Content = Interface.StartDumping;
App.Instance.MediaScanButton.IsEnabled = true;
@@ -692,80 +725,12 @@ namespace MPF.UI.ViewModels
}
/// <summary>
/// Recolor all UI elements back to normal values
/// Recolor all UI elements for light mode
/// </summary>
private void DisableDarkMode()
private void EnableLightMode()
{
// Handle application-wide resources
Application.Current.Resources[SystemColors.ActiveBorderBrushKey] = null;
Application.Current.Resources[SystemColors.ControlBrushKey] = null;
Application.Current.Resources[SystemColors.ControlTextBrushKey] = null;
Application.Current.Resources[SystemColors.GrayTextBrushKey] = null;
Application.Current.Resources[SystemColors.WindowBrushKey] = null;
Application.Current.Resources[SystemColors.WindowTextBrushKey] = null;
// Handle Button-specific resources
Application.Current.Resources["Button.Disabled.Background"] = new SolidColorBrush(Color.FromArgb(0xFF, 0xF4, 0xF4, 0xF4));
Application.Current.Resources["Button.MouseOver.Background"] = new SolidColorBrush(Color.FromArgb(0xFF, 0xBE, 0xE6, 0xFD));
Application.Current.Resources["Button.Pressed.Background"] = new SolidColorBrush(Color.FromArgb(0xFF, 0xC4, 0xE5, 0xF6));
Application.Current.Resources["Button.Static.Background"] = new SolidColorBrush(Color.FromArgb(0xFF, 0xDD, 0xDD, 0xDD));
// Handle ComboBox-specific resources
Application.Current.Resources["ComboBox.Disabled.Background"] = new SolidColorBrush(Color.FromArgb(0xFF, 0xF0, 0xF0, 0xF0));
Application.Current.Resources["ComboBox.Disabled.Editable.Background"] = new SolidColorBrush(Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF));
Application.Current.Resources["ComboBox.Disabled.Editable.Button.Background"] = Brushes.Transparent;
Application.Current.Resources["ComboBox.MouseOver.Background"] = new LinearGradientBrush(
Color.FromArgb(0xFF, 0xEC, 0xF4, 0xFC),
Color.FromArgb(0xFF, 0xDC, 0xEC, 0xFC),
new Point(0, 0),
new Point(0, 1));
Application.Current.Resources["ComboBox.MouseOver.Editable.Background"] = new SolidColorBrush(Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF));
Application.Current.Resources["ComboBox.MouseOver.Editable.Button.Background"] = new LinearGradientBrush(
Color.FromArgb(0xFF, 0xEB, 0xF4, 0xFC),
Color.FromArgb(0xFF, 0xDC, 0xEC, 0xFC),
new Point(0, 0),
new Point(0, 1));
Application.Current.Resources["ComboBox.Pressed.Background"] = new LinearGradientBrush(
Color.FromArgb(0xFF, 0xDA, 0xEC, 0xFC),
Color.FromArgb(0xFF, 0xC4, 0xE0, 0xFC),
new Point(0, 0),
new Point(0, 1));
Application.Current.Resources["ComboBox.Pressed.Editable.Background"] = new SolidColorBrush(Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF));
Application.Current.Resources["ComboBox.Pressed.Editable.Button.Background"] = new LinearGradientBrush(
Color.FromArgb(0xFF, 0xDA, 0xEB, 0xFC),
Color.FromArgb(0xFF, 0xC4, 0xE0, 0xFC),
new Point(0, 0),
new Point(0, 1));
Application.Current.Resources["ComboBox.Static.Background"] = new LinearGradientBrush(
Color.FromArgb(0xFF, 0xF0, 0xF0, 0xF0),
Color.FromArgb(0xFF, 0xE5, 0xE5, 0xE5),
new Point(0, 0),
new Point(0, 1));
Application.Current.Resources["ComboBox.Static.Editable.Background"] = new SolidColorBrush(Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF));
Application.Current.Resources["ComboBox.Static.Editable.Button.Background"] = Brushes.Transparent;
Application.Current.Resources["TextBox.Static.Background"] = new SolidColorBrush(Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF));
// Handle CustomMessageBox-specific resources
Application.Current.Resources["CustomMessageBox.Static.Background"] = null;
// Handle MenuItem-specific resources
Application.Current.Resources["MenuItem.SubMenu.Background"] = new SolidColorBrush(Color.FromArgb(0xFF, 0xF0, 0xF0, 0xF0));
Application.Current.Resources["MenuItem.SubMenu.Border"] = Brushes.DarkGray;
// Handle ProgressBar-specific resources
Application.Current.Resources["ProgressBar.Background"] = new SolidColorBrush(Color.FromArgb(0xFF, 0xE6, 0xE6, 0xE6));
// Handle ScrollViewer-specific resources
Application.Current.Resources["ScrollViewer.ScrollBar.Background"] = Brushes.LightGray;
// Handle TabItem-specific resources
Application.Current.Resources["TabItem.Selected.Background"] = new SolidColorBrush(Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF));
Application.Current.Resources["TabItem.Static.Background"] = new LinearGradientBrush(
Color.FromArgb(0xFF, 0xF0, 0xF0, 0xF0),
Color.FromArgb(0xFF, 0xE5, 0xE5, 0xE5),
new Point(0, 0),
new Point(0, 1));
Application.Current.Resources["TabItem.Static.Border"] = Brushes.DarkGray;
var theme = new LightModeTheme();
theme.Apply();
}
/// <summary>
@@ -773,55 +738,8 @@ namespace MPF.UI.ViewModels
/// </summary>
private void EnableDarkMode()
{
// Setup needed brushes
var darkModeBrush = new SolidColorBrush { Color = Color.FromArgb(0xff, 0x20, 0x20, 0x20) };
// Handle application-wide resources
Application.Current.Resources[SystemColors.ActiveBorderBrushKey] = Brushes.Black;
Application.Current.Resources[SystemColors.ControlBrushKey] = darkModeBrush;
Application.Current.Resources[SystemColors.ControlTextBrushKey] = Brushes.White;
Application.Current.Resources[SystemColors.GrayTextBrushKey] = Brushes.DarkGray;
Application.Current.Resources[SystemColors.WindowBrushKey] = darkModeBrush;
Application.Current.Resources[SystemColors.WindowTextBrushKey] = Brushes.White;
// Handle Button-specific resources
Application.Current.Resources["Button.Disabled.Background"] = darkModeBrush;
Application.Current.Resources["Button.MouseOver.Background"] = darkModeBrush;
Application.Current.Resources["Button.Pressed.Background"] = darkModeBrush;
Application.Current.Resources["Button.Static.Background"] = darkModeBrush;
// Handle ComboBox-specific resources
Application.Current.Resources["ComboBox.Disabled.Background"] = darkModeBrush;
Application.Current.Resources["ComboBox.Disabled.Editable.Background"] = darkModeBrush;
Application.Current.Resources["ComboBox.Disabled.Editable.Button.Background"] = darkModeBrush;
Application.Current.Resources["ComboBox.MouseOver.Background"] = darkModeBrush;
Application.Current.Resources["ComboBox.MouseOver.Editable.Background"] = darkModeBrush;
Application.Current.Resources["ComboBox.MouseOver.Editable.Button.Background"] = darkModeBrush;
Application.Current.Resources["ComboBox.Pressed.Background"] = darkModeBrush;
Application.Current.Resources["ComboBox.Pressed.Editable.Background"] = darkModeBrush;
Application.Current.Resources["ComboBox.Pressed.Editable.Button.Background"] = darkModeBrush;
Application.Current.Resources["ComboBox.Static.Background"] = darkModeBrush;
Application.Current.Resources["ComboBox.Static.Editable.Background"] = darkModeBrush;
Application.Current.Resources["ComboBox.Static.Editable.Button.Background"] = darkModeBrush;
Application.Current.Resources["TextBox.Static.Background"] = darkModeBrush;
// Handle CustomMessageBox-specific resources
Application.Current.Resources["CustomMessageBox.Static.Background"] = darkModeBrush;
// Handle MenuItem-specific resources
Application.Current.Resources["MenuItem.SubMenu.Background"] = darkModeBrush;
Application.Current.Resources["MenuItem.SubMenu.Border"] = Brushes.DarkGray;
// Handle ProgressBar-specific resources
Application.Current.Resources["ProgressBar.Background"] = darkModeBrush;
// Handle ScrollViewer-specific resources
Application.Current.Resources["ScrollViewer.ScrollBar.Background"] = darkModeBrush;
// Handle TabItem-specific resources
Application.Current.Resources["TabItem.Selected.Background"] = darkModeBrush;
Application.Current.Resources["TabItem.Static.Background"] = darkModeBrush;
Application.Current.Resources["TabItem.Static.Border"] = Brushes.DarkGray;
var theme = new DarkModeTheme();
theme.Apply();
}
#endregion
@@ -877,13 +795,13 @@ namespace MPF.UI.ViewModels
if (defaultMediaType == MediaType.NONE)
defaultMediaType = MediaType.CDROM;
#if NET48 || NETSTANDARD2_1
// If we're skipping detection, set the default value
if (App.Options.SkipMediaTypeDetection)
{
App.Logger.VerboseLogLn($"Media type detection disabled, defaulting to {defaultMediaType.LongName()}.");
CurrentMediaType = defaultMediaType;
}
// If the drive is marked active, try to read from it
else if (drive.MarkedActive)
{
@@ -913,6 +831,11 @@ namespace MPF.UI.ViewModels
App.Logger.VerboseLogLn($"Drive marked as empty, defaulting to {defaultMediaType.LongName()}.");
CurrentMediaType = defaultMediaType;
}
#else
// Media type detection on initialize is always disabled
App.Logger.VerboseLogLn($"Media type detection not available, defaulting to {defaultMediaType.LongName()}.");
CurrentMediaType = defaultMediaType;
#endif
// Ensure the UI gets updated
App.Instance.UpdateLayout();
@@ -929,6 +852,7 @@ namespace MPF.UI.ViewModels
App.Instance.DriveLetterComboBox.SelectedItem as Drive,
App.Instance.SystemTypeComboBox.SelectedItem as RedumpSystemComboBoxItem,
App.Instance.MediaTypeComboBox.SelectedItem as Element<MediaType>,
App.Instance.DumpingProgramComboBox.SelectedItem as Element<InternalProgram>,
App.Instance.ParametersTextBox.Text);
}
@@ -1078,6 +1002,9 @@ namespace MPF.UI.ViewModels
else
Env.Parameters.Speed = App.Instance.DriveSpeedComboBox.SelectedValue as int?;
// Disable change handling
DisableEventHandlers();
string trimmedPath = Env.Parameters.OutputPath?.Trim('"') ?? string.Empty;
trimmedPath = InfoTool.NormalizeOutputPaths(trimmedPath);
App.Instance.OutputPathTextBox.Text = trimmedPath;
@@ -1086,6 +1013,9 @@ namespace MPF.UI.ViewModels
int mediaTypeIndex = MediaTypes.FindIndex(m => m == mediaType);
if (mediaTypeIndex > -1)
App.Instance.MediaTypeComboBox.SelectedIndex = mediaTypeIndex;
// Reenable change handling
EnableEventHandlers();
}
/// <summary>
@@ -1115,12 +1045,12 @@ namespace MPF.UI.ViewModels
(var protections, string error) = await Protection.RunProtectionScanOnPath(drive.Letter + ":\\", App.Options, progress);
string output = Protection.FormatProtections(protections);
// If SmartE is detected on the current disc, remove `/sf` from the flags for DIC only
if (Env.Options.InternalProgram == InternalProgram.DiscImageCreator && output.Contains("SmartE"))
{
((Modules.DiscImageCreator.Parameters)Env.Parameters)[Modules.DiscImageCreator.FlagStrings.ScanFileProtect] = false;
App.Logger.VerboseLogLn($"SmartE detected, removing {Modules.DiscImageCreator.FlagStrings.ScanFileProtect} from parameters");
}
// If SmartE is detected on the current disc, remove `/sf` from the flags for DIC only -- Disabled until further notice
//if (Env.InternalProgram == InternalProgram.DiscImageCreator && output.Contains("SmartE"))
//{
// ((Modules.DiscImageCreator.Parameters)Env.Parameters)[Modules.DiscImageCreator.FlagStrings.ScanFileProtect] = false;
// App.Logger.VerboseLogLn($"SmartE detected, removing {Modules.DiscImageCreator.FlagStrings.ScanFileProtect} from parameters");
//}
if (!App.Instance.LogPanel.IsExpanded)
{
@@ -1266,8 +1196,8 @@ namespace MPF.UI.ViewModels
// If "No", then we continue with the current known environment
}
// Run path adjustments for DiscImageCreator
Env.AdjustPathsForDiscImageCreator();
// Run path adjustments for DiscImageCreator -- Disabled until further notice
//Env.AdjustPathsForDiscImageCreator();
try
{
@@ -1515,6 +1445,15 @@ namespace MPF.UI.ViewModels
EnsureDiscInformation();
}
/// <summary>
/// Handler for DumpingProgramComboBox SelectionChanged event
/// </summary>
private void DumpingProgramComboBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (_canExecuteSelectionChanged)
EnsureDiscInformation();
}
/// <summary>
/// Handler for EnableParametersCheckBox Click event
/// </summary>
@@ -1546,7 +1485,10 @@ namespace MPF.UI.ViewModels
/// Handler for OutputPathTextBox TextChanged event
/// </summary>
private void OutputPathTextBoxTextChanged(object sender, TextChangedEventArgs e)
=> EnsureDiscInformation();
{
if (_canExecuteSelectionChanged)
EnsureDiscInformation();
}
/// <summary>
/// Handler for StartStopButton Click event

View File

@@ -209,9 +209,9 @@ namespace MPF.UI.ViewModels
return success;
}
#endregion
#endregion
#region UI Functionality
#region UI Functionality
/// <summary>
/// Create an open folder dialog box
@@ -240,9 +240,9 @@ namespace MPF.UI.ViewModels
private System.Windows.Controls.TextBox TextBoxForPathSetting(string name) =>
Parent.FindName(name + "TextBox") as System.Windows.Controls.TextBox;
#endregion
#endregion
#region Event Handlers
#region Event Handlers
/// <summary>
/// Handler for generic Click event
@@ -273,6 +273,6 @@ namespace MPF.UI.ViewModels
_ = await TestRedumpLogin();
#endif
#endregion
#endregion
}
}

View File

@@ -119,6 +119,7 @@
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Label x:Name="SystemMediaTypeLabel" Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" Content="System/Media Type" />
@@ -152,9 +153,12 @@
<Label x:Name="DriveSpeedLabel" Grid.Row="3" Grid.Column="0" VerticalAlignment="Center" Content="Drive Speed"/>
<ComboBox x:Name="DriveSpeedComboBox" Grid.Row="3" Grid.Column="1" Height="22" Width="60" HorizontalAlignment="Left" Style="{DynamicResource CustomComboBoxStyle}" />
<Label x:Name="ParametersLabel" Grid.Row="4" Grid.Column="0" VerticalAlignment="Center" Content="Parameters"/>
<TextBox x:Name="ParametersTextBox" Grid.Row="4" Grid.Column="1" Height="22" Width="370" HorizontalAlignment="Left" IsEnabled="False" VerticalContentAlignment="Center" />
<CheckBox x:Name="EnableParametersCheckBox" Grid.Row="4" Grid.Column="1" Height="22" HorizontalAlignment="Right" IsChecked="False" />
<Label x:Name="DumpingProgramLabel" Grid.Row="4" Grid.Column="0" VerticalAlignment="Center" Content="Dumping Program"/>
<ComboBox x:Name="DumpingProgramComboBox" Grid.Row="4" Grid.Column="1" Height="22" Width="250" HorizontalAlignment="Left" Style="{DynamicResource CustomComboBoxStyle}" />
<Label x:Name="ParametersLabel" Grid.Row="5" Grid.Column="0" VerticalAlignment="Center" Content="Parameters"/>
<TextBox x:Name="ParametersTextBox" Grid.Row="5" Grid.Column="1" Height="22" Width="370" HorizontalAlignment="Left" IsEnabled="False" VerticalContentAlignment="Center" />
<CheckBox x:Name="EnableParametersCheckBox" Grid.Row="5" Grid.Column="1" Height="22" HorizontalAlignment="Right" IsChecked="False" />
</Grid>
</GroupBox>

View File

@@ -118,7 +118,7 @@
<Button x:Name="RedumperPathButton" Grid.Row="3" Grid.Column="2" Height="22" Width="22" Content="..."
Style="{DynamicResource CustomButtonStyle}" />
<Label Grid.Row="4" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Dumping Program" />
<Label Grid.Row="4" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Default Dumping Program" />
<ComboBox x:Name="InternalProgramComboBox" Grid.Row="4" Grid.Column="1" Height="22" HorizontalAlignment="Stretch"
ItemsSource="{Binding InternalPrograms}" Style="{DynamicResource CustomComboBoxStyle}" />
@@ -133,7 +133,7 @@
<StackPanel>
<GroupBox Margin="5,5,5,5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Header="Dumping">
<UniformGrid Columns="2" Rows="9">
<CheckBox VerticalAlignment="Center" Content="Skip Type Detect"
<CheckBox x:Name="SkipMediaTypeDetectionCheckBox" VerticalAlignment="Center" Content="Skip Type Detect"
IsChecked="{Binding Options.SkipMediaTypeDetection}"
ToolTip="Disable trying to guess media type inserted (may improve performance at startup)" Margin="0,4"
/>
@@ -370,7 +370,17 @@
</TabItem>
<TabItem Header="Redumper" Style="{DynamicResource CustomTabItemStyle}">
<UniformGrid Columns="2" Rows="1">
<UniformGrid Columns="2" Rows="2">
<CheckBox VerticalAlignment="Center" Content="Enable Debug Output"
IsChecked="{Binding Options.RedumperEnableDebug}"
ToolTip="Enable debug output in logs" Margin="0,4"
/>
<CheckBox VerticalAlignment="Center" Content="Enable Verbose Output"
IsChecked="{Binding Options.RedumperEnableVerbose}"
ToolTip="Enable verbose output in logs" Margin="0,4"
/>
<Label Content="Reread Tries:" VerticalAlignment="Center" HorizontalAlignment="Right"/>
<TextBox VerticalAlignment="Center" VerticalContentAlignment="Center"
Text="{Binding Options.RedumperRereadCount}"
@@ -406,7 +416,7 @@
<TabItem Header="Login Info" Style="{DynamicResource CustomTabItemStyle}">
<StackPanel>
<GroupBox Margin="5,5,5,5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Header="Redump Credentials">
<UniformGrid Columns="5" Rows="1">
<UniformGrid Columns="5">
<Label VerticalAlignment="Center" HorizontalAlignment="Right" Content="Username" />
<TextBox x:Name="RedumpUsernameTextBox" Height="22" HorizontalAlignment="Stretch"
Text="{Binding Options.RedumpUsername}" />
@@ -418,6 +428,12 @@
Style="{DynamicResource CustomButtonStyle}" />
</UniformGrid>
</GroupBox>
<Label>
<Label.Content>
<TextBlock TextWrapping="Wrap"><Bold Foreground="Red">WARNING:</Bold> If you choose to enable validation and information retrieval, you are responsible for ensuring that all data populated matches your actual media. Some information may be marked to check for validity as a reminder, but all information should be subject to the same scrutiny.</TextBlock>
</Label.Content>
</Label>
</StackPanel>
</TabItem>
</TabControl>

View File

@@ -20,6 +20,12 @@ namespace MPF.Windows
{
InitializeComponent();
DataContext = new OptionsViewModel(this);
#if NET6_0_OR_GREATER
this.SkipMediaTypeDetectionCheckBox.IsEnabled = false;
this.SkipMediaTypeDetectionCheckBox.IsChecked = false;
this.SkipMediaTypeDetectionCheckBox.ToolTip = "This feature is not enabled for .NET 6";
#endif
}
}
}

View File

@@ -13,17 +13,69 @@ For those who would rather use the most recent stable build, download the latest
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)
## System Requirements
## Media Preservation Frontend (MPF)
Even though this is written in C#, this program can only be used on Windows systems due to one of the base programs, DiscImageCreator, being Windows-only. There is some preliminary support for Linux underway, and we will try to integrate with that when the time comes.
MPF is the main, UI-centric application of the MPF suite. This program allows users to use DiscImageCreator, Aaru, Redumper, or dd for Windows 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 (x86 or 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.
- Windows 7 (newest version of Windows recommended) or Mono-compatible Linux environment (MPF.Check only)
- .NET Framework 4.8 or .NET 6.0 Runtimes (.NET 6.0 is mostly functional due to a dependency issues but may be unstable in some situations)
- 1 GB of free RAM
- 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.
### Build Instructions
To build for .NET Framework 4.8 (Windows only), ensure that the .NET Framework 4.8 SDK is installed and included in your PATH. Then, run the following commands from command prompt, Powershell, or Terminal:
```
dotnet restore
msbuild MPF\MPF.csproj -property:TargetFramework=net48 -property:RuntimeIdentifiers=win7-x64
```
To build for .NET 6.0 (Windows only), ensure that the .NET 6.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 net6.0-windows --runtime [win7-x64|win8-x64|win81-x64|win10-x64]
```
Choose one of `[win7-x64|win8-x64|win81-x64|win10-x64]` depending on the machine you are targeting. `win10-x64` also includes Windows 11.
## 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 DiscImageCreator, Aaru, Redumper, dd for Windows, Cleanrip, and UmdImageCreator. Running this program without any parameters will display the help text, including all supported parameters.
### System Requirements
- Windows 8.1 (x86 or x64) or newer, GNU/Linux x64, or OSX x64
- .NET Framework 4.8 (Windows or `mono` only) or .NET 6.0 Runtimes
### Build Instructions
To build for .NET Framework 4.8 (Windows only), ensure that the .NET Framework 4.8 SDK is installed and included in your PATH. Then, run the following commands from command prompt, Powershell, or Terminal:
```
dotnet restore
msbuild MPF.Check\MPF.Check.csproj -property:TargetFramework=net48 -property:RuntimeIdentifiers=win7-x64
```
To build for .NET 6.0 (All supported OSes), ensure that the .NET 6.0 SDK (or later) is installed and included in your PATH. Then, run the following commands from command prompt, Powershell, Terminal, or shell:
```
dotnet build MPF.Check\MPF.Check.csproj --framework net6.0 --runtime [win7-x64|win8-x64|win81-x64|win10-x64|linux-x64|osx-x64]
```
Choose one of `[win7-x64|win8-x64|win81-x64|win10-x64|linux-x64|osx-x64]` depending on the machine you are targeting. `win10-x64` also includes Windows 11.
## Information
For all additional information, including information about the individual components included in the project and what dumping programs are supported, please see [the wiki](https://github.com/SabreTools/MPF/wiki) for more details.

View File

@@ -56,14 +56,14 @@ namespace RedumpLib.Data
[HumanReadable(LongName = "BD-25")]
BD25,
//[HumanReadable(LongName = "BD-33")]
//BD33,
[HumanReadable(LongName = "BD-33")]
BD33,
[HumanReadable(LongName = "BD-50")]
BD50,
//[HumanReadable(LongName = "BD-66")]
//BD66,
[HumanReadable(LongName = "BD-66")]
BD66,
[HumanReadable(LongName = "BD-100")]
BD100,
@@ -1948,6 +1948,9 @@ namespace RedumpLib.Data
[System(Category = SystemCategory.DiscBasedConsole, Available = false, LongName = "Fujitsu FM Towns Marty")]
FujitsuFMTownsMarty,
[System(Category = SystemCategory.DiscBasedConsole, Available = false, LongName = "Hasbro iON Educational Gaming System")]
HasbroiONEducationalGamingSystem,
[System(Category = SystemCategory.DiscBasedConsole, LongName = "Hasbro VideoNow", ShortName = "hvn", IsBanned = true, HasCues = true, HasDat = true)]
HasbroVideoNow,
@@ -1966,6 +1969,9 @@ namespace RedumpLib.Data
[System(Category = SystemCategory.DiscBasedConsole, LongName = "Mattel HyperScan", ShortName = "hs", HasCues = true, HasDat = true)]
MattelHyperScan,
[System(Category = SystemCategory.DiscBasedConsole, LongName = "Memorex Visual Information System", ShortName = "vis", HasCues = true, HasDat = true)]
MemorexVisualInformationSystem,
[System(Category = SystemCategory.DiscBasedConsole, LongName = "Microsoft Xbox", ShortName = "xbox", HasCues = true, HasDat = true)]
MicrosoftXbox,
@@ -1975,12 +1981,9 @@ namespace RedumpLib.Data
[System(Category = SystemCategory.DiscBasedConsole, LongName = "Microsoft Xbox One", ShortName = "xboxone", IsBanned = true, HasDat = true)]
MicrosoftXboxOne,
[System(Category = SystemCategory.DiscBasedConsole, LongName = "Microsoft Xbox Series X", ShortName = "xboxsx", IsBanned = true)]
[System(Category = SystemCategory.DiscBasedConsole, LongName = "Microsoft Xbox Series X", ShortName = "xboxsx", IsBanned = true, HasDat = true)]
MicrosoftXboxSeriesXS,
[System(Category = SystemCategory.DiscBasedConsole, LongName = "Memorex Visual Information System", ShortName = "vis", HasCues = true, HasDat = true)]
MemorexVisualInformationSystem,
[System(Category = SystemCategory.DiscBasedConsole, LongName = "NEC PC Engine CD & TurboGrafx CD", ShortName = "pce", HasCues = true, HasDat = true)]
NECPCEngineCDTurboGrafxCD,
@@ -2035,7 +2038,7 @@ namespace RedumpLib.Data
[System(Category = SystemCategory.DiscBasedConsole, LongName = "Sony PlayStation 4", ShortName = "ps4", IsBanned = true, HasDat = true)]
SonyPlayStation4,
[System(Category = SystemCategory.DiscBasedConsole, LongName = "Sony PlayStation 5", ShortName = "ps5", IsBanned = true)]
[System(Category = SystemCategory.DiscBasedConsole, LongName = "Sony PlayStation 5", ShortName = "ps5", IsBanned = true, HasDat = true)]
SonyPlayStation5,
[System(Category = SystemCategory.DiscBasedConsole, LongName = "Sony PlayStation Portable", ShortName = "psp", HasDat = true)]
@@ -2213,7 +2216,7 @@ namespace RedumpLib.Data
[System(Category = SystemCategory.Computer, LongName = "Acorn Archimedes", ShortName = "arch", HasCues = true, HasDat = true)]
AcornArchimedes,
[System(Category = SystemCategory.Computer, LongName = "Apple Macintosh", ShortName = "mac", HasCues = true, HasDat = true)]
[System(Category = SystemCategory.Computer, LongName = "Apple Macintosh", ShortName = "mac", HasCues = true, HasDat = true, HasLsd = true, HasSbi = true)]
AppleMacintosh,
[System(Category = SystemCategory.Computer, LongName = "Commodore Amiga CD", ShortName = "acd", HasCues = true, HasDat = true)]
@@ -2283,6 +2286,9 @@ namespace RedumpLib.Data
[System(Category = SystemCategory.Arcade, Available = false, LongName = "Incredible Technologies PC-based Systems")]
IncredibleTechnologiesVarious,
[System(Category = SystemCategory.Arcade, Available = false, LongName = "JVL iTouch")]
JVLiTouch,
[System(Category = SystemCategory.Arcade, LongName = "Konami e-Amusement", ShortName = "kea", HasCues = true, HasDat = true)]
KonamieAmusement,
@@ -2298,7 +2304,7 @@ namespace RedumpLib.Data
[System(Category = SystemCategory.Arcade, Available = false, LongName = "Konami Python 2")]
KonamiPython2,
[System(Category = SystemCategory.Arcade, LongName = "Konami System 573", ShortName = "ks573")]
[System(Category = SystemCategory.Arcade, LongName = "Konami System 573", ShortName = "ks573", HasCues = true, HasDat = true)]
KonamiSystem573,
[System(Category = SystemCategory.Arcade, LongName = "Konami System GV", ShortName = "ksgv", HasCues = true, HasDat = true)]
@@ -2400,6 +2406,9 @@ namespace RedumpLib.Data
[System(Category = SystemCategory.Arcade, Available = false, LongName = "Tsunami TsuMo Multi-Game Motion System")]
TsunamiTsuMoMultiGameMotionSystem,
[System(Category = SystemCategory.Arcade, Available = false, LongName = "UltraCade PC-based Systems")]
UltraCade,
// End of arcade section delimiter
MarkerArcadeEnd,

View File

@@ -62,6 +62,11 @@ namespace RedumpLib.Data
types.Add(MediaType.FloppyDisk);
break;
// http://videogamekraken.com/ion-educational-gaming-system-by-hasbro
case RedumpSystem.HasbroiONEducationalGamingSystem:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/VideoNow
case RedumpSystem.HasbroVideoNow:
types.Add(MediaType.CDROM);
@@ -372,6 +377,12 @@ namespace RedumpLib.Data
types.Add(MediaType.DVD);
break;
// UNKNOWN
case RedumpSystem.JVLiTouch:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
break;
// https://en.wikipedia.org/wiki/E-Amusement
case RedumpSystem.KonamieAmusement:
types.Add(MediaType.CDROM);
@@ -514,6 +525,7 @@ namespace RedumpLib.Data
types.Add(MediaType.DVD);
break;
// UNKNOWN
case RedumpSystem.SegaALLS:
types.Add(MediaType.DVD);
break;
@@ -604,6 +616,12 @@ namespace RedumpLib.Data
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/UltraCade_Technologies
case RedumpSystem.UltraCade:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
break;
#endregion
#region Others
@@ -752,9 +770,9 @@ namespace RedumpLib.Data
switch (discType)
{
case DiscType.BD25:
//case DiscType.BD33:
case DiscType.BD33:
case DiscType.BD50:
//case DiscType.BD66:
case DiscType.BD66:
case DiscType.BD100:
case DiscType.BD128:
return MediaType.BluRay;
@@ -857,15 +875,15 @@ namespace RedumpLib.Data
case "bd25":
case "bd-25":
return DiscType.BD25;
//case "bd33":
//case "bd-33":
// return DiscType.BD33;
case "bd33":
case "bd-33":
return DiscType.BD33;
case "bd50":
case "bd-50":
return DiscType.BD50;
//case "bd66":
//case "bd-66":
// return DiscType.BD66;
case "bd66":
case "bd-66":
return DiscType.BD66;
case "bd100":
case "bd-100":
return DiscType.BD100;
@@ -1339,6 +1357,12 @@ namespace RedumpLib.Data
case "fujitsufmtownsmarty":
case "fujitsu fm towns marty":
return RedumpSystem.FujitsuFMTownsMarty;
case "ion":
case "ionegs":
case "hasbroion":
case "hasbroioneducationalgamingsystem":
case "hasbro ion educational gaming system":
return RedumpSystem.HasbroiONEducationalGamingSystem;
case "hvn":
case "videonow":
case "hasbrovideonow":
@@ -1748,6 +1772,9 @@ namespace RedumpLib.Data
case "itpc":
case "incredible technologies pc-based systems":
return RedumpSystem.IncredibleTechnologiesVarious;
case "jvlitouch":
case "jvl itouch":
return RedumpSystem.JVLiTouch;
case "kea":
case "eamusement":
case "e-amusement":
@@ -1972,6 +1999,11 @@ namespace RedumpLib.Data
case "tsunami tsumo":
case "tsunami tsumo multi-game motion system":
return RedumpSystem.TsunamiTsuMoMultiGameMotionSystem;
case "ultracade":
case "ultracadepc":
case "ultracade pc":
case "ultracade pc-based systems":
return RedumpSystem.UltraCade;
#endregion
@@ -2103,6 +2135,24 @@ namespace RedumpLib.Data
/// <returns></returns>
public static string LongName(this YesNo? yesno) => AttributeHelper<YesNo?>.GetAttribute(yesno)?.LongName ?? "Yes/No";
/// <summary>
/// Get the YesNo enum value for a given nullable boolean
/// </summary>
/// <param name="yesno">Nullable boolean value to convert</param>
/// <returns>YesNo represented by the nullable boolean, if possible</returns>
public static YesNo? ToYesNo(this bool? yesno)
{
switch (yesno)
{
case false:
return YesNo.No;
case true:
return YesNo.Yes;
default:
return YesNo.NULL;
}
}
/// <summary>
/// Get the YesNo enum value for a given string
/// </summary>

View File

@@ -12,7 +12,7 @@ namespace RedumpLib.Data
/// Version of the current schema
/// </summary>
[JsonProperty(PropertyName = "schema_version", DefaultValueHandling = DefaultValueHandling.Ignore)]
public int SchemaVersion { get; set; } = 2;
public int SchemaVersion { get; set; } = 3;
/// <summary>
/// Fully matched Redump ID
@@ -494,6 +494,9 @@ namespace RedumpLib.Data
[JsonProperty(PropertyName = "d_layerbreak_3", NullValueHandling = NullValueHandling.Ignore)]
public long Layerbreak3 { get; set; }
[JsonProperty(PropertyName = "d_pic_identifier", NullValueHandling = NullValueHandling.Ignore)]
public string PICIdentifier { get; set; }
[JsonProperty(PropertyName = "d_size", NullValueHandling = NullValueHandling.Ignore)]
public long Size { get; set; }
@@ -513,6 +516,7 @@ namespace RedumpLib.Data
Layerbreak = this.Layerbreak,
Layerbreak2 = this.Layerbreak2,
Layerbreak3 = this.Layerbreak3,
PICIdentifier = this.PICIdentifier,
Size = this.Size,
CRC32 = this.CRC32,
MD5 = this.MD5,

View File

@@ -2,12 +2,12 @@
<PropertyGroup>
<TargetFrameworks>net48;net6.0</TargetFrameworks>
<RuntimeIdentifiers>win7-x64;win-x86;win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
<RuntimeIdentifiers>win7-x64;win8-x64;win81-x64;win10-x64;linux-x64;osx-x64</RuntimeIdentifiers>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>
</Project>

View File

@@ -1,5 +1,5 @@
# version format
version: 2.4-{build}
version: 2.6.2-{build}
# pull request template
pull_requests:
@@ -29,12 +29,14 @@ build_script:
- msbuild MPF.Check\MPF.Check.csproj -target:Publish -property:TargetFramework=net48 -property:RuntimeIdentifiers=win7-x64
# .NET 6.0
- dotnet publish MPF\MPF.csproj --framework net6.0-windows --runtime win-x86 --self-contained true
- dotnet publish MPF\MPF.csproj --framework net6.0-windows --runtime win-x64 --self-contained true
#- dotnet publish MPF\MPF.csproj --framework net6.0-windows --runtime linux-x64 --self-contained true
#- dotnet publish MPF\MPF.csproj --framework net6.0-windows --runtime osx-x64 --self-contained true
- dotnet publish MPF.Check\MPF.Check.csproj --framework net6.0 --runtime win-x86 --self-contained true -p:PublishSingleFile=true
- dotnet publish MPF.Check\MPF.Check.csproj --framework net6.0 --runtime win-x64 --self-contained true -p:PublishSingleFile=true
- dotnet publish MPF\MPF.csproj --framework net6.0-windows --runtime win7-x64 --self-contained true -p:PublishSingleFile=true
- dotnet publish MPF\MPF.csproj --framework net6.0-windows --runtime win8-x64 --self-contained true -p:PublishSingleFile=true
- dotnet publish MPF\MPF.csproj --framework net6.0-windows --runtime win81-x64 --self-contained true -p:PublishSingleFile=true
- dotnet publish MPF\MPF.csproj --framework net6.0-windows --runtime win10-x64 --self-contained true -p:PublishSingleFile=true
- dotnet publish MPF.Check\MPF.Check.csproj --framework net6.0 --runtime win7-x64 --self-contained true -p:PublishSingleFile=true
- dotnet publish MPF.Check\MPF.Check.csproj --framework net6.0 --runtime win8-x64 --self-contained true -p:PublishSingleFile=true
- dotnet publish MPF.Check\MPF.Check.csproj --framework net6.0 --runtime win81-x64 --self-contained true -p:PublishSingleFile=true
- dotnet publish MPF.Check\MPF.Check.csproj --framework net6.0 --runtime win10-x64 --self-contained true -p:PublishSingleFile=true
- dotnet publish MPF.Check\MPF.Check.csproj --framework net6.0 --runtime linux-x64 --self-contained true -p:PublishSingleFile=true
- dotnet publish MPF.Check\MPF.Check.csproj --framework net6.0 --runtime osx-x64 --self-contained true -p:PublishSingleFile=true
@@ -44,63 +46,76 @@ 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\net48\publish\Programs\Aaru *
- 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\net6.0-windows\win-x86\publish\Programs\Aaru *
#- 7z x aaru-5.3.2_windows_x64.zip -oMPF\bin\Debug\net6.0-windows\linux-x64\publish\Programs\Aaru *
#- 7z x aaru-5.3.2_windows_x64.zip -oMPF\bin\Debug\net6.0-windows\osx-x64\publish\Programs\Aaru *
- 7z x aaru-5.3.2_windows_x64.zip -oMPF\bin\Debug\net6.0-windows\win7-x64\publish\Programs\Aaru *
- 7z x aaru-5.3.2_windows_x64.zip -oMPF\bin\Debug\net6.0-windows\win8-x64\publish\Programs\Aaru *
- 7z x aaru-5.3.2_windows_x64.zip -oMPF\bin\Debug\net6.0-windows\win81-x64\publish\Programs\Aaru *
- 7z x aaru-5.3.2_windows_x64.zip -oMPF\bin\Debug\net6.0-windows\win10-x64\publish\Programs\Aaru *
# dd for Windows
- ps: appveyor DownloadFile http://www.chrysocome.net/downloads/8ab730cd2a29e76ddd89be1f99357942/dd-0.6beta3.zip
- 7z e dd-0.6beta3.zip -oMPF\bin\Debug\net48\publish\Programs\DD *
- 7z e dd-0.6beta3.zip -oMPF\bin\Debug\net6.0-windows\win-x64\publish\Programs\DD *
- 7z e dd-0.6beta3.zip -oMPF\bin\Debug\net6.0-windows\win-x86\publish\Programs\DD *
#- 7z e dd-0.6beta3.zip -oMPF\bin\Debug\net6.0-windows\linux-x64\publish\Programs\DD *
#- 7z e dd-0.6beta3.zip -oMPF\bin\Debug\net6.0-windows\osx-x64\publish\Programs\DD *
- 7z e dd-0.6beta3.zip -oMPF\bin\Debug\net6.0-windows\win7-x64\publish\Programs\DD *
- 7z e dd-0.6beta3.zip -oMPF\bin\Debug\net6.0-windows\win8-x64\publish\Programs\DD *
- 7z e dd-0.6beta3.zip -oMPF\bin\Debug\net6.0-windows\win81-x64\publish\Programs\DD *
- 7z e dd-0.6beta3.zip -oMPF\bin\Debug\net6.0-windows\win10-x64\publish\Programs\DD *
# DiscImageCreator
- ps: appveyor DownloadFile https://github.com/saramibreak/DiscImageCreator/files/10931241/DiscImageCreator_20230309.zip
- 7z e DiscImageCreator_20230309.zip -oMPF\bin\Debug\net48\publish\Programs\Creator Release_ANSI\*
- 7z e DiscImageCreator_20230309.zip -oMPF\bin\Debug\net6.0-windows\win-x64\publish\Programs\Creator Release_ANSI\*
- 7z e DiscImageCreator_20230309.zip -oMPF\bin\DebugFix \net6.0-windows\win-x86\publish\Programs\Creator Release_ANSI\*
#- 7z e DiscImageCreator_20230309.zip -oMPF\bin\Debug\net6.0-windows\linux-x64\publish\Programs\Creator Release_ANSI\*
#- 7z e DiscImageCreator_20230309.zip -oMPF\bin\Debug\net6.0-windows\osx-x64\publish\Programs\Creator Release_ANSI\*
- ps: appveyor DownloadFile https://github.com/saramibreak/DiscImageCreator/files/11660558/DiscImageCreator_20230606.zip
- 7z e DiscImageCreator_20230606.zip -oMPF\bin\Debug\net48\publish\Programs\Creator Release_ANSI\*
- 7z e DiscImageCreator_20230606.zip -oMPF\bin\Debug\net6.0-windows\win7-x64\publish\Programs\Creator Release_ANSI\*
- 7z e DiscImageCreator_20230606.zip -oMPF\bin\Debug\net6.0-windows\win8-x64\publish\Programs\Creator Release_ANSI\*
- 7z e DiscImageCreator_20230606.zip -oMPF\bin\Debug\net6.0-windows\win81-x64\publish\Programs\Creator Release_ANSI\*
- 7z e DiscImageCreator_20230606.zip -oMPF\bin\Debug\net6.0-windows\win10-x64\publish\Programs\Creator Release_ANSI\*
# Redumper
- ps: appveyor DownloadFile https://github.com/superg/redumper/releases/download/build_106/redumper-2023.02.19_build106-win64.zip
- 7z e redumper-2023.02.19_build106-win64.zip -oMPF\bin\Debug\net48\publish\Programs\Redumper redumper-2023.02.19_build106-win64\bin\*
- 7z e redumper-2023.02.19_build106-win64.zip -oMPF\bin\Debug\net6.0-windows\win-x64\publish\Programs\Redumper redumper-2023.02.19_build106-win64\bin\*
- 7z e redumper-2023.02.19_build106-win64.zip -oMPF\bin\Debug\net6.0-windows\win-x86\publish\Programs\Redumper redumper-2023.02.19_build106-win64\bin\*
#- 7z e redumper-2023.02.19_build106-win64.zip -oMPF\bin\Debug\net6.0-windows\linux-x64\publish\Programs\Redumper redumper-2023.02.19_build106-win64\bin\*
#- 7z e redumper-2023.02.19_build106-win64.zip -oMPF\bin\Debug\net6.0-windows\osx-x64\publish\Programs\Redumper redumper-2023.02.19_build106-win64\bin\*
- ps: appveyor DownloadFile https://github.com/superg/redumper/releases/download/build_183/redumper-2023.07.09_build183-win64.zip
- 7z e redumper-2023.07.09_build183-win64.zip -oMPF\bin\Debug\net48\publish\Programs\Redumper redumper-2023.07.09_build183-win64\bin\*
- 7z e redumper-2023.07.09_build183-win64.zip -oMPF\bin\Debug\net6.0-windows\win7-x64\publish\Programs\Redumper redumper-2023.07.09_build183-win64\bin\*
- 7z e redumper-2023.07.09_build183-win64.zip -oMPF\bin\Debug\net6.0-windows\win8-x64\publish\Programs\Redumper redumper-2023.07.09_build183-win64\bin\*
- 7z e redumper-2023.07.09_build183-win64.zip -oMPF\bin\Debug\net6.0-windows\win81-x64\publish\Programs\Redumper redumper-2023.07.09_build183-win64\bin\*
- 7z e redumper-2023.07.09_build183-win64.zip -oMPF\bin\Debug\net6.0-windows\win10-x64\publish\Programs\Redumper redumper-2023.07.09_build183-win64\bin\*
# Subdump
- ps: appveyor DownloadFile https://archive.org/download/subdump_fua_0x28/subdump_fua_0x28.zip
- 7z e subdump_fua_0x28.zip -oMPF\bin\Debug\net48\publish *
- mkdir MPF\bin\Debug\net48\publish\Programs\Subdump
- mv MPF\bin\Debug\net48\publish\subdump_fua_0x28.exe MPF\bin\Debug\net48\publish\Programs\Subdump\subdump.exe
#- 7z e subdump_fua_0x28.zip -oMPF\bin\Debug\net6.0 *
#- mkdir MPF\bin\Debug\net6.0-windows\Programs\Subdump
#- mv MPF\bin\Debug\net6.0-windows\subdump_fua_0x28.exe MPF\bin\Debug\net6.0-windows\Programs\Subdump\subdump.exe
- 7z e subdump_fua_0x28.zip -oMPF\bin\Debug\net6.0-windows *
- mkdir MPF\bin\Debug\net6.0-windows\win7-x64\publish\Programs\Subdump
- mv MPF\bin\Debug\net6.0-windows\subdump_fua_0x28.exe MPF\bin\Debug\net6.0-windows\win7-x64\publish\Programs\Subdump\subdump.exe
- 7z e subdump_fua_0x28.zip -oMPF\bin\Debug\net6.0-windows *
- mkdir MPF\bin\Debug\net6.0-windows\win8-x64\publish\Programs\Subdump
- mv MPF\bin\Debug\net6.0-windows\subdump_fua_0x28.exe MPF\bin\Debug\net6.0-windows\win8-x64\publish\Programs\Subdump\subdump.exe
- 7z e subdump_fua_0x28.zip -oMPF\bin\Debug\net6.0-windows *
- mkdir MPF\bin\Debug\net6.0-windows\win81-x64\publish\Programs\Subdump
- mv MPF\bin\Debug\net6.0-windows\subdump_fua_0x28.exe MPF\bin\Debug\net6.0-windows\win81-x64\publish\Programs\Subdump\subdump.exe
- 7z e subdump_fua_0x28.zip -oMPF\bin\Debug\net6.0-windows *
- mkdir MPF\bin\Debug\net6.0-windows\win10-x64\publish\Programs\Subdump
- mv MPF\bin\Debug\net6.0-windows\subdump_fua_0x28.exe MPF\bin\Debug\net6.0-windows\win10-x64\publish\Programs\Subdump\subdump.exe
# MPF
- cd %APPVEYOR_BUILD_FOLDER%\MPF\bin\Debug\net48\publish\
- 7z a -tzip %APPVEYOR_BUILD_FOLDER%\MPF_net48.zip *
- cd %APPVEYOR_BUILD_FOLDER%\MPF\bin\Debug\net6.0-windows\win-x86\publish\
- 7z a -tzip %APPVEYOR_BUILD_FOLDER%\MPF_net6.0_win-x86.zip *
- cd %APPVEYOR_BUILD_FOLDER%\MPF\bin\Debug\net6.0-windows\win-x64\publish\
- 7z a -tzip %APPVEYOR_BUILD_FOLDER%\MPF_net6.0_win-x64.zip *
#- cd %APPVEYOR_BUILD_FOLDER%\MPF\bin\Debug\net6.0-windows\linux-x64\publish\
#- 7z a -tzip %APPVEYOR_BUILD_FOLDER%\MPF_net6.0_linux-x64.zip *
#- cd %APPVEYOR_BUILD_FOLDER%\MPF\bin\Debug\net6.0-windows\osx-x64\publish\
#- 7z a -tzip %APPVEYOR_BUILD_FOLDER%\MPF_net6.0_osx-x64.zip *
- cd %APPVEYOR_BUILD_FOLDER%\MPF\bin\Debug\net6.0-windows\win7-x64\publish\
- 7z a -tzip %APPVEYOR_BUILD_FOLDER%\MPF_net6.0_win7-x64.zip *
- cd %APPVEYOR_BUILD_FOLDER%\MPF\bin\Debug\net6.0-windows\win8-x64\publish\
- 7z a -tzip %APPVEYOR_BUILD_FOLDER%\MPF_net6.0_win8-x64.zip *
- cd %APPVEYOR_BUILD_FOLDER%\MPF\bin\Debug\net6.0-windows\win81-x64\publish\
- 7z a -tzip %APPVEYOR_BUILD_FOLDER%\MPF_net6.0_win81-x64.zip *
- cd %APPVEYOR_BUILD_FOLDER%\MPF\bin\Debug\net6.0-windows\win10-x64\publish\
- 7z a -tzip %APPVEYOR_BUILD_FOLDER%\MPF_net6.0_win10-x64.zip *
# MPF.Check
- cd %APPVEYOR_BUILD_FOLDER%\MPF.Check\bin\Debug\net48\publish\
- 7z a -tzip %APPVEYOR_BUILD_FOLDER%\MPF.Check_net48.zip *
- cd %APPVEYOR_BUILD_FOLDER%\MPF.Check\bin\Debug\net6.0\win-x86\publish\
- 7z a -tzip %APPVEYOR_BUILD_FOLDER%\MPF.Check_net6.0_win-x86.zip *
- cd %APPVEYOR_BUILD_FOLDER%\MPF.Check\bin\Debug\net6.0\win-x64\publish\
- 7z a -tzip %APPVEYOR_BUILD_FOLDER%\MPF.Check_net6.0_win-x64.zip *
- cd %APPVEYOR_BUILD_FOLDER%\MPF.Check\bin\Debug\net6.0\win7-x64\publish\
- 7z a -tzip %APPVEYOR_BUILD_FOLDER%\MPF.Check_net6.0_win7-x64.zip *
- cd %APPVEYOR_BUILD_FOLDER%\MPF.Check\bin\Debug\net6.0\win8-x64\publish\
- 7z a -tzip %APPVEYOR_BUILD_FOLDER%\MPF.Check_net6.0_win8-x64.zip *
- cd %APPVEYOR_BUILD_FOLDER%\MPF.Check\bin\Debug\net6.0\win81-x64\publish\
- 7z a -tzip %APPVEYOR_BUILD_FOLDER%\MPF.Check_net6.0_win81-x64.zip *
- cd %APPVEYOR_BUILD_FOLDER%\MPF.Check\bin\Debug\net6.0\win10-x64\publish\
- 7z a -tzip %APPVEYOR_BUILD_FOLDER%\MPF.Check_net6.0_win10-x64.zip *
- cd %APPVEYOR_BUILD_FOLDER%\MPF.Check\bin\Debug\net6.0\linux-x64\publish\
- 7z a -tzip %APPVEYOR_BUILD_FOLDER%\MPF.Check_net6.0_linux-x64.zip *
- cd %APPVEYOR_BUILD_FOLDER%\MPF.Check\bin\Debug\net6.0\osx-x64\publish\
@@ -118,22 +133,26 @@ on_failure:
artifacts:
- path: MPF_net48.zip
name: MPF (.NET Framework 4.8)
- path: MPF_net6.0_win-x86.zip
name: MPF (.NET 6.0, Windows x86)
- path: MPF_net6.0_win-x64.zip
name: MPF (.NET 6.0, Windows x64)
#- path: MPF_net6.0_linux-x64.zip
# name: MPF (.NET 6.0, Linux x64)
#- path: MPF_net6.0_osx-x64.zip
# name: MPF (.NET 6.0, OSX x64)
- path: MPF_net6.0_win7-x64.zip
name: MPF (.NET 6.0, Windows 7 x64)
- path: MPF_net6.0_win8-x64.zip
name: MPF (.NET 6.0, Windows 8 x64)
- path: MPF_net6.0_win81-x64.zip
name: MPF (.NET 6.0, Windows 8.1 x64)
- path: MPF_net6.0_win10-x64.zip
name: MPF (.NET 6.0, Windows 10 x64)
- path: MPF.Check_net48.zip
name: MPF Check (.NET Framework 4.8)
- path: MPF.Check_net6.0_win-x86.zip
name: MPF.Check (.NET 6.0, Windows x86)
- path: MPF.Check_net6.0_win-x64.zip
name: MPF.Check (.NET 6.0, Windows x64)
- path: MPF.Check_net6.0_win7-x64.zip
name: MPF.Check (.NET 6.0, Windows 7 x64)
- path: MPF.Check_net6.0_win8-x64.zip
name: MPF.Check (.NET 6.0, Windows 8 x64)
- path: MPF.Check_net6.0_win81-x64.zip
name: MPF.Check (.NET 6.0, Windows 8.1 x64)
- path: MPF.Check_net6.0_win10-x64.zip
name: MPF.Check (.NET 6.0, Windows 10 x64)
- path: MPF.Check_net6.0_linux-x64.zip
name: MPF.Check (.NET 6.0, Linux x64)
- path: MPF.Check_net6.0_osx-x64.zip
name: MPF.Check (.NET 6.0, OSX x64)
name: MPF.Check (.NET 6.0, OSX x64)

57
publish-nix.sh Executable file
View File

@@ -0,0 +1,57 @@
#! /bin/bash
# This batch file assumes the following:
# - .NET 6.0 (or newer) SDK is installed and in PATH
# - zip is installed and in PATH
# - The relevant commandline programs are already downloaded
# and put into their respective folders
#
# If any of these are not satisfied, the operation may fail
# in an unpredictable way and result in an incomplete output.
# TODO: Re-enable MPF building after figuring out how to build Windows desktop applications on Linux
# This may require an additional package to be installed?
# Set the current directory as a variable
BUILD_FOLDER=$PWD
# Restore Nuget packages for all builds
echo "Restoring Nuget packages"
dotnet restore
# .NET 6.0
echo "Building .NET 6.0 releases"
#dotnet publish MPF/MPF.csproj --framework net6.0-windows --runtime win7-x64 --self-contained true -p:PublishSingleFile=true
#dotnet publish MPF/MPF.csproj --framework net6.0-windows --runtime win8-x64 --self-contained true -p:PublishSingleFile=true
#dotnet publish MPF/MPF.csproj --framework net6.0-windows --runtime win81-x64 --self-contained true -p:PublishSingleFile=true
#dotnet publish MPF/MPF.csproj --framework net6.0-windows --runtime win10-x64 --self-contained true -p:PublishSingleFile=true
dotnet publish MPF.Check/MPF.Check.csproj --framework net6.0 --runtime win7-x64 --self-contained true -p:PublishSingleFile=true
dotnet publish MPF.Check/MPF.Check.csproj --framework net6.0 --runtime win8-x64 --self-contained true -p:PublishSingleFile=true
dotnet publish MPF.Check/MPF.Check.csproj --framework net6.0 --runtime win81-x64 --self-contained true -p:PublishSingleFile=true
dotnet publish MPF.Check/MPF.Check.csproj --framework net6.0 --runtime win10-x64 --self-contained true -p:PublishSingleFile=true
dotnet publish MPF.Check/MPF.Check.csproj --framework net6.0 --runtime linux-x64 --self-contained true -p:PublishSingleFile=true
dotnet publish MPF.Check/MPF.Check.csproj --framework net6.0 --runtime osx-x64 --self-contained true -p:PublishSingleFile=true
# Create MPF archives
#cd $BUILD_FOLDER/MPF/bin/Debug/net6.0-windows/win7-x64/publish/
#zip -r $BUILD_FOLDER/MPF_net6.0_win7-x64.zip .
#cd $BUILD_FOLDER/MPF/bin/Debug/net6.0-windows/win8-x64/publish/
#zip -r $BUILD_FOLDER/MPF_net6.0_win8-x64.zip .
#cd $BUILD_FOLDER/MPF/bin/Debug/net6.0-windows/win81-x64/publish/
#zip -r $BUILD_FOLDER/MPF_net6.0_win81-x64.zip .
#cd $BUILD_FOLDER/MPF/bin/Debug/net6.0-windows/win10-x64/publish/
#zip -r $BUILD_FOLDER/MPF_net6.0_win10-x64.zip .
# Create MPF.Check archives
cd $BUILD_FOLDER/MPF.Check/bin/Debug/net6.0/win7-x64/publish/
zip -r $BUILD_FOLDER/MPF.Check_net6.0_win7-x64.zip .
cd $BUILD_FOLDER/MPF.Check/bin/Debug/net6.0/win8-x64/publish/
zip -r $BUILD_FOLDER/MPF.Check_net6.0_win8-x64.zip .
cd $BUILD_FOLDER/MPF.Check/bin/Debug/net6.0/win81-x64/publish/
zip -r $BUILD_FOLDER/MPF.Check_net6.0_win81-x64.zip .
cd $BUILD_FOLDER/MPF.Check/bin/Debug/net6.0/win10-x64/publish/
zip -r $BUILD_FOLDER/MPF.Check_net6.0_win10-x64.zip .
cd $BUILD_FOLDER/MPF.Check/bin/Debug/net6.0/linux-x64/publish/
zip -r $BUILD_FOLDER/MPF.Check_net6.0_linux-x64.zip .
cd $BUILD_FOLDER/MPF.Check/bin/Debug/net6.0/osx-x64/publish/
zip -r $BUILD_FOLDER/MPF.Check_net6.0_osx-x64.zip .

64
publish-win.bat Normal file
View File

@@ -0,0 +1,64 @@
@echo OFF
REM This batch file assumes the following:
REM - .NET Framework 4.8 SDK is installed and in PATH
REM - .NET 6.0 (or newer) SDK is installed and in PATH
REM - 7-zip commandline (7z.exe) is installed and in PATH
REM - The relevant commandline programs are already downloaded
REM and put into their respective folders
REM
REM If any of these are not satisfied, the operation may fail
REM in an unpredictable way and result in an incomplete output.
REM Set the current directory as a variable
set BUILD_FOLDER=%~dp0
REM Restore Nuget packages for all builds
echo Restoring Nuget packages
dotnet restore
REM .NET Framework 4.8
echo Building .NET Framework 4.8 releases
msbuild MPF\MPF.csproj -target:Publish -property:TargetFramework=net48 -property:RuntimeIdentifiers=win7-x64
msbuild MPF.Check\MPF.Check.csproj -target:Publish -property:TargetFramework=net48 -property:RuntimeIdentifiers=win7-x64
REM .NET 6.0
echo Building .NET 6.0 releases
dotnet publish MPF\MPF.csproj --framework net6.0-windows --runtime win7-x64 --self-contained true -p:PublishSingleFile=true
dotnet publish MPF\MPF.csproj --framework net6.0-windows --runtime win8-x64 --self-contained true -p:PublishSingleFile=true
dotnet publish MPF\MPF.csproj --framework net6.0-windows --runtime win81-x64 --self-contained true -p:PublishSingleFile=true
dotnet publish MPF\MPF.csproj --framework net6.0-windows --runtime win10-x64 --self-contained true -p:PublishSingleFile=true
dotnet publish MPF.Check\MPF.Check.csproj --framework net6.0 --runtime win7-x64 --self-contained true -p:PublishSingleFile=true
dotnet publish MPF.Check\MPF.Check.csproj --framework net6.0 --runtime win8-x64 --self-contained true -p:PublishSingleFile=true
dotnet publish MPF.Check\MPF.Check.csproj --framework net6.0 --runtime win81-x64 --self-contained true -p:PublishSingleFile=true
dotnet publish MPF.Check\MPF.Check.csproj --framework net6.0 --runtime win10-x64 --self-contained true -p:PublishSingleFile=true
dotnet publish MPF.Check\MPF.Check.csproj --framework net6.0 --runtime linux-x64 --self-contained true -p:PublishSingleFile=true
dotnet publish MPF.Check\MPF.Check.csproj --framework net6.0 --runtime osx-x64 --self-contained true -p:PublishSingleFile=true
REM Create MPF archives
cd %BUILD_FOLDER%\MPF\bin\Debug\net48\publish\
7z a -tzip %BUILD_FOLDER%\MPF_net48.zip *
cd %BUILD_FOLDER%\MPF\bin\Debug\net6.0-windows\win7-x64\publish\
7z a -tzip %BUILD_FOLDER%\MPF_net6.0_win7-x64.zip *
cd %BUILD_FOLDER%\MPF\bin\Debug\net6.0-windows\win8-x64\publish\
7z a -tzip %BUILD_FOLDER%\MPF_net6.0_win8-x64.zip *
cd %BUILD_FOLDER%\MPF\bin\Debug\net6.0-windows\win81-x64\publish\
7z a -tzip %BUILD_FOLDER%\MPF_net6.0_win81-x64.zip *
cd %BUILD_FOLDER%\MPF\bin\Debug\net6.0-windows\win10-x64\publish\
7z a -tzip %BUILD_FOLDER%\MPF_net6.0_win10-x64.zip *
REM Create MPF.Check archives
cd %BUILD_FOLDER%\MPF.Check\bin\Debug\net48\publish\
7z a -tzip %BUILD_FOLDER%\MPF.Check_net48.zip *
cd %BUILD_FOLDER%\MPF.Check\bin\Debug\net6.0\win7-x64\publish\
7z a -tzip %BUILD_FOLDER%\MPF.Check_net6.0_win7-x64.zip *
cd %BUILD_FOLDER%\MPF.Check\bin\Debug\net6.0\win8-x64\publish\
7z a -tzip %BUILD_FOLDER%\MPF.Check_net6.0_win8-x64.zip *
cd %BUILD_FOLDER%\MPF.Check\bin\Debug\net6.0\win81-x64\publish\
7z a -tzip %BUILD_FOLDER%\MPF.Check_net6.0_win81-x64.zip *
cd %BUILD_FOLDER%\MPF.Check\bin\Debug\net6.0\win10-x64\publish\
7z a -tzip %BUILD_FOLDER%\MPF.Check_net6.0_win10-x64.zip *
cd %BUILD_FOLDER%\MPF.Check\bin\Debug\net6.0\linux-x64\publish\
7z a -tzip %BUILD_FOLDER%\MPF.Check_net6.0_linux-x64.zip *
cd %BUILD_FOLDER%\MPF.Check\bin\Debug\net6.0\osx-x64\publish\
7z a -tzip %BUILD_FOLDER%\MPF.Check_net6.0_osx-x64.zip *