Compare commits

...

121 Commits
3.3.0 ... 3.3.3

Author SHA1 Message Date
Matt Nadareski
d3993a48e4 Bump version 2025-07-18 08:20:54 -04:00
Deterous
d522bb6c76 Update redumper to build 631 (#875)
* Update redumper to build 631

* add flag to tests
2025-07-16 08:04:27 -04:00
Matt Nadareski
816672a817 Slightly better IRD organization 2025-07-15 13:06:05 -04:00
Matt Nadareski
f8171da306 Better handle mixed-separator paths 2025-07-15 08:00:55 -04:00
Matt Nadareski
ce073e5fbf Simplify code from previous commit 2025-07-14 13:13:25 -04:00
Matt Nadareski
28205e42f0 Strip errant whitespace during path normalization (fixes #874) 2025-07-14 12:58:44 -04:00
Matt Nadareski
0160366530 Add new help and version flags for CLI and Check (fixes #873) 2025-07-12 16:04:54 -04:00
Matt Nadareski
663477d408 Update RedumpLib to 1.6.8 (fixes #872) 2025-07-11 12:49:12 -04:00
Matt Nadareski
bd2e012eef Net Yaroze only for PS1 2025-07-11 12:09:06 -04:00
Matt Nadareski
a514374169 Remove legacy codes from info window (fixes #871) 2025-07-11 12:05:03 -04:00
Matt Nadareski
f73c0730e2 Update changelog 2025-07-09 07:23:38 -04:00
fuzzball
a658c80de7 Empty should be null (#868) 2025-07-09 07:23:09 -04:00
Matt Nadareski
b806bc6cd1 Fix unnecessary null assignment 2025-06-26 10:35:47 -04:00
Matt Nadareski
cf9675f620 Only use serial for PS3/4/5 if no custom volume label 2025-06-26 10:34:49 -04:00
Matt Nadareski
ea18051709 Swap PS1/2 back to original name handling 2025-06-26 08:38:46 -04:00
Matt Nadareski
4fdf8e5dde Use reasonable default names for PlayStation systems (fixes #866) 2025-06-26 08:30:14 -04:00
Deterous
a4616d139d Better handling of Xbox/360, redumper build 613 (#865)
* Better handling of bad SS, redumper build 613

* Add missing helper function

* Fix new func signature

* Fix var name

* Nulls

* Don't get vollabel for xbox/360

* formatting

* formatting v2
2025-06-23 21:03:42 -04:00
Matt Nadareski
0f09a9c913 Address nullable default value 2025-06-18 09:40:00 -04:00
Matt Nadareski
48ffd6f40c Set some default values for CLI (fixes #863) 2025-06-18 09:34:35 -04:00
Matt Nadareski
6612c8ea4d Remove dead code in DIC processor 2025-06-18 09:13:44 -04:00
Matt Nadareski
68d1a0664a IsAudio cleanup cleanup 2025-06-18 09:08:37 -04:00
Matt Nadareski
86d8590789 IsAudio cleanup 2025-06-18 08:52:51 -04:00
Matt Nadareski
e23427d7c9 Update redumper to build 611 2025-06-17 21:00:52 -04:00
Matt Nadareski
cd19a2e4a0 Use the correct base path for Check 2025-06-17 17:55:10 -04:00
Matt Nadareski
000e7d88a8 Fix start index in Check 2025-06-17 17:18:12 -04:00
Matt Nadareski
e3beb1ef77 Rename disc info to media info 2025-06-17 16:35:03 -04:00
Matt Nadareski
a3a75b1c2d Fix missed test updates 2025-06-17 15:52:48 -04:00
Matt Nadareski
11850a8d6b Enable Check to determine media type automatically 2025-06-17 15:36:23 -04:00
Matt Nadareski
bf6b58d64b Fill out DetermineMediaType for DiscImageCreator 2025-06-17 14:26:13 -04:00
Matt Nadareski
1789334625 Fill out DetermineMediaType for Aaru 2025-06-17 13:05:35 -04:00
Matt Nadareski
9520f58240 Fill out DetermineMediaType for Redumper 2025-06-17 11:37:37 -04:00
Matt Nadareski
48e5e01729 Add DetermineMediaType scaffolding and tests 2025-06-17 09:45:16 -04:00
Matt Nadareski
8c7959fb08 Reduce media-specific checks where unnecessary 2025-06-17 08:51:57 -04:00
Matt Nadareski
8ef7543cf1 Ignore volume labels with path separators 2025-06-16 09:26:56 -04:00
Matt Nadareski
f9e39ee4be Further clarify configuration requirements for CLI (fixes #861) 2025-06-16 07:43:51 -04:00
Matt Nadareski
0a4621c963 Handle layers for PS3CFW (fixes #859) 2025-06-13 20:35:32 -04:00
Matt Nadareski
04b4f528ba Fix changelog location 2025-06-12 08:34:49 -04:00
Matt Nadareski
f024e49c21 Bump version 2025-06-12 08:33:55 -04:00
Deterous
7ca404f9dd Update redumper to build 610 (#858) 2025-06-12 07:50:51 -04:00
Matt Nadareski
18fc162cd8 Fix size retrieval for Aaru 2025-06-09 09:28:04 -04:00
Matt Nadareski
b577bbae37 Create multi-size icon (fixes #857) 2025-06-06 08:38:44 -04:00
Matt Nadareski
02f9509b86 Simplify Options naming where possible 2025-06-02 10:19:48 -04:00
Matt Nadareski
8b00e3deed Decouple retieval from login 2025-06-02 09:35:26 -04:00
Matt Nadareski
3ffea60402 Remove unnecessary options property 2025-06-02 09:08:15 -04:00
Matt Nadareski
f8eab60ecc Fix tests from last commit 2025-06-01 20:54:16 -04:00
Matt Nadareski
9e8d46fb03 Fix Redump default options (fixes #855) 2025-06-01 20:49:30 -04:00
Matt Nadareski
3831922f29 Add currently-hidden RetrieveMatchInformation option 2025-06-01 20:36:18 -04:00
Matt Nadareski
7f7416c053 Update tooltips/labels for controversial options 2025-05-30 12:48:23 -04:00
Matt Nadareski
529ada1b8b Fix issues with last commit 2025-05-30 12:43:25 -04:00
Deterous
6260f1a1fe Update redumper, MPF options, SS sanity check (#854)
* Update redumper, add DriveType option

* Fix typo

* Don't save ss file if invalid SS

* Update changelist

* LongName for DriveType

* Fix typo

* Fix tests

* Redo tests

* Fix test typo

* Remove additional space from test

* Simplify redumper program options

* semicolon
2025-05-30 12:40:22 -04:00
Matt Nadareski
a7f6e09226 Update RedumpLib to 1.6.7 (fixes #853) 2025-05-23 12:54:27 -04:00
Matt Nadareski
4b49815a7a Include Aaru in automatic builds 2025-05-23 12:16:51 -04:00
Matt Nadareski
14c17bbdf7 Bump version 2025-05-23 12:02:56 -04:00
Matt Nadareski
0fe30d2d4f Remove unnecessary conditional 2025-05-22 12:11:01 -04:00
Matt Nadareski
1c3f65e7f9 Handle error count resets in Redumper (fixes #852) 2025-05-22 12:07:50 -04:00
Matt Nadareski
62ff0f955a Reset Redump errors when an INFO block is found 2025-05-22 11:24:20 -04:00
Deterous
a942e6142a Minor Check UI improvements (#851)
* Minor Check UI improvements

* Move Check warning below status box

* Hover text on status message

* Full status in tooltip

* Add ellipsis to status text

* null ref assignment

* OneWay

* trigger StatusFirstLine property changed

* Better status property block

* wrong op
2025-05-22 10:46:53 -04:00
Matt Nadareski
f637e629a3 Add and use status label for Check window 2025-05-22 08:55:18 -04:00
Deterous
72b00953d8 Don't hash bad SS (#850)
* Don't hash bad SS

* fix build

* proper namespace
2025-05-22 08:31:24 -04:00
Matt Nadareski
cfac607c7d Use null for 0 speed internally 2025-05-22 08:21:06 -04:00
Matt Nadareski
e9a84e5429 Further fix speed dropdown with Redumper (fixes #849) 2025-05-22 07:56:57 -04:00
Matt Nadareski
2f985d0526 Update redumper to build 585 2025-05-21 11:39:26 -04:00
Matt Nadareski
e1ace14753 Fix speed dropdown with Redumper (fixes #849) 2025-05-21 09:17:19 -04:00
Matt Nadareski
9c29967f65 Fix bracket formatting from last commit 2025-05-19 11:56:15 -04:00
Deterous
5612d7989d Relax PS3CFW output filename requirements (#848)
* Relax PS3CFW output filename requirements

* don't use Linq

* better regex

* literal backslash

* requested changes

* fix

* Update MPF.Processors/PS3CFW.cs

Co-authored-by: Matt Nadareski <mnadareski@outlook.com>

---------

Co-authored-by: Matt Nadareski <mnadareski@outlook.com>
2025-05-19 11:54:37 -04:00
Matt Nadareski
f872a6be29 Minor cleanup from last commit 2025-05-19 08:48:09 -04:00
Deterous
59e7ecfa8a Better audio-only check (#847)
* Better IsAudio()

* null deref

* Don't set fields if empty

* Update Changelist

* Requested changes

* fix build

* fix build again

* string literal

* C# is dumb

* Revert to original

* revert further

* remove extra comma
2025-05-19 08:23:25 -04:00
Deterous
79cce37cf6 Add newlines to pkg info printing (#846)
* Add newlines to pkg info printing

* newline for ps4 too
2025-05-16 11:00:04 -04:00
Matt Nadareski
4016b3fc19 Serialize JSON a slightly different way 2025-05-12 21:44:47 -04:00
Matt Nadareski
e5bcada606 Simplify WriteOutputData path handling 2025-05-12 21:37:48 -04:00
Matt Nadareski
60d31363e3 Explicitly unset Redumper speed, if needed 2025-05-08 07:46:49 -04:00
Matt Nadareski
22a125a838 One more note about hidden settings 2025-05-05 21:29:17 -04:00
Matt Nadareski
0a86781d61 Clarification on some options 2025-05-05 21:14:35 -04:00
Matt Nadareski
c5649ecdbb Add Check warnings around overwriting and parsing 2025-05-05 13:05:35 -04:00
Matt Nadareski
df22336ba0 Support checking Redumper DAT from zip; add tests 2025-05-05 12:45:02 -04:00
Matt Nadareski
2d7350cbaf Close the log archive, if it exists 2025-05-05 11:49:33 -04:00
Deterous
6a56a58b7c Update redumper to build 565 (#842) 2025-05-04 19:54:09 -04:00
Matt Nadareski
a97c94885c Fix lines wiped before displayed 2025-05-04 11:23:24 -04:00
Matt Nadareski
9548993982 Tweak to previous commit for some build versions 2025-05-04 11:18:28 -04:00
Matt Nadareski
1476972c26 Pre-clean file path in CLI interactive mode 2025-05-04 11:14:46 -04:00
Matt Nadareski
85cde67d0a Update RedumpLib to 1.6.6 (fixes #841) 2025-05-01 11:00:04 -04:00
Matt Nadareski
bfaf24c237 Update to DIC 20250501 2025-05-01 10:27:31 -04:00
Matt Nadareski
adfa8a9a0c Normalize Shift-JIS characters, when possible (fixes #827) 2025-05-01 09:58:48 -04:00
Matt Nadareski
3d68d880f6 Update Nuget packages 2025-05-01 09:40:42 -04:00
Matt Nadareski
77bc7e7b1a Fix package reference layout 2025-05-01 09:35:41 -04:00
Matt Nadareski
23837ee555 Update RedumpLib to 1.6.5 (fixes #809, fixes #834) 2025-04-30 21:03:01 -04:00
Matt Nadareski
0553d1256a Allow exiting from interactive modes 2025-04-30 20:32:49 -04:00
Matt Nadareski
68f0c6cf35 Avoid redundant redundancy 2025-04-30 20:27:42 -04:00
Matt Nadareski
32d3996432 Make interactive mode cleaner 2025-04-30 20:14:04 -04:00
Matt Nadareski
5af02fe508 It's not dumping, it's checking 2025-04-30 16:52:40 -04:00
Matt Nadareski
eba6a7ce4a Fix menu title in Check interactive 2025-04-30 16:50:04 -04:00
Matt Nadareski
7faedc92e4 Add interactive mode to Check 2025-04-30 16:49:28 -04:00
Matt Nadareski
3de48fc24e Clean up case-sensitivity 2025-04-30 16:29:34 -04:00
Matt Nadareski
9400523c4f Add padding above root interactive node label 2025-04-30 16:22:04 -04:00
Matt Nadareski
48c945f194 Add interactive mode to CLI (fixes #819) 2025-04-30 16:19:19 -04:00
Matt Nadareski
d9a8050beb Fix removing empty subdirectories 2025-04-30 15:15:27 -04:00
Matt Nadareski
6ec179f0ed Comment download scripts more 2025-04-30 15:01:30 -04:00
Matt Nadareski
620851af73 Fix minor packing issues 2025-04-30 14:43:16 -04:00
Matt Nadareski
f5c4b7ebdf Enable packing programs for CLI 2025-04-30 14:19:44 -04:00
Matt Nadareski
364ae1b837 Replace old download implementations (fixes #840) 2025-04-30 13:54:44 -04:00
Matt Nadareski
b4b864cd9f Fix issue with some downloads 2025-04-30 13:47:41 -04:00
Matt Nadareski
acc2f30bd2 Fix most issues in new download code 2025-04-30 13:41:36 -04:00
Matt Nadareski
dc0675d8c6 Add cleanup to download functions 2025-04-30 12:03:06 -04:00
Matt Nadareski
33ce0e4024 Add initial extraction to new functions 2025-04-30 12:00:41 -04:00
Matt Nadareski
fa8fdac0ce Trailing commas caused issues 2025-04-30 11:49:11 -04:00
Matt Nadareski
a4d876d273 Fix elif 2025-04-30 11:39:36 -04:00
Matt Nadareski
3cc779ba77 Unify download maps 2025-04-30 11:38:36 -04:00
Matt Nadareski
5c8f4b9cac Smarter mapping of URLs to runtimes 2025-04-30 11:29:00 -04:00
Matt Nadareski
fb2b926986 Move function definitions 2025-04-30 11:02:58 -04:00
Matt Nadareski
3442a1f5b2 Add commented placeholders instead of omitting 2025-04-30 09:58:30 -04:00
Matt Nadareski
1fb9039985 Make more paths configurable 2025-04-30 09:54:49 -04:00
Matt Nadareski
0032066363 Add all separate downloads 2025-04-30 09:28:13 -04:00
Matt Nadareski
c1ed042190 Start defining all download URLs 2025-04-30 09:16:28 -04:00
Matt Nadareski
6c0f2415b7 Short-circuit CLI first-run experience 2025-04-30 09:02:36 -04:00
Matt Nadareski
ca898c4689 Always write full configuration file (fixes #839) 2025-04-30 08:55:37 -04:00
Matt Nadareski
3be4378b61 Normalize file path in CLI (fixes #826) 2025-04-30 08:53:20 -04:00
Deterous
c1641d7461 Allow max speed dumping (#838)
(0) in options
2025-04-19 08:16:05 -04:00
Deterous
aefb5a3778 Change redumper default commands (#837)
* Allow "0" drive speed

* Default speed 1 for unknown system

* default speed of 1

* No skeleton

* No base command by default

* Change speed in redumper tests

* Dump no longer dumping command

* Re-allow quick exiting always

* No base command is a dumping command

* Only one mode command per redumper call

* Proper capitalization for None

* Readd disc as default command mode
2025-04-18 09:05:33 -04:00
Deterous
4557017fc5 Quality of life fixes (#836)
* Account for N-type discs in Redumper processor

* MediaType prefix

* Delete after zipping, ask before closing during dump

* Proper closing function

* proper using

* nullable object

* YesNoCancel isn't a thing for CustomMessageBox

* Ctrl-Z
2025-04-17 11:37:32 -04:00
Deterous
d77e9c1612 Update redumper to build 549 (#835)
* Update redumper to build 549

* Add more redumper tests

* Add type

* Support .flip and .cache outputs

* Fix typo

* Fix test name

* Update tests

* Update tests again

* Don't check dmi/pfi/ss hashes against redump

* Fix incorrect flag

* Get last SCSI error count

* Fix test

* Fix test again

* Fix test finally

* Fix test final

* Review

* SACD doesn't need skeleton

* Proper SACD system handling

* Final final

* delete
2025-04-17 08:39:10 -04:00
bikerspade
455fb8228a Fix typo for L1Toolstamp!.Label (#828) 2025-02-27 12:02:15 -05:00
100 changed files with 4698 additions and 1768 deletions

View File

@@ -1,3 +1,125 @@
### 3.3.3 (2025-07-18)
- Handle layers for PS3CFW
- Further clarify configuration requirements for CLI
- Ignore volume labels with path separators
- Reduce media-specific checks where unnecessary
- Add DetermineMediaType scaffolding and tests
- Fill out DetermineMediaType for Redumper
- Fill out DetermineMediaType for Aaru
- Fill out DetermineMediaType for DiscImageCreator
- Enable Check to determine media type automatically
- Fix missed test updates
- Rename disc info to media info
- Fix start index in Check
- Use the correct base path for Check
- Update redumper to build 611
- IsAudio cleanup
- IsAudio cleanup cleanup
- Remove dead code in DIC processor
- Set some default values for CLI
- Address nullable default value
- Better handling of Xbox/360, redumper build 613
- Use reasonable default names for PlayStation systems
- Swap PS1/2 back to original name handling
- Only use serial for PS3/4/5 if no custom volume label
- Fix unnecessary null assignment
- Empty should be null (fuzz6001)
- Remove legacy codes from info window
- Net Yaroze only for PS1
- Update RedumpLib to 1.6.8
- Add new help and version flags for CLI and Check
- Strip errant whitespace during path normalization
- Simplify code from previous commit
- Better handle mixed-separator paths
- Slightly better IRD organization
- Update redumper to build 631
### 3.3.2 (2025-06-12)
- Include Aaru in automatic builds
- Update RedumpLib to 1.6.7
- Update redumper, DriveType option, SS sanity check
- Fix issues with last commit
- Update tooltips/labels for controversial options
- Add currently-hidden RetrieveMatchInformation option
- Fix Redump default options
- Fix tests from last commit
- Remove unnecessary options property
- Decouple retieval from login
- Simplify Options naming where possible
- Create multi-size icon
- Fix size retrieval for Aaru
- Update redumper to build 610
### 3.3.1 (2025-05-23)
- Fix typo for L1Toolstamp!.Label (bikerspade)
- Update redumper to build 549
- Allow max speed dumping ("0")
- Normalize file path in CLI
- Always write full configuration file
- Short-circuit CLI first-run experience
- Start defining all download URLs
- Add all separate downloads
- Make more paths configurable
- Add commented placeholders instead of omitting
- Move function definitions
- Smarter mapping of URLs to runtimes
- Unify download maps
- Trailing commas caused issues
- Add initial extraction to new functions
- Add cleanup to download functions
- Fix most issues in new download code
- Fix issue with some downloads
- Replace old download implementations
- Enable packing programs for CLI
- Fix minor packing issues
- Comment download scripts more
- Fix removing empty subdirectories
- Add interactive mode to CLI
- Add padding above root interactive node label
- Clean up case-sensitivity
- Add interactive mode to Check
- Fix menu title in Check interactive
- It's not dumping, it's checking
- Make interactive mode cleaner
- Avoid redundant redundancy
- Allow exiting from interactive modes
- Update RedumpLib to 1.6.5
- Fix package reference layout
- Update Nuget packages
- Normalize Shift-JIS characters, when possible
- Update to DIC 20250501
- Update RedumpLib to 1.6.6
- Pre-clean file path in CLI interactive mode
- Tweak to previous commit for some build versions
- Fix lines wiped before displayed
- Update redumper to build 565
- Close the log archive, if it exists
- Support checking Redumper DAT from zip; add tests
- Add Check warnings around overwriting and parsing
- Clarification on some options
- One more note about hidden settings
- Explicitly unset Redumper speed, if needed
- Simplify WriteOutputData path handling
- Serialize JSON a slightly different way
- Add newlines to pkg info printing
- Better audio-only check
- Minor cleanup from last commit
- Relax PS3CFW output filename requirements
- Fix bracket formatting from last commit
- Fix speed dropdown with Redumper
- Update redumper to build 585
- Further fix speed dropdown with Redumper
- Use null for 0 speed internally
- Don't hash bad SS
- Add and use status label for Check window
- Minor Check UI improvements
- Reset Redump errors when an INFO block is found
- Handle error count resets in Redumper
- Remove unnecessary conditional
### 3.3.0 (2025-01-03)
- Update packages

View File

@@ -12,7 +12,7 @@
<Nullable>enable</Nullable>
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<VersionPrefix>3.3.0</VersionPrefix>
<VersionPrefix>3.3.3</VersionPrefix>
<!-- Package Properties -->
<Title>MPF CLI</Title>
@@ -43,7 +43,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="SabreTools.RedumpLib" Version="1.6.4" />
<PackageReference Include="SabreTools.RedumpLib" Version="1.6.8" />
</ItemGroup>
</Project>

View File

@@ -26,7 +26,11 @@ namespace MPF.CLI
// Reset first run
options.FirstRun = false;
OptionsLoader.SaveToConfig(options, saveDefault: true);
OptionsLoader.SaveToConfig(options);
// Display non-error message
DisplayHelp("First-run detected! Please fill out config.json and run again.");
return;
}
// Try processing the standalone arguments
@@ -38,40 +42,56 @@ namespace MPF.CLI
return;
}
// Try processing the common arguments
bool success = OptionsLoader.ProcessCommonArguments(args, out MediaType mediaType, out RedumpSystem? knownSystem, out var error);
if (!success)
// Setup common outputs
CommandOptions opts;
MediaType mediaType;
RedumpSystem? knownSystem;
// Use interactive mode
if (args.Length > 0 && (args[0] == "-i" || args[0] == "--interactive"))
{
DisplayHelp(error);
return;
opts = InteractiveMode(options, out mediaType, out knownSystem);
}
// Validate the supplied credentials
if (!string.IsNullOrEmpty(options.RedumpUsername) && !string.IsNullOrEmpty(options.RedumpPassword))
// Use normal commandline parameters
else
{
bool? validated = RedumpClient.ValidateCredentials(options.RedumpUsername!, options.RedumpPassword!).GetAwaiter().GetResult();
string message = validated switch
// Try processing the common arguments
bool success = OptionsLoader.ProcessCommonArguments(args, out mediaType, out knownSystem, out var error);
if (!success)
{
true => "Redump username and password accepted!",
false => "Redump username and password denied!",
null => "An error occurred validating your credentials!",
};
DisplayHelp(error);
return;
}
// Validate the supplied credentials
if (options.RetrieveMatchInformation
&& !string.IsNullOrEmpty(options.RedumpUsername)
&& !string.IsNullOrEmpty(options.RedumpPassword))
{
bool? validated = RedumpClient.ValidateCredentials(options.RedumpUsername!, options.RedumpPassword!).GetAwaiter().GetResult();
string message = validated switch
{
true => "Redump username and password accepted!",
false => "Redump username and password denied!",
null => "An error occurred validating your credentials!",
};
if (!string.IsNullOrEmpty(message))
Console.WriteLine(message);
}
// Process any custom parameters
int startIndex = 2;
opts = LoadFromArguments(args, options, ref startIndex);
}
// Process any custom parameters
int startIndex = 2;
CommandOptions opts = LoadFromArguments(args, options, ref startIndex);
// Validate the internal program
switch (options.InternalProgram)
{
case InternalProgram.Aaru:
if (!File.Exists(options.AaruPath))
{
DisplayHelp("A path needs to be supplied for Aaru, exiting...");
DisplayHelp("A path needs to be supplied in config.json for Aaru, exiting...");
return;
}
break;
@@ -79,7 +99,7 @@ namespace MPF.CLI
case InternalProgram.DiscImageCreator:
if (!File.Exists(options.DiscImageCreatorPath))
{
DisplayHelp("A path needs to be supplied for DIC, exiting...");
DisplayHelp("A path needs to be supplied in config.json for DIC, exiting...");
return;
}
break;
@@ -87,7 +107,7 @@ namespace MPF.CLI
case InternalProgram.Redumper:
if (!File.Exists(options.RedumperPath))
{
DisplayHelp("A path needs to be supplied for Redumper, exiting...");
DisplayHelp("A path needs to be supplied in config.json for Redumper, exiting...");
return;
}
break;
@@ -104,6 +124,10 @@ namespace MPF.CLI
return;
}
// Normalize the file path
if (opts.FilePath != null)
opts.FilePath = FrontendTool.NormalizeOutputPaths(opts.FilePath, getFullPath: true);
// Get the speed from the options
int speed = opts.DriveSpeed ?? FrontendTool.GetDefaultSpeedForMediaType(mediaType, options);
@@ -113,22 +137,23 @@ namespace MPF.CLI
opts.FilePath,
drive,
knownSystem,
mediaType,
options.InternalProgram,
parameters: null);
options.InternalProgram);
env.SetExecutionContext(mediaType, null);
env.SetProcessor();
// Process the parameters
string? paramStr = opts.CustomParams ?? env.GetFullParameters(speed);
string? paramStr = opts.CustomParams ?? env.GetFullParameters(mediaType, speed);
if (string.IsNullOrEmpty(paramStr))
{
DisplayHelp("No valid environment could be created, exiting...");
return;
}
env.SetExecutionContext(paramStr);
env.SetExecutionContext(mediaType, paramStr);
// Invoke the dumping program
Console.WriteLine($"Invoking {options.InternalProgram} using '{paramStr}'");
var dumpResult = env.Run().GetAwaiter().GetResult();
var dumpResult = env.Run(mediaType).GetAwaiter().GetResult();
Console.WriteLine(dumpResult.Message);
if (!dumpResult)
return;
@@ -148,13 +173,13 @@ namespace MPF.CLI
opts.FilePath,
drive,
knownSystem,
mediaType,
internalProgram: null,
parameters: null);
internalProgram: null);
env.SetExecutionContext(mediaType, null);
env.SetProcessor();
}
// Finally, attempt to do the output dance
var verifyResult = env.VerifyAndSaveDumpOutput()
var verifyResult = env.VerifyAndSaveDumpOutput(mediaType: mediaType)
.ConfigureAwait(false).GetAwaiter().GetResult();
Console.WriteLine(verifyResult.Message);
}
@@ -172,15 +197,17 @@ namespace MPF.CLI
Console.WriteLine("MPF.CLI <mediatype> <system> [options]");
Console.WriteLine();
Console.WriteLine("Standalone Options:");
Console.WriteLine("-h, -? Show this help text");
Console.WriteLine("-h, -?, --help Show this help text");
Console.WriteLine("--version Print the program version");
Console.WriteLine("-lc, --listcodes List supported comment/content site codes");
Console.WriteLine("-lm, --listmedia List supported media types");
Console.WriteLine("-ls, --listsystems List supported system types");
Console.WriteLine("-lp, --listprograms List supported dumping program outputs");
Console.WriteLine("-i, --interactive Enable interactive mode");
Console.WriteLine();
Console.WriteLine("CLI Options:");
Console.WriteLine("-u, --use <program> Override default dumping program");
Console.WriteLine("-u, --use <program> Override configured dumping program name");
Console.WriteLine("-d, --device <devicepath> Physical drive path (Required if no custom parameters set)");
Console.WriteLine("-m, --mounted <dirpath> Mounted filesystem path for additional checks");
Console.WriteLine("-f, --file \"<filepath>\" Output file path (Required if no custom parameters set)");
@@ -188,6 +215,11 @@ namespace MPF.CLI
Console.WriteLine("-c, --custom \"<params>\" Custom parameters to use");
Console.WriteLine();
Console.WriteLine("Dumping program paths and other settings can be found in the config.json file");
Console.WriteLine("generated next to the program by default. Ensure that all settings are to user");
Console.WriteLine("preference before running MPF.CLI.");
Console.WriteLine();
Console.WriteLine("Custom dumping parameters, if used, will fully replace the default parameters.");
Console.WriteLine("All dumping parameters need to be supplied if doing this.");
Console.WriteLine("Otherwise, both a drive path and output file path are required.");
@@ -198,10 +230,157 @@ namespace MPF.CLI
Console.WriteLine();
}
/// <summary>
/// Enable interactive mode for entering information
/// </summary>
private static CommandOptions InteractiveMode(Options options, out MediaType mediaType, out RedumpSystem? system)
{
// Create return values
var opts = new CommandOptions
{
FilePath = Path.Combine(options.DefaultOutputPath ?? "ISO", "track.bin"),
};
mediaType = MediaType.NONE;
system = options.DefaultSystem;
// Create state values
string? result = string.Empty;
root:
Console.Clear();
Console.WriteLine("MPF.CLI Interactive Mode - Main Menu");
Console.WriteLine("-------------------------");
Console.WriteLine();
Console.WriteLine($"1) Set media type (Currently '{mediaType}')");
Console.WriteLine($"2) Set system (Currently '{system}')");
Console.WriteLine($"3) Set dumping program (Currently '{options.InternalProgram}')");
Console.WriteLine($"4) Set device path (Currently '{opts.DevicePath}')");
Console.WriteLine($"5) Set mounted path (Currently '{opts.MountedPath}')");
Console.WriteLine($"6) Set file path (Currently '{opts.FilePath}')");
Console.WriteLine($"7) Set override speed (Currently '{opts.DriveSpeed}')");
Console.WriteLine($"8) Set custom parameters (Currently '{opts.CustomParams}')");
Console.WriteLine();
Console.WriteLine($"Q) Exit the program");
Console.WriteLine($"X) Start dumping");
Console.Write("> ");
result = Console.ReadLine();
switch (result)
{
case "1":
goto mediaType;
case "2":
goto system;
case "3":
goto dumpingProgram;
case "4":
goto devicePath;
case "5":
goto mountedPath;
case "6":
goto filePath;
case "7":
goto overrideSpeed;
case "8":
goto customParams;
case "q":
case "Q":
Environment.Exit(0);
break;
case "x":
case "X":
Console.Clear();
goto exit;
case "z":
case "Z":
Console.WriteLine("It is pitch black. You are likely to be eaten by a grue.");
Console.Write("> ");
Console.ReadLine();
goto root;
default:
Console.WriteLine($"Invalid selection: {result}");
Console.ReadLine();
goto root;
}
mediaType:
Console.WriteLine();
Console.WriteLine("Input the media type and press Enter:");
Console.Write("> ");
result = Console.ReadLine();
mediaType = OptionsLoader.ToMediaType(result);
goto root;
system:
Console.WriteLine();
Console.WriteLine("Input the system and press Enter:");
Console.Write("> ");
result = Console.ReadLine();
system = Extensions.ToRedumpSystem(result);
goto root;
dumpingProgram:
Console.WriteLine();
Console.WriteLine("Input the dumping program and press Enter:");
Console.Write("> ");
result = Console.ReadLine();
options.InternalProgram = result.ToInternalProgram();
goto root;
devicePath:
Console.WriteLine();
Console.WriteLine("Input the device path and press Enter:");
Console.Write("> ");
opts.DevicePath = Console.ReadLine();
goto root;
mountedPath:
Console.WriteLine();
Console.WriteLine("Input the mounted path and press Enter:");
Console.Write("> ");
opts.MountedPath = Console.ReadLine();
goto root;
filePath:
Console.WriteLine();
Console.WriteLine("Input the file path and press Enter:");
Console.Write("> ");
result = Console.ReadLine();
if (!string.IsNullOrEmpty(result))
result = Path.GetFullPath(result!);
opts.FilePath = result;
goto root;
overrideSpeed:
Console.WriteLine();
Console.WriteLine("Input the override speed and press Enter:");
Console.Write("> ");
result = Console.ReadLine();
if (!int.TryParse(result, out int speed))
speed = -1;
opts.DriveSpeed = speed;
goto root;
customParams:
Console.WriteLine();
Console.WriteLine("Input the custom parameters and press Enter:");
Console.Write("> ");
opts.CustomParams = Console.ReadLine();
goto root;
exit:
return opts;
}
/// <summary>
/// Load the current set of options from application arguments
/// </summary>
private static CommandOptions LoadFromArguments(string[] args, Frontend.Options options, ref int startIndex)
private static CommandOptions LoadFromArguments(string[] args, Options options, ref int startIndex)
{
// Create return values
var opts = new CommandOptions();

View File

@@ -12,7 +12,7 @@
<Nullable>enable</Nullable>
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<VersionPrefix>3.3.0</VersionPrefix>
<VersionPrefix>3.3.3</VersionPrefix>
<!-- Package Properties -->
<Title>MPF Check</Title>
@@ -43,7 +43,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="SabreTools.RedumpLib" Version="1.6.4" />
<PackageReference Include="SabreTools.RedumpLib" Version="1.6.8" />
</ItemGroup>
</Project>

View File

@@ -16,7 +16,7 @@ namespace MPF.Check
public static void Main(string[] args)
{
// Create a default options object
var options = new Frontend.Options()
var options = new Options()
{
// Internal Program
InternalProgram = InternalProgram.NONE,
@@ -38,6 +38,7 @@ namespace MPF.Check
HideDriveLetters = false,
// Redump Login Information
RetrieveMatchInformation = true,
RedumpUsername = null,
RedumpPassword = null,
};
@@ -51,17 +52,34 @@ namespace MPF.Check
return;
}
// Try processing the common arguments
bool success = OptionsLoader.ProcessCommonArguments(args, out MediaType mediaType, out RedumpSystem? knownSystem, out var error);
if (!success)
// Setup common outputs
CommandOptions opts;
RedumpSystem? knownSystem;
int startIndex;
// Use interactive mode
if (args.Length > 0 && (args[0] == "-i" || args[0] == "--interactive"))
{
DisplayHelp(error);
return;
startIndex = 1;
opts = InteractiveMode(options, out knownSystem);
}
// Use normal commandline parameters
else
{
// Try processing the common arguments
bool success = OptionsLoader.ProcessCommonArguments(args, out knownSystem, out var error);
if (!success)
{
DisplayHelp(error);
return;
}
// Loop through and process options
startIndex = 1;
opts = LoadFromArguments(args, options, ref startIndex);
}
// Loop through and process options
int startIndex = 2;
CommandOptions opts = LoadFromArguments(args, options, ref startIndex);
if (options.InternalProgram == InternalProgram.NONE)
{
DisplayHelp("A program name needs to be provided");
@@ -69,7 +87,9 @@ namespace MPF.Check
}
// Validate the supplied credentials
if (!string.IsNullOrEmpty(options.RedumpUsername) && !string.IsNullOrEmpty(options.RedumpPassword))
if (options.RetrieveMatchInformation
&& !string.IsNullOrEmpty(options.RedumpUsername)
&& !string.IsNullOrEmpty(options.RedumpPassword))
{
bool? validated = RedumpClient.ValidateCredentials(options.RedumpUsername!, options.RedumpPassword!).GetAwaiter().GetResult();
string message = validated switch
@@ -79,8 +99,7 @@ namespace MPF.Check
null => "An error occurred validating your credentials!",
};
if (!string.IsNullOrEmpty(message))
Console.WriteLine(message);
Console.WriteLine(message);
}
// Loop through all the rest of the args
@@ -101,7 +120,12 @@ namespace MPF.Check
if (!string.IsNullOrEmpty(opts.DevicePath))
drive = Drive.Create(null, opts.DevicePath!);
var env = new DumpEnvironment(options, filepath, drive, knownSystem, mediaType, internalProgram: null, parameters: null);
var env = new DumpEnvironment(options,
filepath,
drive,
knownSystem,
internalProgram: null);
env.SetProcessor();
// Finally, attempt to do the output dance
var result = env.VerifyAndSaveDumpOutput(seedInfo: opts.Seed)
@@ -120,14 +144,16 @@ namespace MPF.Check
Console.WriteLine(error);
Console.WriteLine("Usage:");
Console.WriteLine("MPF.Check <mediatype> <system> [options] </path/to/output.cue/iso> ...");
Console.WriteLine("MPF.Check <system> [options] </path/to/output.cue/iso> ...");
Console.WriteLine();
Console.WriteLine("Standalone Options:");
Console.WriteLine("-h, -? Show this help text");
Console.WriteLine("-h, -?, --help Show this help text");
Console.WriteLine("--version Print the program version");
Console.WriteLine("-lc, --listcodes List supported comment/content site codes");
Console.WriteLine("-lm, --listmedia List supported media types");
Console.WriteLine("-ls, --listsystems List supported system types");
Console.WriteLine("-lp, --listprograms List supported dumping program outputs");
Console.WriteLine("-i, --interactive Enable interactive mode");
Console.WriteLine();
Console.WriteLine("Check Options:");
@@ -135,7 +161,8 @@ namespace MPF.Check
Console.WriteLine(" --load-seed <path> Load a seed submission JSON for user information");
Console.WriteLine(" --no-placeholders Disable placeholder values in submission info");
Console.WriteLine(" --create-ird Create IRD from output files (PS3 only)");
Console.WriteLine("-c, --credentials <user> <pw> Redump username and password");
Console.WriteLine(" --no-retrieve Disable retrieving match information from Redump");
Console.WriteLine("-c, --credentials <user> <pw> Redump username and password (incompatible with --no-retrieve)");
Console.WriteLine(" --pull-all Pull all information from Redump (requires --credentials)");
Console.WriteLine("-p, --path <drivepath> Physical drive path for additional checks");
Console.WriteLine("-s, --scan Enable copy protection scan (requires --path)");
@@ -148,12 +175,204 @@ namespace MPF.Check
Console.WriteLine("-z, --zip Enable log file compression");
Console.WriteLine("-d, --delete Enable unnecessary file deletion");
Console.WriteLine();
Console.WriteLine("WARNING: Check will overwrite both any existing submission information files as well");
Console.WriteLine("as any log archives. Please make backups of those if you need to before running Check.");
Console.WriteLine();
}
/// <summary>
/// Enable interactive mode for entering information
/// </summary>
private static CommandOptions InteractiveMode(Options options, out RedumpSystem? system)
{
// Create return values
var opts = new CommandOptions();
system = null;
// These values require multiple parts to be active
bool scan = false,
enableArchives = true,
enableDebug = false,
hideDriveLetters = false;
// Create state values
string? result = string.Empty;
root:
Console.Clear();
Console.WriteLine("MPF.Check Interactive Mode - Main Menu");
Console.WriteLine("-------------------------");
Console.WriteLine();
Console.WriteLine($"1) Set system (Currently '{system}')");
Console.WriteLine($"2) Set dumping program (Currently '{options.InternalProgram}')");
Console.WriteLine($"3) Set seed path (Currently '{opts.Seed}')");
Console.WriteLine($"4) Add placeholders (Currently '{options.AddPlaceholders}')");
Console.WriteLine($"5) Create IRD (Currently '{options.CreateIRDAfterDumping}')");
Console.WriteLine($"6) Attempt Redump matches (Currently '{options.RetrieveMatchInformation}')");
Console.WriteLine($"7) Redump credentials (Currently '{options.RedumpUsername}')");
Console.WriteLine($"8) Pull all information (Currently '{options.PullAllInformation}')");
Console.WriteLine($"9) Set device path (Currently '{opts.DevicePath}')");
Console.WriteLine($"A) Scan for protection (Currently '{scan}')");
Console.WriteLine($"B) Scan archives for protection (Currently '{enableArchives}')");
Console.WriteLine($"C) Debug protection scan output (Currently '{enableDebug}')");
Console.WriteLine($"D) Hide drive letters in protection output (Currently '{hideDriveLetters}')");
Console.WriteLine($"E) Hide filename suffix (Currently '{options.AddFilenameSuffix}')");
Console.WriteLine($"F) Output submission JSON (Currently '{options.OutputSubmissionJSON}')");
Console.WriteLine($"G) Include JSON artifacts (Currently '{options.IncludeArtifacts}')");
Console.WriteLine($"H) Compress logs (Currently '{options.CompressLogFiles}')");
Console.WriteLine($"I) Delete unnecessary files (Currently '{options.DeleteUnnecessaryFiles}')");
Console.WriteLine();
Console.WriteLine($"Q) Exit the program");
Console.WriteLine($"X) Start checking");
Console.Write("> ");
result = Console.ReadLine();
switch (result)
{
case "1":
goto system;
case "2":
goto dumpingProgram;
case "3":
goto seedPath;
case "4":
options.AddPlaceholders = !options.AddPlaceholders;
goto root;
case "5":
options.CreateIRDAfterDumping = !options.CreateIRDAfterDumping;
goto root;
case "6":
options.RetrieveMatchInformation = !options.RetrieveMatchInformation;
goto root;
case "7":
goto redumpCredentials;
case "8":
options.PullAllInformation = !options.PullAllInformation;
goto root;
case "9":
goto devicePath;
case "a":
case "A":
scan = !scan;
goto root;
case "b":
case "B":
enableArchives = !enableArchives;
goto root;
case "c":
case "C":
enableDebug = !enableDebug;
goto root;
case "d":
case "D":
hideDriveLetters = !hideDriveLetters;
goto root;
case "e":
case "E":
options.AddFilenameSuffix = !options.AddFilenameSuffix;
goto root;
case "f":
case "F":
options.OutputSubmissionJSON = !options.OutputSubmissionJSON;
goto root;
case "g":
case "G":
options.IncludeArtifacts = !options.IncludeArtifacts;
goto root;
case "h":
case "H":
options.CompressLogFiles = !options.CompressLogFiles;
goto root;
case "i":
case "I":
options.DeleteUnnecessaryFiles = !options.DeleteUnnecessaryFiles;
goto root;
case "q":
case "Q":
Environment.Exit(0);
break;
case "x":
case "X":
Console.Clear();
goto exit;
case "z":
case "Z":
Console.WriteLine("It is pitch black. You are likely to be eaten by a grue.");
Console.Write("> ");
Console.ReadLine();
goto root;
default:
Console.WriteLine($"Invalid selection: {result}");
Console.ReadLine();
goto root;
}
system:
Console.WriteLine();
Console.WriteLine("Input the system and press Enter:");
Console.Write("> ");
result = Console.ReadLine();
system = Extensions.ToRedumpSystem(result);
goto root;
dumpingProgram:
Console.WriteLine();
Console.WriteLine("Input the dumping program and press Enter:");
Console.Write("> ");
result = Console.ReadLine();
options.InternalProgram = result.ToInternalProgram();
goto root;
seedPath:
Console.WriteLine();
Console.WriteLine("Input the seed path and press Enter:");
Console.Write("> ");
result = Console.ReadLine();
opts.Seed = Builder.CreateFromFile(result);
goto root;
redumpCredentials:
Console.WriteLine();
Console.WriteLine("Enter your Redumper username and press Enter:");
Console.Write("> ");
options.RedumpUsername = Console.ReadLine();
Console.WriteLine("Enter your Redumper password (hidden) and press Enter:");
Console.Write("> ");
options.RedumpPassword = string.Empty;
while (true)
{
var key = Console.ReadKey(true);
if (key.Key == ConsoleKey.Enter)
break;
options.RedumpPassword += key.KeyChar;
}
goto root;
devicePath:
Console.WriteLine();
Console.WriteLine("Input the device path and press Enter:");
Console.Write("> ");
opts.DevicePath = Console.ReadLine();
goto root;
exit:
// Now deal with the complex options
options.ScanForProtection = scan && !string.IsNullOrEmpty(opts.DevicePath);
options.ScanArchivesForProtection = enableArchives && scan && !string.IsNullOrEmpty(opts.DevicePath);
options.IncludeDebugProtectionInformation = enableDebug && scan && !string.IsNullOrEmpty(opts.DevicePath);
options.HideDriveLetters = hideDriveLetters && scan && !string.IsNullOrEmpty(opts.DevicePath);
return opts;
}
/// <summary>
/// Load the current set of options from application arguments
/// </summary>
private static CommandOptions LoadFromArguments(string[] args, Frontend.Options options, ref int startIndex)
private static CommandOptions LoadFromArguments(string[] args, Options options, ref int startIndex)
{
// Create return values
var opts = new CommandOptions();
@@ -216,6 +435,12 @@ namespace MPF.Check
options.CreateIRDAfterDumping = true;
}
// Retrieve Redump match information
else if (args[startIndex] == "--no-retrieve")
{
options.RetrieveMatchInformation = false;
}
// Redump login
else if (args[startIndex].StartsWith("-c=") || args[startIndex].StartsWith("--credentials="))
{
@@ -283,7 +508,7 @@ namespace MPF.Check
options.OutputSubmissionJSON = true;
}
// Output submission JSON
// Include JSON artifacts
else if (args[startIndex].Equals("--include-artifacts"))
{
options.IncludeArtifacts = true;
@@ -295,7 +520,7 @@ namespace MPF.Check
options.CompressLogFiles = true;
}
// Delete unnecessary files files
// Delete unnecessary files
else if (args[startIndex].Equals("-d") || args[startIndex].Equals("--delete"))
{
options.DeleteUnnecessaryFiles = true;

View File

@@ -90,10 +90,10 @@ namespace MPF.ExecutionContexts.Test
#region Audio
[Theory]
[InlineData("audio F filename.bin 0 1 2 /be raw /c2 1 2 3 1 5 6 /d8 /d /q /f 0 /np /nq /nr /r /am /sf 1 /ss /sk 1 0 /s 0 /t")]
[InlineData("audio F filename.bin 0 1 2 /be raw /c2 1 2 3 1 5 6 /c2new 1 /d8 /d /q /f 0 /np /nq /nr /r /am /sf 1 /ss /sk 1 0 /s 0 /t")]
public void AudioTest(string parameters)
{
string? expected = "audio F \"filename.bin\" 0 1 2 /be raw /c2 1 2 3 1 5 6 /d8 /d /q /f 0 /np /nq /nr /r /am /sf 1 /ss /sk 1 0 /s 0 /t";
string? expected = "audio F \"filename.bin\" 0 1 2 /be raw /c2 1 2 3 1 5 6 /c2new 1 /d8 /d /q /f 0 /np /nq /nr /r /am /sf 1 /ss /sk 1 0 /s 0 /t";
var context = new ExecutionContext(parameters);
string? actual = context.GenerateParameters();
Assert.Equal(expected, actual);
@@ -135,10 +135,10 @@ namespace MPF.ExecutionContexts.Test
#region CompactDisc
[Theory]
[InlineData("cd f filename.bin 0 /a 0 /p /aj /be raw /c2 1 2 3 1 5 6 /d8 /d /q /mscf /f 0 /fulltoc /mr 0 /np /nq /nl /ns /nr /am /sf 1 /ss /74 /s 0 /toc /trp /vn 0 /vnc /vnx")]
[InlineData("cd f filename.bin 0 /a 0 /p /aj /be raw /c2 1 2 3 1 5 6 /c2new 1 /d8 /d /q /mscf /fdesc sync edc /f 0 /fulltoc /mr 0 /np /nq /nl /ns /nr /am /sf 1 /ss /74 /s 0 /toc /trp /vn 0 /vnc /vnx")]
public void CompactDiscTest(string parameters)
{
string? expected = "cd f \"filename.bin\" 0 /a 0 /p /aj /be raw /c2 1 2 3 1 5 6 /d8 /d /q /mscf /f 0 /fulltoc /mr 0 /np /nq /nl /ns /nr /am /sf 1 /ss /74 /s 0 /toc /trp /vn 0 /vnc /vnx";
string? expected = "cd f \"filename.bin\" 0 /a 0 /p /aj /be raw /c2 1 2 3 1 5 6 /c2new 1 /d8 /d /q /mscf /fdesc sync edc /f 0 /fulltoc /mr 0 /np /nq /nl /ns /nr /am /sf 1 /ss /74 /s 0 /toc /trp /vn 0 /vnc /vnx";
var context = new ExecutionContext(parameters);
string? actual = context.GenerateParameters();
Assert.Equal(expected, actual);
@@ -150,10 +150,10 @@ namespace MPF.ExecutionContexts.Test
#region Data
[Theory]
[InlineData("data F filename.bin 0 1 2 /be raw /c2 1 2 3 1 5 6 /d8 /d /q /f 0 /np /nq /nr /r /am /sf 1 /ss /sk 1 0 /s 0 /t")]
[InlineData("data F filename.bin 0 1 2 /be raw /c2 1 2 3 1 5 6 /c2new 1 /d8 /d /q /f 0 /np /nq /nr /r /am /sf 1 /ss /sk 1 0 /s 0 /t")]
public void DataTest(string parameters)
{
string? expected = "data F \"filename.bin\" 0 1 2 /be raw /c2 1 2 3 1 5 6 /d8 /d /q /f 0 /np /nq /nr /r /am /sf 1 /ss /sk 1 0 /s 0 /t";
string? expected = "data F \"filename.bin\" 0 1 2 /be raw /c2 1 2 3 1 5 6 /c2new 1 /d8 /d /q /f 0 /np /nq /nr /r /am /sf 1 /ss /sk 1 0 /s 0 /t";
var context = new ExecutionContext(parameters);
string? actual = context.GenerateParameters();
Assert.Equal(expected, actual);
@@ -240,10 +240,10 @@ namespace MPF.ExecutionContexts.Test
#region GDROM
[Theory]
[InlineData("gd f filename.bin 0 /be raw /c2 1 2 3 1 5 6 /d8 /d /q /f 0 /np /nq /nr /s 0")]
[InlineData("gd f filename.bin 0 /be raw /c2 1 2 3 1 5 6 /c2new 1 /d8 /d /q /f 0 /np /nq /nr /s 0")]
public void GDROMTest(string parameters)
{
string? expected = "gd f \"filename.bin\" 0 /be raw /c2 1 2 3 1 5 6 /d8 /d /q /f 0 /np /nq /nr /s 0";
string? expected = "gd f \"filename.bin\" 0 /be raw /c2 1 2 3 1 5 6 /c2new 1 /d8 /d /q /f 0 /np /nq /nr /s 0";
var context = new ExecutionContext(parameters);
string? actual = context.GenerateParameters();
Assert.Equal(expected, actual);
@@ -360,10 +360,10 @@ namespace MPF.ExecutionContexts.Test
#region Swap
[Theory]
[InlineData("swap f filename.bin 0 /a 0 /be raw /c2 1 2 3 1 5 6 /d8 /d /q /f 0 /np /nq /nl /ns /nr /am /sf 1 /ss /74 /s 0 /trp /vn 0 /vnc /vnx")]
[InlineData("swap f filename.bin 0 /a 0 /be raw /c2 1 2 3 1 5 6 /c2new 1 /d8 /d /q /f 0 /np /nq /nl /ns /nr /am /sf 1 /ss /74 /s 0 /trp /vn 0 /vnc /vnx")]
public void SwapTest(string parameters)
{
string? expected = "swap f \"filename.bin\" 0 /a 0 /be raw /c2 1 2 3 1 5 6 /d8 /d /q /f 0 /np /nq /nl /ns /nr /am /sf 1 /ss /74 /s 0 /trp /vn 0 /vnc /vnx";
string? expected = "swap f \"filename.bin\" 0 /a 0 /be raw /c2 1 2 3 1 5 6 /c2new 1 /d8 /d /q /f 0 /np /nq /nl /ns /nr /am /sf 1 /ss /74 /s 0 /trp /vn 0 /vnc /vnx";
var context = new ExecutionContext(parameters);
string? actual = context.GenerateParameters();
Assert.Equal(expected, actual);

View File

@@ -14,22 +14,22 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeCoverage" Version="17.12.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageReference Include="Microsoft.CodeCoverage" Version="17.13.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.13.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="SabreTools.RedumpLib" Version="1.6.4" />
<PackageReference Include="xunit" Version="2.9.2" />
<PackageReference Include="SabreTools.RedumpLib" Version="1.6.8" />
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.abstractions" Version="2.0.3" />
<PackageReference Include="xunit.analyzers" Version="1.18.0" />
<PackageReference Include="xunit.assert" Version="2.9.2" />
<PackageReference Include="xunit.core" Version="2.9.2" />
<PackageReference Include="xunit.extensibility.core" Version="2.9.2" />
<PackageReference Include="xunit.extensibility.execution" Version="2.9.2" />
<PackageReference Include="xunit.runner.console" Version="2.9.2">
<PackageReference Include="xunit.analyzers" Version="1.21.0" />
<PackageReference Include="xunit.assert" Version="2.9.3" />
<PackageReference Include="xunit.core" Version="2.9.3" />
<PackageReference Include="xunit.extensibility.core" Version="2.9.3" />
<PackageReference Include="xunit.extensibility.execution" Version="2.9.3" />
<PackageReference Include="xunit.runner.console" Version="2.9.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="xunit.runner.visualstudio" Version="3.0.0">
<PackageReference Include="xunit.runner.visualstudio" Version="3.0.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>

View File

@@ -32,26 +32,23 @@ namespace MPF.ExecutionContexts.Test
private static Dictionary<string, string?> AllOptions = new()
{
[SettingConstants.EnableDebug] = "true",
[SettingConstants.EnableLeadinRetry] = "true",
[SettingConstants.EnableVerbose] = "true",
[SettingConstants.LeadinRetryCount] = "1000",
[SettingConstants.ReadMethod] = "BE",
[SettingConstants.RereadCount] = "1000",
[SettingConstants.SectorOrder] = "DATA_C2_SUB",
[SettingConstants.UseGenericDriveType] = "true",
[SettingConstants.DriveType] = "GENERIC",
};
[Theory]
[InlineData(null, null, null, "filename.bin", null, "")]
[InlineData(RedumpSystem.IBMPCcompatible, MediaType.CDROM, "/dev/sr0", "path/filename.bin", 2, "cd skeleton --verbose --debug --drive=/dev/sr0 --speed=1000 --retries=1000 --image-path=\"path\" --image-name=\"filename\" --drive-type=GENERIC --drive-read-method=BE --drive-sector-order=DATA_C2_SUB")]
[InlineData(RedumpSystem.SuperAudioCD, MediaType.CDROM, "/dev/sr0", "path/filename.bin", 2, "sacd --verbose --debug --drive=/dev/sr0 --speed=1000 --retries=1000 --image-path=\"path\" --image-name=\"filename\" --drive-type=GENERIC --drive-read-method=BE --drive-sector-order=DATA_C2_SUB")]
[InlineData(RedumpSystem.IBMPCcompatible, MediaType.DVD, "/dev/sr0", "path/filename.bin", 2, "dvd --verbose --debug --drive=/dev/sr0 --speed=1000 --retries=1000 --image-path=\"path\" --image-name=\"filename\" --drive-type=GENERIC --drive-read-method=BE --drive-sector-order=DATA_C2_SUB")]
[InlineData(RedumpSystem.NintendoGameCube, MediaType.NintendoGameCubeGameDisc, "/dev/sr0", "path/filename.bin", 2, "dvd --verbose --debug --drive=/dev/sr0 --speed=1000 --retries=1000 --image-path=\"path\" --image-name=\"filename\" --drive-type=GENERIC --drive-read-method=BE --drive-sector-order=DATA_C2_SUB")]
[InlineData(RedumpSystem.NintendoWii, MediaType.NintendoWiiOpticalDisc, "/dev/sr0", "path/filename.bin", 2, "dvd --verbose --debug --drive=/dev/sr0 --speed=1000 --retries=1000 --image-path=\"path\" --image-name=\"filename\" --drive-type=GENERIC --drive-read-method=BE --drive-sector-order=DATA_C2_SUB")]
[InlineData(RedumpSystem.HDDVDVideo, MediaType.HDDVD, "/dev/sr0", "path/filename.bin", 2, "dvd --verbose --debug --drive=/dev/sr0 --speed=1000 --retries=1000 --image-path=\"path\" --image-name=\"filename\" --drive-type=GENERIC --drive-read-method=BE --drive-sector-order=DATA_C2_SUB")]
[InlineData(RedumpSystem.BDVideo, MediaType.BluRay, "/dev/sr0", "path/filename.bin", 2, "bd --verbose --debug --drive=/dev/sr0 --speed=1000 --retries=1000 --image-path=\"path\" --image-name=\"filename\" --drive-type=GENERIC --drive-read-method=BE --drive-sector-order=DATA_C2_SUB")]
[InlineData(RedumpSystem.NintendoWiiU, MediaType.NintendoWiiUOpticalDisc, "/dev/sr0", "path/filename.bin", 2, "bd --verbose --debug --drive=/dev/sr0 --speed=1000 --retries=1000 --image-path=\"path\" --image-name=\"filename\" --drive-type=GENERIC --drive-read-method=BE --drive-sector-order=DATA_C2_SUB")]
[InlineData(RedumpSystem.IBMPCcompatible, MediaType.CDROM, "/dev/sr0", "path/filename.bin", 2, "disc --verbose --skeleton --drive=/dev/sr0 --speed=2 --retries=1000 --image-path=\"path\" --image-name=\"filename\" --drive-type=GENERIC --drive-read-method=BE --drive-sector-order=DATA_C2_SUB --plextor-leadin-retries=1000")]
[InlineData(RedumpSystem.IBMPCcompatible, MediaType.DVD, "/dev/sr0", "path/filename.bin", 2, "disc --verbose --drive=/dev/sr0 --speed=2 --retries=1000 --image-path=\"path\" --image-name=\"filename\" --drive-type=GENERIC --drive-read-method=BE --drive-sector-order=DATA_C2_SUB --plextor-leadin-retries=1000")]
[InlineData(RedumpSystem.NintendoGameCube, MediaType.NintendoGameCubeGameDisc, "/dev/sr0", "path/filename.bin", 2, "disc --verbose --drive=/dev/sr0 --speed=2 --retries=1000 --image-path=\"path\" --image-name=\"filename\" --drive-type=GENERIC --drive-read-method=BE --drive-sector-order=DATA_C2_SUB --plextor-leadin-retries=1000")]
[InlineData(RedumpSystem.NintendoWii, MediaType.NintendoWiiOpticalDisc, "/dev/sr0", "path/filename.bin", 2, "disc --verbose --drive=/dev/sr0 --speed=2 --retries=1000 --image-path=\"path\" --image-name=\"filename\" --drive-type=GENERIC --drive-read-method=BE --drive-sector-order=DATA_C2_SUB --plextor-leadin-retries=1000")]
[InlineData(RedumpSystem.HDDVDVideo, MediaType.HDDVD, "/dev/sr0", "path/filename.bin", 2, "disc --verbose --drive=/dev/sr0 --speed=2 --retries=1000 --image-path=\"path\" --image-name=\"filename\" --drive-type=GENERIC --drive-read-method=BE --drive-sector-order=DATA_C2_SUB --plextor-leadin-retries=1000")]
[InlineData(RedumpSystem.BDVideo, MediaType.BluRay, "/dev/sr0", "path/filename.bin", 2, "disc --verbose --drive=/dev/sr0 --speed=2 --retries=1000 --image-path=\"path\" --image-name=\"filename\" --drive-type=GENERIC --drive-read-method=BE --drive-sector-order=DATA_C2_SUB --plextor-leadin-retries=1000")]
[InlineData(RedumpSystem.NintendoWiiU, MediaType.NintendoWiiUOpticalDisc, "/dev/sr0", "path/filename.bin", 2, "disc --verbose --drive=/dev/sr0 --speed=2 --retries=1000 --image-path=\"path\" --image-name=\"filename\" --drive-type=GENERIC --drive-read-method=BE --drive-sector-order=DATA_C2_SUB --plextor-leadin-retries=1000")]
public void DefaultValueTest(RedumpSystem? system,
MediaType? type,
string? drivePath,
@@ -66,14 +63,14 @@ namespace MPF.ExecutionContexts.Test
#endregion
#region CD
#region Disc
[Theory]
[InlineData("cd -h --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext")]
[InlineData("cd --help --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext")]
public void CDTest(string parameters)
[InlineData("disc -h --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs")]
[InlineData("disc --help --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs")]
public void DiscTest(string parameters)
{
string? expected = "cd --help --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=\"path\" --image-name=\"image\" --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext";
string? expected = "disc --help --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=\"path\" --image-name=\"image\" --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs";
var context = new ExecutionContext(parameters);
string? actual = context.GenerateParameters();
Assert.Equal(expected, actual);
@@ -81,74 +78,10 @@ namespace MPF.ExecutionContexts.Test
}
[Theory]
[InlineData("cd --drive=dr --image-path=\"directory name\" --image-name=\"image name.bin\"")]
[InlineData("disc --drive=dr --image-path=\"directory name\" --image-name=\"image name.bin\"")]
public void SpacesTest(string parameters)
{
string? expected = "cd --drive=dr --image-path=\"directory name\" --image-name=\"image name.bin\"";
var context = new ExecutionContext(parameters);
string? actual = context.GenerateParameters();
Assert.Equal(expected, actual);
Assert.True(context.IsDumpingCommand());
}
#endregion
#region DVD
[Theory]
[InlineData("dvd -h --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext")]
[InlineData("dvd --help --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext")]
public void DVDTest(string parameters)
{
string? expected = "dvd --help --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=\"path\" --image-name=\"image\" --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext";
var context = new ExecutionContext(parameters);
string? actual = context.GenerateParameters();
Assert.Equal(expected, actual);
Assert.True(context.IsDumpingCommand());
}
#endregion
#region BD
[Theory]
[InlineData("bd -h --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext")]
[InlineData("bd --help --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext")]
public void BDTest(string parameters)
{
string? expected = "bd --help --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=\"path\" --image-name=\"image\" --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext";
var context = new ExecutionContext(parameters);
string? actual = context.GenerateParameters();
Assert.Equal(expected, actual);
Assert.True(context.IsDumpingCommand());
}
#endregion
#region SACD
[Theory]
[InlineData("sacd -h --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext")]
[InlineData("sacd --help --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext")]
public void SACDTest(string parameters)
{
string? expected = "sacd --help --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=\"path\" --image-name=\"image\" --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext";
var context = new ExecutionContext(parameters);
string? actual = context.GenerateParameters();
Assert.Equal(expected, actual);
Assert.True(context.IsDumpingCommand());
}
#endregion
#region New
[Theory]
[InlineData("new -h --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext")]
[InlineData("new --help --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext")]
public void NewTest(string parameters)
{
string? expected = "new --help --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=\"path\" --image-name=\"image\" --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext";
string? expected = "disc --drive=dr --image-path=\"directory name\" --image-name=\"image name.bin\"";
var context = new ExecutionContext(parameters);
string? actual = context.GenerateParameters();
Assert.Equal(expected, actual);
@@ -160,11 +93,11 @@ namespace MPF.ExecutionContexts.Test
#region Rings
[Theory]
[InlineData("rings -h --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext")]
[InlineData("rings --help --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext")]
[InlineData("rings -h --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs")]
[InlineData("rings --help --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs")]
public void RingsTest(string parameters)
{
string? expected = "rings --help --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=\"path\" --image-name=\"image\" --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext";
string? expected = "rings --help --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=\"path\" --image-name=\"image\" --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs";
var context = new ExecutionContext(parameters);
string? actual = context.GenerateParameters();
Assert.Equal(expected, actual);
@@ -176,43 +109,11 @@ namespace MPF.ExecutionContexts.Test
#region Dump
[Theory]
[InlineData("dump -h --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext")]
[InlineData("dump --help --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext")]
[InlineData("dump -h --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs")]
[InlineData("dump --help --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs")]
public void DumpTest(string parameters)
{
string? expected = "dump --help --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=\"path\" --image-name=\"image\" --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext";
var context = new ExecutionContext(parameters);
string? actual = context.GenerateParameters();
Assert.Equal(expected, actual);
Assert.True(context.IsDumpingCommand());
}
#endregion
#region DumpNew
[Theory]
[InlineData("dumpnew -h --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext")]
[InlineData("dumpnew --help --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext")]
public void DumpNewTest(string parameters)
{
string? expected = "dumpnew --help --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=\"path\" --image-name=\"image\" --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext";
var context = new ExecutionContext(parameters);
string? actual = context.GenerateParameters();
Assert.Equal(expected, actual);
Assert.True(context.IsDumpingCommand());
}
#endregion
#region Refine
[Theory]
[InlineData("refine -h --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext")]
[InlineData("refine --help --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext")]
public void RefineTest(string parameters)
{
string? expected = "refine --help --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=\"path\" --image-name=\"image\" --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext";
string? expected = "dump --help --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=\"path\" --image-name=\"image\" --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs";
var context = new ExecutionContext(parameters);
string? actual = context.GenerateParameters();
Assert.Equal(expected, actual);
@@ -221,14 +122,30 @@ namespace MPF.ExecutionContexts.Test
#endregion
#region RefineNew
#region DumpExtra
[Theory]
[InlineData("refinenew -h --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext")]
[InlineData("refinenew --help --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext")]
public void RefineNewTest(string parameters)
[InlineData("dump::extra -h --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs")]
[InlineData("dump::extra --help --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs")]
public void DumpExtraTest(string parameters)
{
string? expected = "refinenew --help --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=\"path\" --image-name=\"image\" --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext";
string? expected = "dump::extra --help --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=\"path\" --image-name=\"image\" --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs";
var context = new ExecutionContext(parameters);
string? actual = context.GenerateParameters();
Assert.Equal(expected, actual);
Assert.False(context.IsDumpingCommand());
}
#endregion
#region Refine
[Theory]
[InlineData("refine -h --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs")]
[InlineData("refine --help --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs")]
public void RefineTest(string parameters)
{
string? expected = "refine --help --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=\"path\" --image-name=\"image\" --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs";
var context = new ExecutionContext(parameters);
string? actual = context.GenerateParameters();
Assert.Equal(expected, actual);
@@ -240,11 +157,11 @@ namespace MPF.ExecutionContexts.Test
#region Verify
[Theory]
[InlineData("verify -h --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext")]
[InlineData("verify --help --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext")]
[InlineData("verify -h --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs")]
[InlineData("verify --help --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs")]
public void VerifyTest(string parameters)
{
string? expected = "verify --help --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=\"path\" --image-name=\"image\" --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext";
string? expected = "verify --help --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=\"path\" --image-name=\"image\" --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs";
var context = new ExecutionContext(parameters);
string? actual = context.GenerateParameters();
Assert.Equal(expected, actual);
@@ -256,11 +173,11 @@ namespace MPF.ExecutionContexts.Test
#region DVDKey
[Theory]
[InlineData("dvdkey -h --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext")]
[InlineData("dvdkey --help --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext")]
[InlineData("dvdkey -h --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs")]
[InlineData("dvdkey --help --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs")]
public void DVDKeyTest(string parameters)
{
string? expected = "dvdkey --help --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=\"path\" --image-name=\"image\" --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext";
string? expected = "dvdkey --help --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=\"path\" --image-name=\"image\" --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs";
var context = new ExecutionContext(parameters);
string? actual = context.GenerateParameters();
Assert.Equal(expected, actual);
@@ -272,11 +189,11 @@ namespace MPF.ExecutionContexts.Test
#region Eject
[Theory]
[InlineData("eject -h --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext")]
[InlineData("eject --help --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext")]
[InlineData("eject -h --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs")]
[InlineData("eject --help --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs")]
public void EjectTest(string parameters)
{
string? expected = "eject --help --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=\"path\" --image-name=\"image\" --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext";
string? expected = "eject --help --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=\"path\" --image-name=\"image\" --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs";
var context = new ExecutionContext(parameters);
string? actual = context.GenerateParameters();
Assert.Equal(expected, actual);
@@ -288,11 +205,11 @@ namespace MPF.ExecutionContexts.Test
#region DVDIsoKey
[Theory]
[InlineData("dvdisokey -h --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext")]
[InlineData("dvdisokey --help --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext")]
[InlineData("dvdisokey -h --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs")]
[InlineData("dvdisokey --help --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs")]
public void DVDIsoKeyTest(string parameters)
{
string? expected = "dvdisokey --help --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=\"path\" --image-name=\"image\" --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext";
string? expected = "dvdisokey --help --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=\"path\" --image-name=\"image\" --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs";
var context = new ExecutionContext(parameters);
string? actual = context.GenerateParameters();
Assert.Equal(expected, actual);
@@ -304,11 +221,11 @@ namespace MPF.ExecutionContexts.Test
#region Protection
[Theory]
[InlineData("protection -h --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext")]
[InlineData("protection --help --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext")]
[InlineData("protection -h --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs")]
[InlineData("protection --help --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext")]
public void ProtectionTest(string parameters)
{
string? expected = "protection --help --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=\"path\" --image-name=\"image\" --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext";
string? expected = "protection --help --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=\"path\" --image-name=\"image\" --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs";
var context = new ExecutionContext(parameters);
string? actual = context.GenerateParameters();
Assert.Equal(expected, actual);
@@ -320,11 +237,11 @@ namespace MPF.ExecutionContexts.Test
#region Split
[Theory]
[InlineData("split -h --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext")]
[InlineData("split --help --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext")]
[InlineData("split -h --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs")]
[InlineData("split --help --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs")]
public void SplitTest(string parameters)
{
string? expected = "split --help --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=\"path\" --image-name=\"image\" --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext";
string? expected = "split --help --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=\"path\" --image-name=\"image\" --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs";
var context = new ExecutionContext(parameters);
string? actual = context.GenerateParameters();
Assert.Equal(expected, actual);
@@ -336,11 +253,11 @@ namespace MPF.ExecutionContexts.Test
#region Hash
[Theory]
[InlineData("hash -h --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext")]
[InlineData("hash --help --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext")]
[InlineData("hash -h --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs")]
[InlineData("hash --help --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs")]
public void HashTest(string parameters)
{
string? expected = "hash --help --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=\"path\" --image-name=\"image\" --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext";
string? expected = "hash --help --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=\"path\" --image-name=\"image\" --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs";
var context = new ExecutionContext(parameters);
string? actual = context.GenerateParameters();
Assert.Equal(expected, actual);
@@ -352,11 +269,11 @@ namespace MPF.ExecutionContexts.Test
#region Info
[Theory]
[InlineData("info -h --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext")]
[InlineData("info --help --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext")]
[InlineData("info -h --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs")]
[InlineData("info --help --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs")]
public void InfoTest(string parameters)
{
string? expected = "info --help --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=\"path\" --image-name=\"image\" --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext";
string? expected = "info --help --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=\"path\" --image-name=\"image\" --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs";
var context = new ExecutionContext(parameters);
string? actual = context.GenerateParameters();
Assert.Equal(expected, actual);
@@ -368,11 +285,27 @@ namespace MPF.ExecutionContexts.Test
#region Skeleton
[Theory]
[InlineData("skeleton -h --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext")]
[InlineData("skeleton --help --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext")]
[InlineData("skeleton -h --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs")]
[InlineData("skeleton --help --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs")]
public void SkeletonTest(string parameters)
{
string? expected = "skeleton --help --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=\"path\" --image-name=\"image\" --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext";
string? expected = "skeleton --help --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=\"path\" --image-name=\"image\" --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs";
var context = new ExecutionContext(parameters);
string? actual = context.GenerateParameters();
Assert.Equal(expected, actual);
Assert.False(context.IsDumpingCommand());
}
#endregion
#region Subchannel
[Theory]
[InlineData("subchannel -h --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs")]
[InlineData("subchannel --help --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs")]
public void SubchannelTest(string parameters)
{
string? expected = "subchannel --help --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=\"path\" --image-name=\"image\" --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs";
var context = new ExecutionContext(parameters);
string? actual = context.GenerateParameters();
Assert.Equal(expected, actual);
@@ -384,11 +317,11 @@ namespace MPF.ExecutionContexts.Test
#region Debug
[Theory]
[InlineData("debug -h --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext")]
[InlineData("debug --help --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext")]
[InlineData("debug -h --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs")]
[InlineData("debug --help --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs")]
public void DebugTest(string parameters)
{
string? expected = "debug --help --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=\"path\" --image-name=\"image\" --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext";
string? expected = "debug --help --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=\"path\" --image-name=\"image\" --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs";
var context = new ExecutionContext(parameters);
string? actual = context.GenerateParameters();
Assert.Equal(expected, actual);
@@ -397,20 +330,49 @@ namespace MPF.ExecutionContexts.Test
#endregion
// Currently disabled
#region FixMSF
// [Theory]
// [InlineData("fixmsf -h --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext")]
// [InlineData("fixmsf --help --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext")]
// public void FixMSFTest(string parameters)
// {
// string? expected = "fixmsf --help --version --verbose --auto-eject --drive=dr --speed=0 --retries=0 --image-path=\"path\" --image-name=\"image\" --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs --disable-cdtext";
// var context = new ExecutionContext(parameters);
// string? actual = context.GenerateParameters();
// Assert.Equal(expected, actual);
// }
[Theory]
[InlineData("fixmsf -h --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs")]
[InlineData("fixmsf --help --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs")]
public void FixMSFTest(string parameters)
{
string? expected = "fixmsf --help --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=\"path\" --image-name=\"image\" --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs";
var context = new ExecutionContext(parameters);
string? actual = context.GenerateParameters();
Assert.Equal(expected, actual);
}
#endregion
#region DebugFlip
[Theory]
[InlineData("debug::flip -h --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs")]
[InlineData("debug::flip --help --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs")]
public void DebugFlipTest(string parameters)
{
string? expected = "debug::flip --help --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=\"path\" --image-name=\"image\" --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs";
var context = new ExecutionContext(parameters);
string? actual = context.GenerateParameters();
Assert.Equal(expected, actual);
}
#endregion
#region DriveTest
[Theory]
[InlineData("drive::test -h --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs")]
[InlineData("drive::test --help --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=path --image-name=image --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs")]
public void DriveTestTest(string parameters)
{
string? expected = "drive::test --help --version --verbose --auto-eject --skeleton --drive=dr --speed=8 --retries=0 --image-path=\"path\" --image-name=\"image\" --overwrite --drive-type=dt --drive-read-offset=0 --drive-c2-shift=0 --drive-pregap-start=0 --drive-read-method=drm --drive-sector-order=dso --plextor-skip-leadin --plextor-leadin-retries=0 --asus-skip-leadout --disable-cdtext --force-offset=0 --audio-silence-threshold=0 --correct-offset-shift --offset-shift-relocate --force-split --leave-unchanged --force-qtoc --skip-fill=0 --iso9660-trim --lba-start=0 --lba-end=0 --refine-subchannel --refine-sector-mode --skip=0 --dump-write-offset=0 --dump-read-size=0 --overread-leadout --force-unscrambled --legacy-subs";
var context = new ExecutionContext(parameters);
string? actual = context.GenerateParameters();
Assert.Equal(expected, actual);
}
#endregion
}
}
}

View File

@@ -97,6 +97,13 @@ namespace MPF.ExecutionContexts.DiscImageCreator
/// </summary>
public int? FixValue { get; set; }
/// <summary>
/// Force descramble value
/// Possible values: sync, edc, sync edc, ecc, sync ecc, edc ecc
/// </summary>
/// TODO: Make this an enum
public string? ForceDescrambleSectorValue { get; set; }
/// <summary>
/// Set the force unit access flag value (default 1)
/// </summary>
@@ -185,6 +192,7 @@ namespace MPF.ExecutionContexts.DiscImageCreator
[
FlagStrings.BEOpcode,
FlagStrings.C2Opcode,
FlagStrings.C2OpcodeNew,
FlagStrings.D8Opcode,
FlagStrings.DatExpand,
FlagStrings.DisableBeep,
@@ -220,10 +228,12 @@ namespace MPF.ExecutionContexts.DiscImageCreator
FlagStrings.AtariJaguar,
FlagStrings.BEOpcode,
FlagStrings.C2Opcode,
FlagStrings.C2OpcodeNew,
FlagStrings.D8Opcode,
FlagStrings.DatExpand,
FlagStrings.DisableBeep,
FlagStrings.ExtractMicroSoftCabFile,
FlagStrings.ForceDescrambleSector,
FlagStrings.ForceUnitAccess,
FlagStrings.FullToc,
FlagStrings.MultiSectorRead,
@@ -248,6 +258,7 @@ namespace MPF.ExecutionContexts.DiscImageCreator
[
FlagStrings.BEOpcode,
FlagStrings.C2Opcode,
FlagStrings.C2OpcodeNew,
FlagStrings.D8Opcode,
FlagStrings.DatExpand,
FlagStrings.DisableBeep,
@@ -300,6 +311,7 @@ namespace MPF.ExecutionContexts.DiscImageCreator
[
FlagStrings.BEOpcode,
FlagStrings.C2Opcode,
FlagStrings.C2OpcodeNew,
FlagStrings.D8Opcode,
FlagStrings.DatExpand,
FlagStrings.DisableBeep,
@@ -333,6 +345,7 @@ namespace MPF.ExecutionContexts.DiscImageCreator
FlagStrings.AddOffset,
FlagStrings.BEOpcode,
FlagStrings.C2Opcode,
FlagStrings.C2OpcodeNew,
FlagStrings.D8Opcode,
FlagStrings.DatExpand,
FlagStrings.DisableBeep,
@@ -594,6 +607,22 @@ namespace MPF.ExecutionContexts.DiscImageCreator
}
}
// C2 Opcode New
if (IsFlagSupported(FlagStrings.C2OpcodeNew))
{
if (this[FlagStrings.C2OpcodeNew] == true)
{
parameters.Append($"{FlagStrings.C2OpcodeNew} ");
if (C2OpcodeValue[0] != null)
{
if (C2OpcodeValue[0] > 0)
parameters.Append($"{C2OpcodeValue[0]} ");
else
return null;
}
}
}
// Copyright Management Information
if (IsFlagSupported(FlagStrings.CopyrightManagementInformation))
{
@@ -653,6 +682,19 @@ namespace MPF.ExecutionContexts.DiscImageCreator
}
}
// Force Descramble Sector
if (IsFlagSupported(FlagStrings.ForceDescrambleSector))
{
if (this[FlagStrings.ForceDescrambleSector] == true)
{
parameters.Append($"{FlagStrings.ForceDescrambleSector} ");
if (ForceDescrambleSectorValue != null)
parameters.Append($"{ForceDescrambleSectorValue} ");
else
return null;
}
}
// Force Unit Access
if (IsFlagSupported(FlagStrings.ForceUnitAccess))
{
@@ -974,6 +1016,7 @@ namespace MPF.ExecutionContexts.DiscImageCreator
C2OpcodeValue = new int?[6];
DVDRereadValue = null;
FixValue = null;
ForceDescrambleSectorValue = null;
ForceUnitAccessValue = null;
NoSkipSecuritySectorValue = null;
ScanFileProtectValue = null;
@@ -1531,6 +1574,25 @@ namespace MPF.ExecutionContexts.DiscImageCreator
}
}
// C2 Opcode New
if (parts[i] == FlagStrings.C2OpcodeNew && IsFlagSupported(FlagStrings.C2OpcodeNew))
{
this[FlagStrings.C2OpcodeNew] = true;
if (!DoesExist(parts, i + 1))
{
return false;
}
else if (!IsValidInt32(parts[i + 1], lowerBound: 0))
{
return false;
}
else
{
C2OpcodeValue[0] = int.Parse(parts[i + 1]);
i++;
}
}
// Copyright Management Information
ProcessFlagParameter(parts, FlagStrings.CopyrightManagementInformation, ref i);
@@ -1556,6 +1618,63 @@ namespace MPF.ExecutionContexts.DiscImageCreator
if (intValue != null && intValue != int.MinValue)
FixValue = intValue;
// Force Descramble Sector
stringValue = ProcessStringParameter(parts, FlagStrings.ForceDescrambleSector, ref i);
if (!string.IsNullOrEmpty(stringValue))
{
if (string.Equals(stringValue, "sync"))
{
if (DoesExist(parts, i + 1))
{
if (parts[i + 1] == "edc")
{
ForceDescrambleSectorValue = "sync edc";
i++;
}
else if (parts[i + 1] == "ecc")
{
ForceDescrambleSectorValue = "sync ecc";
i++;
}
else
{
ForceDescrambleSectorValue = "sync";
}
}
else
{
ForceDescrambleSectorValue = "sync";
}
}
else if (string.Equals(stringValue, "edc"))
{
if (DoesExist(parts, i + 1))
{
if (parts[i + 1] == "ecc")
{
ForceDescrambleSectorValue = "edc ecc";
i++;
}
else
{
ForceDescrambleSectorValue = "edc";
}
}
else
{
ForceDescrambleSectorValue = "edc";
}
}
else if (string.Equals(stringValue, "ecc"))
{
ForceDescrambleSectorValue = "ecc";
}
else
{
return false;
}
}
// Force Unit Access
intValue = ProcessInt32Parameter(parts, FlagStrings.ForceUnitAccess, ref i, missingAllowed: true);
if (intValue != null && intValue != int.MinValue && intValue >= 0)

View File

@@ -10,6 +10,7 @@ namespace MPF.ExecutionContexts.DiscImageCreator
public const string AtariJaguar = "/aj";
public const string BEOpcode = "/be";
public const string C2Opcode = "/c2";
public const string C2OpcodeNew = "/c2new";
public const string CopyrightManagementInformation = "/c";
public const string D8Opcode = "/d8";
public const string DatExpand = "/d";
@@ -17,6 +18,7 @@ namespace MPF.ExecutionContexts.DiscImageCreator
public const string DVDReread = "/rr";
public const string ExtractMicroSoftCabFile = "/mscf";
public const string Fix = "/fix";
public const string ForceDescrambleSector = "/fdesc";
public const string ForceUnitAccess = "/f";
public const string FullToc = "/fulltoc";
public const string MultiSectorRead = "/mr";

View File

@@ -11,7 +11,7 @@
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<VersionPrefix>3.3.0</VersionPrefix>
<VersionPrefix>3.3.3</VersionPrefix>
<WarningsNotAsErrors>NU5104</WarningsNotAsErrors>
<!-- Package Properties -->
@@ -32,7 +32,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="SabreTools.RedumpLib" Version="1.6.4" />
<PackageReference Include="SabreTools.RedumpLib" Version="1.6.8" />
</ItemGroup>
</Project>

View File

@@ -6,16 +6,11 @@ namespace MPF.ExecutionContexts.Redumper
public static class CommandStrings
{
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 New = "new"; // Synonym for CD; Temporary command, to be removed later
public const string Disc = "disc";
public const string Rings = "rings";
public const string Dump = "dump";
public const string DumpNew = "dumpnew"; // Temporary command, to be removed later
public const string DumpExtra = "dump::extra";
public const string Refine = "refine";
public const string RefineNew = "refinenew"; // Temporary command, to be removed later
public const string Verify = "verify";
public const string DVDKey = "dvdkey";
public const string Eject = "eject";
@@ -25,7 +20,11 @@ namespace MPF.ExecutionContexts.Redumper
public const string Hash = "hash";
public const string Info = "info";
public const string Skeleton = "skeleton";
public const string FlashMT1339 = "flash::mt1339";
public const string Subchannel = "subchannel";
public const string Debug = "debug";
public const string FixMSF = "fixmsf";
public const string DebugFlip = "debug::flip";
public const string DriveTest = "drive::test";
}
}

View File

@@ -1,5 +1,21 @@
namespace MPF.ExecutionContexts.Redumper
{
/// <summary>
/// Drive type option
/// </summary>
public enum DriveType
{
NONE = 0,
GENERIC,
PLEXTOR,
LG_ASU8A,
LG_ASU8B,
LG_ASU8C,
LG_ASU3,
LG_ASU2,
}
/// <summary>
/// Drive read method option
/// </summary>
@@ -9,7 +25,6 @@ namespace MPF.ExecutionContexts.Redumper
BE,
D8,
BE_CDDA,
}
/// <summary>
@@ -24,4 +39,4 @@ namespace MPF.ExecutionContexts.Redumper
DATA_SUB,
DATA_C2,
}
}
}

View File

@@ -32,7 +32,16 @@ namespace MPF.ExecutionContexts.Redumper
}
set
{
(_inputs[FlagStrings.Speed] as Int32Input)?.SetValue(value);
if (value != null && value > 0)
{
this[FlagStrings.Speed] = true;
(_inputs[FlagStrings.Speed] as Int32Input)?.SetValue(value);
}
else
{
this[FlagStrings.Speed] = false;
(_inputs[FlagStrings.Speed] as Int32Input)?.SetValue(null);
}
}
}
@@ -41,9 +50,9 @@ namespace MPF.ExecutionContexts.Redumper
#region Flag Values
/// <summary>
/// List of all modes being run
/// Mode being run
/// </summary>
public List<string>? ModeValues { get; set; }
public string? ModeValue { get; set; }
/// <summary>
/// Set of all command flags
@@ -54,17 +63,19 @@ namespace MPF.ExecutionContexts.Redumper
[FlagStrings.HelpLong] = new FlagInput(FlagStrings.HelpShort, FlagStrings.HelpLong),
[FlagStrings.Version] = new FlagInput(FlagStrings.Version),
[FlagStrings.Verbose] = new FlagInput(FlagStrings.Verbose),
[FlagStrings.ListRecommendedDrives] = new FlagInput(FlagStrings.ListRecommendedDrives),
[FlagStrings.ListAllDrives] = new FlagInput(FlagStrings.ListAllDrives),
[FlagStrings.AutoEject] = new FlagInput(FlagStrings.AutoEject),
[FlagStrings.Debug] = new FlagInput(FlagStrings.Debug),
[FlagStrings.Skeleton] = new FlagInput(FlagStrings.Skeleton),
[FlagStrings.Drive] = new StringInput(FlagStrings.Drive),
[FlagStrings.Speed] = new Int32Input(FlagStrings.Speed),
[FlagStrings.Retries] = new Int32Input(FlagStrings.Retries),
[FlagStrings.ImagePath] = new StringInput(FlagStrings.ImagePath) { Quotes = true },
[FlagStrings.ImageName] = new StringInput(FlagStrings.ImageName) { Quotes = true },
[FlagStrings.Overwrite] = new FlagInput(FlagStrings.Overwrite),
[FlagStrings.DiscType] = new StringInput(FlagStrings.DiscType),
// Drive Configuration
[FlagStrings.Overwrite] = new FlagInput(FlagStrings.Overwrite),
[FlagStrings.DriveType] = new StringInput(FlagStrings.DriveType),
[FlagStrings.DriveReadOffset] = new Int32Input(FlagStrings.DriveReadOffset),
[FlagStrings.DriveC2Shift] = new Int32Input(FlagStrings.DriveC2Shift),
@@ -75,7 +86,11 @@ namespace MPF.ExecutionContexts.Redumper
// Drive Specific
[FlagStrings.PlextorSkipLeadin] = new FlagInput(FlagStrings.PlextorSkipLeadin),
[FlagStrings.PlextorLeadinRetries] = new Int32Input(FlagStrings.PlextorLeadinRetries),
[FlagStrings.PlextorLeadinForceStore] = new FlagInput(FlagStrings.PlextorLeadinForceStore),
[FlagStrings.KreonPartialSS] = new FlagInput(FlagStrings.KreonPartialSS),
[FlagStrings.AsusSkipLeadout] = new FlagInput(FlagStrings.AsusSkipLeadout),
[FlagStrings.AsusLeadoutRetries] = new Int32Input(FlagStrings.AsusLeadoutRetries),
[FlagStrings.DisableCDText] = new FlagInput(FlagStrings.DisableCDText),
// Offset
[FlagStrings.ForceOffset] = new Int32Input(FlagStrings.ForceOffset),
@@ -90,17 +105,29 @@ namespace MPF.ExecutionContexts.Redumper
[FlagStrings.SkipFill] = new UInt8Input(FlagStrings.SkipFill),
[FlagStrings.ISO9660Trim] = new FlagInput(FlagStrings.ISO9660Trim),
// Drive Test
[FlagStrings.DriveTestSkipPlextorLeadin] = new FlagInput(FlagStrings.DriveTestSkipPlextorLeadin),
[FlagStrings.DriveTestSkipCacheRead] = new FlagInput(FlagStrings.DriveTestSkipCacheRead),
// Miscellaneous
[FlagStrings.Continue] = new StringInput(FlagStrings.Continue),
[FlagStrings.LBAStart] = new Int32Input(FlagStrings.LBAStart),
[FlagStrings.LBAEnd] = new Int32Input(FlagStrings.LBAEnd),
[FlagStrings.RefineSubchannel] = new FlagInput(FlagStrings.RefineSubchannel),
[FlagStrings.RefineSectorMode] = new FlagInput(FlagStrings.RefineSectorMode),
[FlagStrings.Skip] = new StringInput(FlagStrings.Skip),
[FlagStrings.DumpWriteOffset] = new Int32Input(FlagStrings.DumpWriteOffset),
[FlagStrings.DumpReadSize] = new Int32Input(FlagStrings.DumpReadSize),
[FlagStrings.OverreadLeadout] = new FlagInput(FlagStrings.OverreadLeadout),
[FlagStrings.ForceUnscrambled] = new FlagInput(FlagStrings.ForceUnscrambled),
[FlagStrings.ForceRefine] = new FlagInput(FlagStrings.ForceRefine),
//[FlagStrings.Firmware] = new StringInput(FlagStrings.Firmware) { Quotes = true },
[FlagStrings.SkipSubcodeDesync] = new FlagInput(FlagStrings.SkipSubcodeDesync),
[FlagStrings.Rings] = new FlagInput(FlagStrings.Rings),
// Undocumented
[FlagStrings.Debug] = new FlagInput(FlagStrings.Debug),
[FlagStrings.LegacySubs] = new FlagInput(FlagStrings.LegacySubs),
[FlagStrings.DisableCDText] = new FlagInput(FlagStrings.DisableCDText),
};
#endregion
@@ -134,14 +161,17 @@ namespace MPF.ExecutionContexts.Redumper
FlagStrings.HelpShort,
FlagStrings.Version,
FlagStrings.Verbose,
FlagStrings.ListRecommendedDrives,
FlagStrings.ListAllDrives,
FlagStrings.AutoEject,
FlagStrings.Debug,
FlagStrings.Skeleton,
FlagStrings.Drive,
FlagStrings.Speed,
FlagStrings.Retries,
FlagStrings.ImagePath,
FlagStrings.ImageName,
FlagStrings.Overwrite,
FlagStrings.DiscType,
// Drive Configuration
FlagStrings.DriveType,
@@ -154,7 +184,11 @@ namespace MPF.ExecutionContexts.Redumper
// Drive Specific
FlagStrings.PlextorSkipLeadin,
FlagStrings.PlextorLeadinRetries,
FlagStrings.PlextorLeadinForceStore,
FlagStrings.KreonPartialSS,
FlagStrings.AsusSkipLeadout,
FlagStrings.AsusLeadoutRetries,
FlagStrings.DisableCDText,
// Offset
FlagStrings.ForceOffset,
@@ -169,17 +203,29 @@ namespace MPF.ExecutionContexts.Redumper
FlagStrings.SkipFill,
FlagStrings.ISO9660Trim,
// Drive Test
FlagStrings.DriveTestSkipPlextorLeadin,
FlagStrings.DriveTestSkipCacheRead,
// Miscellaneous
FlagStrings.Continue,
FlagStrings.LBAStart,
FlagStrings.LBAEnd,
FlagStrings.RefineSubchannel,
FlagStrings.RefineSectorMode,
FlagStrings.Skip,
FlagStrings.DumpWriteOffset,
FlagStrings.DumpReadSize,
FlagStrings.OverreadLeadout,
FlagStrings.ForceUnscrambled,
FlagStrings.ForceRefine,
//FlagStrings.Firmware,
FlagStrings.SkipSubcodeDesync,
FlagStrings.Rings,
// Undocumented
FlagStrings.Debug,
FlagStrings.LegacySubs,
FlagStrings.DisableCDText,
],
};
}
@@ -194,12 +240,10 @@ namespace MPF.ExecutionContexts.Redumper
{
var parameters = new StringBuilder();
ModeValues ??= [CommandStrings.NONE];
// Modes
string modes = string.Join(" ", [.. ModeValues]);
if (modes.Length > 0)
parameters.Append($"{modes} ");
// Command Mode
ModeValue ??= CommandStrings.NONE;
if (ModeValue != CommandStrings.NONE)
parameters.Append($"{ModeValue} ");
// Loop though and append all existing
foreach (var kvp in _inputs)
@@ -225,13 +269,9 @@ namespace MPF.ExecutionContexts.Redumper
/// <inheritdoc/>
public override bool IsDumpingCommand()
{
return ModeValues?.Contains(CommandStrings.CD) == true
|| ModeValues?.Contains(CommandStrings.DVD) == true
|| ModeValues?.Contains(CommandStrings.BluRay) == true
|| ModeValues?.Contains(CommandStrings.SACD) == true
|| ModeValues?.Contains(CommandStrings.New) == true
|| ModeValues?.Contains(CommandStrings.Dump) == true
|| ModeValues?.Contains(CommandStrings.DumpNew) == true;
// `dump` command does not provide hashes so will error out after dump if run via MPF
return ModeValue == CommandStrings.NONE
|| ModeValue == CommandStrings.Disc;
}
/// <inheritdoc/>
@@ -255,23 +295,13 @@ namespace MPF.ExecutionContexts.Redumper
switch (MediaType)
{
case SabreTools.RedumpLib.Data.MediaType.CDROM:
ModeValues = RedumpSystem switch
{
SabreTools.RedumpLib.Data.RedumpSystem.SuperAudioCD => [CommandStrings.SACD],
_ => [CommandStrings.CD, CommandStrings.Skeleton],
};
break;
case SabreTools.RedumpLib.Data.MediaType.DVD:
case SabreTools.RedumpLib.Data.MediaType.NintendoGameCubeGameDisc:
case SabreTools.RedumpLib.Data.MediaType.NintendoWiiOpticalDisc:
ModeValues = [CommandStrings.DVD];
break;
case SabreTools.RedumpLib.Data.MediaType.HDDVD: // TODO: Keep in sync if another command string shows up
ModeValues = [CommandStrings.DVD];
break;
case SabreTools.RedumpLib.Data.MediaType.HDDVD:
case SabreTools.RedumpLib.Data.MediaType.BluRay:
case SabreTools.RedumpLib.Data.MediaType.NintendoWiiUOpticalDisc:
ModeValues = [CommandStrings.BluRay];
ModeValue = CommandStrings.Disc;
break;
default:
BaseCommand = null;
@@ -281,8 +311,16 @@ namespace MPF.ExecutionContexts.Redumper
this[FlagStrings.Drive] = true;
(_inputs[FlagStrings.Drive] as StringInput)?.SetValue(drivePath ?? string.Empty);
this[FlagStrings.Speed] = true;
(_inputs[FlagStrings.Speed] as Int32Input)?.SetValue(driveSpeed);
if (driveSpeed != null && driveSpeed > 0)
{
this[FlagStrings.Speed] = true;
(_inputs[FlagStrings.Speed] as Int32Input)?.SetValue(driveSpeed);
}
else
{
this[FlagStrings.Speed] = false;
(_inputs[FlagStrings.Speed] as Int32Input)?.SetValue(null);
}
// Set user-defined options
if (GetBooleanSetting(options, SettingConstants.EnableVerbose, SettingConstants.EnableVerboseDefault))
@@ -290,10 +328,25 @@ namespace MPF.ExecutionContexts.Redumper
this[FlagStrings.Verbose] = true;
(_inputs[FlagStrings.Verbose] as FlagInput)?.SetValue(true);
}
if (GetBooleanSetting(options, SettingConstants.EnableDebug, SettingConstants.EnableDebugDefault))
if (GetBooleanSetting(options, SettingConstants.EnableSkeleton, SettingConstants.EnableSkeletonDefault))
{
this[FlagStrings.Debug] = true;
(_inputs[FlagStrings.Debug] as FlagInput)?.SetValue(true);
// Enable skeleton for CD dumps only by default
switch (MediaType)
{
case SabreTools.RedumpLib.Data.MediaType.CDROM:
switch (RedumpSystem)
{
case SabreTools.RedumpLib.Data.RedumpSystem.SuperAudioCD:
break;
default:
this[FlagStrings.Skeleton] = true;
(_inputs[FlagStrings.Skeleton] as FlagInput)?.SetValue(true);
break;
}
break;
default:
break;
}
}
string? readMethod = GetStringSetting(options, SettingConstants.ReadMethod, SettingConstants.ReadMethodDefault);
@@ -311,10 +364,11 @@ namespace MPF.ExecutionContexts.Redumper
(_inputs[FlagStrings.DriveSectorOrder] as StringInput)?.SetValue(sectorOrder!);
}
if (GetBooleanSetting(options, SettingConstants.UseGenericDriveType, SettingConstants.UseGenericDriveTypeDefault))
string? driveType = GetStringSetting(options, SettingConstants.DriveType, SettingConstants.DriveTypeDefault);
if (!string.IsNullOrEmpty(driveType) && driveType != DriveType.NONE.ToString())
{
this[FlagStrings.DriveType] = true;
(_inputs[FlagStrings.DriveType] as StringInput)?.SetValue("GENERIC");
(_inputs[FlagStrings.DriveType] as StringInput)?.SetValue(driveType!);
}
// Set the output paths
@@ -335,13 +389,18 @@ namespace MPF.ExecutionContexts.Redumper
}
}
this[FlagStrings.Retries] = true;
(_inputs[FlagStrings.Retries] as Int32Input)?.SetValue(GetInt32Setting(options, SettingConstants.RereadCount, SettingConstants.RereadCountDefault));
int retries = GetInt32Setting(options, SettingConstants.RereadCount, SettingConstants.RereadCountDefault);
if(retries > 0)
{
this[FlagStrings.Retries] = true;
(_inputs[FlagStrings.Retries] as Int32Input)?.SetValue(retries);
}
if (GetBooleanSetting(options, SettingConstants.EnableLeadinRetry, SettingConstants.EnableLeadinRetryDefault))
int leadinRetries = GetInt32Setting(options, SettingConstants.LeadinRetryCount, SettingConstants.LeadinRetryCountDefault);
if (leadinRetries != SettingConstants.LeadinRetryCountDefault)
{
this[FlagStrings.PlextorLeadinRetries] = true;
(_inputs[FlagStrings.Speed] as Int32Input)?.SetValue(GetInt32Setting(options, SettingConstants.LeadinRetryCount, SettingConstants.LeadinRetryCountDefault));
(_inputs[FlagStrings.PlextorLeadinRetries] as Int32Input)?.SetValue(leadinRetries);
}
}
@@ -358,7 +417,7 @@ namespace MPF.ExecutionContexts.Redumper
string[] parts = SplitParameterString(parameters!);
// Setup the modes
ModeValues = [];
ModeValue = null;
// All modes should be cached separately
int index = 0;
@@ -370,16 +429,11 @@ namespace MPF.ExecutionContexts.Redumper
string part = parts[index];
switch (part)
{
case CommandStrings.CD:
case CommandStrings.DVD:
case CommandStrings.BluRay:
case CommandStrings.SACD:
case CommandStrings.New: // Temporary command, to be removed later
case CommandStrings.Disc:
case CommandStrings.Rings:
case CommandStrings.Dump:
case CommandStrings.DumpNew: // Temporary command, to be removed later
case CommandStrings.DumpExtra:
case CommandStrings.Refine:
case CommandStrings.RefineNew: // Temporary command, to be removed later
case CommandStrings.Verify:
case CommandStrings.DVDKey:
case CommandStrings.Eject:
@@ -389,9 +443,17 @@ namespace MPF.ExecutionContexts.Redumper
case CommandStrings.Hash:
case CommandStrings.Info:
case CommandStrings.Skeleton:
case CommandStrings.FlashMT1339:
case CommandStrings.Subchannel:
case CommandStrings.Debug:
//case CommandStrings.FixMSF:
ModeValues.Add(part);
case CommandStrings.FixMSF:
case CommandStrings.DebugFlip:
case CommandStrings.DriveTest:
// Only allow one mode per command
if (ModeValue != null)
continue;
ModeValue = part;
break;
// Default is either a flag or an invalid mode

View File

@@ -11,14 +11,17 @@ namespace MPF.ExecutionContexts.Redumper
public const string HelpShort = "-h";
public const string Version = "--version";
public const string Verbose = "--verbose";
public const string ListRecommendedDrives = "--list-recommended-drives";
public const string ListAllDrives = "--list-all-drives";
public const string AutoEject = "--auto-eject";
public const string Debug = "--debug";
public const string Skeleton = "--skeleton";
public const string Drive = "--drive";
public const string Speed = "--speed";
public const string Retries = "--retries";
public const string ImagePath = "--image-path";
public const string ImageName = "--image-name";
public const string Overwrite = "--overwrite";
public const string DiscType = "--disc-type";
#endregion
@@ -37,7 +40,11 @@ namespace MPF.ExecutionContexts.Redumper
public const string PlextorSkipLeadin = "--plextor-skip-leadin";
public const string PlextorLeadinRetries = "--plextor-leadin-retries";
public const string PlextorLeadinForceStore = "--plextor-leadin-force-store";
public const string KreonPartialSS = "--kreon-partial-ss";
public const string AsusSkipLeadout = "--asus-skip-leadout";
public const string AsusLeadoutRetries = "--asus-leadout-retries";
public const string DisableCDText = "--disable-cdtext";
#endregion
@@ -60,19 +67,37 @@ namespace MPF.ExecutionContexts.Redumper
#endregion
#region Drive Test
public const string DriveTestSkipPlextorLeadin = "--drive-test-skip-plextor-leadin";
public const string DriveTestSkipCacheRead = "--drive-test-skip-cache-read";
#endregion
#region Miscellaneous
public const string Continue = "--continue";
public const string LBAStart = "--lba-start";
public const string LBAEnd = "--lba-end";
public const string RefineSubchannel = "--refine-subchannel";
public const string RefineSectorMode = "--refine-sector-mode";
public const string Skip = "--skip";
public const string DumpWriteOffset = "--dump-write-offset";
public const string DumpReadSize = "--dump-read-size";
public const string OverreadLeadout = "--overread-leadout";
public const string ForceUnscrambled = "--force-unscrambled";
public const string ForceRefine = "--force-refine";
public const string Firmware = "--firmware";
public const string SkipSubcodeDesync = "--skip-subcode-desync";
public const string Rings = "--rings";
#endregion
#region Undocumented
public const string Debug = "--debug";
public const string LegacySubs = "--legacy-subs";
public const string DisableCDText = "--disable-cdtext";
#endregion
}
}
}

View File

@@ -2,14 +2,14 @@ namespace MPF.ExecutionContexts.Redumper
{
public static class SettingConstants
{
public const string EnableDebug = "RedumperEnableDebug";
public const bool EnableDebugDefault = false;
public const string DriveType = "RedumperDriveType";
public static readonly string DriveTypeDefault = Redumper.DriveType.NONE.ToString();
public const string EnableLeadinRetry = "RedumperEnableLeadinRetry";
public const bool EnableLeadinRetryDefault = false;
public const string EnableSkeleton = "RedumperEnableSkeleton";
public const bool EnableSkeletonDefault = true;
public const string EnableVerbose = "RedumperEnableVerbose";
public const bool EnableVerboseDefault = true;
public const bool EnableVerboseDefault = false;
public const string LeadinRetryCount = "RedumperLeadinRetryCount";
public const int LeadinRetryCountDefault = 4;
@@ -22,8 +22,5 @@ namespace MPF.ExecutionContexts.Redumper
public const string SectorOrder = "RedumperSectorOrder";
public static readonly string SectorOrderDefault = Redumper.SectorOrder.NONE.ToString();
public const string UseGenericDriveType = "RedumperUseGenericDriveType";
public const bool UseGenericDriveTypeDefault = false;
}
}
}

View File

@@ -9,6 +9,7 @@ namespace MPF.Frontend.Test
[InlineData(null, 'D', false, MediaType.NONE, false)]
[InlineData("", 'D', false, MediaType.NONE, false)]
[InlineData("cd F test.bin 8 /c2 20", 'F', false, MediaType.CDROM, true)]
[InlineData("cd F test.bin 8 /c2new 20", 'F', false, MediaType.CDROM, true)]
[InlineData("fd A test.img", 'A', true, MediaType.FloppyDisk, true)]
[InlineData("dvd X test.iso 8 /raw", 'X', false, MediaType.FloppyDisk, false)]
[InlineData("stop D", 'D', false, MediaType.DVD, true)]
@@ -21,9 +22,15 @@ namespace MPF.Frontend.Test
? Drive.Create(InternalDriveType.Floppy, letter.ToString())
: Drive.Create(InternalDriveType.Optical, letter.ToString());
var env = new DumpEnvironment(options, string.Empty, drive, RedumpSystem.IBMPCcompatible, mediaType, null, parameters);
var env = new DumpEnvironment(options,
string.Empty,
drive,
RedumpSystem.IBMPCcompatible,
null);
env.SetExecutionContext(mediaType, parameters);
env.SetProcessor();
bool actual = env.ParametersValid();
bool actual = env.ParametersValid(mediaType);
Assert.Equal(expected, actual);
}
}

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using SabreTools.RedumpLib.Data;
using Xunit;
using RedumperDriveType = MPF.ExecutionContexts.Redumper.DriveType;
using RedumperReadMethod = MPF.ExecutionContexts.Redumper.ReadMethod;
using RedumperSectorOrder = MPF.ExecutionContexts.Redumper.SectorOrder;
@@ -33,7 +34,6 @@ namespace MPF.Frontend.Test
[InlineData(RedumperReadMethod.NONE, "Default")]
[InlineData(RedumperReadMethod.D8, "D8")]
[InlineData(RedumperReadMethod.BE, "BE")]
[InlineData(RedumperReadMethod.BE_CDDA, "BE_CDDA")]
public void LongName_RedumperReadMethod(RedumperReadMethod? method, string? expected)
{
string? actual = method.LongName();
@@ -53,6 +53,22 @@ namespace MPF.Frontend.Test
Assert.Equal(expected, actual);
}
[Theory]
[InlineData(null, "Unknown")]
[InlineData(RedumperDriveType.NONE, "Default")]
[InlineData(RedumperDriveType.GENERIC, "GENERIC")]
[InlineData(RedumperDriveType.PLEXTOR, "PLEXTOR")]
[InlineData(RedumperDriveType.LG_ASU8A, "LG_ASU8A")]
[InlineData(RedumperDriveType.LG_ASU8B, "LG_ASU8B")]
[InlineData(RedumperDriveType.LG_ASU8C, "LG_ASU8C")]
[InlineData(RedumperDriveType.LG_ASU3, "LG_ASU3")]
[InlineData(RedumperDriveType.LG_ASU2, "LG_ASU2")]
public void LongName_RedumperDriveType(RedumperDriveType? type, string? expected)
{
string? actual = type.LongName();
Assert.Equal(expected, actual);
}
#endregion
#region Short Name
@@ -161,4 +177,4 @@ namespace MPF.Frontend.Test
#endregion
}
}
}

View File

@@ -14,22 +14,22 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeCoverage" Version="17.12.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageReference Include="Microsoft.CodeCoverage" Version="17.13.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.13.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="SabreTools.RedumpLib" Version="1.6.4" />
<PackageReference Include="xunit" Version="2.9.2" />
<PackageReference Include="SabreTools.RedumpLib" Version="1.6.8" />
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.abstractions" Version="2.0.3" />
<PackageReference Include="xunit.analyzers" Version="1.18.0" />
<PackageReference Include="xunit.assert" Version="2.9.2" />
<PackageReference Include="xunit.core" Version="2.9.2" />
<PackageReference Include="xunit.extensibility.core" Version="2.9.2" />
<PackageReference Include="xunit.extensibility.execution" Version="2.9.2" />
<PackageReference Include="xunit.runner.console" Version="2.9.2">
<PackageReference Include="xunit.analyzers" Version="1.21.0" />
<PackageReference Include="xunit.assert" Version="2.9.3" />
<PackageReference Include="xunit.core" Version="2.9.3" />
<PackageReference Include="xunit.extensibility.core" Version="2.9.3" />
<PackageReference Include="xunit.extensibility.execution" Version="2.9.3" />
<PackageReference Include="xunit.runner.console" Version="2.9.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="xunit.runner.visualstudio" Version="3.0.0">
<PackageReference Include="xunit.runner.visualstudio" Version="3.0.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>

View File

@@ -81,6 +81,8 @@ namespace MPF.Frontend.Test.Tools
[InlineData("1.2.3.4..bin", true, "1.2.3.4..bin")]
[InlineData("dir/filename.bin", false, "dir/filename.bin")]
[InlineData("dir/filename.bin", true, "dir/filename.bin")]
[InlineData(" dir / filename.bin", false, "dir/filename.bin")]
[InlineData(" dir / filename.bin", true, "dir/filename.bin")]
[InlineData("\0dir/\0filename.bin", false, "_dir/_filename.bin")]
[InlineData("\0dir/\0filename.bin", true, "_dir/_filename.bin")]
public void NormalizeOutputPathsTest(string? path, bool getFullPath, string expected)

View File

@@ -9,24 +9,6 @@ namespace MPF.Frontend.Test.Tools
{
public class InfoToolTests
{
[Theory]
[InlineData(null, "")]
[InlineData(" ", " ")]
[InlineData("super\\blah.bin", "super\\blah.bin")]
[InlineData("super\\hero\\blah.bin", "super\\hero\\blah.bin")]
[InlineData("super.hero\\blah.bin", "super.hero\\blah.bin")]
[InlineData("superhero\\blah.rev.bin", "superhero\\blah.rev.bin")]
[InlineData("super&hero\\blah.bin", "super&hero\\blah.bin")]
[InlineData("superhero\\blah&foo.bin", "superhero\\blah&foo.bin")]
public void NormalizeOutputPathsTest(string? outputPath, string? expectedPath)
{
if (!string.IsNullOrEmpty(expectedPath))
expectedPath = Path.GetFullPath(expectedPath);
string actualPath = FrontendTool.NormalizeOutputPaths(outputPath, true);
Assert.Equal(expectedPath, actualPath);
}
[Fact]
public void ProcessSpecialFieldsCompleteTest()
{

View File

@@ -61,11 +61,6 @@ namespace MPF.Frontend
/// </summary>
private readonly RedumpSystem? _system;
/// <summary>
/// Currently selected media type
/// </summary>
private readonly MediaType? _type;
#endregion
#region Passthrough Fields
@@ -114,16 +109,12 @@ namespace MPF.Frontend
/// <param name="outputPath"></param>
/// <param name="drive"></param>
/// <param name="system"></param>
/// <param name="type"></param>
/// <param name="internalProgram"></param>
/// <param name="parameters"></param>
public DumpEnvironment(Options options,
string? outputPath,
Drive? drive,
RedumpSystem? system,
MediaType? type,
InternalProgram? internalProgram,
string? parameters)
InternalProgram? internalProgram)
{
// Set options object
_options = options;
@@ -134,12 +125,7 @@ namespace MPF.Frontend
// UI information
_drive = drive;
_system = system ?? options.DefaultSystem;
_type = type ?? MediaType.NONE;
_internalProgram = internalProgram ?? options.InternalProgram;
// Dumping program
SetExecutionContext(parameters);
SetProcessor();
}
#region Internal Program Management
@@ -147,28 +133,28 @@ namespace MPF.Frontend
/// <summary>
/// Check output path for matching logs from all dumping programs
/// </summary>
public InternalProgram? CheckForMatchingProgram(string? outputDirectory, string outputFilename)
public InternalProgram? CheckForMatchingProgram(MediaType? mediaType, string? outputDirectory, string outputFilename)
{
// If a complete dump exists from a different program
InternalProgram? programFound = null;
if (programFound == null && _internalProgram != InternalProgram.Redumper)
{
var processor = new Processors.Redumper(_system, _type);
var missingFiles = processor.FoundAllFiles(outputDirectory, outputFilename);
var processor = new Processors.Redumper(_system);
var missingFiles = processor.FoundAllFiles(mediaType, outputDirectory, outputFilename);
if (missingFiles.Count == 0)
programFound = InternalProgram.Redumper;
}
if (programFound == null && _internalProgram != InternalProgram.DiscImageCreator)
{
var processor = new Processors.DiscImageCreator(_system, _type);
var missingFiles = processor.FoundAllFiles(outputDirectory, outputFilename);
var processor = new Processors.DiscImageCreator(_system);
var missingFiles = processor.FoundAllFiles(mediaType, outputDirectory, outputFilename);
if (missingFiles.Count == 0)
programFound = InternalProgram.DiscImageCreator;
}
if (programFound == null && _internalProgram != InternalProgram.Aaru)
{
var processor = new Processors.Aaru(_system, _type);
var missingFiles = processor.FoundAllFiles(outputDirectory, outputFilename);
var processor = new Processors.Aaru(_system);
var missingFiles = processor.FoundAllFiles(mediaType, outputDirectory, outputFilename);
if (missingFiles.Count == 0)
programFound = InternalProgram.Aaru;
}
@@ -179,26 +165,26 @@ namespace MPF.Frontend
/// <summary>
/// Check output path for partial logs from all dumping programs
/// </summary>
public InternalProgram? CheckForPartialProgram(string? outputDirectory, string outputFilename)
public InternalProgram? CheckForPartialProgram(MediaType? mediaType, string? outputDirectory, string outputFilename)
{
// If a complete dump exists from a different program
InternalProgram? programFound = null;
if (programFound == null && _internalProgram != InternalProgram.Redumper)
{
var processor = new Processors.Redumper(_system, _type);
if (processor.FoundAnyFiles(outputDirectory, outputFilename))
var processor = new Processors.Redumper(_system);
if (processor.FoundAnyFiles(mediaType, outputDirectory, outputFilename))
programFound = InternalProgram.Redumper;
}
if (programFound == null && _internalProgram != InternalProgram.DiscImageCreator)
{
var processor = new Processors.DiscImageCreator(_system, _type);
if (processor.FoundAnyFiles(outputDirectory, outputFilename))
var processor = new Processors.DiscImageCreator(_system);
if (processor.FoundAnyFiles(mediaType, outputDirectory, outputFilename))
programFound = InternalProgram.DiscImageCreator;
}
if (programFound == null && _internalProgram != InternalProgram.Aaru)
{
var processor = new Processors.Aaru(_system, _type);
if (processor.FoundAnyFiles(outputDirectory, outputFilename))
var processor = new Processors.Aaru(_system);
if (processor.FoundAnyFiles(mediaType, outputDirectory, outputFilename))
programFound = InternalProgram.Aaru;
}
@@ -208,8 +194,9 @@ namespace MPF.Frontend
/// <summary>
/// Set the parameters object based on the internal program and parameters string
/// </summary>
/// <param name="mediaType">MediaType for specialized dumping parameters</param>
/// <param name="parameters">String representation of the parameters</param>
public bool SetExecutionContext(string? parameters)
public bool SetExecutionContext(MediaType? mediaType, string? parameters)
{
_executionContext = _internalProgram switch
{
@@ -226,7 +213,7 @@ namespace MPF.Frontend
if (_executionContext != null)
{
_executionContext.RedumpSystem = _system;
_executionContext.MediaType = _type;
_executionContext.MediaType = mediaType;
// Set some parameters, if not already set
OutputPath ??= _executionContext.OutputPath!;
@@ -243,13 +230,13 @@ namespace MPF.Frontend
{
_processor = _internalProgram switch
{
InternalProgram.Aaru => new Processors.Aaru(_system, _type),
InternalProgram.CleanRip => new CleanRip(_system, _type),
InternalProgram.DiscImageCreator => new DiscImageCreator(_system, _type),
InternalProgram.PS3CFW => new PS3CFW(_system, _type),
InternalProgram.Redumper => new Redumper(_system, _type),
InternalProgram.UmdImageCreator => new UmdImageCreator(_system, _type),
InternalProgram.XboxBackupCreator => new XboxBackupCreator(_system, _type),
InternalProgram.Aaru => new Processors.Aaru(_system),
InternalProgram.CleanRip => new CleanRip(_system),
InternalProgram.DiscImageCreator => new DiscImageCreator(_system),
InternalProgram.PS3CFW => new PS3CFW(_system),
InternalProgram.Redumper => new Redumper(_system),
InternalProgram.UmdImageCreator => new UmdImageCreator(_system),
InternalProgram.XboxBackupCreator => new XboxBackupCreator(_system),
// If no dumping program found, set to null
InternalProgram.NONE => null,
@@ -262,12 +249,13 @@ namespace MPF.Frontend
/// <summary>
/// Get the full parameter string for either DiscImageCreator or Aaru
/// </summary>
/// <param name="mediaType">MediaType for specialized dumping parameters</param>
/// <param name="driveSpeed">Nullable int representing the drive speed</param>
/// <returns>String representing the params, null on error</returns>
public string? GetFullParameters(int? driveSpeed)
public string? GetFullParameters(MediaType? mediaType, int? driveSpeed)
{
// Populate with the correct params for inputs (if we're not on the default option)
if (_system != null && _type != MediaType.NONE)
if (_system != null && mediaType != MediaType.NONE)
{
// If drive letter is invalid, skip this
if (_drive == null)
@@ -276,9 +264,9 @@ namespace MPF.Frontend
// Set the proper parameters
_executionContext = _internalProgram switch
{
InternalProgram.Aaru => new ExecutionContexts.Aaru.ExecutionContext(_system, _type, _drive.Name, OutputPath, driveSpeed, _options.Settings),
InternalProgram.DiscImageCreator => new ExecutionContexts.DiscImageCreator.ExecutionContext(_system, _type, _drive.Name, OutputPath, driveSpeed, _options.Settings),
InternalProgram.Redumper => new ExecutionContexts.Redumper.ExecutionContext(_system, _type, _drive.Name, OutputPath, driveSpeed, _options.Settings),
InternalProgram.Aaru => new ExecutionContexts.Aaru.ExecutionContext(_system, mediaType, _drive.Name, OutputPath, driveSpeed, _options.Settings),
InternalProgram.DiscImageCreator => new ExecutionContexts.DiscImageCreator.ExecutionContext(_system, mediaType, _drive.Name, OutputPath, driveSpeed, _options.Settings),
InternalProgram.Redumper => new ExecutionContexts.Redumper.ExecutionContext(_system, mediaType, _drive.Name, OutputPath, driveSpeed, _options.Settings),
// If no dumping program found, set to null
InternalProgram.NONE => null,
@@ -304,9 +292,9 @@ namespace MPF.Frontend
/// </summary>
/// <param name="type">MediaType value to check</param>
/// <returns>True if the media has variable dumping speeds, false otherwise</returns>
public bool DoesSupportDriveSpeed()
public bool DoesSupportDriveSpeed(MediaType? mediaType)
{
return _type switch
return mediaType switch
{
MediaType.CDROM
or MediaType.DVD
@@ -320,22 +308,22 @@ namespace MPF.Frontend
};
}
/// <inheritdoc cref="BaseProcessor.FoundAllFiles(string?, string)"/>
public bool FoundAllFiles(string? outputDirectory, string outputFilename)
/// <inheritdoc cref="BaseProcessor.FoundAllFiles(MediaType?, string?, string)"/>
public bool FoundAllFiles(MediaType? mediaType, string? outputDirectory, string outputFilename)
{
if (_processor == null)
return false;
return _processor.FoundAllFiles(outputDirectory, outputFilename).Count == 0;
return _processor.FoundAllFiles(mediaType, outputDirectory, outputFilename).Count == 0;
}
/// <inheritdoc cref="BaseProcessor.FoundAnyFiles(string?, string)"/>
public bool FoundAnyFiles(string? outputDirectory, string outputFilename)
/// <inheritdoc cref="BaseProcessor.FoundAnyFiles(MediaType?, string?, string)"/>
public bool FoundAnyFiles(MediaType? mediaType, string? outputDirectory, string outputFilename)
{
if (_processor == null)
return false;
return _processor.FoundAnyFiles(outputDirectory, outputFilename);
return _processor.FoundAnyFiles(mediaType, outputDirectory, outputFilename);
}
/// <inheritdoc cref="BaseExecutionContext.GetDefaultExtension(MediaType?)"/>
@@ -359,14 +347,14 @@ namespace MPF.Frontend
/// <summary>
/// Verify that, given a system and a media type, they are correct
/// </summary>
public ResultEventArgs GetSupportStatus()
public ResultEventArgs GetSupportStatus(MediaType? mediaType)
{
// No system chosen, update status
if (_system == null)
return ResultEventArgs.Failure("Please select a valid system");
// If we're on an unsupported type, update the status accordingly
return _type switch
return mediaType switch
{
// Fully supported types
MediaType.BluRay
@@ -377,22 +365,22 @@ namespace MPF.Frontend
or MediaType.CompactFlash
or MediaType.SDCard
or MediaType.FlashDrive
or MediaType.HDDVD => ResultEventArgs.Success($"{_type.LongName()} ready to dump"),
or MediaType.HDDVD => ResultEventArgs.Success($"{mediaType.LongName()} ready to dump"),
// Partially supported types
MediaType.GDROM
or MediaType.NintendoGameCubeGameDisc
or MediaType.NintendoWiiOpticalDisc
or MediaType.NintendoWiiUOpticalDisc => ResultEventArgs.Success($"{_type.LongName()} partially supported for dumping"),
or MediaType.NintendoWiiUOpticalDisc => ResultEventArgs.Success($"{mediaType.LongName()} partially supported for dumping"),
// Special case for other supported tools
MediaType.UMD => ResultEventArgs.Failure($"{_type.LongName()} supported for submission info parsing"),
MediaType.UMD => ResultEventArgs.Failure($"{mediaType.LongName()} supported for submission info parsing"),
// Specifically unknown type
MediaType.NONE => ResultEventArgs.Failure($"Please select a valid media type"),
// Undumpable but recognized types
_ => ResultEventArgs.Failure($"{_type.LongName()} media are not supported for dumping"),
_ => ResultEventArgs.Failure($"{mediaType.LongName()} media are not supported for dumping"),
};
}
@@ -420,8 +408,9 @@ namespace MPF.Frontend
/// <summary>
/// Execute the initial invocation of the dumping programs
/// </summary>
/// <param name="mediaType">MediaType for specialized dumping parameters</param>
/// <param name="progress">Optional result progress callback</param>
public async Task<ResultEventArgs> Run(IProgress<ResultEventArgs>? progress = null)
public async Task<ResultEventArgs> Run(MediaType? mediaType, IProgress<ResultEventArgs>? progress = null)
{
// If we don't have parameters
if (_executionContext == null)
@@ -436,7 +425,7 @@ namespace MPF.Frontend
}
// Check that we have the basics for dumping
ResultEventArgs result = IsValidForDump();
ResultEventArgs result = IsValidForDump(mediaType);
if (!result)
return result;
@@ -460,12 +449,14 @@ namespace MPF.Frontend
/// <summary>
/// Verify that the current environment has a complete dump and create submission info is possible
/// </summary>
/// <param name="mediaType">Media type for controlling expected file sets, if available</param>
/// <param name="resultProgress">Optional result progress callback</param>
/// <param name="protectionProgress">Optional protection progress callback</param>
/// <param name="processUserInfo">Optional user prompt to deal with submission information</param>
/// <param name="seedInfo">A seed SubmissionInfo object that contains user data</param>
/// <returns>Result instance with the outcome</returns>
public async Task<ResultEventArgs> VerifyAndSaveDumpOutput(
MediaType? mediaType = null,
IProgress<ResultEventArgs>? resultProgress = null,
IProgress<ProtectionProgress>? protectionProgress = null,
ProcessUserInfoDelegate? processUserInfo = null,
@@ -494,8 +485,11 @@ namespace MPF.Frontend
var outputDirectory = Path.GetDirectoryName(OutputPath);
var outputFilename = Path.GetFileName(OutputPath);
// Determine the media type from the processor, if not provided
mediaType ??= _processor.DetermineMediaType(outputDirectory, outputFilename);
// Check to make sure that the output had all the correct files
List<string> missingFiles = _processor.FoundAllFiles(outputDirectory, outputFilename);
List<string> missingFiles = _processor.FoundAllFiles(mediaType, outputDirectory, outputFilename);
if (missingFiles.Count > 0)
{
resultProgress.Report(ResultEventArgs.Failure($"There were files missing from the output:\n{string.Join("\n", [.. missingFiles])}"));
@@ -508,7 +502,7 @@ namespace MPF.Frontend
OutputPath,
_drive,
_system,
_type,
mediaType,
_options,
_processor,
resultProgress,
@@ -526,12 +520,12 @@ namespace MPF.Frontend
// Get user-modifiable information if configured to
if (_options.PromptForDiscInformation && processUserInfo != null)
{
resultProgress.Report(ResultEventArgs.Success("Waiting for additional disc information..."));
resultProgress.Report(ResultEventArgs.Success("Waiting for additional media information..."));
bool? filledInfo = processUserInfo.Invoke(_options, ref submissionInfo);
if (filledInfo == true)
resultProgress.Report(ResultEventArgs.Success("Additional disc information added!"));
resultProgress.Report(ResultEventArgs.Success("Additional media information added!"));
else
resultProgress.Report(ResultEventArgs.Success("Disc information skipped!"));
resultProgress.Report(ResultEventArgs.Success("Media information skipped!"));
}
// Process special fields for site codes
@@ -593,7 +587,7 @@ namespace MPF.Frontend
await Task.Run(() =>
#endif
{
bool compressSuccess = _processor.CompressLogFiles(outputDirectory, outputFilename, filenameSuffix, out string compressResult);
bool compressSuccess = _processor.CompressLogFiles(mediaType, outputDirectory, outputFilename, filenameSuffix, out string compressResult);
if (compressSuccess)
resultProgress.Report(ResultEventArgs.Success(compressResult));
else
@@ -607,7 +601,7 @@ namespace MPF.Frontend
if (_options.DeleteUnnecessaryFiles)
{
resultProgress.Report(ResultEventArgs.Success("Deleting unnecessary files..."));
bool deleteSuccess = _processor.DeleteUnnecessaryFiles(outputDirectory, outputFilename, out string deleteResult);
bool deleteSuccess = _processor.DeleteUnnecessaryFiles(mediaType, outputDirectory, outputFilename, out string deleteResult);
if (deleteSuccess)
resultProgress.Report(ResultEventArgs.Success(deleteResult));
else
@@ -615,10 +609,10 @@ namespace MPF.Frontend
}
// Create PS3 IRD, if required
if (_options.CreateIRDAfterDumping && _system == RedumpSystem.SonyPlayStation3 && _type == MediaType.BluRay)
if (_options.CreateIRDAfterDumping && _system == RedumpSystem.SonyPlayStation3 && mediaType == MediaType.BluRay)
{
resultProgress.Report(ResultEventArgs.Success("Creating IRD... please wait!"));
bool deleteSuccess = await WriteIRD(OutputPath, submissionInfo?.Extras?.DiscKey, submissionInfo?.Extras?.DiscID, submissionInfo?.Extras?.PIC, submissionInfo?.SizeAndChecksums?.Layerbreak, submissionInfo?.SizeAndChecksums?.CRC32);
bool deleteSuccess = await IRDTool.WriteIRD(OutputPath, submissionInfo?.Extras?.DiscKey, submissionInfo?.Extras?.DiscID, submissionInfo?.Extras?.PIC, submissionInfo?.SizeAndChecksums?.Layerbreak, submissionInfo?.SizeAndChecksums?.CRC32);
if (deleteSuccess)
resultProgress.Report(ResultEventArgs.Success("IRD created!"));
else
@@ -633,18 +627,18 @@ namespace MPF.Frontend
/// Checks if the parameters are valid
/// </summary>
/// <returns>True if the configuration is valid, false otherwise</returns>
internal bool ParametersValid()
internal bool ParametersValid(MediaType? mediaType)
{
// Missing drive means it can never be valid
if (_drive == null)
return false;
bool parametersValid = _executionContext?.IsValid() ?? false;
bool floppyValid = !(_drive.InternalDriveType == InternalDriveType.Floppy ^ _type == MediaType.FloppyDisk);
bool floppyValid = !(_drive.InternalDriveType == InternalDriveType.Floppy ^ mediaType == MediaType.FloppyDisk);
// TODO: HardDisk being in the Removable category is a hack, fix this later
bool removableDiskValid = !((_drive.InternalDriveType == InternalDriveType.Removable || _drive.InternalDriveType == InternalDriveType.HardDisk)
^ (_type == MediaType.CompactFlash || _type == MediaType.SDCard || _type == MediaType.FlashDrive || _type == MediaType.HardDisk));
^ (mediaType == MediaType.CompactFlash || mediaType == MediaType.SDCard || mediaType == MediaType.FlashDrive || mediaType == MediaType.HardDisk));
return parametersValid && floppyValid && removableDiskValid;
}
@@ -653,10 +647,10 @@ namespace MPF.Frontend
/// Validate the current environment is ready for a dump
/// </summary>
/// <returns>Result instance with the outcome</returns>
private ResultEventArgs IsValidForDump()
private ResultEventArgs IsValidForDump(MediaType? mediaType)
{
// Validate that everything is good
if (_executionContext == null || !ParametersValid())
if (_executionContext == null || !ParametersValid(mediaType))
return ResultEventArgs.Failure("Error! Current configuration is not supported!");
// Fix the output paths, just in case
@@ -676,7 +670,7 @@ namespace MPF.Frontend
return ResultEventArgs.Failure("Error! Cannot dump same drive that executable resides on!");
// Validate that the current configuration is supported
return GetSupportStatus();
return GetSupportStatus(mediaType);
}
#endregion
@@ -743,43 +737,38 @@ namespace MPF.Frontend
try
{
// Serialize the JSON and get it writable
string json = JsonConvert.SerializeObject(info, Formatting.Indented);
byte[] jsonBytes = Encoding.UTF8.GetBytes(json);
// Get the output path
var path = string.Empty;
if (string.IsNullOrEmpty(outputDirectory) && string.IsNullOrEmpty(filenameSuffix))
path = "!submissionInfo.json";
else if (string.IsNullOrEmpty(outputDirectory) && !string.IsNullOrEmpty(filenameSuffix))
path = $"!submissionInfo_{filenameSuffix}.json";
else if (!string.IsNullOrEmpty(outputDirectory) && string.IsNullOrEmpty(filenameSuffix))
path = Path.Combine(outputDirectory, "!submissionInfo.json");
else if (!string.IsNullOrEmpty(outputDirectory) && !string.IsNullOrEmpty(filenameSuffix))
path = Path.Combine(outputDirectory, $"!submissionInfo_{filenameSuffix}.json");
// Ensure the extension is correct for the output
if (includedArtifacts)
path += ".gz";
// Create and open the output file
using var fs = File.Create(path);
// Create the JSON serializer
var serializer = new JsonSerializer { Formatting = Formatting.Indented };
// If we included artifacts, write to a GZip-compressed file
if (includedArtifacts)
{
var path = string.Empty;
if (string.IsNullOrEmpty(outputDirectory) && string.IsNullOrEmpty(filenameSuffix))
path = "!submissionInfo.json.gz";
else if (string.IsNullOrEmpty(outputDirectory) && !string.IsNullOrEmpty(filenameSuffix))
path = $"!submissionInfo_{filenameSuffix}.json.gz";
else if (!string.IsNullOrEmpty(outputDirectory) && string.IsNullOrEmpty(filenameSuffix))
path = Path.Combine(outputDirectory, "!submissionInfo.json.gz");
else if (!string.IsNullOrEmpty(outputDirectory) && !string.IsNullOrEmpty(filenameSuffix))
path = Path.Combine(outputDirectory, $"!submissionInfo_{filenameSuffix}.json.gz");
using var fs = File.Create(path);
using var gs = new GZipStream(fs, CompressionMode.Compress);
gs.Write(jsonBytes, 0, jsonBytes.Length);
using var sw = new StreamWriter(gs, Encoding.UTF8);
serializer.Serialize(sw, info);
}
// Otherwise, write out to a normal JSON
else
{
var path = string.Empty;
if (string.IsNullOrEmpty(outputDirectory) && string.IsNullOrEmpty(filenameSuffix))
path = "!submissionInfo.json";
else if (string.IsNullOrEmpty(outputDirectory) && !string.IsNullOrEmpty(filenameSuffix))
path = $"!submissionInfo_{filenameSuffix}.json";
else if (!string.IsNullOrEmpty(outputDirectory) && string.IsNullOrEmpty(filenameSuffix))
path = Path.Combine(outputDirectory, "!submissionInfo.json");
else if (!string.IsNullOrEmpty(outputDirectory) && !string.IsNullOrEmpty(filenameSuffix))
path = Path.Combine(outputDirectory, $"!submissionInfo_{filenameSuffix}.json");
using var fs = File.Create(path);
fs.Write(jsonBytes, 0, jsonBytes.Length);
using var sw = new StreamWriter(fs, Encoding.UTF8);
serializer.Serialize(sw, info);
}
}
catch
@@ -847,66 +836,6 @@ namespace MPF.Frontend
return true;
}
/// <summary>
/// Create an IRD and write it to the specified output directory with optional filename suffix
/// </summary>
/// <param name="outputDirectory">Output folder to use as the base path</param>
/// <param name="filenameSuffix">Optional suffix to append to the filename</param>
/// <param name="outputFilename">Output filename to use as the base path</param>
/// <returns>True on success, false on error</returns>
private static async Task<bool> WriteIRD(string isoPath,
string? discKeyString,
string? discIDString,
string? picString,
long? layerbreak,
string? crc32)
{
try
{
// Output IRD file path
string irdPath = Path.ChangeExtension(isoPath, ".ird");
// Parse disc key from submission info (Required)
byte[]? discKey = ProcessingTool.ParseHexKey(discKeyString);
if (discKey == null)
return false;
// Parse Disc ID from submission info (Optional)
byte[]? discID = ProcessingTool.ParseDiscID(discIDString);
// Parse PIC from submission info (Optional)
byte[]? pic = ProcessingTool.ParsePIC(picString);
// Parse CRC32 strings into ISO hash for Unique ID field (Optional)
uint? uid = ProcessingTool.ParseCRC32(crc32);
// Ensure layerbreak value is valid (Optional)
layerbreak = ProcessingTool.ParseLayerbreak(layerbreak);
// Create Redump-style reproducible IRD
#if NET40
LibIRD.ReIRD ird = await Task.Factory.StartNew(() =>
#else
LibIRD.ReIRD ird = await Task.Run(() =>
#endif
new LibIRD.ReIRD(isoPath, discKey, layerbreak, uid));
if (pic != null)
ird.PIC = pic;
if (discID != null && ird.DiscID[15] != 0x00)
ird.DiscID = discID;
// Write IRD to file
ird.Write(irdPath);
return true;
}
catch (Exception)
{
// We don't care what the error is
return false;
}
}
#endregion
}
}

View File

@@ -6,6 +6,7 @@ using System.Collections.Concurrent;
#endif
using System.Reflection;
using SabreTools.RedumpLib.Data;
using RedumperDriveType = MPF.ExecutionContexts.Redumper.DriveType;
using RedumperReadMethod = MPF.ExecutionContexts.Redumper.ReadMethod;
using RedumperSectorOrder = MPF.ExecutionContexts.Redumper.SectorOrder;
@@ -102,7 +103,6 @@ namespace MPF.Frontend
{
RedumperReadMethod.D8 => "D8",
RedumperReadMethod.BE => "BE",
RedumperReadMethod.BE_CDDA => "BE_CDDA",
RedumperReadMethod.NONE => "Default",
_ => "Unknown",
@@ -128,6 +128,28 @@ namespace MPF.Frontend
};
}
/// <summary>
/// Get the string representation of the RedumperDriveType enum values
/// </summary>
/// <param name="order">RedumperDriveType value to convert</param>
/// <returns>String representing the value, if possible</returns>
public static string LongName(this RedumperDriveType? type)
{
return type switch
{
RedumperDriveType.GENERIC => "GENERIC",
RedumperDriveType.PLEXTOR => "PLEXTOR",
RedumperDriveType.LG_ASU8A => "LG_ASU8A",
RedumperDriveType.LG_ASU8B => "LG_ASU8B",
RedumperDriveType.LG_ASU8C => "LG_ASU8C",
RedumperDriveType.LG_ASU3 => "LG_ASU3",
RedumperDriveType.LG_ASU2 => "LG_ASU2",
RedumperDriveType.NONE => "Default",
_ => "Unknown",
};
}
#endregion
#region Convert to Short Name
@@ -221,10 +243,6 @@ namespace MPF.Frontend
{
"d8" => RedumperReadMethod.D8,
"be" => RedumperReadMethod.BE,
"be_cdda"
or "be cdda"
or "be-cdda"
or "becdda" => RedumperReadMethod.BE_CDDA,
_ => RedumperReadMethod.NONE,
};
@@ -260,6 +278,47 @@ namespace MPF.Frontend
};
}
/// <summary>
/// Get the RedumperDriveType enum value for a given string
/// </summary>
/// <param name="order">String value to convert</param>
/// <returns>RedumperDriveType represented by the string, if possible</returns>
public static RedumperDriveType ToRedumperDriveType(this string? type)
{
return (type?.ToLowerInvariant()) switch
{
"generic" => RedumperDriveType.GENERIC,
"plextor" => RedumperDriveType.PLEXTOR,
"lg_asus8a"
or "lg-asus8a"
or "lgasus8a"
or "lg_asus_8a"
or "lg-asus-8a" => RedumperDriveType.LG_ASU8A,
"lg_asus8b"
or "lg-asus8b"
or "lgasus8b"
or "lg_asus_8b"
or "lg-asus-8b" => RedumperDriveType.LG_ASU8B,
"lg_asus8c"
or "lg-asus8c"
or "lgasus8c"
or "lg_asus_8c"
or "lg-asus-8c" => RedumperDriveType.LG_ASU8C,
"lg_asus3"
or "lg-asus3"
or "lgasus3"
or "lg_asus_3"
or "lg-asus-3" => RedumperDriveType.LG_ASU3,
"lg_asus2"
or "lg-asus2"
or "lgasus2"
or "lg_asus_2"
or "lg-asus-2" => RedumperDriveType.LG_ASU2,
_ => RedumperDriveType.NONE,
};
}
#endregion
#region Functionality Support

View File

@@ -11,7 +11,7 @@ namespace MPF.Frontend
/// <summary>
/// Set of all accepted speed values
/// </summary>
private static readonly List<int> _speedValues = [1, 2, 3, 4, 6, 8, 12, 16, 20, 24, 32, 40, 44, 48, 52, 56, 72];
private static readonly List<int> _speedValues = [0, 1, 2, 3, 4, 6, 8, 12, 16, 20, 24, 32, 40, 44, 48, 52, 56, 72];
/// <summary>
/// Set of accepted speeds for CD and GD media
@@ -36,7 +36,7 @@ namespace MPF.Frontend
/// <summary>
/// Set of accepted speeds for all other media
/// </summary>
public static List<int> Unknown => _speedValues.FindAll(s => s <= 1);
public static List<int> Unknown => [1];
/// <summary>
/// Get list of all drive speeds for a given MediaType

View File

@@ -10,7 +10,7 @@
<Nullable>enable</Nullable>
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<VersionPrefix>3.3.0</VersionPrefix>
<VersionPrefix>3.3.3</VersionPrefix>
<!-- Package Properties -->
<Authors>Matt Nadareski;ReignStumble;Jakz</Authors>
@@ -30,20 +30,14 @@
<ProjectReference Include="..\MPF.Processors\MPF.Processors.csproj" />
</ItemGroup>
<!-- Support for old .NET versions -->
<ItemGroup Condition="$(TargetFramework.StartsWith(`net452`))">
<PackageReference Include="Microsoft.Net.Http" Version="2.2.29" />
</ItemGroup>
<ItemGroup Condition="!$(TargetFramework.StartsWith(`net2`)) AND !$(TargetFramework.StartsWith(`net3`)) AND !$(TargetFramework.StartsWith(`net40`)) AND !$(TargetFramework.StartsWith(`net452`))">
<PackageReference Include="Microsoft.Management.Infrastructure" Version="3.0.0" />
<PackageReference Include="System.Net.Http" Version="4.3.4" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="BinaryObjectScanner" Version="3.3.4" />
<PackageReference Include="LibIRD" Version="0.9.3" />
<PackageReference Include="Microsoft.Management.Infrastructure" Version="3.0.0" Condition="!$(TargetFramework.StartsWith(`net2`)) AND !$(TargetFramework.StartsWith(`net3`)) AND !$(TargetFramework.StartsWith(`net40`)) AND !$(TargetFramework.StartsWith(`net452`))" />
<PackageReference Include="Microsoft.Net.Http" Version="2.2.29" Condition="$(TargetFramework.StartsWith(`net452`))" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="SabreTools.RedumpLib" Version="1.6.4" />
<PackageReference Include="SabreTools.RedumpLib" Version="1.6.8" />
<PackageReference Include="System.Net.Http" Version="4.3.4" Condition="!$(TargetFramework.StartsWith(`net2`)) AND !$(TargetFramework.StartsWith(`net3`)) AND !$(TargetFramework.StartsWith(`net40`)) AND !$(TargetFramework.StartsWith(`net452`))" />
</ItemGroup>
</Project>

View File

@@ -2,6 +2,7 @@
using SabreTools.RedumpLib.Data;
using AaruSettings = MPF.ExecutionContexts.Aaru.SettingConstants;
using DICSettings = MPF.ExecutionContexts.DiscImageCreator.SettingConstants;
using RedumperDriveType = MPF.ExecutionContexts.Redumper.DriveType;
using RedumperReadMethod = MPF.ExecutionContexts.Redumper.ReadMethod;
using RedumperSectorOrder = MPF.ExecutionContexts.Redumper.SectorOrder;
using RedumperSettings = MPF.ExecutionContexts.Redumper.SettingConstants;
@@ -86,6 +87,7 @@ namespace MPF.Frontend
/// <summary>
/// Enable purple mode for UI elements
/// </summary>
/// <remarks>This is a hidden setting</remarks>
public bool EnablePurpMode
{
get { return GetBooleanSetting(Settings, "EnablePurpMode", false); }
@@ -95,6 +97,7 @@ namespace MPF.Frontend
/// <summary>
/// Custom color setting
/// </summary>
/// <remarks>This is a hidden setting</remarks>
public string? CustomBackgroundColor
{
get { return GetStringSetting(Settings, "CustomBackgroundColor", null); }
@@ -104,6 +107,7 @@ namespace MPF.Frontend
/// <summary>
/// Custom color setting
/// </summary>
/// <remarks>This is a hidden setting</remarks>
public string? CustomTextColor
{
get { return GetStringSetting(Settings, "CustomTextColor", null); }
@@ -155,7 +159,7 @@ namespace MPF.Frontend
}
/// <summary>
/// Default output path for dumps
/// Show the debug menu item
/// </summary>
/// <remarks>This is a hidden setting</remarks>
public bool ShowDebugViewMenuItem
@@ -330,21 +334,13 @@ namespace MPF.Frontend
#region Redumper
/// <summary>
/// Enable debug output while dumping by default
/// Enable skeleton output while dumping by default
/// </summary>
public bool RedumperEnableDebug
/// <remarks>This is a hidden setting</remarks>
public bool RedumperEnableSkeleton
{
get { return GetBooleanSetting(Settings, RedumperSettings.EnableDebug, RedumperSettings.EnableDebugDefault); }
set { Settings[RedumperSettings.EnableDebug] = value.ToString(); }
}
/// <summary>
/// Enable Redumper custom lead-in retries for Plextor drives
/// </summary>
public bool RedumperEnableLeadinRetry
{
get { return GetBooleanSetting(Settings, RedumperSettings.EnableLeadinRetry, RedumperSettings.EnableLeadinRetryDefault); }
set { Settings[RedumperSettings.EnableLeadinRetry] = value.ToString(); }
get { return GetBooleanSetting(Settings, RedumperSettings.EnableSkeleton, RedumperSettings.EnableSkeletonDefault); }
set { Settings[RedumperSettings.EnableSkeleton] = value.ToString(); }
}
/// <summary>
@@ -375,12 +371,19 @@ namespace MPF.Frontend
}
/// <summary>
/// Enable generic drive type by default with Redumper
/// Currently selected default redumper drive type
/// </summary>
public bool RedumperUseGenericDriveType
public RedumperDriveType RedumperDriveType
{
get { return GetBooleanSetting(Settings, RedumperSettings.UseGenericDriveType, RedumperSettings.UseGenericDriveTypeDefault); }
set { Settings[RedumperSettings.UseGenericDriveType] = value.ToString(); }
get
{
var valueString = GetStringSetting(Settings, RedumperSettings.DriveType, RedumperSettings.DriveTypeDefault);
return valueString.ToRedumperDriveType();
}
set
{
Settings[RedumperSettings.DriveType] = value.ToString();
}
}
/// <summary>
@@ -447,7 +450,7 @@ namespace MPF.Frontend
}
/// <summary>
/// Show the disc information window after dumping
/// Show the media information window after dumping
/// </summary>
public bool PromptForDiscInformation
{
@@ -483,7 +486,7 @@ namespace MPF.Frontend
}
/// <summary>
/// Show disc eject reminder before the disc information window is shown
/// Show disc eject reminder before the media information window is shown
/// </summary>
public bool ShowDiscEjectReminder
{
@@ -633,6 +636,15 @@ namespace MPF.Frontend
#region Redump Login Information
/// <summary>
/// Enable retrieving match information from Redump
/// </summary>
public bool RetrieveMatchInformation
{
get { return GetBooleanSetting(Settings, "RetrieveMatchInformation", true); }
set { Settings["RetrieveMatchInformation"] = value.ToString(); }
}
public string? RedumpUsername
{
get { return GetStringSetting(Settings, "RedumpUsername", ""); }
@@ -642,18 +654,10 @@ namespace MPF.Frontend
// TODO: Figure out a way to keep this encrypted in some way, BASE64 to start?
public string? RedumpPassword
{
get
{
return GetStringSetting(Settings, "RedumpPassword", "");
}
get { return GetStringSetting(Settings, "RedumpPassword", ""); }
set { Settings["RedumpPassword"] = value; }
}
/// <summary>
/// Determine if a complete set of Redump credentials might exist
/// </summary>
public bool HasRedumpLogin { get => !string.IsNullOrEmpty(RedumpUsername) && !string.IsNullOrEmpty(RedumpPassword); }
#endregion
/// <summary>

View File

@@ -2,6 +2,7 @@ using System;
using System.IO;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using SabreTools.RedumpLib.Data;
namespace MPF.Frontend.Tools
@@ -522,7 +523,6 @@ namespace MPF.Frontend.Tools
/// <param name="path">Path value to normalize</param>
public static string NormalizeOutputPaths(string? path, bool getFullPath)
{
// The easy way
try
{
// If we have an invalid path
@@ -536,21 +536,27 @@ namespace MPF.Frontend.Tools
// Remove invalid path characters
foreach (char c in Path.GetInvalidPathChars())
{
path = path.Replace(c, '_');
}
// Try getting the combined path and returning that directly
string fullPath = getFullPath ? Path.GetFullPath(path) : path;
var fullDirectory = Path.GetDirectoryName(fullPath);
string fullFile = Path.GetFileName(fullPath);
var fullDirectory = Path.GetDirectoryName(fullPath)?.Trim();
string fullFile = Path.GetFileName(fullPath).Trim();
// Remove invalid filename characters
foreach (char c in Path.GetInvalidFileNameChars())
{
fullFile = fullFile.Replace(c, '_');
}
if (string.IsNullOrEmpty(fullDirectory))
return fullFile;
else
return Path.Combine(fullDirectory, fullFile);
// Rebuild the path, if necessary
if (!string.IsNullOrEmpty(fullDirectory))
fullFile = Path.Combine(fullDirectory, fullFile);
// Remove spaces before and after separators
return Regex.Replace(fullFile, @"\s*([\\|/])\s*", @"$1");
}
catch { }

View File

@@ -0,0 +1,99 @@
using System;
using System.IO;
using System.Threading.Tasks;
using MPF.Processors;
namespace MPF.Frontend.Tools
{
internal static class IRDTool
{
/// <summary>
/// Create an IRD and write it next to the input ISO path
/// </summary>
/// <param name="isoPath">Path to the original ISO</param>
/// <param name="discKeyString">Required hexadecimal disc key as a string</param>
/// <param name="discIDString">Optional hexadecimal disc ID as a string</param>
/// <param name="picString">Optional string representation of the PIC information</param>
/// <param name="layerbreak">Optional disc layerbreak value</param>
/// <param name="crc32">Optional ISO CRC-32 value for the Unique ID field</param>
/// <returns>True on success, false on error</returns>
public static async Task<bool> WriteIRD(string isoPath,
string? discKeyString,
string? discIDString,
string? picString,
long? layerbreak,
string? crc32)
{
try
{
// Parse string values into required formats
byte[]? discKey = ProcessingTool.ParseHexKey(discKeyString);
byte[]? discID = ProcessingTool.ParseDiscID(discIDString);
byte[]? pic = ProcessingTool.ParsePIC(picString);
uint? uid = ProcessingTool.ParseCRC32(crc32);
return await WriteIRD(isoPath, discKey, discID, pic, layerbreak, uid);
}
catch (Exception)
{
// We don't care what the error is
return false;
}
}
/// <summary>
/// Create an IRD and write it next to the input ISO path
/// </summary>
/// <param name="isoPath">Path to the original ISO</param>
/// <param name="discKey">Required hexadecimal disc key as a byte array</param>
/// <param name="discID">Optional hexadecimal disc ID as a byte array</param>
/// <param name="pic">Optional byte array representation of the PIC information</param>
/// <param name="layerbreak">Optional disc layerbreak value</param>
/// <param name="uid">Optional ISO CRC-32 value for the Unique ID field</param>
/// <returns>True on success, false on error</returns>
public static async Task<bool> WriteIRD(string isoPath,
byte[]? discKey,
byte[]? discID,
byte[]? pic,
long? layerbreak,
uint? uid)
{
try
{
// Fail on a missing disc key
if (discKey == null)
return false;
// Output IRD file path
string irdPath = Path.ChangeExtension(isoPath, ".ird");
// Ensure layerbreak value is valid
layerbreak = ProcessingTool.ParseLayerbreak(layerbreak);
// Create Redump-style reproducible IRD
#if NET40
LibIRD.ReIRD ird = await Task.Factory.StartNew(() =>
#else
LibIRD.ReIRD ird = await Task.Run(() =>
#endif
new LibIRD.ReIRD(isoPath, discKey, layerbreak, uid));
// Set optional fields if valid
if (pic != null)
ird.PIC = pic;
if (discID != null && ird.DiscID[15] != 0x00)
ird.DiscID = discID;
// Write IRD to file
ird.Write(irdPath);
return true;
}
catch (Exception)
{
// We don't care what the error is
return false;
}
}
}
}

View File

@@ -39,9 +39,15 @@ namespace MPF.Frontend.Tools
public static bool? ProcessStandaloneArguments(string[] args)
{
// Help options
if (args.Length == 0 || args[0] == "-h" || args[0] == "-?")
if (args.Length == 0 || args[0] == "-h" || args[0] == "-?" || args[0] == "--help")
return null;
if (args[0] == "--version")
{
Console.WriteLine(FrontendTool.GetCurrentVersion() ?? "Unknown version");
return true;
}
// List options
if (args[0] == "-lc" || args[0] == "--listcodes")
{
@@ -87,6 +93,32 @@ namespace MPF.Frontend.Tools
return false;
}
/// <summary>
/// Process common arguments for all functionality
/// </summary>
/// <returns>True if all arguments pass, false otherwise</returns>
public static bool ProcessCommonArguments(string[] args, out RedumpSystem? system, out string? message)
{
// All other use requires at least 3 arguments
if (args.Length < 2)
{
system = null;
message = "Invalid number of arguments";
return false;
}
// Check the RedumpSystem
system = Extensions.ToRedumpSystem(args[0].Trim('"'));
if (system == null)
{
message = $"{args[0]} is not a recognized system";
return false;
}
message = null;
return true;
}
/// <summary>
/// Process common arguments for all functionality
/// </summary>
@@ -123,32 +155,14 @@ namespace MPF.Frontend.Tools
return true;
}
/// <summary>
/// List all programs with their short usable names
/// </summary>
private static List<string> ListPrograms()
{
var programs = new List<string>();
foreach (var val in Enum.GetValues(typeof(InternalProgram)))
{
if (((InternalProgram)val!) == InternalProgram.NONE)
continue;
programs.Add($"{((InternalProgram?)val).ShortName()} - {((InternalProgram?)val).LongName()}");
}
return programs;
}
/// <summary>
/// Get the MediaType enum value for a given string
/// </summary>
/// <param name="type">String value to convert</param>
/// <returns>MediaType represented by the string, if possible</returns>
private static MediaType ToMediaType(string type)
public static MediaType ToMediaType(string? type)
{
return (type.ToLowerInvariant()) switch
return (type?.ToLowerInvariant()) switch
{
#region Punched Media
@@ -284,6 +298,24 @@ namespace MPF.Frontend.Tools
};
}
/// <summary>
/// List all programs with their short usable names
/// </summary>
private static List<string> ListPrograms()
{
var programs = new List<string>();
foreach (var val in Enum.GetValues(typeof(InternalProgram)))
{
if (((InternalProgram)val!) == InternalProgram.NONE)
continue;
programs.Add($"{((InternalProgram?)val).ShortName()} - {((InternalProgram?)val).LongName()}");
}
return programs;
}
#endregion
#region Configuration
@@ -315,29 +347,26 @@ namespace MPF.Frontend.Tools
/// <summary>
/// Save the current set of options to the application configuration
/// </summary>
public static void SaveToConfig(Options options, bool saveDefault = false)
public static void SaveToConfig(Options options)
{
// If no options path can be found
if (string.IsNullOrEmpty(ConfigurationPath))
return;
// If default values should be saved as well
if (saveDefault)
// Ensure default values are included
PropertyInfo[] properties = typeof(Options).GetProperties();
foreach (var property in properties)
{
PropertyInfo[] properties = typeof(Options).GetProperties();
foreach (var property in properties)
{
// Skip dictionary properties
if (property.Name == "Item")
continue;
// Skip dictionary properties
if (property.Name == "Item")
continue;
// Skip non-option properties
if (property.Name == "Settings" || property.Name == "HasRedumpLogin")
continue;
// Skip non-option properties
if (property.Name == "Settings" || property.Name == "HasRedumpLogin")
continue;
var val = property.GetValue(options, null);
property.SetValue(options, val, null);
}
var val = property.GetValue(options, null);
property.SetValue(options, val, null);
}
// Handle a very strange edge case
@@ -368,7 +397,7 @@ namespace MPF.Frontend.Tools
// Local folder
#if NET20 || NET35 || NET40 || NET452
string runtimeDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
string runtimeDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
#else
string runtimeDir = AppContext.BaseDirectory;
#endif

View File

@@ -549,7 +549,7 @@ namespace MPF.Frontend.Tools
var appPkgHeader = appPkgHeaderDeserializer.Deserialize(fileStream);
if (appPkgHeader != null)
pkgInfo += $"{appPkgHeader.ContentID}";
pkgInfo += $"{appPkgHeader.ContentID}" + Environment.NewLine;
}
if (pkgInfo == "")
@@ -700,7 +700,7 @@ namespace MPF.Frontend.Tools
var appPkgHeader = appPkgHeaderDeserializer.Deserialize(fileStream);
if (appPkgHeader != null)
pkgInfo += $"{appPkgHeader.ContentID}";
pkgInfo += $"{appPkgHeader.ContentID}" + Environment.NewLine;
}
if (pkgInfo == "")

View File

@@ -60,7 +60,7 @@ namespace MPF.Frontend.Tools
string outputFilename = Path.GetFileName(outputPath);
// Check that all of the relevant files are there
List<string> missingFiles = processor.FoundAllFiles(outputDirectory, outputFilename);
List<string> missingFiles = processor.FoundAllFiles(mediaType, outputDirectory, outputFilename);
if (missingFiles.Count > 0)
{
resultProgress?.Report(ResultEventArgs.Failure($"There were files missing from the output:\n{string.Join("\n", [.. missingFiles])}"));
@@ -77,12 +77,15 @@ namespace MPF.Frontend.Tools
SubmissionInfo info = CreateDefaultSubmissionInfo(processor, system, mediaType, options.AddPlaceholders);
// Get specific tool output handling
processor?.GenerateSubmissionInfo(info, basePath, options.EnableRedumpCompatibility);
processor?.GenerateSubmissionInfo(info, mediaType, basePath, options.EnableRedumpCompatibility);
if (options.IncludeArtifacts)
info.Artifacts = processor?.GenerateArtifacts(outputDirectory, outputFilename);
info.Artifacts = processor?.GenerateArtifacts(mediaType, outputDirectory, outputFilename);
// Add a placeholder for the logs link
info.CommonDiscInfo!.CommentsSpecialFields![SiteCode.LogsLink] = "[Please provide a link to your logs here]";
// Get a list of matching IDs for each line in the DAT
if (!string.IsNullOrEmpty(info.TracksAndWriteOffsets!.ClrMameProData) && options.HasRedumpLogin)
if (!string.IsNullOrEmpty(info.TracksAndWriteOffsets!.ClrMameProData))
_ = await FillFromRedump(options, info, resultProgress);
// If we have both ClrMamePro and Size and Checksums data, remove the ClrMamePro
@@ -157,27 +160,29 @@ namespace MPF.Frontend.Tools
SubmissionInfo info,
IProgress<ResultEventArgs>? resultProgress = null)
{
// If no username is provided
if (string.IsNullOrEmpty(options.RedumpUsername) || string.IsNullOrEmpty(options.RedumpPassword))
// If information should not be pulled at all
if (!options.RetrieveMatchInformation)
return false;
// Set the current dumper based on username
info.DumpersAndStatus ??= new DumpersAndStatusSection();
info.DumpersAndStatus.Dumpers = [options.RedumpUsername!];
info.DumpersAndStatus.Dumpers = [options.RedumpUsername ?? "Anonymous User"];
info.PartiallyMatchedIDs = [];
// Login to Redump
// Login to Redump, if possible
var wc = new RedumpClient();
bool? loggedIn = await wc.Login(options.RedumpUsername ?? string.Empty, options.RedumpPassword ?? string.Empty);
if (loggedIn == null)
if (options.RedumpUsername != null && options.RedumpPassword != null)
{
resultProgress?.Report(ResultEventArgs.Failure("There was an unknown error connecting to Redump"));
return false;
}
else if (loggedIn == false)
{
// Don't log the as a failure or error
return false;
bool? loggedIn = await wc.Login(options.RedumpUsername, options.RedumpPassword);
if (loggedIn == null)
{
resultProgress?.Report(ResultEventArgs.Failure("There was an unknown error connecting to Redump, skipping..."));
return false;
}
else if (loggedIn == false)
{
resultProgress?.Report(ResultEventArgs.Failure("Provided Redump credentials were invalid, not using..."));
}
}
// Setup the checks
@@ -199,14 +204,34 @@ namespace MPF.Frontend.Tools
}
// If the line ends in a known extra track names, skip them for checking
if (hashData.Contains("(Track 0).bin")
// TODO: Smarter method to ignore all tracks that start with 0. 00. A. or AA.
if (hashData.Contains(".dmi")
|| hashData.Contains(".pfi")
|| hashData.Contains(".ss")
|| hashData.Contains("(Track 0).bin")
|| hashData.Contains("(Track 0.1).bin")
|| hashData.Contains("(Track 0.2).bin")
|| hashData.Contains("(Track 0.3).bin")
|| hashData.Contains("(Track 0.4).bin")
|| hashData.Contains("(Track 0.5).bin")
|| hashData.Contains("(Track 00).bin")
|| hashData.Contains("(Track 00.1).bin")
|| hashData.Contains("(Track 00.2).bin")
|| hashData.Contains("(Track 00.3).bin")
|| hashData.Contains("(Track 00.4).bin")
|| hashData.Contains("(Track 00.5).bin")
|| hashData.Contains("(Track A).bin")
|| hashData.Contains("(Track A.1).bin")
|| hashData.Contains("(Track A.2).bin")
|| hashData.Contains("(Track A.3).bin")
|| hashData.Contains("(Track A.4).bin")
|| hashData.Contains("(Track A.5).bin")
|| hashData.Contains("(Track AA).bin")
|| hashData.Contains("(Track AA.2).bin"))
|| hashData.Contains("(Track AA.1).bin")
|| hashData.Contains("(Track AA.2).bin")
|| hashData.Contains("(Track AA.3).bin")
|| hashData.Contains("(Track AA.4).bin")
|| hashData.Contains("(Track AA.5).bin"))
{
trackCount--;
resultProgress?.Report(ResultEventArgs.Success("Extra track found, skipping!"));
@@ -434,6 +459,11 @@ namespace MPF.Frontend.Tools
if (driveLabel != null && driveLabel.Length == 0)
driveLabel = null;
// Treat "path" labels as null -- Indicates a mounted path
// This can over-match if a label contains a directory separator somehow
if (driveLabel != null && (driveLabel.Contains("/") || driveLabel.Contains("\\")))
driveLabel = null;
// Must have at least one label to format
if (driveLabel == null && (labels == null || labels.Count == 0))
return null;

View File

@@ -1,7 +1,9 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Threading.Tasks;
using BinaryObjectScanner;
using MPF.Frontend.ComboBoxItems;
using MPF.Frontend.Tools;
using SabreTools.RedumpLib.Data;
@@ -162,6 +164,39 @@ namespace MPF.Frontend.ViewModels
}
private bool _dumpingProgramComboBoxEnabled;
/// <summary>
/// Currently displayed status
/// </summary>
public string Status
{
get => _status;
set
{
_status = value;
TriggerPropertyChanged(nameof(Status));
TriggerPropertyChanged(nameof(StatusFirstLine));
}
}
private string _status;
/// <summary>
/// Currently displayed status trimmed to one line
/// </summary>
public string StatusFirstLine
{
get
{
if (string.IsNullOrEmpty(Status))
return string.Empty;
var statusLines = Status.Split('\n');
if (statusLines.Length > 1)
return statusLines[0] + " (...)";
return statusLines[0];
}
}
/// <summary>
/// Indicates the status of the check dump button
/// </summary>
@@ -247,6 +282,7 @@ namespace MPF.Frontend.ViewModels
_internalPrograms = [];
_inputPath = string.Empty;
_systems = [];
_status = string.Empty;
SystemTypeComboBoxEnabled = true;
InputPathTextBoxEnabled = true;
@@ -455,17 +491,26 @@ namespace MPF.Frontend.ViewModels
bool cachedCanExecuteSelectionChanged = CanExecuteSelectionChanged;
DisableEventHandlers();
// Get progress indicators
var resultProgress = new Progress<ResultEventArgs>();
resultProgress.ProgressChanged += ProgressUpdated;
var protectionProgress = new Progress<ProtectionProgress>();
protectionProgress.ProgressChanged += ProgressUpdated;
// Populate an environment
var env = new DumpEnvironment(Options,
Path.GetFullPath(InputPath.Trim('"')),
null,
CurrentSystem,
CurrentMediaType,
CurrentProgram,
parameters: null);
CurrentProgram);
env.SetProcessor();
// Finally, attempt to do the output dance
var result = await env.VerifyAndSaveDumpOutput(processUserInfo: processUserInfo);
var result = await env.VerifyAndSaveDumpOutput(
mediaType: CurrentMediaType,
resultProgress: resultProgress,
protectionProgress: protectionProgress,
processUserInfo: processUserInfo);
// Reenable UI and event handlers, if necessary
EnableUIElements();
@@ -475,6 +520,23 @@ namespace MPF.Frontend.ViewModels
return result.Message;
}
/// <summary>
/// Handler for Result ProgressChanged event
/// </summary>
private void ProgressUpdated(object? sender, ResultEventArgs value)
{
Status = value?.Message ?? string.Empty;
}
/// <summary>
/// Handler for ProtectionProgress ProgressChanged event
/// </summary>
private void ProgressUpdated(object? sender, ProtectionProgress value)
{
string message = $"{value.Percentage * 100:N2}%: {value.Filename} - {value.Protection}";
Status = message;
}
#endregion
}
}

View File

@@ -74,6 +74,20 @@ namespace MPF.Frontend.ViewModels
#region Properties
/// <summary>
/// Indicates the status of the check dump menu item
/// </summary>
public bool AskBeforeQuit
{
get => _askBeforeQuit;
set
{
_askBeforeQuit = value;
TriggerPropertyChanged(nameof(AskBeforeQuit));
}
}
private bool _askBeforeQuit;
/// <summary>
/// Indicates the status of the check dump menu item
/// </summary>
@@ -554,6 +568,7 @@ namespace MPF.Frontend.ViewModels
_status = string.Empty;
_systems = [];
AskBeforeQuit = false;
OptionsMenuItemEnabled = true;
CheckDumpMenuItemEnabled = true;
CreateIRDMenuItemEnabled = true;
@@ -755,11 +770,11 @@ namespace MPF.Frontend.ViewModels
public void ChangeDumpingProgram()
{
VerboseLogLn($"Changed dumping program to: {((InternalProgram?)CurrentProgram).LongName()}");
EnsureDiscInformation();
EnsureMediaInformation();
// New output name depends on new environment
GetOutputNames(false);
// New environment depends on new output name
EnsureDiscInformation();
EnsureMediaInformation();
}
/// <summary>
@@ -772,7 +787,7 @@ namespace MPF.Frontend.ViewModels
SetSupportedDriveSpeed();
GetOutputNames(false);
EnsureDiscInformation();
EnsureMediaInformation();
}
/// <summary>
@@ -783,7 +798,7 @@ namespace MPF.Frontend.ViewModels
VerboseLogLn($"Changed system to: {CurrentSystem.LongName()}");
PopulateMediaType();
GetOutputNames(false);
EnsureDiscInformation();
EnsureMediaInformation();
}
/// <summary>
@@ -1048,7 +1063,7 @@ namespace MPF.Frontend.ViewModels
SetSupportedDriveSpeed();
_environment = DetermineEnvironment();
GetOutputNames(true);
EnsureDiscInformation();
EnsureMediaInformation();
// Enable event handlers
EnableEventHandlers();
@@ -1085,7 +1100,7 @@ namespace MPF.Frontend.ViewModels
// Set the initial environment and UI values
_environment = DetermineEnvironment();
GetOutputNames(true);
EnsureDiscInformation();
EnsureMediaInformation();
// Enable event handlers
EnableEventHandlers();
@@ -1238,14 +1253,15 @@ namespace MPF.Frontend.ViewModels
/// <returns>Filled DumpEnvironment Parent</returns>
private DumpEnvironment DetermineEnvironment()
{
return new DumpEnvironment(
var env = new DumpEnvironment(
Options,
EvaluateOutputPath(OutputPath),
CurrentDrive,
CurrentSystem,
CurrentMediaType,
CurrentProgram,
Parameters);
CurrentProgram);
env.SetExecutionContext(CurrentMediaType, Parameters);
env.SetProcessor();
return env;
}
/// <summary>
@@ -1346,15 +1362,15 @@ namespace MPF.Frontend.ViewModels
}
/// <summary>
/// Ensure information is consistent with the currently selected disc type
/// Ensure information is consistent with the currently selected media type
/// </summary>
public void EnsureDiscInformation()
public void EnsureMediaInformation()
{
// Get the current environment information
_environment = DetermineEnvironment();
// Get the status to write out
ResultEventArgs result = _environment.GetSupportStatus();
ResultEventArgs result = _environment.GetSupportStatus(CurrentMediaType);
if (CurrentProgram == InternalProgram.NONE)
Status = "No dumping program found";
else
@@ -1364,12 +1380,12 @@ namespace MPF.Frontend.ViewModels
StartStopButtonEnabled = result && ShouldEnableDumpingButton();
// If we're in a type that doesn't support drive speeds
DriveSpeedComboBoxEnabled = _environment.DoesSupportDriveSpeed();
DriveSpeedComboBoxEnabled = _environment.DoesSupportDriveSpeed(CurrentMediaType);
// If input params are enabled, generate the full parameters from the environment
if (ParametersCheckBoxEnabled)
{
var generated = _environment.GetFullParameters(DriveSpeed);
var generated = _environment.GetFullParameters(CurrentMediaType, DriveSpeed);
if (generated != null)
Parameters = generated;
}
@@ -1867,7 +1883,7 @@ namespace MPF.Frontend.ViewModels
public void ProcessCustomParameters()
{
// Set the execution context and processor
if (_environment?.SetExecutionContext(Parameters) != true)
if (_environment?.SetExecutionContext(CurrentMediaType, Parameters) != true)
return;
if (_environment?.SetProcessor() != true)
return;
@@ -1992,32 +2008,51 @@ namespace MPF.Frontend.ViewModels
/// </summary>
private static string? GetFormattedVolumeLabel(Drive? drive)
{
// If the drive is invalid
if (drive == null)
return null;
string? volumeLabel = DiscNotDetectedValue;
// If the drive is marked as inactive
if (!drive.MarkedActive)
return volumeLabel;
return DiscNotDetectedValue;
if (!string.IsNullOrEmpty(drive.VolumeLabel))
// Use internal serials where appropriate
string? volumeLabel = string.IsNullOrEmpty(drive.VolumeLabel) ? null : drive.VolumeLabel;
switch (GetRedumpSystem(drive))
{
volumeLabel = drive.VolumeLabel;
}
else
{
// No Volume Label found, fallback to something sensible
switch (GetRedumpSystem(drive))
{
case RedumpSystem.SonyPlayStation:
case RedumpSystem.SonyPlayStation2:
string? serial = PhysicalTool.GetPlayStationSerial(drive);
volumeLabel = serial ?? "track";
break;
case RedumpSystem.SonyPlayStation:
case RedumpSystem.SonyPlayStation2:
string? ps12Serial = PhysicalTool.GetPlayStationSerial(drive);
volumeLabel ??= ps12Serial ?? "track";
break;
default:
volumeLabel = "track";
break;
}
case RedumpSystem.SonyPlayStation3:
string? ps3Serial = PhysicalTool.GetPlayStation3Serial(drive);
if (volumeLabel == "PS3VOLUME")
volumeLabel = ps3Serial ?? volumeLabel;
else
volumeLabel ??= ps3Serial ?? "track";
break;
case RedumpSystem.SonyPlayStation4:
string? ps4Serial = PhysicalTool.GetPlayStation4Serial(drive);
if (volumeLabel == "PS4VOLUME")
volumeLabel = ps4Serial ?? volumeLabel;
else
volumeLabel ??= ps4Serial ?? "track";
break;
case RedumpSystem.SonyPlayStation5:
string? ps5Serial = PhysicalTool.GetPlayStation5Serial(drive);
if (volumeLabel == "PS5VOLUME")
volumeLabel = ps5Serial ?? volumeLabel;
else
volumeLabel ??= ps5Serial ?? "track";
break;
default:
volumeLabel ??= "track";
break;
}
foreach (char c in Path.GetInvalidFileNameChars())
@@ -2146,6 +2181,9 @@ namespace MPF.Frontend.ViewModels
/// </summary>
public async void StartDumping()
{
// Ask user to confirm before exiting application during a dump
AskBeforeQuit = true;
// One last check to determine environment, just in case
_environment = DetermineEnvironment();
@@ -2155,24 +2193,29 @@ namespace MPF.Frontend.ViewModels
// If still in custom parameter mode, check that users meant to continue or not
if (ParametersCheckBoxEnabled == false && _displayUserMessage != null)
{
bool? result = _displayUserMessage("Custom Changes", "It looks like you have custom parameters that have not been saved. Would you like to apply those changes before starting to dump?", 3, true);
bool? result = _displayUserMessage("Custom Changes", "It looks like you have custom parameters that have not been saved. Would you like to dump with these custom parameters?", 2, true);
if (result == true)
{
ParametersCheckBoxEnabled = true;
ProcessCustomParameters();
}
else if (result == null)
else
{
// Re-allow quick exiting
AskBeforeQuit = false;
return;
}
// If false, then we continue with the current known environment
}
try
{
// Run pre-dumping validation checks
if (!ValidateBeforeDumping())
{
// Re-allow quick exiting
AskBeforeQuit = false;
return;
}
// Disable all UI elements apart from dumping button
DisableAllUIElements();
@@ -2193,7 +2236,7 @@ namespace MPF.Frontend.ViewModels
_environment.ReportStatus += ProgressUpdated;
// Run the program with the parameters
ResultEventArgs result = await _environment.Run(resultProgress);
ResultEventArgs result = await _environment.Run(CurrentMediaType, resultProgress);
// If we didn't execute a dumping command we cannot get submission output
if (!_environment.IsDumpingCommand())
@@ -2201,6 +2244,9 @@ namespace MPF.Frontend.ViewModels
LogLn("No dumping command was run, submission information will not be gathered.");
Status = "Execution complete!";
// Re-allow quick exiting
AskBeforeQuit = false;
// Reset all UI elements
EnableAllUIElements();
return;
@@ -2210,9 +2256,10 @@ namespace MPF.Frontend.ViewModels
if (result)
{
result = await _environment.VerifyAndSaveDumpOutput(
resultProgress,
protectionProgress,
_processUserInfo);
mediaType: CurrentMediaType,
resultProgress: resultProgress,
protectionProgress: protectionProgress,
processUserInfo: _processUserInfo);
}
else
{
@@ -2227,6 +2274,9 @@ namespace MPF.Frontend.ViewModels
}
finally
{
// Re-allow quick exiting
AskBeforeQuit = false;
// Reset all UI elements
EnableAllUIElements();
}
@@ -2315,7 +2365,7 @@ namespace MPF.Frontend.ViewModels
string outputFilename = Path.GetFileName(_environment.OutputPath);
// If a complete or partial dump already exists
bool foundAllFiles = _environment.FoundAllFiles(outputDirectory, outputFilename);
bool foundAllFiles = _environment.FoundAllFiles(CurrentMediaType, outputDirectory, outputFilename);
if (foundAllFiles && _displayUserMessage != null)
{
bool? mbresult = _displayUserMessage("Overwrite?", "A complete dump already exists! Are you sure you want to overwrite?", 2, true);
@@ -2328,7 +2378,7 @@ namespace MPF.Frontend.ViewModels
else
{
// If a partial dump exists
bool foundAnyFiles = _environment.FoundAnyFiles(outputDirectory, outputFilename);
bool foundAnyFiles = _environment.FoundAnyFiles(CurrentMediaType, outputDirectory, outputFilename);
if (foundAnyFiles && _displayUserMessage != null)
{
bool? mbresult = _displayUserMessage("Overwrite?", $"A partial dump already exists! Dumping here may cause issues. Are you sure you want to overwrite?", 2, true);
@@ -2341,7 +2391,7 @@ namespace MPF.Frontend.ViewModels
else
{
// If a complete dump exists from a different program
InternalProgram? completeProgramFound = _environment.CheckForMatchingProgram(outputDirectory, outputFilename);
InternalProgram? completeProgramFound = _environment.CheckForMatchingProgram(CurrentMediaType, outputDirectory, outputFilename);
if (completeProgramFound != null && _displayUserMessage != null)
{
bool? mbresult = _displayUserMessage("Overwrite?", $"A complete dump from {completeProgramFound} already exists! Dumping here may cause issues. Are you sure you want to overwrite?", 2, true);
@@ -2354,7 +2404,7 @@ namespace MPF.Frontend.ViewModels
else
{
// If a partial dump exists from a different program
InternalProgram? partialProgramFound = _environment.CheckForPartialProgram(outputDirectory, outputFilename);
InternalProgram? partialProgramFound = _environment.CheckForPartialProgram(CurrentMediaType, outputDirectory, outputFilename);
if (partialProgramFound != null && _displayUserMessage != null)
{
bool? mbresult = _displayUserMessage("Overwrite?", $"A partial dump from {partialProgramFound} already exists! Dumping here may cause issues. Are you sure you want to overwrite?", 2, true);

View File

@@ -6,7 +6,7 @@ using SabreTools.RedumpLib.Data;
namespace MPF.Frontend.ViewModels
{
public class DiscInformationViewModel
public class MediaInformationViewModel
{
#region Fields
@@ -194,7 +194,7 @@ namespace MPF.Frontend.ViewModels
/// <summary>
/// Constructor
/// </summary>
public DiscInformationViewModel(Options options, SubmissionInfo? submissionInfo)
public MediaInformationViewModel(Options options, SubmissionInfo? submissionInfo)
{
Options = options;
SubmissionInfo = submissionInfo?.Clone() as SubmissionInfo ?? new SubmissionInfo();

View File

@@ -1,6 +1,7 @@
using System.Collections.Generic;
using System.ComponentModel;
using MPF.Frontend.ComboBoxItems;
using RedumperDriveType = MPF.ExecutionContexts.Redumper.DriveType;
using RedumperReadMethod = MPF.ExecutionContexts.Redumper.ReadMethod;
using RedumperSectorOrder = MPF.ExecutionContexts.Redumper.SectorOrder;
@@ -59,6 +60,11 @@ namespace MPF.Frontend.ViewModels
/// </summary>
public static List<Element<RedumperSectorOrder>> RedumperSectorOrders => PopulateRedumperSectorOrders();
/// <summary>
/// Current list of supported Redumper drive types
/// </summary>
public static List<Element<RedumperDriveType>> RedumperDriveTypes => PopulateRedumperDriveTypes();
/// <summary>
/// Current list of supported system profiles
/// </summary>
@@ -98,7 +104,7 @@ namespace MPF.Frontend.ViewModels
/// </summary>
private static List<Element<RedumperReadMethod>> PopulateRedumperReadMethods()
{
var readMethods = new List<RedumperReadMethod> { RedumperReadMethod.NONE, RedumperReadMethod.D8, RedumperReadMethod.BE, RedumperReadMethod.BE_CDDA };
var readMethods = new List<RedumperReadMethod> { RedumperReadMethod.NONE, RedumperReadMethod.D8, RedumperReadMethod.BE };
return readMethods.ConvertAll(rm => new Element<RedumperReadMethod>(rm));
}
@@ -111,6 +117,15 @@ namespace MPF.Frontend.ViewModels
return sectorOrders.ConvertAll(so => new Element<RedumperSectorOrder>(so));
}
/// <summary>
/// Get a complete list of supported redumper drive types
/// </summary>
private static List<Element<RedumperDriveType>> PopulateRedumperDriveTypes()
{
var driveTypes = new List<RedumperDriveType> { RedumperDriveType.NONE, RedumperDriveType.GENERIC, RedumperDriveType.PLEXTOR, RedumperDriveType.LG_ASU8A, RedumperDriveType.LG_ASU8B, RedumperDriveType.LG_ASU8C, RedumperDriveType.LG_ASU3, RedumperDriveType.LG_ASU2 };
return driveTypes.ConvertAll(dt => new Element<RedumperDriveType>(dt));
}
#endregion
#region UI Commands
@@ -135,7 +150,7 @@ namespace MPF.Frontend.ViewModels
{
Options.RedumperReadMethod = RedumperReadMethod.NONE;
Options.RedumperSectorOrder = RedumperSectorOrder.NONE;
Options.RedumperUseGenericDriveType = false;
Options.RedumperDriveType = RedumperDriveType.NONE;
TriggerPropertyChanged(nameof(Options));
}

View File

@@ -11,6 +11,41 @@ namespace MPF.Processors.Test
// TODO: Add tests around remaining helper methods
public class AaruTests
{
// TODO: Create minimal sidecars for all other supported types
#region DetermineMediaType
[Fact]
public void DetermineMediaType_Empty_Null()
{
string? outputDirectory = null;
string outputFilename = string.Empty;
var processor = new Aaru(RedumpSystem.IBMPCcompatible);
var actual = processor.DetermineMediaType(outputDirectory, outputFilename);
Assert.Null(actual);
}
[Fact]
public void DetermineMediaType_Invalid_Null()
{
string? outputDirectory = null;
string outputFilename = "INVALID";
var processor = new Aaru(RedumpSystem.IBMPCcompatible);
var actual = processor.DetermineMediaType(outputDirectory, outputFilename);
Assert.Null(actual);
}
[Fact]
public void DetermineMediaType_CD_Valid_CD()
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "Aaru", "CDROM");
string outputFilename = "test";
var processor = new Aaru(RedumpSystem.IBMPCcompatible);
var actual = processor.DetermineMediaType(outputDirectory, outputFilename);
Assert.Equal(MediaType.CDROM, actual);
}
#endregion
#region GetOutputFiles
[Fact]
@@ -18,9 +53,9 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = "test";
var processor = new Aaru(RedumpSystem.IBMPCcompatible, null);
var processor = new Aaru(RedumpSystem.IBMPCcompatible);
var actual = processor.GetOutputFiles(outputDirectory, outputFilename);
var actual = processor.GetOutputFiles(null, outputDirectory, outputFilename);
Assert.Empty(actual);
}
@@ -29,9 +64,9 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = "test";
var processor = new Aaru(RedumpSystem.IBMPCcompatible, MediaType.CDROM);
var processor = new Aaru(RedumpSystem.IBMPCcompatible);
var actual = processor.GetOutputFiles(outputDirectory, outputFilename);
var actual = processor.GetOutputFiles(MediaType.CDROM, outputDirectory, outputFilename);
Assert.Equal(8, actual.Count);
}
@@ -40,9 +75,9 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = "test";
var processor = new Aaru(RedumpSystem.IBMPCcompatible, MediaType.DVD);
var processor = new Aaru(RedumpSystem.IBMPCcompatible);
var actual = processor.GetOutputFiles(outputDirectory, outputFilename);
var actual = processor.GetOutputFiles(MediaType.DVD, outputDirectory, outputFilename);
Assert.Equal(7, actual.Count);
}
@@ -51,9 +86,9 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = "test";
var processor = new Aaru(RedumpSystem.IBMPCcompatible, MediaType.HDDVD);
var processor = new Aaru(RedumpSystem.IBMPCcompatible);
var actual = processor.GetOutputFiles(outputDirectory, outputFilename);
var actual = processor.GetOutputFiles(MediaType.HDDVD, outputDirectory, outputFilename);
Assert.Equal(7, actual.Count);
}
@@ -62,9 +97,9 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = "test";
var processor = new Aaru(RedumpSystem.IBMPCcompatible, MediaType.BluRay);
var processor = new Aaru(RedumpSystem.IBMPCcompatible);
var actual = processor.GetOutputFiles(outputDirectory, outputFilename);
var actual = processor.GetOutputFiles(MediaType.BluRay, outputDirectory, outputFilename);
Assert.Equal(7, actual.Count);
}
@@ -73,9 +108,9 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = "test";
var processor = new Aaru(RedumpSystem.IBMPCcompatible, MediaType.ApertureCard);
var processor = new Aaru(RedumpSystem.IBMPCcompatible);
var actual = processor.GetOutputFiles(outputDirectory, outputFilename);
var actual = processor.GetOutputFiles(MediaType.ApertureCard, outputDirectory, outputFilename);
Assert.Empty(actual);
}
@@ -88,8 +123,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = string.Empty;
var processor = new Aaru(RedumpSystem.IBMPCcompatible, MediaType.CDROM);
var actual = processor.FoundAllFiles(outputDirectory, outputFilename);
var processor = new Aaru(RedumpSystem.IBMPCcompatible);
var actual = processor.FoundAllFiles(MediaType.CDROM, outputDirectory, outputFilename);
Assert.Equal(7, actual.Count);
}
@@ -98,8 +133,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "Aaru", "CDROM");
string outputFilename = "test.aaruf";
var processor = new Aaru(RedumpSystem.IBMPCcompatible, MediaType.CDROM);
var actual = processor.FoundAllFiles(outputDirectory, outputFilename);
var processor = new Aaru(RedumpSystem.IBMPCcompatible);
var actual = processor.FoundAllFiles(MediaType.CDROM, outputDirectory, outputFilename);
Assert.Empty(actual);
}
@@ -112,8 +147,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = string.Empty;
var processor = new Aaru(RedumpSystem.IBMPCcompatible, MediaType.CDROM);
var actual = processor.FoundAnyFiles(outputDirectory, outputFilename);
var processor = new Aaru(RedumpSystem.IBMPCcompatible);
var actual = processor.FoundAnyFiles(MediaType.CDROM, outputDirectory, outputFilename);
Assert.False(actual);
}
@@ -122,8 +157,18 @@ namespace MPF.Processors.Test
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "Aaru", "CDROM");
string outputFilename = "test.aaruf";
var processor = new Aaru(RedumpSystem.IBMPCcompatible, MediaType.CDROM);
var actual = processor.FoundAnyFiles(outputDirectory, outputFilename);
var processor = new Aaru(RedumpSystem.IBMPCcompatible);
var actual = processor.FoundAnyFiles(MediaType.CDROM, outputDirectory, outputFilename);
Assert.True(actual);
}
[Fact]
public void FoundAnyFiles_ValidZip_Empty()
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "Aaru", "CDROM-zip");
string outputFilename = "test.aaruf";
var processor = new Aaru(RedumpSystem.IBMPCcompatible);
var actual = processor.FoundAnyFiles(MediaType.CDROM, outputDirectory, outputFilename);
Assert.True(actual);
}
@@ -136,8 +181,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = string.Empty;
var processor = new Aaru(RedumpSystem.IBMPCcompatible, MediaType.CDROM);
var actual = processor.GenerateArtifacts(outputDirectory, outputFilename);
var processor = new Aaru(RedumpSystem.IBMPCcompatible);
var actual = processor.GenerateArtifacts(MediaType.CDROM, outputDirectory, outputFilename);
Assert.Empty(actual);
}
@@ -146,8 +191,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "Aaru", "CDROM");
string outputFilename = "test.aaruf";
var processor = new Aaru(RedumpSystem.IBMPCcompatible, MediaType.CDROM);
var actual = processor.GenerateArtifacts(outputDirectory, outputFilename);
var processor = new Aaru(RedumpSystem.IBMPCcompatible);
var actual = processor.GenerateArtifacts(MediaType.CDROM, outputDirectory, outputFilename);
Assert.Equal(7, actual.Count);
}
@@ -160,8 +205,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = string.Empty;
var processor = new Aaru(RedumpSystem.IBMPCcompatible, MediaType.CDROM);
var actual = processor.GetDeleteableFilePaths(outputDirectory, outputFilename);
var processor = new Aaru(RedumpSystem.IBMPCcompatible);
var actual = processor.GetDeleteableFilePaths(MediaType.CDROM, outputDirectory, outputFilename);
Assert.Empty(actual);
}
@@ -170,8 +215,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "Aaru", "CDROM");
string outputFilename = "test.aaruf";
var processor = new Aaru(RedumpSystem.IBMPCcompatible, MediaType.CDROM);
var actual = processor.GetDeleteableFilePaths(outputDirectory, outputFilename);
var processor = new Aaru(RedumpSystem.IBMPCcompatible);
var actual = processor.GetDeleteableFilePaths(MediaType.CDROM, outputDirectory, outputFilename);
Assert.Empty(actual);
}
@@ -184,8 +229,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = string.Empty;
var processor = new Aaru(RedumpSystem.IBMPCcompatible, MediaType.CDROM);
var actual = processor.GetZippableFilePaths(outputDirectory, outputFilename);
var processor = new Aaru(RedumpSystem.IBMPCcompatible);
var actual = processor.GetZippableFilePaths(MediaType.CDROM, outputDirectory, outputFilename);
Assert.Empty(actual);
}
@@ -194,8 +239,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "Aaru", "CDROM");
string outputFilename = "test.aaruf";
var processor = new Aaru(RedumpSystem.IBMPCcompatible, MediaType.CDROM);
var actual = processor.GetZippableFilePaths(outputDirectory, outputFilename);
var processor = new Aaru(RedumpSystem.IBMPCcompatible);
var actual = processor.GetZippableFilePaths(MediaType.CDROM, outputDirectory, outputFilename);
Assert.Equal(7, actual.Count);
}
@@ -375,5 +420,149 @@ namespace MPF.Processors.Test
}
#endregion
#region GetDiscTypeFromStrings
[Theory]
[InlineData(null, "ANY", null)]
[InlineData("", "ANY", null)]
[InlineData("INVALID", "ANY", null)]
[InlineData("3\" floppy", "ANY", MediaType.FloppyDisk)]
[InlineData("3.5\" floppy", "ANY", MediaType.FloppyDisk)]
[InlineData("3.5\" magneto-optical", "ANY", MediaType.Floptical)]
[InlineData("3.5\" SyQuest cartridge", "ANY", null)]
[InlineData("3.9\" SyQuest cartridge", "ANY", null)]
[InlineData("5.25\" floppy", "ANY", MediaType.FloppyDisk)]
[InlineData("5.25\" magneto-optical", "ANY", MediaType.Floptical)]
[InlineData("5.25\" SyQuest cartridge", "ANY", null)]
[InlineData("8\" floppy", "ANY", MediaType.FloppyDisk)]
[InlineData("300mm magneto optical", "ANY", MediaType.Floptical)]
[InlineData("356mm magneto-optical", "ANY", MediaType.Floptical)]
[InlineData("Advanced Digital Recording", "ANY", null)]
[InlineData("Advanced Intelligent Tape", "ANY", null)]
[InlineData("Archival Disc", "ANY", null)]
[InlineData("BeeCard", "ANY", null)]
[InlineData("Blu-ray", "Wii U Optical Disc", MediaType.NintendoWiiUOpticalDisc)]
[InlineData("Blu-ray", "ANY", MediaType.BluRay)]
[InlineData("Borsu", "ANY", null)]
[InlineData("Compact Cassette", "ANY", MediaType.Cassette)]
[InlineData("Compact Disc", "ANY", MediaType.CDROM)]
[InlineData("Compact Flash", "ANY", MediaType.CompactFlash)]
[InlineData("CompacTape", "ANY", null)]
[InlineData("CRVdisc", "ANY", null)]
[InlineData("Data8", "ANY", null)]
[InlineData("DataPlay", "ANY", null)]
[InlineData("DataStore", "ANY", null)]
[InlineData("DDCD", "ANY", MediaType.CDROM)]
[InlineData("DECtape", "ANY", null)]
[InlineData("DemiDiskette", "ANY", null)]
[InlineData("Digital Audio Tape", "ANY", null)]
[InlineData("Digital Data Storage", "ANY", MediaType.DataCartridge)]
[InlineData("Digital Linear Tape", "ANY", null)]
[InlineData("DIR", "ANY", null)]
[InlineData("DST", "ANY", null)]
[InlineData("DTF", "ANY", null)]
[InlineData("DTF2", "ANY", null)]
[InlineData("DV tape", "ANY", null)]
[InlineData("DVD", "GameCube Game Disc", MediaType.NintendoGameCubeGameDisc)]
[InlineData("DVD", "Wii Optical Disc", MediaType.NintendoWiiOpticalDisc)]
[InlineData("DVD", "ANY", MediaType.DVD)]
[InlineData("EVD", "ANY", null)]
[InlineData("Exatape", "ANY", null)]
[InlineData("Express Card", "ANY", null)]
[InlineData("FDDVD", "ANY", null)]
[InlineData("Flextra", "ANY", null)]
[InlineData("Floptical", "ANY", MediaType.Floptical)]
[InlineData("FVD", "ANY", null)]
[InlineData("GD", "ANY", MediaType.GDROM)]
[InlineData("Hard Disk Drive", "ANY", MediaType.HardDisk)]
[InlineData("HD DVD", "ANY", MediaType.HDDVD)]
[InlineData("HD VMD", "ANY", null)]
[InlineData("HiFD", "ANY", MediaType.FloppyDisk)]
[InlineData("HiTC", "ANY", null)]
[InlineData("HuCard", "ANY", MediaType.Cartridge)]
[InlineData("HVD", "ANY", null)]
[InlineData("HyperFlex", "ANY", null)]
[InlineData("IBM 3470", "ANY", null)]
[InlineData("IBM 3480", "ANY", null)]
[InlineData("IBM 3490", "ANY", null)]
[InlineData("IBM 3490E", "ANY", null)]
[InlineData("IBM 3592", "ANY", null)]
[InlineData("Iomega Bernoulli Box", "ANY", MediaType.IomegaBernoulliDisk)]
[InlineData("Iomega Bernoulli Box II", "ANY", MediaType.IomegaBernoulliDisk)]
[InlineData("Iomega Ditto", "ANY", null)]
[InlineData("Iomega Jaz", "ANY", MediaType.IomegaJaz)]
[InlineData("Iomega PocketZip", "ANY", MediaType.IomegaZip)]
[InlineData("Iomega REV", "ANY", null)]
[InlineData("Iomega ZIP", "ANY", MediaType.IomegaZip)]
[InlineData("Kodak Verbatim", "ANY", null)]
[InlineData("LaserDisc", "ANY", MediaType.LaserDisc)]
[InlineData("Linear Tape-Open", "ANY", null)]
[InlineData("LT1", "ANY", null)]
[InlineData("Magneto-optical", "ANY", MediaType.Floptical)]
[InlineData("Memory Stick", "ANY", MediaType.SDCard)]
[InlineData("MiniCard", "ANY", null)]
[InlineData("MiniDisc", "ANY", null)]
[InlineData("MultiMediaCard", "ANY", MediaType.SDCard)]
[InlineData("Nintendo 3DS Game Card", "ANY", MediaType.Cartridge)]
[InlineData("Nintendo 64 Disk", "ANY", MediaType.Nintendo64DD)]
[InlineData("Nintendo 64 Game Pak", "ANY", MediaType.Cartridge)]
[InlineData("Nintendo Disk Card", "ANY", MediaType.NintendoFamicomDiskSystem)]
[InlineData("Nintendo DS Game Card", "ANY", MediaType.Cartridge)]
[InlineData("Nintendo DSi Game Card", "ANY", MediaType.Cartridge)]
[InlineData("Nintendo Entertainment System Game Pak", "ANY", MediaType.Cartridge)]
[InlineData("Nintendo Famicom Game Pak", "ANY", MediaType.Cartridge)]
[InlineData("Nintendo Game Boy Advance Game Pak", "ANY", MediaType.Cartridge)]
[InlineData("Nintendo Game Boy Game Pak", "ANY", MediaType.Cartridge)]
[InlineData("Nintendo Switch Game Card", "ANY", MediaType.Cartridge)]
[InlineData("Optical Disc Archive", "ANY", null)]
[InlineData("Orb", "ANY", null)]
[InlineData("PCMCIA Card", "ANY", null)]
[InlineData("PD650", "ANY", null)]
[InlineData("PlayStation Memory Card", "ANY", null)]
[InlineData("Quarter-inch cartridge", "ANY", MediaType.DataCartridge)]
[InlineData("Quarter-inch mini cartridge", "ANY", MediaType.DataCartridge)]
[InlineData("QuickDisk", "ANY", null)]
[InlineData("RDX", "ANY", null)]
[InlineData("SACD", "ANY", MediaType.DVD)]
[InlineData("Scalable Linear Recording", "ANY", null)]
[InlineData("Secure Digital", "ANY", MediaType.SDCard)]
[InlineData("SmartMedia", "ANY", MediaType.SDCard)]
[InlineData("Sony Professional Disc", "ANY", null)]
[InlineData("Sony Professional Disc for DATA", "ANY", null)]
[InlineData("STK 4480", "ANY", null)]
[InlineData("STK 4490", "ANY", null)]
[InlineData("STK 9490", "ANY", null)]
[InlineData("STK T-9840", "ANY", null)]
[InlineData("STK T-9940", "ANY", null)]
[InlineData("STK T-10000", "ANY", null)]
[InlineData("Super Advanced Intelligent Tape", "ANY", null)]
[InlineData("Super Digital Linear Tape", "ANY", null)]
[InlineData("Super Nintendo Game Pak", "ANY", MediaType.Cartridge)]
[InlineData("Super Nintendo Game Pak (US)", "ANY", MediaType.Cartridge)]
[InlineData("SuperDisk", "ANY", MediaType.FloppyDisk)]
[InlineData("SVOD", "ANY", null)]
[InlineData("Travan", "ANY", null)]
[InlineData("UDO", "ANY", null)]
[InlineData("UHD144", "ANY", null)]
[InlineData("UMD", "ANY", MediaType.UMD)]
[InlineData("Unknown", "ANY", null)]
[InlineData("USB flash drive", "ANY", MediaType.FlashDrive)]
[InlineData("VCDHD", "ANY", null)]
[InlineData("VideoFloppy", "ANY", null)]
[InlineData("VideoNow", "ANY", MediaType.CDROM)]
[InlineData("VXA", "ANY", MediaType.FlashDrive)]
[InlineData("Wafer", "ANY", null)]
[InlineData("xD", "ANY", null)]
[InlineData("XQD", "ANY", null)]
[InlineData("Zoned Hard Disk Drive", "ANY", MediaType.HardDisk)]
[InlineData("ZX Microdrive", "ANY", null)]
public void GetDiscTypeFromStringsTest(string? discType, string? discSubType, MediaType? expected)
{
var actual = Aaru.GetDiscTypeFromStrings(discType, discSubType);
Assert.Equal(expected, actual);
}
#endregion
}
}

View File

@@ -1,5 +1,6 @@
using System;
using System.IO;
using SabreTools.Models.Logiqx;
using Xunit;
namespace MPF.Processors.Test
@@ -85,6 +86,43 @@ namespace MPF.Processors.Test
#endregion
#region GenerateDatafile
[Fact]
public void GenerateDatafile_Empty_Null()
{
string iso = string.Empty;
Datafile? actual = BaseProcessor.GenerateDatafile(iso);
Assert.Null(actual);
}
[Fact]
public void GenerateDatafile_Invalid_Null()
{
string iso = "INVALID";
Datafile? actual = BaseProcessor.GenerateDatafile(iso);
Assert.Null(actual);
}
[Fact]
public void GenerateDatafile_Valid_Filled()
{
string iso = Path.Combine(Environment.CurrentDirectory, "TestData", "PS3CFW", "BluRay", "test.iso");
var actual = BaseProcessor.GenerateDatafile(iso);
Assert.NotNull(actual);
Assert.NotNull(actual.Game);
var game = Assert.Single(actual.Game);
Assert.NotNull(game.Rom);
var rom = Assert.Single(game.Rom);
Assert.Equal("9", rom.Size);
Assert.Equal("560b9f59", rom.CRC);
Assert.Equal("edbb6676247e65c2245dd4883ed9fc24", rom.MD5);
Assert.Equal("1b33ad54d78085be5ecb1cf1b3e9da821e708075", rom.SHA1);
}
#endregion
#region GetPIC
[Fact]
@@ -140,6 +178,76 @@ namespace MPF.Processors.Test
#endregion
#region IsAudio
[Fact]
public void IsAudio_Null_False()
{
string? cue = null;
bool actual = BaseProcessor.IsAudio(cue);
Assert.False(actual);
}
[Fact]
public void IsAudio_Empty_False()
{
string? cue = string.Empty;
bool actual = BaseProcessor.IsAudio(cue);
Assert.False(actual);
}
[Fact]
public void IsAudio_Invalid_False()
{
string? cue = @"INVALID";
bool actual = BaseProcessor.IsAudio(cue);
Assert.False(actual);
}
[Fact]
public void IsAudio_NoAudio_False()
{
string? cue = @"FILE ""track (Track 1).bin"" BINARY
TRACK 01 MODE1/2352
INDEX 01 00:00:00
FILE ""track (Track 2).bin"" BINARY
TRACK 02 MODE1/2352
INDEX 01 00:00:00";
bool actual = BaseProcessor.IsAudio(cue);
Assert.False(actual);
}
[Fact]
public void IsAudio_MixedTracks_False()
{
string? cue = @"FILE ""track (Track 1).bin"" BINARY
TRACK 01 MODE1/2352
INDEX 01 00:00:00
FILE ""track (Track 2).bin"" BINARY
TRACK 02 AUDIO
INDEX 00 00:00:00
INDEX 01 00:02:00";
bool actual = BaseProcessor.IsAudio(cue);
Assert.False(actual);
}
[Fact]
public void IsAudio_AllAudio_True()
{
string? cue = @"FILE ""track (Track 1).bin"" BINARY
TRACK 01 AUDIO
INDEX 00 00:00:00
INDEX 01 00:02:00
FILE ""track (Track 2).bin"" BINARY
TRACK 02 AUDIO
INDEX 00 00:00:00
INDEX 01 00:02:00";
bool actual = BaseProcessor.IsAudio(cue);
Assert.True(actual);
}
#endregion
#region SplitString
[Fact]

View File

@@ -7,17 +7,111 @@ namespace MPF.Processors.Test
{
public class CleanRipTests
{
#region DetermineMediaType
[Fact]
public void DetermineMediaType_GC_Empty_GC()
{
string? outputDirectory = null;
string outputFilename = string.Empty;
var processor = new CleanRip(RedumpSystem.NintendoGameCube);
var actual = processor.DetermineMediaType(outputDirectory, outputFilename);
Assert.Equal(MediaType.NintendoGameCubeGameDisc, actual);
}
[Fact]
public void DetermineMediaType_Wii_Null_Wii()
{
string? outputDirectory = null;
string outputFilename = string.Empty;
var processor = new CleanRip(RedumpSystem.NintendoWii);
var actual = processor.DetermineMediaType(outputDirectory, outputFilename);
Assert.Equal(MediaType.NintendoWiiOpticalDisc, actual);
}
[Fact]
public void DetermineMediaType_Other_Null_Null()
{
string? outputDirectory = null;
string outputFilename = string.Empty;
var processor = new CleanRip(RedumpSystem.IBMPCcompatible);
var actual = processor.DetermineMediaType(outputDirectory, outputFilename);
Assert.Null(actual);
}
[Fact]
public void DetermineMediaType_GC_Invalid_GC()
{
string? outputDirectory = null;
string outputFilename = "INVALID";
var processor = new CleanRip(RedumpSystem.NintendoGameCube);
var actual = processor.DetermineMediaType(outputDirectory, outputFilename);
Assert.Equal(MediaType.NintendoGameCubeGameDisc, actual);
}
[Fact]
public void DetermineMediaType_Wii_Invalid_Wii()
{
string? outputDirectory = null;
string outputFilename = "INVALID";
var processor = new CleanRip(RedumpSystem.NintendoWii);
var actual = processor.DetermineMediaType(outputDirectory, outputFilename);
Assert.Equal(MediaType.NintendoWiiOpticalDisc, actual);
}
[Fact]
public void DetermineMediaType_Other_Invalid_Invalid()
{
string? outputDirectory = null;
string outputFilename = "INVALID";
var processor = new CleanRip(RedumpSystem.IBMPCcompatible);
var actual = processor.DetermineMediaType(outputDirectory, outputFilename);
Assert.Null(actual);
}
[Fact]
public void DetermineMediaType_GC_Valid_GC()
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "CleanRip", "DVD");
string outputFilename = "test";
var processor = new CleanRip(RedumpSystem.NintendoGameCube);
var actual = processor.DetermineMediaType(outputDirectory, outputFilename);
Assert.Equal(MediaType.NintendoGameCubeGameDisc, actual);
}
[Fact]
public void DetermineMediaType_Wii_Valid_Wii()
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "CleanRip", "DVD");
string outputFilename = "test";
var processor = new CleanRip(RedumpSystem.NintendoWii);
var actual = processor.DetermineMediaType(outputDirectory, outputFilename);
Assert.Equal(MediaType.NintendoWiiOpticalDisc, actual);
}
[Fact]
public void DetermineMediaType_Other_Valid_Valid()
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "CleanRip", "DVD");
string outputFilename = "test";
var processor = new CleanRip(RedumpSystem.IBMPCcompatible);
var actual = processor.DetermineMediaType(outputDirectory, outputFilename);
Assert.Null(actual);
}
#endregion
#region GetOutputFiles
[Fact]
public void GetOutputFiles_Null_Empty()
public void GetOutputFiles_Null_Populated()
{
string? outputDirectory = null;
string outputFilename = "test";
var processor = new CleanRip(RedumpSystem.NintendoGameCube, null);
var processor = new CleanRip(RedumpSystem.NintendoGameCube);
var actual = processor.GetOutputFiles(outputDirectory, outputFilename);
Assert.Empty(actual);
var actual = processor.GetOutputFiles(null, outputDirectory, outputFilename);
Assert.Equal(3, actual.Count);
}
[Fact]
@@ -25,9 +119,9 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = "test";
var processor = new CleanRip(RedumpSystem.NintendoGameCube, MediaType.DVD);
var processor = new CleanRip(RedumpSystem.NintendoGameCube);
var actual = processor.GetOutputFiles(outputDirectory, outputFilename);
var actual = processor.GetOutputFiles(MediaType.DVD, outputDirectory, outputFilename);
Assert.Equal(3, actual.Count);
}
@@ -36,9 +130,9 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = "test";
var processor = new CleanRip(RedumpSystem.NintendoGameCube, MediaType.NintendoGameCubeGameDisc);
var processor = new CleanRip(RedumpSystem.NintendoGameCube);
var actual = processor.GetOutputFiles(outputDirectory, outputFilename);
var actual = processor.GetOutputFiles(MediaType.NintendoGameCubeGameDisc, outputDirectory, outputFilename);
Assert.Equal(3, actual.Count);
}
@@ -47,21 +141,21 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = "test";
var processor = new CleanRip(RedumpSystem.NintendoGameCube, MediaType.NintendoWiiOpticalDisc);
var processor = new CleanRip(RedumpSystem.NintendoWii);
var actual = processor.GetOutputFiles(outputDirectory, outputFilename);
var actual = processor.GetOutputFiles(MediaType.NintendoWiiOpticalDisc, outputDirectory, outputFilename);
Assert.Equal(3, actual.Count);
}
[Fact]
public void GetOutputFiles_Other_Empty()
public void GetOutputFiles_Other_Populated()
{
string? outputDirectory = null;
string outputFilename = "test";
var processor = new CleanRip(RedumpSystem.NintendoGameCube, MediaType.ApertureCard);
var processor = new CleanRip(RedumpSystem.NintendoGameCube);
var actual = processor.GetOutputFiles(outputDirectory, outputFilename);
Assert.Empty(actual);
var actual = processor.GetOutputFiles(MediaType.ApertureCard, outputDirectory, outputFilename);
Assert.Equal(3, actual.Count);
}
#endregion
@@ -73,8 +167,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = string.Empty;
var processor = new CleanRip(RedumpSystem.NintendoGameCube, MediaType.DVD);
var actual = processor.FoundAllFiles(outputDirectory, outputFilename);
var processor = new CleanRip(RedumpSystem.NintendoGameCube);
var actual = processor.FoundAllFiles(MediaType.DVD, outputDirectory, outputFilename);
Assert.Equal(3, actual.Count);
}
@@ -83,8 +177,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "CleanRip", "DVD");
string outputFilename = "test.iso";
var processor = new CleanRip(RedumpSystem.NintendoGameCube, MediaType.DVD);
var actual = processor.FoundAllFiles(outputDirectory, outputFilename);
var processor = new CleanRip(RedumpSystem.NintendoGameCube);
var actual = processor.FoundAllFiles(MediaType.DVD, outputDirectory, outputFilename);
Assert.Empty(actual);
}
@@ -97,8 +191,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = string.Empty;
var processor = new CleanRip(RedumpSystem.NintendoGameCube, MediaType.DVD);
var actual = processor.FoundAnyFiles(outputDirectory, outputFilename);
var processor = new CleanRip(RedumpSystem.NintendoGameCube);
var actual = processor.FoundAnyFiles(MediaType.DVD, outputDirectory, outputFilename);
Assert.False(actual);
}
@@ -107,8 +201,18 @@ namespace MPF.Processors.Test
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "CleanRip", "DVD");
string outputFilename = "test.iso";
var processor = new CleanRip(RedumpSystem.NintendoGameCube, MediaType.DVD);
var actual = processor.FoundAnyFiles(outputDirectory, outputFilename);
var processor = new CleanRip(RedumpSystem.NintendoGameCube);
var actual = processor.FoundAnyFiles(MediaType.DVD, outputDirectory, outputFilename);
Assert.True(actual);
}
[Fact]
public void FoundAnyFiles_ValidZip_Empty()
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "CleanRip", "DVD-zip");
string outputFilename = "test.iso";
var processor = new CleanRip(RedumpSystem.NintendoGameCube);
var actual = processor.FoundAnyFiles(MediaType.DVD, outputDirectory, outputFilename);
Assert.True(actual);
}
@@ -121,8 +225,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = string.Empty;
var processor = new CleanRip(RedumpSystem.NintendoGameCube, MediaType.DVD);
var actual = processor.GenerateArtifacts(outputDirectory, outputFilename);
var processor = new CleanRip(RedumpSystem.NintendoGameCube);
var actual = processor.GenerateArtifacts(MediaType.DVD, outputDirectory, outputFilename);
Assert.Empty(actual);
}
@@ -131,8 +235,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "CleanRip", "DVD");
string outputFilename = "test.iso";
var processor = new CleanRip(RedumpSystem.NintendoGameCube, MediaType.DVD);
var actual = processor.GenerateArtifacts(outputDirectory, outputFilename);
var processor = new CleanRip(RedumpSystem.NintendoGameCube);
var actual = processor.GenerateArtifacts(MediaType.DVD, outputDirectory, outputFilename);
Assert.Equal(2, actual.Count);
}
@@ -145,8 +249,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = string.Empty;
var processor = new CleanRip(RedumpSystem.NintendoGameCube, MediaType.DVD);
var actual = processor.GetDeleteableFilePaths(outputDirectory, outputFilename);
var processor = new CleanRip(RedumpSystem.NintendoGameCube);
var actual = processor.GetDeleteableFilePaths(MediaType.DVD, outputDirectory, outputFilename);
Assert.Empty(actual);
}
@@ -155,8 +259,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "CleanRip", "DVD");
string outputFilename = "test.iso";
var processor = new CleanRip(RedumpSystem.NintendoGameCube, MediaType.DVD);
var actual = processor.GetDeleteableFilePaths(outputDirectory, outputFilename);
var processor = new CleanRip(RedumpSystem.NintendoGameCube);
var actual = processor.GetDeleteableFilePaths(MediaType.DVD, outputDirectory, outputFilename);
Assert.Empty(actual);
}
@@ -169,8 +273,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = string.Empty;
var processor = new CleanRip(RedumpSystem.NintendoGameCube, MediaType.DVD);
var actual = processor.GetZippableFilePaths(outputDirectory, outputFilename);
var processor = new CleanRip(RedumpSystem.NintendoGameCube);
var actual = processor.GetZippableFilePaths(MediaType.DVD, outputDirectory, outputFilename);
Assert.Empty(actual);
}
@@ -179,8 +283,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "CleanRip", "DVD");
string outputFilename = "test.iso";
var processor = new CleanRip(RedumpSystem.NintendoGameCube, MediaType.DVD);
var actual = processor.GetZippableFilePaths(outputDirectory, outputFilename);
var processor = new CleanRip(RedumpSystem.NintendoGameCube);
var actual = processor.GetZippableFilePaths(MediaType.DVD, outputDirectory, outputFilename);
Assert.Equal(2, actual.Count);
}

View File

@@ -10,6 +10,70 @@ namespace MPF.Processors.Test
// TODO: Add tests around remaining helper methods
public class DiscImageCreatorTests
{
#region DetermineMediaType
[Fact]
public void DetermineMediaType_Null_Null()
{
string? outputDirectory = null;
string outputFilename = string.Empty;
var processor = new DiscImageCreator(RedumpSystem.IBMPCcompatible);
var actual = processor.DetermineMediaType(outputDirectory, outputFilename);
Assert.Null(actual);
}
[Fact]
public void DetermineMediaType_Invalid_Null()
{
string? outputDirectory = null;
string outputFilename = "INVALID";
var processor = new DiscImageCreator(RedumpSystem.IBMPCcompatible);
var actual = processor.DetermineMediaType(outputDirectory, outputFilename);
Assert.Null(actual);
}
[Fact]
public void DetermineMediaType_BD_Filled()
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "DiscImageCreator", "BluRay");
string outputFilename = "test";
var processor = new DiscImageCreator(RedumpSystem.IBMPCcompatible);
var actual = processor.DetermineMediaType(outputDirectory, outputFilename);
Assert.Equal(MediaType.BluRay, actual);
}
[Fact]
public void DetermineMediaType_CD_Filled()
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "DiscImageCreator", "CDROM");
string outputFilename = "test";
var processor = new DiscImageCreator(RedumpSystem.IBMPCcompatible);
var actual = processor.DetermineMediaType(outputDirectory, outputFilename);
Assert.Equal(MediaType.CDROM, actual);
}
[Fact]
public void DetermineMediaType_DVD_Filled()
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "DiscImageCreator", "DVD");
string outputFilename = "test";
var processor = new DiscImageCreator(RedumpSystem.IBMPCcompatible);
var actual = processor.DetermineMediaType(outputDirectory, outputFilename);
Assert.Equal(MediaType.DVD, actual);
}
[Fact]
public void DetermineMediaType_HDDVD_Filled()
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "DiscImageCreator", "HDDVD");
string outputFilename = "test";
var processor = new DiscImageCreator(RedumpSystem.IBMPCcompatible);
var actual = processor.DetermineMediaType(outputDirectory, outputFilename);
Assert.Equal(MediaType.HDDVD, actual);
}
#endregion
#region GetOutputFiles
[Fact]
@@ -17,9 +81,9 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = "test";
var processor = new DiscImageCreator(RedumpSystem.IBMPCcompatible, null);
var processor = new DiscImageCreator(RedumpSystem.IBMPCcompatible);
var actual = processor.GetOutputFiles(outputDirectory, outputFilename);
var actual = processor.GetOutputFiles(null, outputDirectory, outputFilename);
Assert.Empty(actual);
}
@@ -28,9 +92,9 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = "test";
var processor = new DiscImageCreator(RedumpSystem.IBMPCcompatible, MediaType.CDROM);
var processor = new DiscImageCreator(RedumpSystem.IBMPCcompatible);
var actual = processor.GetOutputFiles(outputDirectory, outputFilename);
var actual = processor.GetOutputFiles(MediaType.CDROM, outputDirectory, outputFilename);
Assert.Equal(26, actual.Count);
}
@@ -39,9 +103,9 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = "test";
var processor = new DiscImageCreator(RedumpSystem.IBMPCcompatible, MediaType.GDROM);
var processor = new DiscImageCreator(RedumpSystem.IBMPCcompatible);
var actual = processor.GetOutputFiles(outputDirectory, outputFilename);
var actual = processor.GetOutputFiles(MediaType.GDROM, outputDirectory, outputFilename);
Assert.Equal(10, actual.Count);
}
@@ -50,9 +114,9 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = "test";
var processor = new DiscImageCreator(RedumpSystem.IBMPCcompatible, MediaType.DVD);
var processor = new DiscImageCreator(RedumpSystem.IBMPCcompatible);
var actual = processor.GetOutputFiles(outputDirectory, outputFilename);
var actual = processor.GetOutputFiles(MediaType.DVD, outputDirectory, outputFilename);
Assert.Equal(16, actual.Count);
}
@@ -61,9 +125,9 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = "test";
var processor = new DiscImageCreator(RedumpSystem.IBMPCcompatible, MediaType.NintendoGameCubeGameDisc);
var processor = new DiscImageCreator(RedumpSystem.IBMPCcompatible);
var actual = processor.GetOutputFiles(outputDirectory, outputFilename);
var actual = processor.GetOutputFiles(MediaType.NintendoGameCubeGameDisc, outputDirectory, outputFilename);
Assert.Equal(16, actual.Count);
}
@@ -72,9 +136,9 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = "test";
var processor = new DiscImageCreator(RedumpSystem.IBMPCcompatible, MediaType.NintendoWiiOpticalDisc);
var processor = new DiscImageCreator(RedumpSystem.IBMPCcompatible);
var actual = processor.GetOutputFiles(outputDirectory, outputFilename);
var actual = processor.GetOutputFiles(MediaType.NintendoWiiOpticalDisc, outputDirectory, outputFilename);
Assert.Equal(16, actual.Count);
}
@@ -83,9 +147,9 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = "test";
var processor = new DiscImageCreator(RedumpSystem.IBMPCcompatible, MediaType.HDDVD);
var processor = new DiscImageCreator(RedumpSystem.IBMPCcompatible);
var actual = processor.GetOutputFiles(outputDirectory, outputFilename);
var actual = processor.GetOutputFiles(MediaType.HDDVD, outputDirectory, outputFilename);
Assert.Equal(15, actual.Count);
}
@@ -94,9 +158,9 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = "test";
var processor = new DiscImageCreator(RedumpSystem.IBMPCcompatible, MediaType.BluRay);
var processor = new DiscImageCreator(RedumpSystem.IBMPCcompatible);
var actual = processor.GetOutputFiles(outputDirectory, outputFilename);
var actual = processor.GetOutputFiles(MediaType.BluRay, outputDirectory, outputFilename);
Assert.Equal(15, actual.Count);
}
@@ -105,9 +169,9 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = "test";
var processor = new DiscImageCreator(RedumpSystem.IBMPCcompatible, MediaType.FloppyDisk);
var processor = new DiscImageCreator(RedumpSystem.IBMPCcompatible);
var actual = processor.GetOutputFiles(outputDirectory, outputFilename);
var actual = processor.GetOutputFiles(MediaType.FloppyDisk, outputDirectory, outputFilename);
Assert.Equal(4, actual.Count);
}
@@ -116,9 +180,9 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = "test";
var processor = new DiscImageCreator(RedumpSystem.IBMPCcompatible, MediaType.HardDisk);
var processor = new DiscImageCreator(RedumpSystem.IBMPCcompatible);
var actual = processor.GetOutputFiles(outputDirectory, outputFilename);
var actual = processor.GetOutputFiles(MediaType.HardDisk, outputDirectory, outputFilename);
Assert.Equal(4, actual.Count);
}
@@ -127,9 +191,9 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = "test";
var processor = new DiscImageCreator(RedumpSystem.IBMPCcompatible, MediaType.ApertureCard);
var processor = new DiscImageCreator(RedumpSystem.IBMPCcompatible);
var actual = processor.GetOutputFiles(outputDirectory, outputFilename);
var actual = processor.GetOutputFiles(MediaType.ApertureCard, outputDirectory, outputFilename);
Assert.Empty(actual);
}
@@ -142,9 +206,9 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = string.Empty;
var processor = new DiscImageCreator(RedumpSystem.IBMPCcompatible, MediaType.CDROM);
var actual = processor.FoundAllFiles(outputDirectory, outputFilename);
Assert.Equal(17, actual.Count);
var processor = new DiscImageCreator(RedumpSystem.IBMPCcompatible);
var actual = processor.FoundAllFiles(MediaType.CDROM, outputDirectory, outputFilename);
Assert.Equal(15, actual.Count);
}
[Fact]
@@ -152,8 +216,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "DiscImageCreator", "CDROM");
string outputFilename = "test.cue";
var processor = new DiscImageCreator(RedumpSystem.IBMPCcompatible, MediaType.CDROM);
var actual = processor.FoundAllFiles(outputDirectory, outputFilename);
var processor = new DiscImageCreator(RedumpSystem.IBMPCcompatible);
var actual = processor.FoundAllFiles(MediaType.CDROM, outputDirectory, outputFilename);
Assert.Empty(actual);
}
@@ -166,8 +230,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = string.Empty;
var processor = new DiscImageCreator(RedumpSystem.IBMPCcompatible, MediaType.CDROM);
var actual = processor.FoundAnyFiles(outputDirectory, outputFilename);
var processor = new DiscImageCreator(RedumpSystem.IBMPCcompatible);
var actual = processor.FoundAnyFiles(MediaType.CDROM, outputDirectory, outputFilename);
Assert.False(actual);
}
@@ -176,8 +240,18 @@ namespace MPF.Processors.Test
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "DiscImageCreator", "CDROM");
string outputFilename = "test.cue";
var processor = new DiscImageCreator(RedumpSystem.IBMPCcompatible, MediaType.CDROM);
var actual = processor.FoundAnyFiles(outputDirectory, outputFilename);
var processor = new DiscImageCreator(RedumpSystem.IBMPCcompatible);
var actual = processor.FoundAnyFiles(MediaType.CDROM, outputDirectory, outputFilename);
Assert.True(actual);
}
[Fact]
public void FoundAnyFiles_ValidZip_Empty()
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "DiscImageCreator", "CDROM-zip");
string outputFilename = "test.cue";
var processor = new DiscImageCreator(RedumpSystem.IBMPCcompatible);
var actual = processor.FoundAnyFiles(MediaType.CDROM, outputDirectory, outputFilename);
Assert.True(actual);
}
@@ -190,8 +264,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = string.Empty;
var processor = new DiscImageCreator(RedumpSystem.IBMPCcompatible, MediaType.CDROM);
var actual = processor.GenerateArtifacts(outputDirectory, outputFilename);
var processor = new DiscImageCreator(RedumpSystem.IBMPCcompatible);
var actual = processor.GenerateArtifacts(MediaType.CDROM, outputDirectory, outputFilename);
Assert.Empty(actual);
}
@@ -200,8 +274,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "DiscImageCreator", "CDROM");
string outputFilename = "test.cue";
var processor = new DiscImageCreator(RedumpSystem.IBMPCcompatible, MediaType.CDROM);
var actual = processor.GenerateArtifacts(outputDirectory, outputFilename);
var processor = new DiscImageCreator(RedumpSystem.IBMPCcompatible);
var actual = processor.GenerateArtifacts(MediaType.CDROM, outputDirectory, outputFilename);
Assert.Equal(21, actual.Count);
}
@@ -214,8 +288,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = string.Empty;
var processor = new DiscImageCreator(RedumpSystem.IBMPCcompatible, MediaType.CDROM);
var actual = processor.GetDeleteableFilePaths(outputDirectory, outputFilename);
var processor = new DiscImageCreator(RedumpSystem.IBMPCcompatible);
var actual = processor.GetDeleteableFilePaths(MediaType.CDROM, outputDirectory, outputFilename);
Assert.Empty(actual);
}
@@ -224,8 +298,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "DiscImageCreator", "CDROM");
string outputFilename = "test.cue";
var processor = new DiscImageCreator(RedumpSystem.IBMPCcompatible, MediaType.CDROM);
var actual = processor.GetDeleteableFilePaths(outputDirectory, outputFilename);
var processor = new DiscImageCreator(RedumpSystem.IBMPCcompatible);
var actual = processor.GetDeleteableFilePaths(MediaType.CDROM, outputDirectory, outputFilename);
Assert.Equal(2, actual.Count);
}
@@ -238,8 +312,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = string.Empty;
var processor = new DiscImageCreator(RedumpSystem.IBMPCcompatible, MediaType.CDROM);
var actual = processor.GetZippableFilePaths(outputDirectory, outputFilename);
var processor = new DiscImageCreator(RedumpSystem.IBMPCcompatible);
var actual = processor.GetZippableFilePaths(MediaType.CDROM, outputDirectory, outputFilename);
Assert.Empty(actual);
}
@@ -248,8 +322,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "DiscImageCreator", "CDROM");
string outputFilename = "test.cue";
var processor = new DiscImageCreator(RedumpSystem.IBMPCcompatible, MediaType.CDROM);
var actual = processor.GetZippableFilePaths(outputDirectory, outputFilename);
var processor = new DiscImageCreator(RedumpSystem.IBMPCcompatible);
var actual = processor.GetZippableFilePaths(MediaType.CDROM, outputDirectory, outputFilename);
Assert.Equal(23, actual.Count);
}
@@ -341,15 +415,45 @@ namespace MPF.Processors.Test
}
[Fact]
public void GetDiscType_Valid_Filled()
public void GetDiscType_BD_Filled()
{
string? expected = "CD-ROM, GD-ROM, DVD-ROM, BD-ROM";
string? expected = "BDO";
string disc = Path.Combine(Environment.CurrentDirectory, "TestData", "DiscImageCreator", "BluRay", "test_disc.txt");
bool actual = DiscImageCreator.GetDiscType(disc, out string? discTypeOrBookType);
Assert.True(actual);
Assert.Equal(expected, discTypeOrBookType);
}
[Fact]
public void GetDiscType_CD_Filled()
{
string? expected = "CD-ROM";
string disc = Path.Combine(Environment.CurrentDirectory, "TestData", "DiscImageCreator", "CDROM", "test_disc.txt");
bool actual = DiscImageCreator.GetDiscType(disc, out string? discTypeOrBookType);
Assert.True(actual);
Assert.Equal(expected, discTypeOrBookType);
}
[Fact]
public void GetDiscType_DVD_Filled()
{
string? expected = "DVD-ROM";
string disc = Path.Combine(Environment.CurrentDirectory, "TestData", "DiscImageCreator", "DVD", "test_disc.txt");
bool actual = DiscImageCreator.GetDiscType(disc, out string? discTypeOrBookType);
Assert.True(actual);
Assert.Equal(expected, discTypeOrBookType);
}
[Fact]
public void GetDiscType_HDDVD_Filled()
{
string? expected = "HD DVD-ROM";
string disc = Path.Combine(Environment.CurrentDirectory, "TestData", "DiscImageCreator", "HDDVD", "test_disc.txt");
bool actual = DiscImageCreator.GetDiscType(disc, out string? discTypeOrBookType);
Assert.True(actual);
Assert.Equal(expected, discTypeOrBookType);
}
#endregion
#region GetDVDProtection

View File

@@ -24,22 +24,22 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeCoverage" Version="17.12.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageReference Include="Microsoft.CodeCoverage" Version="17.13.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.13.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="SabreTools.RedumpLib" Version="1.6.4" />
<PackageReference Include="xunit" Version="2.9.2" />
<PackageReference Include="SabreTools.RedumpLib" Version="1.6.8" />
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.abstractions" Version="2.0.3" />
<PackageReference Include="xunit.analyzers" Version="1.18.0" />
<PackageReference Include="xunit.assert" Version="2.9.2" />
<PackageReference Include="xunit.core" Version="2.9.2" />
<PackageReference Include="xunit.extensibility.core" Version="2.9.2" />
<PackageReference Include="xunit.extensibility.execution" Version="2.9.2" />
<PackageReference Include="xunit.runner.console" Version="2.9.2">
<PackageReference Include="xunit.analyzers" Version="1.21.0" />
<PackageReference Include="xunit.assert" Version="2.9.3" />
<PackageReference Include="xunit.core" Version="2.9.3" />
<PackageReference Include="xunit.extensibility.core" Version="2.9.3" />
<PackageReference Include="xunit.extensibility.execution" Version="2.9.3" />
<PackageReference Include="xunit.runner.console" Version="2.9.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="xunit.runner.visualstudio" Version="3.0.0">
<PackageReference Include="xunit.runner.visualstudio" Version="3.0.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>

View File

@@ -1,6 +1,5 @@
using System;
using System.IO;
using SabreTools.Models.Logiqx;
using SabreTools.RedumpLib.Data;
using Xunit;
@@ -8,17 +7,51 @@ namespace MPF.Processors.Test
{
public class PS3CFWTests
{
#region DetermineMediaType
[Fact]
public void DetermineMediaType_Null_BluRay()
{
string? outputDirectory = null;
string outputFilename = string.Empty;
var processor = new PS3CFW(RedumpSystem.SonyPlayStation3);
var actual = processor.DetermineMediaType(outputDirectory, outputFilename);
Assert.Equal(MediaType.BluRay, actual);
}
[Fact]
public void DetermineMediaType_Invalid_BluRay()
{
string? outputDirectory = null;
string outputFilename = "INVALID";
var processor = new PS3CFW(RedumpSystem.SonyPlayStation3);
var actual = processor.DetermineMediaType(outputDirectory, outputFilename);
Assert.Equal(MediaType.BluRay, actual);
}
[Fact]
public void DetermineMediaType_Valid_BluRay()
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "PS3CFW", "BluRay");
string outputFilename = "test";
var processor = new PS3CFW(RedumpSystem.SonyPlayStation3);
var actual = processor.DetermineMediaType(outputDirectory, outputFilename);
Assert.Equal(MediaType.BluRay, actual);
}
#endregion
#region GetOutputFiles
[Fact]
public void GetOutputFiles_Null_Empty()
public void GetOutputFiles_Null_Populated()
{
string? outputDirectory = null;
string outputFilename = "test";
var processor = new PS3CFW(RedumpSystem.SonyPlayStation3, null);
var processor = new PS3CFW(RedumpSystem.SonyPlayStation3);
var actual = processor.GetOutputFiles(outputDirectory, outputFilename);
Assert.Empty(actual);
var actual = processor.GetOutputFiles(null, outputDirectory, outputFilename);
Assert.Equal(4, actual.Count);
}
[Fact]
@@ -26,21 +59,21 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = "test";
var processor = new PS3CFW(RedumpSystem.SonyPlayStation3, MediaType.BluRay);
var processor = new PS3CFW(RedumpSystem.SonyPlayStation3);
var actual = processor.GetOutputFiles(outputDirectory, outputFilename);
var actual = processor.GetOutputFiles(MediaType.BluRay, outputDirectory, outputFilename);
Assert.Equal(4, actual.Count);
}
[Fact]
public void GetOutputFiles_Other_Empty()
public void GetOutputFiles_Other_Populated()
{
string? outputDirectory = null;
string outputFilename = "test";
var processor = new PS3CFW(RedumpSystem.SonyPlayStation3, MediaType.ApertureCard);
var processor = new PS3CFW(RedumpSystem.SonyPlayStation3);
var actual = processor.GetOutputFiles(outputDirectory, outputFilename);
Assert.Empty(actual);
var actual = processor.GetOutputFiles(MediaType.ApertureCard, outputDirectory, outputFilename);
Assert.Equal(4, actual.Count);
}
#endregion
@@ -52,8 +85,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = string.Empty;
var processor = new PS3CFW(RedumpSystem.SonyPlayStation3, MediaType.BluRay);
var actual = processor.FoundAllFiles(outputDirectory, outputFilename);
var processor = new PS3CFW(RedumpSystem.SonyPlayStation3);
var actual = processor.FoundAllFiles(MediaType.BluRay, outputDirectory, outputFilename);
Assert.Equal(3, actual.Count);
}
@@ -62,8 +95,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "PS3CFW", "BluRay");
string outputFilename = "test.iso";
var processor = new PS3CFW(RedumpSystem.SonyPlayStation3, MediaType.BluRay);
var actual = processor.FoundAllFiles(outputDirectory, outputFilename);
var processor = new PS3CFW(RedumpSystem.SonyPlayStation3);
var actual = processor.FoundAllFiles(MediaType.BluRay, outputDirectory, outputFilename);
Assert.Empty(actual);
}
@@ -76,8 +109,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = string.Empty;
var processor = new PS3CFW(RedumpSystem.SonyPlayStation3, MediaType.BluRay);
var actual = processor.FoundAnyFiles(outputDirectory, outputFilename);
var processor = new PS3CFW(RedumpSystem.SonyPlayStation3);
var actual = processor.FoundAnyFiles(MediaType.BluRay, outputDirectory, outputFilename);
Assert.False(actual);
}
@@ -86,8 +119,18 @@ namespace MPF.Processors.Test
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "PS3CFW", "BluRay");
string outputFilename = "test.iso";
var processor = new PS3CFW(RedumpSystem.SonyPlayStation3, MediaType.BluRay);
var actual = processor.FoundAnyFiles(outputDirectory, outputFilename);
var processor = new PS3CFW(RedumpSystem.SonyPlayStation3);
var actual = processor.FoundAnyFiles(MediaType.BluRay, outputDirectory, outputFilename);
Assert.True(actual);
}
[Fact]
public void FoundAnyFiles_ValidZip_Empty()
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "PS3CFW", "BluRay-zip");
string outputFilename = "test.iso";
var processor = new PS3CFW(RedumpSystem.SonyPlayStation3);
var actual = processor.FoundAnyFiles(MediaType.BluRay, outputDirectory, outputFilename);
Assert.True(actual);
}
@@ -100,8 +143,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = string.Empty;
var processor = new PS3CFW(RedumpSystem.SonyPlayStation3, MediaType.BluRay);
var actual = processor.GenerateArtifacts(outputDirectory, outputFilename);
var processor = new PS3CFW(RedumpSystem.SonyPlayStation3);
var actual = processor.GenerateArtifacts(MediaType.BluRay, outputDirectory, outputFilename);
Assert.Empty(actual);
}
@@ -110,8 +153,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "PS3CFW", "BluRay");
string outputFilename = "test.iso";
var processor = new PS3CFW(RedumpSystem.SonyPlayStation3, MediaType.BluRay);
var actual = processor.GenerateArtifacts(outputDirectory, outputFilename);
var processor = new PS3CFW(RedumpSystem.SonyPlayStation3);
var actual = processor.GenerateArtifacts(MediaType.BluRay, outputDirectory, outputFilename);
Assert.Equal(2, actual.Count);
}
@@ -124,8 +167,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = string.Empty;
var processor = new PS3CFW(RedumpSystem.SonyPlayStation3, MediaType.BluRay);
var actual = processor.GetDeleteableFilePaths(outputDirectory, outputFilename);
var processor = new PS3CFW(RedumpSystem.SonyPlayStation3);
var actual = processor.GetDeleteableFilePaths(MediaType.BluRay, outputDirectory, outputFilename);
Assert.Empty(actual);
}
@@ -134,8 +177,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "PS3CFW", "BluRay");
string outputFilename = "test.iso";
var processor = new PS3CFW(RedumpSystem.SonyPlayStation3, MediaType.BluRay);
var actual = processor.GetDeleteableFilePaths(outputDirectory, outputFilename);
var processor = new PS3CFW(RedumpSystem.SonyPlayStation3);
var actual = processor.GetDeleteableFilePaths(MediaType.BluRay, outputDirectory, outputFilename);
Assert.Empty(actual);
}
@@ -148,8 +191,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = string.Empty;
var processor = new PS3CFW(RedumpSystem.SonyPlayStation3, MediaType.BluRay);
var actual = processor.GetZippableFilePaths(outputDirectory, outputFilename);
var processor = new PS3CFW(RedumpSystem.SonyPlayStation3);
var actual = processor.GetZippableFilePaths(MediaType.BluRay, outputDirectory, outputFilename);
Assert.Empty(actual);
}
@@ -158,48 +201,11 @@ namespace MPF.Processors.Test
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "PS3CFW", "BluRay");
string outputFilename = "test.iso";
var processor = new PS3CFW(RedumpSystem.SonyPlayStation3, MediaType.BluRay);
var actual = processor.GetZippableFilePaths(outputDirectory, outputFilename);
var processor = new PS3CFW(RedumpSystem.SonyPlayStation3);
var actual = processor.GetZippableFilePaths(MediaType.BluRay, outputDirectory, outputFilename);
Assert.Equal(2, actual.Count);
}
#endregion
#region GeneratePS3CFWDatafile
[Fact]
public void GeneratePS3CFWDatafile_Empty_Null()
{
string iso = string.Empty;
Datafile? actual = PS3CFW.GeneratePS3CFWDatafile(iso);
Assert.Null(actual);
}
[Fact]
public void GeneratePS3CFWDatafile_Invalid_Null()
{
string iso = "INVALID";
Datafile? actual = PS3CFW.GeneratePS3CFWDatafile(iso);
Assert.Null(actual);
}
[Fact]
public void GeneratePS3CFWDatafile_Valid_Filled()
{
string iso = Path.Combine(Environment.CurrentDirectory, "TestData", "PS3CFW", "BluRay", "test.iso");
var actual = PS3CFW.GeneratePS3CFWDatafile(iso);
Assert.NotNull(actual);
Assert.NotNull(actual.Game);
var game = Assert.Single(actual.Game);
Assert.NotNull(game.Rom);
var rom = Assert.Single(game.Rom);
Assert.Equal("9", rom.Size);
Assert.Equal("560b9f59", rom.CRC);
Assert.Equal("edbb6676247e65c2245dd4883ed9fc24", rom.MD5);
Assert.Equal("1b33ad54d78085be5ecb1cf1b3e9da821e708075", rom.SHA1);
}
#endregion
}
}

View File

@@ -426,6 +426,46 @@ namespace MPF.Processors.Test
#endregion
#region NormalizeShiftJIS
[Fact]
public void NormalizeShiftJIS_Null_Empty()
{
byte[]? contents = null;
string? actual = ProcessingTool.NormalizeShiftJIS(contents);
Assert.NotNull(actual);
Assert.Empty(actual);
}
[Fact]
public void NormalizeShiftJIS_Empty_Empty()
{
byte[]? contents = [];
string? actual = ProcessingTool.NormalizeShiftJIS(contents);
Assert.NotNull(actual);
Assert.Empty(actual);
}
[Fact]
public void NormalizeShiftJIS_NoShiftJIS_Valid()
{
string? expected = "ABCDE";
byte[]? contents = [0x41, 0x42, 0x43, 0x44, 0x45];
string? actual = ProcessingTool.NormalizeShiftJIS(contents);
Assert.Equal(expected, actual);
}
[Fact]
public void NormalizeShiftJIS_ShiftJIS_Valid()
{
string? expected = "ABCDE ひらがな";
byte[]? contents = [0x41, 0x42, 0x43, 0x44, 0x45, 0x20, 0x82, 0xD0, 0x82, 0xE7, 0x82, 0xAA, 0x82, 0xC8];
string? actual = ProcessingTool.NormalizeShiftJIS(contents);
Assert.Equal(expected, actual);
}
#endregion
#region GetUMDCategory
[Theory]

View File

@@ -8,6 +8,80 @@ namespace MPF.Processors.Test
{
public class RedumperTests
{
#region DetermineMediaType
[Fact]
public void DetermineMediaType_Null_Null()
{
string? outputDirectory = null;
string outputFilename = string.Empty;
var processor = new Redumper(RedumpSystem.IBMPCcompatible);
var actual = processor.DetermineMediaType(outputDirectory, outputFilename);
Assert.Null(actual);
}
[Fact]
public void DetermineMediaType_Invalid_Null()
{
string? outputDirectory = null;
string outputFilename = "INVALID";
var processor = new Redumper(RedumpSystem.IBMPCcompatible);
var actual = processor.DetermineMediaType(outputDirectory, outputFilename);
Assert.Null(actual);
}
[Fact]
public void DetermineMediaType_BD_Filled()
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "Redumper", "BluRay");
string outputFilename = "test";
var processor = new Redumper(RedumpSystem.IBMPCcompatible);
var actual = processor.DetermineMediaType(outputDirectory, outputFilename);
Assert.Equal(MediaType.BluRay, actual);
}
[Fact]
public void DetermineMediaType_BDR_Filled()
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "Redumper", "BDR");
string outputFilename = "test";
var processor = new Redumper(RedumpSystem.IBMPCcompatible);
var actual = processor.DetermineMediaType(outputDirectory, outputFilename);
Assert.Equal(MediaType.BluRay, actual);
}
[Fact]
public void DetermineMediaType_CD_Filled()
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "Redumper", "CDROM");
string outputFilename = "test";
var processor = new Redumper(RedumpSystem.IBMPCcompatible);
var actual = processor.DetermineMediaType(outputDirectory, outputFilename);
Assert.Equal(MediaType.CDROM, actual);
}
[Fact]
public void DetermineMediaType_DVD_Filled()
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "Redumper", "DVD");
string outputFilename = "test";
var processor = new Redumper(RedumpSystem.IBMPCcompatible);
var actual = processor.DetermineMediaType(outputDirectory, outputFilename);
Assert.Equal(MediaType.DVD, actual);
}
[Fact]
public void DetermineMediaType_HDDVD_Filled()
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "Redumper", "HDDVD");
string outputFilename = "test";
var processor = new Redumper(RedumpSystem.IBMPCcompatible);
var actual = processor.DetermineMediaType(outputDirectory, outputFilename);
Assert.Equal(MediaType.HDDVD, actual);
}
#endregion
#region GetOutputFiles
[Fact]
@@ -15,9 +89,9 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = "test";
var processor = new Redumper(RedumpSystem.IBMPCcompatible, null);
var processor = new Redumper(RedumpSystem.IBMPCcompatible);
var actual = processor.GetOutputFiles(outputDirectory, outputFilename);
var actual = processor.GetOutputFiles(null, outputDirectory, outputFilename);
Assert.Empty(actual);
}
@@ -26,10 +100,10 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = "test";
var processor = new Redumper(RedumpSystem.IBMPCcompatible, MediaType.CDROM);
var processor = new Redumper(RedumpSystem.IBMPCcompatible);
var actual = processor.GetOutputFiles(outputDirectory, outputFilename);
Assert.Equal(14, actual.Count);
var actual = processor.GetOutputFiles(MediaType.CDROM, outputDirectory, outputFilename);
Assert.Equal(16, actual.Count);
}
[Fact]
@@ -37,10 +111,10 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = "test";
var processor = new Redumper(RedumpSystem.IBMPCcompatible, MediaType.DVD);
var processor = new Redumper(RedumpSystem.IBMPCcompatible);
var actual = processor.GetOutputFiles(outputDirectory, outputFilename);
Assert.Equal(16, actual.Count);
var actual = processor.GetOutputFiles(MediaType.DVD, outputDirectory, outputFilename);
Assert.Equal(17, actual.Count);
}
[Fact]
@@ -48,9 +122,9 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = "test";
var processor = new Redumper(RedumpSystem.IBMPCcompatible, MediaType.HDDVD);
var processor = new Redumper(RedumpSystem.IBMPCcompatible);
var actual = processor.GetOutputFiles(outputDirectory, outputFilename);
var actual = processor.GetOutputFiles(MediaType.HDDVD, outputDirectory, outputFilename);
Assert.Equal(10, actual.Count);
}
@@ -59,9 +133,9 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = "test";
var processor = new Redumper(RedumpSystem.IBMPCcompatible, MediaType.BluRay);
var processor = new Redumper(RedumpSystem.IBMPCcompatible);
var actual = processor.GetOutputFiles(outputDirectory, outputFilename);
var actual = processor.GetOutputFiles(MediaType.BluRay, outputDirectory, outputFilename);
Assert.Equal(10, actual.Count);
}
@@ -70,9 +144,9 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = "test";
var processor = new Redumper(RedumpSystem.IBMPCcompatible, MediaType.ApertureCard);
var processor = new Redumper(RedumpSystem.IBMPCcompatible);
var actual = processor.GetOutputFiles(outputDirectory, outputFilename);
var actual = processor.GetOutputFiles(MediaType.ApertureCard, outputDirectory, outputFilename);
Assert.Empty(actual);
}
@@ -85,8 +159,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = string.Empty;
var processor = new Redumper(RedumpSystem.IBMPCcompatible, MediaType.CDROM);
var actual = processor.FoundAllFiles(outputDirectory, outputFilename);
var processor = new Redumper(RedumpSystem.IBMPCcompatible);
var actual = processor.FoundAllFiles(MediaType.CDROM, outputDirectory, outputFilename);
Assert.Equal(8, actual.Count);
}
@@ -95,8 +169,18 @@ namespace MPF.Processors.Test
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "Redumper", "CDROM");
string outputFilename = "test.cue";
var processor = new Redumper(RedumpSystem.IBMPCcompatible, MediaType.CDROM);
var actual = processor.FoundAllFiles(outputDirectory, outputFilename);
var processor = new Redumper(RedumpSystem.IBMPCcompatible);
var actual = processor.FoundAllFiles(MediaType.CDROM, outputDirectory, outputFilename);
Assert.Empty(actual);
}
[Fact]
public void FoundAllFiles_ValidZip_Empty()
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "Redumper", "CDROM-zip");
string outputFilename = "test.cue";
var processor = new Redumper(RedumpSystem.IBMPCcompatible);
var actual = processor.FoundAllFiles(MediaType.CDROM, outputDirectory, outputFilename);
Assert.Empty(actual);
}
@@ -109,8 +193,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = string.Empty;
var processor = new Redumper(RedumpSystem.IBMPCcompatible, MediaType.CDROM);
var actual = processor.FoundAnyFiles(outputDirectory, outputFilename);
var processor = new Redumper(RedumpSystem.IBMPCcompatible);
var actual = processor.FoundAnyFiles(MediaType.CDROM, outputDirectory, outputFilename);
Assert.False(actual);
}
@@ -119,8 +203,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "Redumper", "CDROM");
string outputFilename = "test.cue";
var processor = new Redumper(RedumpSystem.IBMPCcompatible, MediaType.CDROM);
var actual = processor.FoundAnyFiles(outputDirectory, outputFilename);
var processor = new Redumper(RedumpSystem.IBMPCcompatible);
var actual = processor.FoundAnyFiles(MediaType.CDROM, outputDirectory, outputFilename);
Assert.True(actual);
}
@@ -133,8 +217,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = string.Empty;
var processor = new Redumper(RedumpSystem.IBMPCcompatible, MediaType.CDROM);
var actual = processor.GenerateArtifacts(outputDirectory, outputFilename);
var processor = new Redumper(RedumpSystem.IBMPCcompatible);
var actual = processor.GenerateArtifacts(MediaType.CDROM, outputDirectory, outputFilename);
Assert.Empty(actual);
}
@@ -143,9 +227,9 @@ namespace MPF.Processors.Test
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "Redumper", "CDROM");
string outputFilename = "test.cue";
var processor = new Redumper(RedumpSystem.IBMPCcompatible, MediaType.CDROM);
var actual = processor.GenerateArtifacts(outputDirectory, outputFilename);
Assert.Equal(9, actual.Count);
var processor = new Redumper(RedumpSystem.IBMPCcompatible);
var actual = processor.GenerateArtifacts(MediaType.CDROM, outputDirectory, outputFilename);
Assert.Equal(10, actual.Count);
}
#endregion
@@ -157,8 +241,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = string.Empty;
var processor = new Redumper(RedumpSystem.IBMPCcompatible, MediaType.CDROM);
var actual = processor.GetDeleteableFilePaths(outputDirectory, outputFilename);
var processor = new Redumper(RedumpSystem.IBMPCcompatible);
var actual = processor.GetDeleteableFilePaths(MediaType.CDROM, outputDirectory, outputFilename);
Assert.Empty(actual);
}
@@ -167,8 +251,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "Redumper", "CDROM");
string outputFilename = "test.cue";
var processor = new Redumper(RedumpSystem.IBMPCcompatible, MediaType.CDROM);
var actual = processor.GetDeleteableFilePaths(outputDirectory, outputFilename);
var processor = new Redumper(RedumpSystem.IBMPCcompatible);
var actual = processor.GetDeleteableFilePaths(MediaType.CDROM, outputDirectory, outputFilename);
Assert.Single(actual);
}
@@ -181,8 +265,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = string.Empty;
var processor = new Redumper(RedumpSystem.IBMPCcompatible, MediaType.CDROM);
var actual = processor.GetZippableFilePaths(outputDirectory, outputFilename);
var processor = new Redumper(RedumpSystem.IBMPCcompatible);
var actual = processor.GetZippableFilePaths(MediaType.CDROM, outputDirectory, outputFilename);
Assert.Empty(actual);
}
@@ -191,9 +275,9 @@ namespace MPF.Processors.Test
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "Redumper", "CDROM");
string outputFilename = "test.cue";
var processor = new Redumper(RedumpSystem.IBMPCcompatible, MediaType.CDROM);
var actual = processor.GetZippableFilePaths(outputDirectory, outputFilename);
Assert.Equal(9, actual.Count);
var processor = new Redumper(RedumpSystem.IBMPCcompatible);
var actual = processor.GetZippableFilePaths(MediaType.CDROM, outputDirectory, outputFilename);
Assert.Equal(10, actual.Count);
}
#endregion
@@ -256,32 +340,154 @@ namespace MPF.Processors.Test
#endregion
#region GetDiscProfile
[Fact]
public void GetDiscProfile_Empty_Null()
{
string log = string.Empty;
bool actual = Redumper.GetDiscProfile(log, out string? discProfile);
Assert.False(actual);
Assert.Null(discProfile);
}
[Fact]
public void GetDiscProfile_Invalid_Null()
{
string log = "INVALID";
bool actual = Redumper.GetDiscProfile(log, out string? discProfile);
Assert.False(actual);
Assert.Null(discProfile);
}
[Fact]
public void GetDiscProfile_Valid_Filled()
{
string? expected = "CD-ROM";
string log = Path.Combine(Environment.CurrentDirectory, "TestData", "Redumper", "CDROM", "test.log");
bool actual = Redumper.GetDiscProfile(log, out string? discProfile);
Assert.True(actual);
Assert.Equal(expected, discProfile);
}
#endregion
#region GetDiscType
[Fact]
public void GetDiscType_Empty_Null()
{
string log = string.Empty;
bool actual = Redumper.GetDiscType(log, out string? discTypeOrBookType);
bool actual = Redumper.GetDiscType(log, out MediaType? discType);
Assert.False(actual);
Assert.Null(discType);
}
[Fact]
public void GetDiscType_Invalid_Null()
{
string log = "INVALID";
bool actual = Redumper.GetDiscType(log, out string? discTypeOrBookType);
bool actual = Redumper.GetDiscType(log, out MediaType? discType);
Assert.False(actual);
Assert.Null(discType);
}
[Fact]
public void GetDiscType_Valid_Filled()
public void GetDiscType_BD_Filled()
{
string? expected = "CD-ROM";
string log = Path.Combine(Environment.CurrentDirectory, "TestData", "Redumper", "CDROM", "test.log");
bool actual = Redumper.GetDiscType(log, out string? discTypeOrBookType);
MediaType? expected = MediaType.BluRay;
string log = Path.Combine(Environment.CurrentDirectory, "TestData", "Redumper", "BluRay", "test.log");
bool actual = Redumper.GetDiscType(log, out MediaType? discType);
Assert.True(actual);
Assert.Equal(expected, discTypeOrBookType);
Assert.Equal(expected, discType);
}
[Fact]
public void GetDiscType_BDR_Filled()
{
MediaType? expected = MediaType.BluRay;
string log = Path.Combine(Environment.CurrentDirectory, "TestData", "Redumper", "BDR", "test.log");
bool actual = Redumper.GetDiscType(log, out MediaType? discType);
Assert.True(actual);
Assert.Equal(expected, discType);
}
[Fact]
public void GetDiscType_CD_Filled()
{
MediaType? expected = MediaType.CDROM;
string log = Path.Combine(Environment.CurrentDirectory, "TestData", "Redumper", "CDROM", "test.log");
bool actual = Redumper.GetDiscType(log, out MediaType? discType);
Assert.True(actual);
Assert.Equal(expected, discType);
}
[Fact]
public void GetDiscType_DVD_Filled()
{
MediaType? expected = MediaType.DVD;
string log = Path.Combine(Environment.CurrentDirectory, "TestData", "Redumper", "DVD", "test.log");
bool actual = Redumper.GetDiscType(log, out MediaType? discType);
Assert.True(actual);
Assert.Equal(expected, discType);
}
[Fact]
public void GetDiscType_HDDVD_Filled()
{
MediaType? expected = MediaType.HDDVD;
string log = Path.Combine(Environment.CurrentDirectory, "TestData", "Redumper", "HDDVD", "test.log");
bool actual = Redumper.GetDiscType(log, out MediaType? discType);
Assert.True(actual);
Assert.Equal(expected, discType);
}
#endregion
#region GetDiscTypeFromProfile
[Theory]
[InlineData(null, null)]
[InlineData("", null)]
[InlineData("INVALID", null)]
[InlineData("reserved", null)]
[InlineData("non removable disk", null)]
[InlineData("removable disk", null)]
[InlineData("MO erasable", null)]
[InlineData("MO write once", null)]
[InlineData("AS MO", null)]
[InlineData("CD-ROM", MediaType.CDROM)]
[InlineData("CD-R", MediaType.CDROM)]
[InlineData("CD-RW", MediaType.CDROM)]
[InlineData("DVD-ROM", MediaType.DVD)]
[InlineData("DVD-R", MediaType.DVD)]
[InlineData("DVD-RAM", MediaType.DVD)]
[InlineData("DVD-RW RO", MediaType.DVD)]
[InlineData("DVD-RW", MediaType.DVD)]
[InlineData("DVD-R DL", MediaType.DVD)]
[InlineData("DVD-R DL LJR", MediaType.DVD)]
[InlineData("DVD+RW", MediaType.DVD)]
[InlineData("DVD+R", MediaType.DVD)]
[InlineData("DDCD-ROM", MediaType.CDROM)]
[InlineData("DDCD-R", MediaType.CDROM)]
[InlineData("DDCD-RW", MediaType.CDROM)]
[InlineData("DVD+RW DL", MediaType.DVD)]
[InlineData("DVD+R DL", MediaType.DVD)]
[InlineData("BD-ROM", MediaType.BluRay)]
[InlineData("BD-R", MediaType.BluRay)]
[InlineData("BD-R RRM", MediaType.BluRay)]
[InlineData("BD-RW", MediaType.BluRay)]
[InlineData("HD DVD-ROM", MediaType.HDDVD)]
[InlineData("HD DVD-R", MediaType.HDDVD)]
[InlineData("HD DVD-RAM", MediaType.HDDVD)]
[InlineData("HD DVD-RW", MediaType.HDDVD)]
[InlineData("HD DVD-R DL", MediaType.HDDVD)]
[InlineData("HD DVD-RW DL", MediaType.HDDVD)]
[InlineData("NON STANDARD", null)]
public void GetDiscTypeFromProfileTest(string? profile, MediaType? expected)
{
var actual = Redumper.GetDiscTypeFromProfile(profile);
Assert.Equal(expected, actual);
}
#endregion
@@ -997,7 +1203,7 @@ namespace MPF.Processors.Test
[Fact]
public void GetSCSIErrorCount_Valid_Filled()
{
long expected = 12345;
long expected = 23456;
string log = Path.Combine(Environment.CurrentDirectory, "TestData", "Redumper", "CDROM", "test.log");
long actual = Redumper.GetSCSIErrorCount(log);
Assert.Equal(expected, actual);
@@ -1170,7 +1376,7 @@ namespace MPF.Processors.Test
[Fact]
public void GetVersion_Valid_Filled()
{
string? expected = "v1980.01.01 build_00";
string? expected = "v1980.01.01 build_000";
string log = Path.Combine(Environment.CurrentDirectory, "TestData", "Redumper", "CDROM", "test.log");
string? actual = Redumper.GetVersion(log);
Assert.Equal(expected, actual);
@@ -1236,7 +1442,7 @@ namespace MPF.Processors.Test
[Fact]
public void GetWriteOffset_Valid_Filled()
{
string? expected = "offset";
string? expected = "+0";
string log = Path.Combine(Environment.CurrentDirectory, "TestData", "Redumper", "CDROM", "test.log");
string? actual = Redumper.GetWriteOffset(log);
Assert.Equal(expected, actual);

View File

@@ -0,0 +1 @@
TEST DATA

View File

@@ -1 +1,6 @@
TEST DATA
<CICMMetadata>
<OpticalDisc>
<DiscType>Compact Disc</DiscType>
<DiscSubType>CD-ROM</DiscSubType>
</OpticalDisc>
</CICMMetadata>

View File

@@ -0,0 +1 @@
TEST DATA

View File

@@ -0,0 +1,2 @@
<< GetDiscType >>
DiscTypeIdentifier: BDO

View File

@@ -0,0 +1 @@
TEST DATA

View File

@@ -0,0 +1 @@
TEST DATA

View File

@@ -0,0 +1 @@
TEST DATA

View File

@@ -0,0 +1 @@
TEST DATA

View File

@@ -0,0 +1,3 @@
<< GetDVDProtection >>
DecryptedDiscKey[020]: No Key
LBA: 0, Filename: FILE, No TitleKey

View File

@@ -1,8 +1,5 @@
<< GetDiscType >>
DiscType: CD-ROM
DiscTypeIdentifier: GD-ROM
DiscTypeSpecific: DVD-ROM
BookType: BD-ROM
<< GetDVDProtection >>
========== CopyrightInformation ==========

View File

@@ -0,0 +1,2 @@
<< GetDiscType >>
BookType: DVD-ROM

View File

@@ -0,0 +1,2 @@
<< GetDiscType >>
BookType: HD DVD-ROM

View File

@@ -0,0 +1 @@
TEST DATA

View File

@@ -0,0 +1,3 @@
<< GetDiscType >>
disc type: INVALID
disc type: BLURAY-R

View File

@@ -0,0 +1,3 @@
<< GetDiscType >>
disc type: INVALID
disc type: BLURAY

View File

@@ -0,0 +1 @@
TEST DATA

View File

@@ -0,0 +1 @@
TEST DATA

View File

@@ -0,0 +1 @@
TEST DATA

View File

@@ -0,0 +1 @@
TEST DATA

View File

@@ -1,5 +1,5 @@
DUMPING DATE (DateTime.Now)
redumper v1980.01.01 build_00 [Jan 01 1980, 00:00:00]
redumper v1980.01.01 build_000
<< GetVersion (above) >>
<< GetParameters >>
@@ -13,9 +13,13 @@ CUE [
dat:
<rom name="INVALID" size="12345" crc="00000000" md5="d41d8cd98f00b204e9800998ecf8427e" sha1="da39a3ee5e6b4b0d3255bfef95601890afd80709" />
<< GetDiscType >>
<< GetDiscProfile >>
current profile: CD-ROM
<< GetDiscType >>
disc type: INVALID
disc type: CD
<< GetDVDProtection >>
copyright:
protection system type: none
@@ -31,6 +35,8 @@ REDUMP.ORG errors: 12345
C2: 1
REDUMP.ORG errors: 2
C2: 12 samples
<< GetGDROMHeader >>
DC [
build date: date
@@ -127,8 +133,8 @@ SS [
00F0 TEST DATA
<< GetSCSIErrorCount >>
SCSI: 23456 samples
SCSI: 12345
SCSI: 23456
SCSI: 12345 samples
<< GetSecuROMData >>
SecuROM [
@@ -162,4 +168,4 @@ Universal Hash (SHA-1): da39a3ee5e6b4b0d3255bfef95601890afd80709
volume identifier: label
<< GetWriteOffset >>
disc write offset: offset
disc write offset: +0

View File

@@ -0,0 +1,3 @@
<< GetDiscType >>
disc type: INVALID
disc type: DVD

View File

@@ -0,0 +1,3 @@
<< GetDiscType >>
disc type: INVALID
disc type: HD-DVD

View File

@@ -0,0 +1 @@
TEST DATA

View File

@@ -0,0 +1 @@
TEST DATA

View File

@@ -8,17 +8,51 @@ namespace MPF.Processors.Test
{
public class UmdImageCreatorTests
{
#region DetermineMediaType
[Fact]
public void DetermineMediaType_Null_DVD()
{
string? outputDirectory = null;
string outputFilename = string.Empty;
var processor = new UmdImageCreator(RedumpSystem.SonyPlayStationPortable);
var actual = processor.DetermineMediaType(outputDirectory, outputFilename);
Assert.Equal(MediaType.UMD, actual);
}
[Fact]
public void DetermineMediaType_Invalid_DVD()
{
string? outputDirectory = null;
string outputFilename = "INVALID";
var processor = new UmdImageCreator(RedumpSystem.SonyPlayStationPortable);
var actual = processor.DetermineMediaType(outputDirectory, outputFilename);
Assert.Equal(MediaType.UMD, actual);
}
[Fact]
public void DetermineMediaType_Valid_DVD()
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "UmdImageCreator", "UMD");
string outputFilename = "test";
var processor = new UmdImageCreator(RedumpSystem.SonyPlayStationPortable);
var actual = processor.DetermineMediaType(outputDirectory, outputFilename);
Assert.Equal(MediaType.UMD, actual);
}
#endregion
#region GetOutputFiles
[Fact]
public void GetOutputFiles_Null_Empty()
public void GetOutputFiles_Null_Populated()
{
string? outputDirectory = null;
string outputFilename = "test";
var processor = new UmdImageCreator(RedumpSystem.SonyPlayStationPortable, null);
var processor = new UmdImageCreator(RedumpSystem.SonyPlayStationPortable);
var actual = processor.GetOutputFiles(outputDirectory, outputFilename);
Assert.Empty(actual);
var actual = processor.GetOutputFiles(null, outputDirectory, outputFilename);
Assert.Equal(7, actual.Count);
}
[Fact]
@@ -26,21 +60,21 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = "test";
var processor = new UmdImageCreator(RedumpSystem.SonyPlayStationPortable, MediaType.UMD);
var processor = new UmdImageCreator(RedumpSystem.SonyPlayStationPortable);
var actual = processor.GetOutputFiles(outputDirectory, outputFilename);
var actual = processor.GetOutputFiles(MediaType.UMD, outputDirectory, outputFilename);
Assert.Equal(7, actual.Count);
}
[Fact]
public void GetOutputFiles_Other_Empty()
public void GetOutputFiles_Other_Populated()
{
string? outputDirectory = null;
string outputFilename = "test";
var processor = new UmdImageCreator(RedumpSystem.SonyPlayStationPortable, MediaType.ApertureCard);
var processor = new UmdImageCreator(RedumpSystem.SonyPlayStationPortable);
var actual = processor.GetOutputFiles(outputDirectory, outputFilename);
Assert.Empty(actual);
var actual = processor.GetOutputFiles(MediaType.ApertureCard, outputDirectory, outputFilename);
Assert.Equal(7, actual.Count);
}
#endregion
@@ -52,8 +86,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = string.Empty;
var processor = new UmdImageCreator(RedumpSystem.SonyPlayStationPortable, MediaType.UMD);
var actual = processor.FoundAllFiles(outputDirectory, outputFilename);
var processor = new UmdImageCreator(RedumpSystem.SonyPlayStationPortable);
var actual = processor.FoundAllFiles(MediaType.UMD, outputDirectory, outputFilename);
Assert.Equal(5, actual.Count);
}
@@ -62,8 +96,18 @@ namespace MPF.Processors.Test
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "UmdImageCreator", "UMD");
string outputFilename = "test.iso";
var processor = new UmdImageCreator(RedumpSystem.SonyPlayStationPortable, MediaType.UMD);
var actual = processor.FoundAllFiles(outputDirectory, outputFilename);
var processor = new UmdImageCreator(RedumpSystem.SonyPlayStationPortable);
var actual = processor.FoundAllFiles(MediaType.UMD, outputDirectory, outputFilename);
Assert.Empty(actual);
}
[Fact]
public void FoundAllFiles_ValidZip_Empty()
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "UmdImageCreator", "UMD-zip");
string outputFilename = "test.iso";
var processor = new UmdImageCreator(RedumpSystem.SonyPlayStationPortable);
var actual = processor.FoundAllFiles(MediaType.UMD, outputDirectory, outputFilename);
Assert.Empty(actual);
}
@@ -76,8 +120,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = string.Empty;
var processor = new UmdImageCreator(RedumpSystem.SonyPlayStationPortable, MediaType.UMD);
var actual = processor.FoundAnyFiles(outputDirectory, outputFilename);
var processor = new UmdImageCreator(RedumpSystem.SonyPlayStationPortable);
var actual = processor.FoundAnyFiles(MediaType.UMD, outputDirectory, outputFilename);
Assert.False(actual);
}
@@ -86,8 +130,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "UmdImageCreator", "UMD");
string outputFilename = "test.iso";
var processor = new UmdImageCreator(RedumpSystem.SonyPlayStationPortable, MediaType.UMD);
var actual = processor.FoundAnyFiles(outputDirectory, outputFilename);
var processor = new UmdImageCreator(RedumpSystem.SonyPlayStationPortable);
var actual = processor.FoundAnyFiles(MediaType.UMD, outputDirectory, outputFilename);
Assert.True(actual);
}
@@ -100,8 +144,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = string.Empty;
var processor = new UmdImageCreator(RedumpSystem.SonyPlayStationPortable, MediaType.UMD);
var actual = processor.GenerateArtifacts(outputDirectory, outputFilename);
var processor = new UmdImageCreator(RedumpSystem.SonyPlayStationPortable);
var actual = processor.GenerateArtifacts(MediaType.UMD, outputDirectory, outputFilename);
Assert.Empty(actual);
}
@@ -110,8 +154,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "UmdImageCreator", "UMD");
string outputFilename = "test.iso";
var processor = new UmdImageCreator(RedumpSystem.SonyPlayStationPortable, MediaType.UMD);
var actual = processor.GenerateArtifacts(outputDirectory, outputFilename);
var processor = new UmdImageCreator(RedumpSystem.SonyPlayStationPortable);
var actual = processor.GenerateArtifacts(MediaType.UMD, outputDirectory, outputFilename);
Assert.Equal(6, actual.Count);
}
@@ -124,8 +168,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = string.Empty;
var processor = new UmdImageCreator(RedumpSystem.SonyPlayStationPortable, MediaType.UMD);
var actual = processor.GetDeleteableFilePaths(outputDirectory, outputFilename);
var processor = new UmdImageCreator(RedumpSystem.SonyPlayStationPortable);
var actual = processor.GetDeleteableFilePaths(MediaType.UMD, outputDirectory, outputFilename);
Assert.Empty(actual);
}
@@ -134,8 +178,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "UmdImageCreator", "UMD");
string outputFilename = "test.iso";
var processor = new UmdImageCreator(RedumpSystem.SonyPlayStationPortable, MediaType.UMD);
var actual = processor.GetDeleteableFilePaths(outputDirectory, outputFilename);
var processor = new UmdImageCreator(RedumpSystem.SonyPlayStationPortable);
var actual = processor.GetDeleteableFilePaths(MediaType.UMD, outputDirectory, outputFilename);
Assert.Empty(actual);
}
@@ -148,8 +192,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = string.Empty;
var processor = new UmdImageCreator(RedumpSystem.SonyPlayStationPortable, MediaType.UMD);
var actual = processor.GetZippableFilePaths(outputDirectory, outputFilename);
var processor = new UmdImageCreator(RedumpSystem.SonyPlayStationPortable);
var actual = processor.GetZippableFilePaths(MediaType.UMD, outputDirectory, outputFilename);
Assert.Empty(actual);
}
@@ -158,8 +202,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "UmdImageCreator", "UMD");
string outputFilename = "test.iso";
var processor = new UmdImageCreator(RedumpSystem.SonyPlayStationPortable, MediaType.UMD);
var actual = processor.GetZippableFilePaths(outputDirectory, outputFilename);
var processor = new UmdImageCreator(RedumpSystem.SonyPlayStationPortable);
var actual = processor.GetZippableFilePaths(MediaType.UMD, outputDirectory, outputFilename);
Assert.Equal(6, actual.Count);
}
@@ -279,7 +323,7 @@ namespace MPF.Processors.Test
{
string volDesc = string.Empty;
bool actual = UmdImageCreator.GetVolumeLabels(volDesc, out Dictionary<string, List<string>> volLabels);
Assert.False(actual);
Assert.Empty(volLabels);
}
@@ -289,7 +333,7 @@ namespace MPF.Processors.Test
{
string volDesc = "INVALID";
bool actual = UmdImageCreator.GetVolumeLabels(volDesc, out Dictionary<string, List<string>> volLabels);
Assert.False(actual);
Assert.Empty(volLabels);
}

View File

@@ -8,17 +8,51 @@ namespace MPF.Processors.Test
// TODO: Add tests for RecreateSS
public class XboxBackupCreatorTests
{
#region DetermineMediaType
[Fact]
public void DetermineMediaType_Empty_DVD()
{
string? outputDirectory = null;
string outputFilename = string.Empty;
var processor = new XboxBackupCreator(RedumpSystem.MicrosoftXbox);
var actual = processor.DetermineMediaType(outputDirectory, outputFilename);
Assert.Equal(MediaType.DVD, actual);
}
[Fact]
public void DetermineMediaType_Invalid_DVD()
{
string? outputDirectory = null;
string outputFilename = "INVALID";
var processor = new XboxBackupCreator(RedumpSystem.MicrosoftXbox);
var actual = processor.DetermineMediaType(outputDirectory, outputFilename);
Assert.Equal(MediaType.DVD, actual);
}
[Fact]
public void DetermineMediaType_Valid_DVD()
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "XboxBackupCreator", "DVD");
string outputFilename = "test";
var processor = new XboxBackupCreator(RedumpSystem.MicrosoftXbox);
var actual = processor.DetermineMediaType(outputDirectory, outputFilename);
Assert.Equal(MediaType.DVD, actual);
}
#endregion
#region GetOutputFiles
[Fact]
public void GetOutputFiles_Null_Empty()
public void GetOutputFiles_Null_Populated()
{
string? outputDirectory = null;
string outputFilename = "test";
var processor = new XboxBackupCreator(RedumpSystem.MicrosoftXbox, null);
var processor = new XboxBackupCreator(RedumpSystem.MicrosoftXbox);
var actual = processor.GetOutputFiles(outputDirectory, outputFilename);
Assert.Empty(actual);
var actual = processor.GetOutputFiles(null, outputDirectory, outputFilename);
Assert.Equal(7, actual.Count);
}
[Fact]
@@ -26,21 +60,21 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = "test";
var processor = new XboxBackupCreator(RedumpSystem.MicrosoftXbox, MediaType.DVD);
var processor = new XboxBackupCreator(RedumpSystem.MicrosoftXbox);
var actual = processor.GetOutputFiles(outputDirectory, outputFilename);
var actual = processor.GetOutputFiles(MediaType.DVD, outputDirectory, outputFilename);
Assert.Equal(7, actual.Count);
}
[Fact]
public void GetOutputFiles_Other_Empty()
public void GetOutputFiles_Other_Populated()
{
string? outputDirectory = null;
string outputFilename = "test";
var processor = new XboxBackupCreator(RedumpSystem.MicrosoftXbox, MediaType.ApertureCard);
var processor = new XboxBackupCreator(RedumpSystem.MicrosoftXbox);
var actual = processor.GetOutputFiles(outputDirectory, outputFilename);
Assert.Empty(actual);
var actual = processor.GetOutputFiles(MediaType.ApertureCard, outputDirectory, outputFilename);
Assert.Equal(7, actual.Count);
}
#endregion
@@ -52,8 +86,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = string.Empty;
var processor = new XboxBackupCreator(RedumpSystem.MicrosoftXbox, MediaType.DVD);
var actual = processor.FoundAllFiles(outputDirectory, outputFilename);
var processor = new XboxBackupCreator(RedumpSystem.MicrosoftXbox);
var actual = processor.FoundAllFiles(MediaType.DVD, outputDirectory, outputFilename);
Assert.Equal(5, actual.Count);
}
@@ -62,8 +96,18 @@ namespace MPF.Processors.Test
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "XboxBackupCreator", "DVD");
string outputFilename = "test.iso";
var processor = new XboxBackupCreator(RedumpSystem.MicrosoftXbox, MediaType.DVD);
var actual = processor.FoundAllFiles(outputDirectory, outputFilename);
var processor = new XboxBackupCreator(RedumpSystem.MicrosoftXbox);
var actual = processor.FoundAllFiles(MediaType.DVD, outputDirectory, outputFilename);
Assert.Empty(actual);
}
[Fact]
public void FoundAllFiles_ValidZip_Empty()
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "XboxBackupCreator", "DVD-zip");
string outputFilename = "test.iso";
var processor = new XboxBackupCreator(RedumpSystem.MicrosoftXbox);
var actual = processor.FoundAllFiles(MediaType.DVD, outputDirectory, outputFilename);
Assert.Empty(actual);
}
@@ -76,8 +120,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = string.Empty;
var processor = new XboxBackupCreator(RedumpSystem.MicrosoftXbox, MediaType.DVD);
var actual = processor.FoundAnyFiles(outputDirectory, outputFilename);
var processor = new XboxBackupCreator(RedumpSystem.MicrosoftXbox);
var actual = processor.FoundAnyFiles(MediaType.DVD, outputDirectory, outputFilename);
Assert.False(actual);
}
@@ -86,8 +130,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "XboxBackupCreator", "DVD");
string outputFilename = "test.iso";
var processor = new XboxBackupCreator(RedumpSystem.MicrosoftXbox, MediaType.DVD);
var actual = processor.FoundAnyFiles(outputDirectory, outputFilename);
var processor = new XboxBackupCreator(RedumpSystem.MicrosoftXbox);
var actual = processor.FoundAnyFiles(MediaType.DVD, outputDirectory, outputFilename);
Assert.True(actual);
}
@@ -100,8 +144,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = string.Empty;
var processor = new XboxBackupCreator(RedumpSystem.MicrosoftXbox, MediaType.DVD);
var actual = processor.GenerateArtifacts(outputDirectory, outputFilename);
var processor = new XboxBackupCreator(RedumpSystem.MicrosoftXbox);
var actual = processor.GenerateArtifacts(MediaType.DVD, outputDirectory, outputFilename);
Assert.Empty(actual);
}
@@ -110,8 +154,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "XboxBackupCreator", "DVD");
string outputFilename = "test.iso";
var processor = new XboxBackupCreator(RedumpSystem.MicrosoftXbox, MediaType.DVD);
var actual = processor.GenerateArtifacts(outputDirectory, outputFilename);
var processor = new XboxBackupCreator(RedumpSystem.MicrosoftXbox);
var actual = processor.GenerateArtifacts(MediaType.DVD, outputDirectory, outputFilename);
Assert.Equal(6, actual.Count);
}
@@ -124,8 +168,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = string.Empty;
var processor = new XboxBackupCreator(RedumpSystem.MicrosoftXbox, MediaType.DVD);
var actual = processor.GetDeleteableFilePaths(outputDirectory, outputFilename);
var processor = new XboxBackupCreator(RedumpSystem.MicrosoftXbox);
var actual = processor.GetDeleteableFilePaths(MediaType.DVD, outputDirectory, outputFilename);
Assert.Empty(actual);
}
@@ -134,8 +178,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "XboxBackupCreator", "DVD");
string outputFilename = "test.iso";
var processor = new XboxBackupCreator(RedumpSystem.MicrosoftXbox, MediaType.DVD);
var actual = processor.GetDeleteableFilePaths(outputDirectory, outputFilename);
var processor = new XboxBackupCreator(RedumpSystem.MicrosoftXbox);
var actual = processor.GetDeleteableFilePaths(MediaType.DVD, outputDirectory, outputFilename);
Assert.Empty(actual);
}
@@ -148,8 +192,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = null;
string outputFilename = string.Empty;
var processor = new XboxBackupCreator(RedumpSystem.MicrosoftXbox, MediaType.DVD);
var actual = processor.GetZippableFilePaths(outputDirectory, outputFilename);
var processor = new XboxBackupCreator(RedumpSystem.MicrosoftXbox);
var actual = processor.GetZippableFilePaths(MediaType.DVD, outputDirectory, outputFilename);
Assert.Empty(actual);
}
@@ -158,8 +202,8 @@ namespace MPF.Processors.Test
{
string? outputDirectory = Path.Combine(Environment.CurrentDirectory, "TestData", "XboxBackupCreator", "DVD");
string outputFilename = "test.iso";
var processor = new XboxBackupCreator(RedumpSystem.MicrosoftXbox, MediaType.DVD);
var actual = processor.GetZippableFilePaths(outputDirectory, outputFilename);
var processor = new XboxBackupCreator(RedumpSystem.MicrosoftXbox);
var actual = processor.GetZippableFilePaths(MediaType.DVD, outputDirectory, outputFilename);
Assert.Equal(6, actual.Count);
}
@@ -330,7 +374,7 @@ namespace MPF.Processors.Test
{
long expected = -1;
string? log = null;
var processor = new XboxBackupCreator(RedumpSystem.MicrosoftXbox, MediaType.DVD);
var processor = new XboxBackupCreator(RedumpSystem.MicrosoftXbox);
bool actual = processor.GetReadErrors(log, out long readErrors);
Assert.False(actual);
@@ -342,7 +386,7 @@ namespace MPF.Processors.Test
{
long expected = -1;
string? log = string.Empty;
var processor = new XboxBackupCreator(RedumpSystem.MicrosoftXbox, MediaType.DVD);
var processor = new XboxBackupCreator(RedumpSystem.MicrosoftXbox);
bool actual = processor.GetReadErrors(log, out long readErrors);
Assert.False(actual);
@@ -354,7 +398,7 @@ namespace MPF.Processors.Test
{
long expected = -1;
string? log = "INVALID";
var processor = new XboxBackupCreator(RedumpSystem.MicrosoftXbox, MediaType.DVD);
var processor = new XboxBackupCreator(RedumpSystem.MicrosoftXbox);
bool actual = processor.GetReadErrors(log, out long readErrors);
Assert.False(actual);
@@ -366,7 +410,7 @@ namespace MPF.Processors.Test
{
long expected = 0;
string? log = Path.Combine(Environment.CurrentDirectory, "TestData", "XboxBackupCreator", "DVD", "log.txt");
var processor = new XboxBackupCreator(RedumpSystem.MicrosoftXbox, MediaType.DVD);
var processor = new XboxBackupCreator(RedumpSystem.MicrosoftXbox);
bool actual = processor.GetReadErrors(log, out long readErrors);
Assert.True(actual);
@@ -381,7 +425,7 @@ namespace MPF.Processors.Test
public void GetMediaID_Null_Null()
{
string? log = null;
var processor = new XboxBackupCreator(RedumpSystem.MicrosoftXbox360, MediaType.DVD);
var processor = new XboxBackupCreator(RedumpSystem.MicrosoftXbox360);
string? actual = processor.GetMediaID(log);
Assert.Null(actual);
}
@@ -390,7 +434,7 @@ namespace MPF.Processors.Test
public void GetMediaID_Empty_Null()
{
string? log = string.Empty;
var processor = new XboxBackupCreator(RedumpSystem.MicrosoftXbox360, MediaType.DVD);
var processor = new XboxBackupCreator(RedumpSystem.MicrosoftXbox360);
string? actual = processor.GetMediaID(log);
Assert.Null(actual);
}
@@ -399,7 +443,7 @@ namespace MPF.Processors.Test
public void GetMediaID_Invalid_Null()
{
string? log = "INVALID";
var processor = new XboxBackupCreator(RedumpSystem.MicrosoftXbox360, MediaType.DVD);
var processor = new XboxBackupCreator(RedumpSystem.MicrosoftXbox360);
string? actual = processor.GetMediaID(log);
Assert.Null(actual);
}
@@ -409,7 +453,7 @@ namespace MPF.Processors.Test
{
string? expected = "8B62A812";
string? log = Path.Combine(Environment.CurrentDirectory, "TestData", "XboxBackupCreator", "DVD", "log.txt");
var processor = new XboxBackupCreator(RedumpSystem.MicrosoftXbox360, MediaType.DVD);
var processor = new XboxBackupCreator(RedumpSystem.MicrosoftXbox360);
string? actual = processor.GetMediaID(log);
Assert.Equal(expected, actual);
}

View File

@@ -22,12 +22,35 @@ namespace MPF.Processors
public sealed class Aaru : BaseProcessor
{
/// <inheritdoc/>
public Aaru(RedumpSystem? system, MediaType? type) : base(system, type) { }
public Aaru(RedumpSystem? system) : base(system) { }
#region BaseProcessor Implementations
/// <inheritdoc/>
public override void GenerateSubmissionInfo(SubmissionInfo info, string basePath, bool redumpCompat)
public override MediaType? DetermineMediaType(string? outputDirectory, string outputFilename)
{
// If the filename is invalid
if (string.IsNullOrEmpty(outputFilename))
return null;
// Reassemble the base path
string basePath = Path.GetFileNameWithoutExtension(outputFilename);
if (!string.IsNullOrEmpty(outputDirectory))
basePath = Path.Combine(outputDirectory, basePath);
// Deserialize the sidecar, if possible
var sidecar = GenerateSidecar($"{basePath}.cicm.xml");
// Extract the disc type strings, if possible
if (GetDiscType(sidecar, out string? discType, out string? discSubType))
return GetDiscTypeFromStrings(discType, discSubType);
// The type could not be determined
return null;
}
/// <inheritdoc/>
public override void GenerateSubmissionInfo(SubmissionInfo info, MediaType? mediaType, string basePath, bool redumpCompat)
{
// TODO: Fill in submission info specifics for Aaru
var outputDirectory = Path.GetDirectoryName(basePath);
@@ -36,10 +59,10 @@ namespace MPF.Processors
info = Builder.EnsureAllSections(info);
// TODO: Determine if there's an Aaru version anywhere
info.DumpingInfo!.DumpingDate = ProcessingTool.GetFileModifiedDate(basePath + ".cicm.xml")?.ToString("yyyy-MM-dd HH:mm:ss");
info.DumpingInfo!.DumpingDate = ProcessingTool.GetFileModifiedDate($"{basePath}.cicm.xml")?.ToString("yyyy-MM-dd HH:mm:ss");
// Deserialize the sidecar, if possible
var sidecar = GenerateSidecar(basePath + ".cicm.xml");
var sidecar = GenerateSidecar($"{basePath}.cicm.xml");
// Fill in the hardware data
if (GetHardwareInfo(sidecar, out var manufacturer, out var model, out var firmware))
@@ -63,31 +86,29 @@ namespace MPF.Processors
info.DumpingInfo.ReportedDiscType = fullDiscType;
}
// TODO: Re-enable once PVD generation / finding is fixed
// Generate / obtain the PVD
//info.Extras.PVD = GeneratePVD(sidecar) ?? "Disc has no PVD";
// Get the Datafile information
var datafile = GenerateDatafile(sidecar, basePath);
// Fill in the hash data
info.TracksAndWriteOffsets!.ClrMameProData = ProcessingTool.GenerateDatfile(datafile);
switch (Type)
// Get the error count
long errorCount = GetErrorCount($"{basePath}.resume.xml");
info.CommonDiscInfo!.ErrorsCount = (errorCount == -1 ? "Error retrieving error count" : errorCount.ToString());
// Get the write offset, if it exists
string? writeOffset = GetWriteOffset(sidecar);
info.CommonDiscInfo.RingWriteOffset = writeOffset;
info.TracksAndWriteOffsets.OtherWriteOffsets = writeOffset;
// Extract info based generically on MediaType
switch (mediaType)
{
// 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";
long errorCount = -1;
if (File.Exists(basePath + ".resume.xml"))
errorCount = GetErrorCount(basePath + ".resume.xml");
info.CommonDiscInfo!.ErrorsCount = (errorCount == -1 ? "Error retrieving error count" : errorCount.ToString());
info.TracksAndWriteOffsets.Cuesheet = GenerateCuesheet(sidecar, basePath) ?? string.Empty;
string cdWriteOffset = GetWriteOffset(sidecar) ?? string.Empty;
info.CommonDiscInfo.RingWriteOffset = cdWriteOffset;
info.TracksAndWriteOffsets.OtherWriteOffsets = cdWriteOffset;
break;
case MediaType.DVD:
@@ -97,21 +118,18 @@ namespace MPF.Processors
// Get the individual hash data, as per internal
if (ProcessingTool.GetISOHashValues(datafile, out long size, out var crc32, out var md5, out var sha1))
{
info.SizeAndChecksums!.CRC32 = crc32;
info.SizeAndChecksums!.Size = size;
info.SizeAndChecksums.CRC32 = crc32;
info.SizeAndChecksums.MD5 = md5;
info.SizeAndChecksums.SHA1 = sha1;
}
// TODO: Re-enable once PVD generation / finding is fixed
// Generate / obtain the PVD
//info.Extras.PVD = GeneratePVD(sidecar) ?? "Disc has no PVD";
// TODO: Sync layerbreak finding with other processors
// Deal with the layerbreak
string? layerbreak = null;
if (Type == MediaType.DVD)
if (mediaType == MediaType.DVD)
layerbreak = GetLayerbreak(sidecar) ?? string.Empty;
else if (Type == MediaType.BluRay)
else if (mediaType == MediaType.BluRay)
layerbreak = info.SizeAndChecksums!.Size > 25_025_314_816 ? "25025314816" : null;
// If we have a single-layer disc
@@ -185,12 +203,12 @@ namespace MPF.Processors
}
/// <inheritdoc/>
internal override List<OutputFile> GetOutputFiles(string? outputDirectory, string outputFilename)
internal override List<OutputFile> GetOutputFiles(MediaType? mediaType, string? outputDirectory, string outputFilename)
{
// Remove the extension by default
outputFilename = Path.GetFileNameWithoutExtension(outputFilename);
switch (Type)
switch (mediaType)
{
case MediaType.CDROM:
return [
@@ -889,6 +907,156 @@ namespace MPF.Processors
return !string.IsNullOrEmpty(discType) || !string.IsNullOrEmpty(discSubType);
}
/// <summary>
/// Convert the type and subtype to a media type, if possible
/// </summary>
/// <param name="discType">Disc type string to check</param>
/// <param name="discSubType">Disc subtype string to check</param>
/// <returns>Media type on success, null otherwise</returns>
internal static MediaType? GetDiscTypeFromStrings(string? discType, string? discSubType)
{
return discType switch
{
"3\" floppy" => MediaType.FloppyDisk,
"3.5\" floppy" => MediaType.FloppyDisk,
"3.5\" magneto-optical" => MediaType.Floptical,
"3.5\" SyQuest cartridge" => null,
"3.9\" SyQuest cartridge" => null,
"5.25\" floppy" => MediaType.FloppyDisk,
"5.25\" magneto-optical" => MediaType.Floptical,
"5.25\" SyQuest cartridge" => null,
"8\" floppy" => MediaType.FloppyDisk,
"300mm magneto optical" => MediaType.Floptical,
"356mm magneto-optical" => MediaType.Floptical,
"Advanced Digital Recording" => null,
"Advanced Intelligent Tape" => null,
"Archival Disc" => null,
"BeeCard" => null,
"Blu-ray" => discSubType switch
{
"Wii U Optical Disc" => MediaType.NintendoWiiUOpticalDisc,
_ => MediaType.BluRay,
},
"Borsu" => null,
"Compact Cassette" => MediaType.Cassette,
"Compact Disc" => MediaType.CDROM,
"Compact Flash" => MediaType.CompactFlash,
"CompacTape" => null,
"CRVdisc" => null,
"Data8" => null,
"DataPlay" => null,
"DataStore" => null,
"DDCD" => MediaType.CDROM,
"DECtape" => null,
"DemiDiskette" => null,
"Digital Audio Tape" => null,
"Digital Data Storage" => MediaType.DataCartridge,
"Digital Linear Tape" => null,
"DIR" => null,
"DST" => null,
"DTF" => null,
"DTF2" => null,
"DV tape" => null,
"DVD" => discSubType switch
{
"GameCube Game Disc" => MediaType.NintendoGameCubeGameDisc,
"Wii Optical Disc" => MediaType.NintendoWiiOpticalDisc,
_ => MediaType.DVD,
},
"EVD" => null,
"Exatape" => null,
"Express Card" => null,
"FDDVD" => null,
"Flextra" => null,
"Floptical" => MediaType.Floptical,
"FVD" => null,
"GD" => MediaType.GDROM,
"Hard Disk Drive" => MediaType.HardDisk,
"HD DVD" => MediaType.HDDVD,
"HD VMD" => null,
"HiFD" => MediaType.FloppyDisk,
"HiTC" => null,
"HuCard" => MediaType.Cartridge,
"HVD" => null,
"HyperFlex" => null,
"IBM 3470" => null,
"IBM 3480" => null,
"IBM 3490" => null,
"IBM 3490E" => null,
"IBM 3592" => null,
"Iomega Bernoulli Box" => MediaType.IomegaBernoulliDisk,
"Iomega Bernoulli Box II" => MediaType.IomegaBernoulliDisk,
"Iomega Ditto" => null,
"Iomega Jaz" => MediaType.IomegaJaz,
"Iomega PocketZip" => MediaType.IomegaZip,
"Iomega REV" => null,
"Iomega ZIP" => MediaType.IomegaZip,
"Kodak Verbatim" => null,
"LaserDisc" => MediaType.LaserDisc,
"Linear Tape-Open" => null,
"LT1" => null,
"Magneto-optical" => MediaType.Floptical,
"Memory Stick" => MediaType.SDCard,
"MiniCard" => null,
"MiniDisc" => null,
"MultiMediaCard" => MediaType.SDCard,
"Nintendo 3DS Game Card" => MediaType.Cartridge,
"Nintendo 64 Disk" => MediaType.Nintendo64DD,
"Nintendo 64 Game Pak" => MediaType.Cartridge,
"Nintendo Disk Card" => MediaType.NintendoFamicomDiskSystem,
"Nintendo DS Game Card" => MediaType.Cartridge,
"Nintendo DSi Game Card" => MediaType.Cartridge,
"Nintendo Entertainment System Game Pak" => MediaType.Cartridge,
"Nintendo Famicom Game Pak" => MediaType.Cartridge,
"Nintendo Game Boy Advance Game Pak" => MediaType.Cartridge,
"Nintendo Game Boy Game Pak" => MediaType.Cartridge,
"Nintendo Switch Game Card" => MediaType.Cartridge,
"Optical Disc Archive" => null,
"Orb" => null,
"PCMCIA Card" => null,
"PD650" => null,
"PlayStation Memory Card" => null,
"Quarter-inch cartridge" => MediaType.DataCartridge,
"Quarter-inch mini cartridge" => MediaType.DataCartridge,
"QuickDisk" => null,
"RDX" => null,
"SACD" => MediaType.DVD,
"Scalable Linear Recording" => null,
"Secure Digital" => MediaType.SDCard,
"SmartMedia" => MediaType.SDCard,
"Sony Professional Disc" => null,
"Sony Professional Disc for DATA" => null,
"STK 4480" => null,
"STK 4490" => null,
"STK 9490" => null,
"STK T-9840" => null,
"STK T-9940" => null,
"STK T-10000" => null,
"Super Advanced Intelligent Tape" => null,
"Super Digital Linear Tape" => null,
"Super Nintendo Game Pak" => MediaType.Cartridge,
"Super Nintendo Game Pak (US)" => MediaType.Cartridge,
"SuperDisk" => MediaType.FloppyDisk,
"SVOD" => null,
"Travan" => null,
"UDO" => null,
"UHD144" => null,
"UMD" => MediaType.UMD,
"Unknown" => null,
"USB flash drive" => MediaType.FlashDrive,
"VCDHD" => null,
"VideoFloppy" => null,
"VideoNow" => MediaType.CDROM,
"VXA" => MediaType.FlashDrive,
"Wafer" => null,
"xD" => null,
"XQD" => null,
"Zoned Hard Disk Drive" => MediaType.HardDisk,
"ZX Microdrive" => null,
_ => null,
};
}
/// <summary>
/// Get the DVD protection information, if possible
/// </summary>

View File

@@ -5,6 +5,8 @@ using System.IO;
using System.IO.Compression;
#endif
using System.Text;
using SabreTools.Hashing;
using SabreTools.Models.Logiqx;
using SabreTools.RedumpLib.Data;
namespace MPF.Processors
@@ -23,42 +25,45 @@ namespace MPF.Processors
/// </summary>
public RedumpSystem? System { get; private set; }
/// <summary>
/// Currently represented media type
/// </summary>
public MediaType? Type { get; private set; }
#endregion
/// <summary>
/// Generate processor for a system and media type combination
/// </summary>
/// <param name="system">RedumpSystem value to use</param>
/// <param name="type">MediaType value to use</param>
public BaseProcessor(RedumpSystem? system, MediaType? type)
public BaseProcessor(RedumpSystem? system)
{
System = system;
Type = type;
}
#region Abstract Methods
/// <summary>
/// Determine the media type based on the provided files
/// </summary>
/// <param name="outputDirectory">Output folder to use as the base path</param>
/// <param name="outputFilename">Output filename to use as the base path</param>
/// <returns>MediaType that was determined, if possible</returns>
public abstract MediaType? DetermineMediaType(string? outputDirectory, string outputFilename);
/// <summary>
/// Generate a SubmissionInfo for the output files
/// </summary>
/// <param name="submissionInfo">Base submission info to fill in specifics for</param>
/// <param name="mediaType">Media type for specific information gathering</param>
/// <param name="basePath">Base filename and path to use for checking</param>
/// <param name="redumpCompat">Determines if outputs are processed according to Redump specifications</param>
public abstract void GenerateSubmissionInfo(SubmissionInfo submissionInfo, string basePath, bool redumpCompat);
public abstract void GenerateSubmissionInfo(SubmissionInfo submissionInfo, MediaType? mediaType, string basePath, bool redumpCompat);
// <summary>
/// Generate a list of all output files generated
/// </summary>
/// <param name="mediaType">Media type for controlling expected file sets</param>
/// <param name="outputDirectory">Output folder to use as the base path</param>
/// <param name="outputFilename">Output filename to use as the base path</param>
/// <returns>List of all output files, empty otherwise</returns>
/// <remarks>Assumes filename has an extension</remarks>
internal abstract List<OutputFile> GetOutputFiles(string? outputDirectory, string outputFilename);
internal abstract List<OutputFile> GetOutputFiles(MediaType? mediaType, string? outputDirectory, string outputFilename);
#endregion
@@ -67,13 +72,18 @@ namespace MPF.Processors
/// <summary>
/// Compress log files to save space
/// </summary>
/// <param name="mediaType">Media type for controlling expected file sets</param>
/// <param name="outputDirectory">Output folder to use as the base path</param>
/// <param name="outputFilename">Output filename to use as the base path</param>
/// <param name="filenameSuffix">Output filename to use as the base path</param>
/// <param name="processor">Processor object representing how to process the outputs</param>
/// <returns>True if the process succeeded, false otherwise</returns>
/// <remarks>Assumes filename has an extension</remarks>
public bool CompressLogFiles(string? outputDirectory, string outputFilename, string? filenameSuffix, out string status)
public bool CompressLogFiles(MediaType? mediaType,
string? outputDirectory,
string outputFilename,
string? filenameSuffix,
out string status)
{
#if NET20 || NET35 || NET40
status = "Log compression is not available for this framework version";
@@ -88,7 +98,7 @@ namespace MPF.Processors
string archiveName = $"{basePath}_logs.zip";
// Get the lists of zippable files
var zippableFiles = GetZippableFilePaths(outputDirectory, outputFilename);
var zippableFiles = GetZippableFilePaths(mediaType, outputDirectory, outputFilename);
var generatedFiles = GetGeneratedFilePaths(outputDirectory, filenameSuffix);
// Don't create an archive if there are no paths
@@ -137,15 +147,19 @@ namespace MPF.Processors
/// <summary>
/// Compress log files to save space
/// </summary>
/// <param name="mediaType">Media type for controlling expected file sets</param>
/// <param name="outputDirectory">Output folder to use as the base path</param>
/// <param name="outputFilename">Output filename to use as the base path</param>
/// <param name="processor">Processor object representing how to process the outputs</param>
/// <returns>True if the process succeeded, false otherwise</returns>
/// <remarks>Assumes filename has an extension</remarks>
public bool DeleteUnnecessaryFiles(string? outputDirectory, string outputFilename, out string status)
public bool DeleteUnnecessaryFiles(MediaType? mediaType,
string? outputDirectory,
string outputFilename,
out string status)
{
// Get the list of deleteable files from the parameters object
var files = GetDeleteableFilePaths(outputDirectory, outputFilename);
var files = GetDeleteableFilePaths(mediaType, outputDirectory, outputFilename);
if (files.Count == 0)
{
@@ -170,11 +184,12 @@ namespace MPF.Processors
/// <summary>
/// Ensures that all required output files have been created
/// </summary>
/// <param name="mediaType">Media type for controlling expected file sets</param>
/// <param name="outputDirectory">Output folder to use as the base path</param>
/// <param name="outputFilename">Output filename to use as the base path</param>
/// <returns>A list representing missing files, empty if none</returns>
/// <remarks>Assumes filename has an extension</remarks>
public List<string> FoundAllFiles(string? outputDirectory, string outputFilename)
public List<string> FoundAllFiles(MediaType? mediaType, string? outputDirectory, string outputFilename)
{
// Assemble a base path
string basePath = Path.GetFileNameWithoutExtension(outputFilename);
@@ -182,7 +197,7 @@ namespace MPF.Processors
basePath = Path.Combine(outputDirectory, basePath);
// Get the list of output files
var outputFiles = GetOutputFiles(outputDirectory, outputFilename);
var outputFiles = GetOutputFiles(mediaType, outputDirectory, outputFilename);
if (outputFiles.Count == 0)
return ["Media and system combination not supported"];
@@ -239,17 +254,23 @@ namespace MPF.Processors
#endif
}
#if NET452_OR_GREATER || NETCOREAPP
// Close the log archive, if it exists
logArchive?.Dispose();
#endif
return missingFiles;
}
/// <summary>
/// Ensures that no potential output files have been created
/// </summary>
/// <param name="mediaType">Media type for controlling expected file sets</param>
/// <param name="outputDirectory">Output folder to use as the base path</param>
/// <param name="outputFilename">Output filename to use as the base path</param>
/// <returns>True if any dumping files exist, False if none</returns>
/// <remarks>Assumes filename has an extension</remarks>
public bool FoundAnyFiles(string? outputDirectory, string outputFilename)
public bool FoundAnyFiles(MediaType? mediaType, string? outputDirectory, string outputFilename)
{
// Assemble a base path
string basePath = Path.GetFileNameWithoutExtension(outputFilename);
@@ -257,7 +278,7 @@ namespace MPF.Processors
basePath = Path.Combine(outputDirectory, basePath);
// Get the list of output files
var outputFiles = GetOutputFiles(outputDirectory, outputFilename);
var outputFiles = GetOutputFiles(mediaType, outputDirectory, outputFilename);
if (outputFiles.Count == 0)
return false;
@@ -279,14 +300,15 @@ namespace MPF.Processors
/// <summary>
/// Generate artifacts and return them as a dictionary
/// </summary>
/// <param name="mediaType">Media type for controlling expected file sets</param>
/// <param name="outputDirectory">Output folder to use as the base path</param>
/// <param name="outputFilename">Output filename to use as the base path</param>
/// <returns>Dictiionary of artifact keys to Base64-encoded values, if possible</param>
/// <remarks>Assumes filename has an extension</remarks>
public Dictionary<string, string> GenerateArtifacts(string? outputDirectory, string outputFilename)
public Dictionary<string, string> GenerateArtifacts(MediaType? mediaType, string? outputDirectory, string outputFilename)
{
// Get the list of output files
var outputFiles = GetOutputFiles(outputDirectory, outputFilename);
var outputFiles = GetOutputFiles(mediaType, outputDirectory, outputFilename);
if (outputFiles.Count == 0)
return [];
@@ -402,14 +424,15 @@ namespace MPF.Processors
/// <summary>
/// Generate a list of all deleteable file paths
/// </summary>
/// <param name="mediaType">Media type for controlling expected file sets</param>
/// <param name="outputDirectory">Output folder to use as the base path</param>
/// <param name="outputFilename">Output filename to use as the base path</param>
/// <returns>List of all deleteable file paths, empty otherwise</returns>
/// <remarks>Assumes filename has an extension</remarks>
internal List<string> GetDeleteableFilePaths(string? outputDirectory, string outputFilename)
internal List<string> GetDeleteableFilePaths(MediaType? mediaType, string? outputDirectory, string outputFilename)
{
// Get the list of output files
var outputFiles = GetOutputFiles(outputDirectory, outputFilename);
var outputFiles = GetOutputFiles(mediaType, outputDirectory, outputFilename);
if (outputFiles.Count == 0)
return [];
@@ -485,14 +508,15 @@ namespace MPF.Processors
/// <summary>
/// Generate a list of all zippable file paths
/// </summary>
/// <param name="mediaType">Media type for controlling expected file sets</param>
/// <param name="outputDirectory">Output folder to use as the base path</param>
/// <param name="outputFilename">Output filename to use as the base path</param>
/// <returns>List of all zippable file paths, empty otherwise</returns>
/// <remarks>Assumes filename has an extension</remarks>
internal List<string> GetZippableFilePaths(string? outputDirectory, string outputFilename)
internal List<string> GetZippableFilePaths(MediaType? mediaType, string? outputDirectory, string outputFilename)
{
// Get the list of output files
var outputFiles = GetOutputFiles(outputDirectory, outputFilename);
var outputFiles = GetOutputFiles(mediaType, outputDirectory, outputFilename);
if (outputFiles.Count == 0)
return [];
@@ -515,6 +539,38 @@ namespace MPF.Processors
#region Shared Methods
/// <summary>
/// Generate a CMP XML datfile string based on a single input file
/// </summary>
/// <param name="file">File to generate a datfile for</param>
/// <returns>Datafile containing the hash information, null on error</returns>
internal static Datafile? GenerateDatafile(string file)
{
// If the file is invalid
if (string.IsNullOrEmpty(file))
return null;
if (!File.Exists(file))
return null;
// Attempt to get the hashes
if (!HashTool.GetStandardHashes(file, out long size, out var crc32, out var md5, out var sha1))
return null;
// Generate and return the Datafile
var rom = new Rom
{
Name = string.Empty,
Size = size.ToString(),
CRC = crc32,
MD5 = md5,
SHA1 = sha1,
};
var game = new Game { Rom = [rom] };
var datafile = new Datafile { Game = [game] };
return datafile;
}
/// <summary>
/// Get the hex contents of the PIC file
/// </summary>
@@ -522,8 +578,12 @@ namespace MPF.Processors
/// <param name="trimLength">Number of characters to trim the PIC to, if -1, ignored</param>
/// <returns>PIC data as a hex string if possible, null on error</returns>
/// <remarks>https://stackoverflow.com/questions/9932096/add-separator-to-string-at-every-n-characters</remarks>
internal static string? GetPIC(string picPath, int trimLength = -1)
internal static string? GetPIC(string? picPath, int trimLength = -1)
{
// If the file is invalid
if (picPath == null)
return null;
// If the file doesn't exist, we can't get the info
if (!File.Exists(picPath))
return null;
@@ -605,6 +665,36 @@ namespace MPF.Processors
}
}
/// <summary>
/// Returns true if a Cuesheet consists of only Audio tracks, false otherwise
/// </summary>
internal static bool IsAudio(string? cue)
{
// Ignore invalid inputs
if (string.IsNullOrEmpty(cue))
return false;
bool tracksExist = false;
foreach (string cueLine in cue!.Split(["\r\n", "\n", "\r"], StringSplitOptions.None))
{
string line = cueLine.Trim();
if (line.Length == 0)
continue;
string[] tokens = line.Split([" ", "\t"], StringSplitOptions.RemoveEmptyEntries);
if (tokens.Length < 3 || !tokens[0].Equals("TRACK", StringComparison.OrdinalIgnoreCase))
continue;
tracksExist = true;
string trackType = tokens[2].ToUpperInvariant();
if (trackType != "AUDIO" && trackType != "CDG")
return false;
}
return tracksExist;
}
/// <summary>
/// Split a string with newlines every <paramref name="count"/> characters
/// </summary>

View File

@@ -14,21 +14,32 @@ namespace MPF.Processors
public sealed class CleanRip : BaseProcessor
{
/// <inheritdoc/>
public CleanRip(RedumpSystem? system, MediaType? type) : base(system, type) { }
public CleanRip(RedumpSystem? system) : base(system) { }
#region BaseProcessor Implementations
/// <inheritdoc/>
public override void GenerateSubmissionInfo(SubmissionInfo info, string basePath, bool redumpCompat)
public override MediaType? DetermineMediaType(string? outputDirectory, string outputFilename)
{
return System switch
{
RedumpSystem.NintendoGameCube => MediaType.NintendoGameCubeGameDisc,
RedumpSystem.NintendoWii => MediaType.NintendoWiiOpticalDisc,
_ => null,
};
}
/// <inheritdoc/>
public override void GenerateSubmissionInfo(SubmissionInfo info, MediaType? mediaType, string basePath, bool redumpCompat)
{
// Ensure that required sections exist
info = Builder.EnsureAllSections(info);
// TODO: Determine if there's a CleanRip version anywhere
info.DumpingInfo!.DumpingDate = ProcessingTool.GetFileModifiedDate(basePath + "-dumpinfo.txt")?.ToString("yyyy-MM-dd HH:mm:ss");
info.DumpingInfo!.DumpingDate = ProcessingTool.GetFileModifiedDate($"{basePath}-dumpinfo.txt")?.ToString("yyyy-MM-dd HH:mm:ss");
// Get the Datafile information
var datafile = GenerateCleanripDatafile(basePath + ".iso", basePath + "-dumpinfo.txt");
var datafile = GenerateCleanripDatafile($"{basePath}.iso", $"{basePath}-dumpinfo.txt");
info.TracksAndWriteOffsets!.ClrMameProData = ProcessingTool.GenerateDatfile(datafile);
// Get the individual hash data, as per internal
@@ -44,56 +55,40 @@ namespace MPF.Processors
info.SizeAndChecksums.Layerbreak = 2084960;
}
// Extract info based generically on MediaType
switch (Type)
// Get BCA information, if available
info.Extras!.BCA = GetBCA(basePath + $"{basePath}.bca");
// Get internal information
if (GetGameCubeWiiInformation(basePath + $"{basePath}-dumpinfo.txt", out Region? region, out var version, out var internalName, out var serial))
{
case MediaType.DVD: // Only added here to help users; not strictly correct
case MediaType.NintendoGameCubeGameDisc:
case MediaType.NintendoWiiOpticalDisc:
if (File.Exists(basePath + ".bca"))
info.Extras!.BCA = GetBCA(basePath + ".bca");
if (GetGameCubeWiiInformation(basePath + "-dumpinfo.txt", out Region? gcRegion, out var gcVersion, out var gcName, out var gcSerial))
{
info.CommonDiscInfo!.CommentsSpecialFields![SiteCode.InternalName] = gcName ?? string.Empty;
info.CommonDiscInfo.CommentsSpecialFields![SiteCode.InternalSerialName] = gcSerial ?? string.Empty;
if (!redumpCompat)
{
info.VersionAndEditions!.Version = gcVersion ?? info.VersionAndEditions.Version;
info.CommonDiscInfo.Region = gcRegion ?? info.CommonDiscInfo.Region;
}
}
break;
info.CommonDiscInfo!.CommentsSpecialFields![SiteCode.InternalName] = internalName ?? string.Empty;
info.CommonDiscInfo.CommentsSpecialFields![SiteCode.InternalSerialName] = serial ?? string.Empty;
if (!redumpCompat)
{
info.VersionAndEditions!.Version = version ?? info.VersionAndEditions.Version;
info.CommonDiscInfo.Region = region ?? info.CommonDiscInfo.Region;
}
}
}
/// <inheritdoc/>
internal override List<OutputFile> GetOutputFiles(string? outputDirectory, string outputFilename)
internal override List<OutputFile> GetOutputFiles(MediaType? mediaType, string? outputDirectory, string outputFilename)
{
// Remove the extension by default
outputFilename = Path.GetFileNameWithoutExtension(outputFilename);
switch (Type)
{
case MediaType.DVD: // Only added here to help users; not strictly correct
case MediaType.NintendoGameCubeGameDisc:
case MediaType.NintendoWiiOpticalDisc:
return [
new($"{outputFilename}.bca", OutputFileFlags.Required
| OutputFileFlags.Binary
| OutputFileFlags.Zippable,
"bca"),
new($"{outputFilename}.iso", OutputFileFlags.Required),
return [
new($"{outputFilename}.bca", OutputFileFlags.Required
| OutputFileFlags.Binary
| OutputFileFlags.Zippable,
"bca"),
new($"{outputFilename}.iso", OutputFileFlags.Required),
new($"{outputFilename}-dumpinfo.txt", OutputFileFlags.Required
| OutputFileFlags.Artifact
| OutputFileFlags.Zippable,
"dumpinfo"),
];
}
return [];
new($"{outputFilename}-dumpinfo.txt", OutputFileFlags.Required
| OutputFileFlags.Artifact
| OutputFileFlags.Zippable,
"dumpinfo"),
];
}
#endregion

View File

@@ -63,15 +63,92 @@ namespace MPF.Processors
public sealed class DiscImageCreator : BaseProcessor
{
/// <inheritdoc/>
public DiscImageCreator(RedumpSystem? system, MediaType? type) : base(system, type) { }
public DiscImageCreator(RedumpSystem? system) : base(system) { }
#region BaseProcessor Implementations
/// <inheritdoc/>
public override void GenerateSubmissionInfo(SubmissionInfo info, string basePath, bool redumpCompat)
public override MediaType? DetermineMediaType(string? outputDirectory, string outputFilename)
{
var outputDirectory = Path.GetDirectoryName(basePath);
// If the filename is invalid
if (string.IsNullOrEmpty(outputFilename))
return null;
// Reassemble the base path
string basePath = Path.GetFileNameWithoutExtension(outputFilename);
if (!string.IsNullOrEmpty(outputDirectory))
basePath = Path.Combine(outputDirectory, basePath);
// Get the comma-separated list of values
if (GetDiscType($"{basePath}_disc.txt", out var discType) && discType != null)
{
// CD-ROM
if (discType.Contains("CD-DA or CD-ROM Disc"))
return MediaType.CDROM;
else if (discType.Contains("CD-I Disc"))
return MediaType.CDROM;
else if (discType.Contains("CD-ROM XA Disc"))
return MediaType.CDROM;
// HD-DVD
if (discType.Contains("HD DVD-ROM"))
return MediaType.HDDVD;
else if (discType.Contains("HD DVD-RAM"))
return MediaType.HDDVD;
else if (discType.Contains("HD DVD-R"))
return MediaType.HDDVD;
// DVD
if (discType.Contains("DVD-ROM"))
return MediaType.DVD;
else if (discType.Contains("DVD-RAM"))
return MediaType.DVD;
else if (discType.Contains("DVD-R"))
return MediaType.DVD;
else if (discType.Contains("DVD-RW"))
return MediaType.DVD;
else if (discType.Contains("Reserved1"))
return MediaType.DVD;
else if (discType.Contains("Reserved2"))
return MediaType.DVD;
else if (discType.Contains("DVD+RW"))
return MediaType.DVD;
else if (discType.Contains("DVD+R"))
return MediaType.DVD;
else if (discType.Contains("Reserved3"))
return MediaType.DVD;
else if (discType.Contains("Reserved4"))
return MediaType.DVD;
else if (discType.Contains("DVD+RW DL"))
return MediaType.DVD;
else if (discType.Contains("DVD+R DL"))
return MediaType.DVD;
else if (discType.Contains("Reserved5"))
return MediaType.NintendoWiiOpticalDisc;
// Blu-ray
if (discType.Contains("BDO"))
return MediaType.BluRay;
else if (discType.Contains("BDU"))
return MediaType.BluRay;
else if (discType.Contains("BDW"))
return MediaType.BluRay;
else if (discType.Contains("BDR"))
return MediaType.BluRay;
else if (discType.Contains("XG4"))
return MediaType.BluRay;
// Assume CD-ROM for everything else
return MediaType.CDROM;
}
// The type could not be determined
return null;
}
/// <inheritdoc/>
public override void GenerateSubmissionInfo(SubmissionInfo info, MediaType? mediaType, string basePath, bool redumpCompat)
{
// Ensure that required sections exist
info = Builder.EnsureAllSections(info);
@@ -94,25 +171,36 @@ namespace MPF.Processors
if (GetDiscType($"{basePath}_disc.txt", out var discTypeOrBookType))
info.DumpingInfo.ReportedDiscType = discTypeOrBookType;
// Get the PVD, if it exists
info.Extras!.PVD = GetPVD($"{basePath}_mainInfo.txt") ?? "Disc has no PVD";
// Get the Datafile information
var datafile = ProcessingTool.GetDatafile($"{basePath}.dat");
// Fill in the hash data
info.TracksAndWriteOffsets!.ClrMameProData = ProcessingTool.GenerateDatfile(datafile);
// Get the write offset, if it exists
string? writeOffset = GetWriteOffset($"{basePath}_disc.txt");
info.CommonDiscInfo!.RingWriteOffset = writeOffset;
info.TracksAndWriteOffsets.OtherWriteOffsets = writeOffset;
// Attempt to get multisession data
string? multiSessionInfo = GetMultisessionInformation($"{basePath}_disc.txt");
if (!string.IsNullOrEmpty(multiSessionInfo))
info.CommonDiscInfo.CommentsSpecialFields![SiteCode.Multisession] = multiSessionInfo!;
// Fill in the volume labels
if (GetVolumeLabels($"{basePath}_volDesc.txt", out var volLabels))
VolumeLabels = volLabels;
// Extract info based generically on MediaType
switch (Type)
switch (mediaType)
{
case MediaType.CDROM:
case MediaType.GDROM: // TODO: Verify GD-ROM outputs this
info.Extras!.PVD = GetPVD($"{basePath}_mainInfo.txt") ?? "Disc has no PVD";
info.TracksAndWriteOffsets.Cuesheet = ProcessingTool.GetFullFile($"{basePath}.cue") ?? string.Empty;
// Audio-only discs will fail if there are any C2 errors, so they would never get here
if (System.IsAudio())
if (IsAudio(info.TracksAndWriteOffsets.Cuesheet))
{
info.CommonDiscInfo!.ErrorsCount = "0";
}
@@ -127,19 +215,6 @@ namespace MPF.Processors
info.CommonDiscInfo!.ErrorsCount = (errorCount == -1 ? "Error retrieving error count" : errorCount.ToString());
}
info.TracksAndWriteOffsets.Cuesheet = ProcessingTool.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.Empty;
info.CommonDiscInfo.RingWriteOffset = cdWriteOffset;
info.TracksAndWriteOffsets.OtherWriteOffsets = cdWriteOffset;
// Attempt to get multisession data
string cdMultiSessionInfo = GetMultisessionInformation($"{basePath}_disc.txt") ?? string.Empty;
if (!string.IsNullOrEmpty(cdMultiSessionInfo))
info.CommonDiscInfo.CommentsSpecialFields![SiteCode.Multisession] = cdMultiSessionInfo;
break;
case MediaType.DVD:
@@ -156,12 +231,12 @@ namespace MPF.Processors
}
// Deal with the layerbreaks
if (Type == MediaType.DVD)
if (mediaType == MediaType.DVD)
{
string layerbreak = GetLayerbreak($"{basePath}_disc.txt", System.IsXGD()) ?? string.Empty;
info.SizeAndChecksums!.Layerbreak = !string.IsNullOrEmpty(layerbreak) ? long.Parse(layerbreak) : default;
}
else if (Type == MediaType.BluRay)
else if (mediaType == MediaType.BluRay)
{
var di = ProcessingTool.GetDiscInformation($"{basePath}_PIC.bin");
info.SizeAndChecksums!.PICIdentifier = ProcessingTool.GetPICIdentifier(di);
@@ -178,11 +253,8 @@ namespace MPF.Processors
}
}
// Read the PVD
info.Extras!.PVD = GetPVD($"{basePath}_mainInfo.txt") ?? string.Empty;
// Bluray-specific options
if (Type == MediaType.BluRay)
if (mediaType == MediaType.BluRay)
{
int trimLength = -1;
switch (System)
@@ -322,7 +394,7 @@ namespace MPF.Processors
break;
case RedumpSystem.NamcoSegaNintendoTriforce:
if (Type == MediaType.CDROM)
if (mediaType == MediaType.CDROM)
{
info.Extras!.Header = GetSegaHeader($"{basePath}_mainInfo.txt") ?? string.Empty;
@@ -361,7 +433,7 @@ namespace MPF.Processors
break;
case RedumpSystem.SegaChihiro:
if (Type == MediaType.CDROM)
if (mediaType == MediaType.CDROM)
{
info.Extras!.Header = GetSegaHeader($"{basePath}_mainInfo.txt") ?? string.Empty;
@@ -384,7 +456,7 @@ namespace MPF.Processors
break;
case RedumpSystem.SegaDreamcast:
if (Type == MediaType.CDROM)
if (mediaType == MediaType.CDROM)
{
info.Extras!.Header = GetSegaHeader($"{basePath}_mainInfo.txt") ?? string.Empty;
@@ -407,7 +479,7 @@ namespace MPF.Processors
break;
case RedumpSystem.SegaNaomi:
if (Type == MediaType.CDROM)
if (mediaType == MediaType.CDROM)
{
info.Extras!.Header = GetSegaHeader($"{basePath}_mainInfo.txt") ?? string.Empty;
@@ -430,7 +502,7 @@ namespace MPF.Processors
break;
case RedumpSystem.SegaNaomi2:
if (Type == MediaType.CDROM)
if (mediaType == MediaType.CDROM)
{
info.Extras!.Header = GetSegaHeader($"{basePath}_mainInfo.txt") ?? string.Empty;
@@ -497,12 +569,12 @@ namespace MPF.Processors
}
/// <inheritdoc/>
internal override List<OutputFile> GetOutputFiles(string? outputDirectory, string outputFilename)
internal override List<OutputFile> GetOutputFiles(MediaType? mediaType, string? outputDirectory, string outputFilename)
{
// Remove the extension by default
outputFilename = Path.GetFileNameWithoutExtension(outputFilename);
switch (Type)
switch (mediaType)
{
case MediaType.CDROM:
return [
@@ -518,13 +590,10 @@ namespace MPF.Processors
| OutputFileFlags.Zippable),
new($"{outputFilename}.img", OutputFileFlags.Required
| OutputFileFlags.Deleteable),
new([$"{outputFilename}.img_EdcEcc.txt", $"{outputFilename}.img_EccEdc.txt"], System.IsAudio()
? OutputFileFlags.Artifact | OutputFileFlags.Zippable
: OutputFileFlags.Required | OutputFileFlags.Artifact | OutputFileFlags.Zippable,
new([$"{outputFilename}.img_EdcEcc.txt", $"{outputFilename}.img_EccEdc.txt"], OutputFileFlags.Artifact
| OutputFileFlags.Zippable,
"img_edcecc"),
new([$"{outputFilename}.scm", $"{outputFilename}.scmtmp"], System.IsAudio()
? OutputFileFlags.Deleteable
: OutputFileFlags.Required | OutputFileFlags.Deleteable),
new([$"{outputFilename}.scm", $"{outputFilename}.scmtmp"], OutputFileFlags.Deleteable),
new([$"{outputFilename}.sub", $"{outputFilename}.subtmp"], OutputFileFlags.Required
| OutputFileFlags.Binary
| OutputFileFlags.Zippable,
@@ -2107,7 +2176,7 @@ namespace MPF.Processors
#endif
// Now that we're at the offsets, attempt to get the sample offset
return string.Join("; ", [.. offsets]);
return offsets.Count == 0 ? null : string.Join("; ", [.. offsets]);
}
catch
{

View File

@@ -14,12 +14,18 @@ namespace MPF.Processors
public sealed class Generic : BaseProcessor
{
/// <inheritdoc/>
public Generic(RedumpSystem? system, MediaType? type) : base(system, type) { }
public Generic(RedumpSystem? system) : base(system) { }
#region BaseProcessor Implementations
/// <inheritdoc/>
public override void GenerateSubmissionInfo(SubmissionInfo info, string basePath, bool redumpCompat)
public override MediaType? DetermineMediaType(string? outputDirectory, string outputFilename)
{
throw new NotImplementedException();
}
/// <inheritdoc/>
public override void GenerateSubmissionInfo(SubmissionInfo info, MediaType? mediaType, string basePath, bool redumpCompat)
{
// Ensure that required sections exist
info = Builder.EnsureAllSections(info);
@@ -34,7 +40,7 @@ namespace MPF.Processors
info.TracksAndWriteOffsets!.ClrMameProData = ProcessingTool.GenerateDatfile(datafile);
// Extract info based generically on MediaType
switch (Type)
switch (mediaType)
{
case MediaType.CDROM:
case MediaType.GDROM:
@@ -62,7 +68,7 @@ namespace MPF.Processors
}
/// <inheritdoc/>
internal override List<OutputFile> GetOutputFiles(string? outputDirectory, string outputFilename)
internal override List<OutputFile> GetOutputFiles(MediaType? mediaType, string? outputDirectory, string outputFilename)
{
return [];
}

View File

@@ -12,7 +12,7 @@
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<VersionPrefix>3.3.0</VersionPrefix>
<VersionPrefix>3.3.3</VersionPrefix>
<WarningsNotAsErrors>NU5104</WarningsNotAsErrors>
<!-- Package Properties -->
@@ -32,19 +32,14 @@
<None Include="README.md" Pack="true" PackagePath="" />
</ItemGroup>
<!-- Support for old .NET versions -->
<ItemGroup Condition="!$(TargetFramework.StartsWith(`net2`)) AND !$(TargetFramework.StartsWith(`net3`)) AND !$(TargetFramework.StartsWith(`net40`))">
<PackageReference Include="System.IO.Compression" Version="4.3.0" />
</ItemGroup>
<ItemGroup Condition="!$(TargetFramework.StartsWith(`net2`)) AND !$(TargetFramework.StartsWith(`net3`)) AND !$(TargetFramework.StartsWith(`net40`)) AND !$(TargetFramework.StartsWith(`net452`))">
<PackageReference Include="System.IO.Compression.ZipFile" Version="4.3.0" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="SabreTools.Hashing" Version="1.4.1" />
<PackageReference Include="SabreTools.Hashing" Version="1.4.2" />
<PackageReference Include="SabreTools.Models" Version="1.5.8" />
<PackageReference Include="SabreTools.RedumpLib" Version="1.6.4" />
<PackageReference Include="SabreTools.RedumpLib" Version="1.6.8" />
<PackageReference Include="SabreTools.Serialization" Version="1.8.6" />
<PackageReference Include="System.IO.Compression" Version="4.3.0" Condition="!$(TargetFramework.StartsWith(`net2`)) AND !$(TargetFramework.StartsWith(`net3`)) AND !$(TargetFramework.StartsWith(`net40`))" />
<PackageReference Include="System.IO.Compression.ZipFile" Version="4.3.0" Condition="!$(TargetFramework.StartsWith(`net2`)) AND !$(TargetFramework.StartsWith(`net3`)) AND !$(TargetFramework.StartsWith(`net40`)) AND !$(TargetFramework.StartsWith(`net452`))" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="9.0.4" Condition="!$(TargetFramework.StartsWith(`net2`)) AND !$(TargetFramework.StartsWith(`net3`)) AND !$(TargetFramework.StartsWith(`net40`)) AND !$(TargetFramework.StartsWith(`net452`))" />
</ItemGroup>
</Project>

View File

@@ -1,6 +1,5 @@
using System.Collections.Generic;
using System.IO;
using SabreTools.Hashing;
using SabreTools.Models.Logiqx;
using SabreTools.RedumpLib;
using SabreTools.RedumpLib.Data;
@@ -13,12 +12,16 @@ namespace MPF.Processors
public sealed class PS3CFW : BaseProcessor
{
/// <inheritdoc/>
public PS3CFW(RedumpSystem? system, MediaType? type) : base(system, type) { }
public PS3CFW(RedumpSystem? system) : base(system) { }
#region BaseProcessor Implementations
/// <inheritdoc/>
public override void GenerateSubmissionInfo(SubmissionInfo info, string basePath, bool redumpCompat)
public override MediaType? DetermineMediaType(string? outputDirectory, string outputFilename)
=> MediaType.BluRay;
/// <inheritdoc/>
public override void GenerateSubmissionInfo(SubmissionInfo info, MediaType? mediaType, string basePath, bool redumpCompat)
{
// Ensure that required sections exist
info = Builder.EnsureAllSections(info);
@@ -34,9 +37,7 @@ namespace MPF.Processors
info.DumpingInfo!.DumpingDate = ProcessingTool.GetFileModifiedDate(isoPath)?.ToString("yyyy-MM-dd HH:mm:ss");
// Get the Datafile information
Datafile? datafile = GeneratePS3CFWDatafile(isoPath);
// Fill in the hash data
Datafile? datafile = GenerateDatafile(isoPath);
info.TracksAndWriteOffsets!.ClrMameProData = ProcessingTool.GenerateDatfile(datafile);
// Get the individual hash data, as per internal
@@ -58,19 +59,67 @@ namespace MPF.Processors
// Try to determine the name of the GetKey file
string getKeyPath = string.Empty;
if (File.Exists($"{basePath}.getkey.log"))
{
getKeyPath = $"{basePath}.getkey.log";
}
else if (File.Exists(Path.Combine(baseDir, "getkey.log")))
{
getKeyPath = Path.Combine(baseDir, "getkey.log");
}
else
{
string[] getKeyFiles = Directory.GetFiles(baseDir, "*.getkey.log");
if (getKeyFiles.Length > 0)
getKeyPath = getKeyFiles[0];
}
// Get dumping date from GetKey log date
if (!string.IsNullOrEmpty(getKeyPath))
info.DumpingInfo.DumpingDate = ProcessingTool.GetFileModifiedDate(getKeyPath)?.ToString("yyyy-MM-dd HH:mm:ss");
// TODO: Put info about abnormal PIC info beyond 132 bytes in comments?
// Try to determine the name of the PIC
string? picPath = null;
if (File.Exists($"{basePath}.disc.pic"))
info.Extras!.PIC = GetPIC($"{basePath}.disc.pic", 264);
{
picPath = $"{basePath}.disc.pic";
}
else if (File.Exists(Path.Combine(baseDir, "disc.pic")))
info.Extras!.PIC = GetPIC(Path.Combine(baseDir, "disc.pic"), 264);
{
picPath = Path.Combine(baseDir, "disc.pic");
}
else
{
string[] discPicFiles = Directory.GetFiles(baseDir, "*.disc.pic");
if (discPicFiles.Length > 0)
picPath = discPicFiles[0];
}
// Get the layerbreak information from the PIC
var di = ProcessingTool.GetDiscInformation(picPath);
info.SizeAndChecksums!.PICIdentifier = ProcessingTool.GetPICIdentifier(di);
if (ProcessingTool.GetLayerbreaks(di, out long? layerbreak1, out long? layerbreak2, out long? layerbreak3))
{
if (layerbreak1 != null && layerbreak1 * 2048 < info.SizeAndChecksums.Size)
info.SizeAndChecksums.Layerbreak = layerbreak1.Value;
if (layerbreak2 != null && layerbreak2 * 2048 < info.SizeAndChecksums.Size)
info.SizeAndChecksums.Layerbreak2 = layerbreak2.Value;
if (layerbreak3 != null && layerbreak3 * 2048 < info.SizeAndChecksums.Size)
info.SizeAndChecksums.Layerbreak3 = layerbreak3.Value;
}
// Set the trim length based on the layer count
int trimLength;
if (info.SizeAndChecksums!.Layerbreak3 != default)
trimLength = 520;
else if (info.SizeAndChecksums!.Layerbreak2 != default)
trimLength = 392;
else
trimLength = 264;
// TODO: Put info about abnormal PIC info beyond 132 bytes in comments?
info.Extras!.PIC = GetPIC(picPath, trimLength);
// Parse Disc Key, Disc ID, and PIC from the getkey.log file
if (ProcessingTool.ParseGetKeyLog(getKeyPath, out string? key, out string? id, out string? pic))
@@ -85,64 +134,23 @@ namespace MPF.Processors
}
/// <inheritdoc/>
internal override List<OutputFile> GetOutputFiles(string? outputDirectory, string outputFilename)
internal override List<OutputFile> GetOutputFiles(MediaType? mediaType, string? outputDirectory, string outputFilename)
{
// Remove the extension by default
outputFilename = Path.GetFileNameWithoutExtension(outputFilename);
switch (Type)
{
case MediaType.BluRay:
return [
new([$"{outputFilename}.iso", $"{outputFilename}.ISO"], OutputFileFlags.Required),
new([$"{outputFilename}.cue", $"{outputFilename}.CUE"], OutputFileFlags.Zippable),
new([$"{outputFilename}.getkey.log", "getkey.log"], OutputFileFlags.Required
| OutputFileFlags.Artifact
| OutputFileFlags.Zippable,
"getkey_log"),
new([$"{outputFilename}.disc.pic", "disc.pic"], OutputFileFlags.Required
| OutputFileFlags.Binary
| OutputFileFlags.Zippable,
"disc_pic"),
];
}
return [];
}
#endregion
#region Information Extraction Methods
/// <summary>
/// Get a formatted datfile from the PS3 CFW output, if possible
/// </summary>
/// <param name="iso">Path to ISO file</param>
/// <returns></returns>
internal static Datafile? GeneratePS3CFWDatafile(string iso)
{
// If the ISO file doesn't exist
if (string.IsNullOrEmpty(iso))
return null;
if (!File.Exists(iso))
return null;
try
{
if (HashTool.GetStandardHashes(iso, out long size, out string? crc, out string? md5, out string? sha1))
{
return new Datafile
{
Game = [new Game { Rom = [new Rom { Name = Path.GetFileName(iso), Size = size.ToString(), CRC = crc, MD5 = md5, SHA1 = sha1 }] }]
};
}
return null;
}
catch
{
// We don't care what the exception is right now
return null;
}
return [
new([$"{outputFilename}.iso", $"{outputFilename}.ISO"], OutputFileFlags.Required),
new([$"{outputFilename}.cue", $"{outputFilename}.CUE"], OutputFileFlags.Zippable),
new RegexOutputFile($"getkey\\.log$", OutputFileFlags.Required
| OutputFileFlags.Artifact
| OutputFileFlags.Zippable,
"getkey_log"),
new RegexOutputFile($"disc\\.pic$", OutputFileFlags.Required
| OutputFileFlags.Binary
| OutputFileFlags.Zippable,
"disc_pic"),
];
}
#endregion

View File

@@ -22,6 +22,15 @@ namespace MPF.Processors
/// </summary>
public static class ProcessingTool
{
#region Constants
/// <summary>
/// Shift-JIS encoding for detection and conversion
/// </summary>
private static readonly Encoding ShiftJIS = Encoding.GetEncoding(932);
#endregion
#region Information Extraction
/// <summary>
@@ -120,7 +129,7 @@ namespace MPF.Processors
/// <param name="pic">Path to a PIC.bin file</param>
/// <returns>Filled DiscInformation on success, null on error</returns>
/// <remarks>This omits the emergency brake information, if it exists</remarks>
public static DiscInformation? GetDiscInformation(string pic)
public static DiscInformation? GetDiscInformation(string? pic)
{
try
{
@@ -163,14 +172,15 @@ namespace MPF.Processors
if (!File.Exists(filename))
return null;
// Read the entire file as bytes
byte[] bytes = File.ReadAllBytes(filename);
// If we're reading as binary
if (binary)
{
byte[] bytes = File.ReadAllBytes(filename);
return BitConverter.ToString(bytes).Replace("-", string.Empty);
}
return File.ReadAllText(filename);
// If we're reading as text
return NormalizeShiftJIS(bytes);
}
/// <summary>
@@ -292,6 +302,66 @@ namespace MPF.Processors
return di.Units[0]?.Body?.DiscTypeIdentifier;
}
/// <summary>
/// Normalize a byte array that may contain Shift-JIS characters
/// </summary>
/// <param name="contents">String as a byte array to normalize</param>
/// <returns>Normalized version of a string</returns>
public static string NormalizeShiftJIS(byte[]? contents)
{
// Invalid arrays are passed as-is
if (contents == null || contents.Length == 0)
return string.Empty;
#if NET462_OR_GREATER || NETCOREAPP
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
#endif
// If the line contains Shift-JIS characters
if (BytesContainsShiftJIS(contents))
return ShiftJIS.GetString(contents);
return Encoding.UTF8.GetString(contents);
}
/// <summary>
/// Determine if a byte array contains Shift-JIS encoded characters
/// </summary>
/// <param name="line">Byte array to check for Shift-JIS encoding</param>
/// <returns>True if the byte array contains Shift-JIS characters, false otherwise</returns>
/// <see href="https://www.lemoda.net/c/detect-shift-jis/"/>
internal static bool BytesContainsShiftJIS(byte[] bytes)
{
// Invalid arrays do not count
if (bytes == null || bytes.Length == 0)
return false;
// Loop through and check each pair of bytes
for (int i = 0; i < bytes.Length - 1; i++)
{
byte first = bytes[i];
byte second = bytes[i + 1];
if ((first >= 0x81 && first <= 0x84) ||
(first >= 0x87 && first <= 0x9F))
{
if (second >= 0x40 && second <= 0x9E)
return true;
else if (second >= 0x9F && second <= 0xFC)
return true;
}
else if (first >= 0xE0 && first <= 0xEF)
{
if (second >= 0x40 && second <= 0x9E)
return true;
else if (second >= 0x9F && second <= 0xFC)
return true;
}
}
return false;
}
#endregion
#region Category Extraction
@@ -969,6 +1039,113 @@ namespace MPF.Processors
}
}
/// <summary>
/// Determine if a given SS.bin is valid (Known XGD type and SSv2 if XGD3)
/// </summary>
/// <param name="ssPath">Path to the SS file to check</param>
/// <returns>True if valid, false otherwise</returns>
public static bool IsValidSS(string ssPath)
{
if (!File.Exists(ssPath))
return false;
byte[] ss = File.ReadAllBytes(ssPath);
if (ss.Length != 2048)
return false;
return IsValidSS(ss);
}
/// <summary>
/// Determine if a given SS is valid (2048 bytes, known XGD type, and SSv2 if XGD3)
/// </summary>
/// <param name="ss">Byte array of SS sector</param>
/// <returns>True if SS is valid, false otherwise</returns>
public static bool IsValidSS(byte[] ss)
{
// Check 1 sector long
if (ss.Length != 2048)
return false;
// Must be a valid XGD type
if (!GetXGDType(ss, out int xgdType))
return false;
// Only continue to check SSv2 for XGD3
if (xgdType != 3)
return true;
// Determine if XGD3 SS.bin is SSv1 (Original Kreon) or SSv2 (0800 / Repaired Kreon)
#if NET20
var checkArr = new byte[72];
Array.Copy(ss, 32, checkArr, 0, 72);
return Array.Exists(checkArr, x => x != 0);
#else
return ss.Skip(32).Take(72).Any(x => x != 0);
#endif
}
/// <summary>
/// Determine if a given SS.bin is valid but contains zeroed challenge responses
/// </summary>
/// <param name="ssPath">Path to the SS file to check</param>
/// <returns>True if valid but partial SS.bin, false otherwise</returns>
public static bool IsValidPartialSS(string ssPath)
{
if (!File.Exists(ssPath))
return false;
byte[] ss = File.ReadAllBytes(ssPath);
if (ss.Length != 2048)
return false;
return IsValidPartialSS(ss);
}
/// <summary>
/// Determine if a given SS is valid but contains zeroed challenge responses
/// </summary>
/// <param name="ss">Byte array of SS sector</param>
/// <returns>True if SS is a valid but partial SS, false otherwise</returns>
public static bool IsValidPartialSS(byte[] ss)
{
// Check 1 sector long
if (ss.Length != 2048)
return false;
// Must be a valid XGD type
if (!GetXGDType(ss, out int xgdType))
return false;
// Determine challenge table offset, XGD1 is never partial
int ccrt_offset = 0;
if (xgdType == 1)
return false;
else if (xgdType == 2)
ccrt_offset = 0x200;
else if (xgdType == 3)
ccrt_offset = 0x20;
int[] entry_offsets = {0, 9, 18, 27, 36, 45, 54, 63};
int[] entry_lengths = {8, 8, 8, 8, 4, 4, 4, 4};
for (int i = 0; i < entry_offsets.Length; i++)
{
bool emptyResponse = true;
for (int b = 0; b < entry_lengths[i]; b++)
{
if (ss[ccrt_offset + entry_offsets[i] + b] != 0x00)
{
emptyResponse = false;
break;
}
}
if (emptyResponse)
return true;
}
return false;
}
/// <summary>
/// Determine if a given SS has already been cleaned
/// </summary>
@@ -1105,9 +1282,26 @@ namespace MPF.Processors
if (ss.Length != 2048)
return false;
// Must be a valid SS file
if (!IsValidSS(ss))
return false;
// Determine XGD type
if (!GetXGDType(ss, out int xgdType))
return false;
// Determine if XGD3 SS.bin is SSv1 (Original Kreon) or SSv2 (0800 / Repaired Kreon)
#if NET20
var checkArr = new byte[72];
Array.Copy(ss, 32, checkArr, 0, 72);
bool ssv2 = Array.Exists(checkArr, x => x != 0);
#else
bool ssv2 = ss.Skip(32).Take(72).Any(x => x != 0);
#endif
// Do not produce an SS hash for bad SS (SSv1 XGD3 / Unrepaired Kreon SS)
if(xgdType == 3 && !ssv2)
return false;
switch (xgdType)
{
@@ -1139,15 +1333,6 @@ namespace MPF.Processors
return true;
case 3:
// Determine if XGD3 SS.bin is SSv1 (Kreon) or SSv2 (0800)
#if NET20
var checkArr = new byte[72];
Array.Copy(ss, 32, checkArr, 0, 72);
bool ssv2 = Array.Exists(checkArr, x => x != 0);
#else
bool ssv2 = ss.Skip(32).Take(72).Any(x => x != 0);
#endif
if (ssv2)
{
ss[72] = 1; // 0x01

View File

@@ -1,6 +1,10 @@
using System;
using System.Collections.Generic;
using System.IO;
#if NET452_OR_GREATER || NETCOREAPP
using System.IO.Compression;
#endif
using System.Text;
using System.Text.RegularExpressions;
using SabreTools.Hashing;
using SabreTools.RedumpLib;
@@ -14,12 +18,36 @@ namespace MPF.Processors
public sealed class Redumper : BaseProcessor
{
/// <inheritdoc/>
public Redumper(RedumpSystem? system, MediaType? type) : base(system, type) { }
public Redumper(RedumpSystem? system) : base(system) { }
#region BaseProcessor Implementations
/// <inheritdoc/>
public override void GenerateSubmissionInfo(SubmissionInfo info, string basePath, bool redumpCompat)
public override MediaType? DetermineMediaType(string? outputDirectory, string outputFilename)
{
// If the filename is invalid
if (string.IsNullOrEmpty(outputFilename))
return null;
// Reassemble the base path
string basePath = Path.GetFileNameWithoutExtension(outputFilename);
if (!string.IsNullOrEmpty(outputDirectory))
basePath = Path.Combine(outputDirectory, basePath);
// Use the log first, if it exists
if (GetDiscType($"{basePath}.log", out MediaType? mediaType))
return mediaType;
// Use the profile for older Redumper versions
if (GetDiscProfile($"{basePath}.log", out string? discProfile))
return GetDiscTypeFromProfile(discProfile);
// The type could not be determined
return null;
}
/// <inheritdoc/>
public override void GenerateSubmissionInfo(SubmissionInfo info, MediaType? mediaType, string basePath, bool redumpCompat)
{
// Ensure that required sections exist
info = Builder.EnsureAllSections(info);
@@ -39,25 +67,38 @@ namespace MPF.Processors
}
// Fill in the disc type data
if (GetDiscType($"{basePath}.log", out var discTypeOrBookType))
if (GetDiscProfile($"{basePath}.log", out var discTypeOrBookType))
info.DumpingInfo.ReportedDiscType = discTypeOrBookType;
// Fill in the volume labels
if (GetVolumeLabels($"{basePath}.log", out var volLabels))
VolumeLabels = volLabels;
// Get the PVD, if it exists
info.Extras!.PVD = GetPVD($"{basePath}.log") ?? "Disc has no PVD";
switch (Type)
// Get the Datafile information
info.TracksAndWriteOffsets!.ClrMameProData = GetDatfile($"{basePath}.log");
// Get the write offset, if it exists
string? writeOffset = GetWriteOffset($"{basePath}.log");
info.CommonDiscInfo!.RingWriteOffset = writeOffset;
info.TracksAndWriteOffsets.OtherWriteOffsets = writeOffset;
// Attempt to get multisession data
string? multiSessionInfo = GetMultisessionInformation($"{basePath}.log");
if (!string.IsNullOrEmpty(multiSessionInfo))
info.CommonDiscInfo.CommentsSpecialFields![SiteCode.Multisession] = multiSessionInfo!;
// Fill in the volume labels (ignore for Xbox/Xbox360)
if (System != RedumpSystem.MicrosoftXbox && System != RedumpSystem.MicrosoftXbox360)
{
if (GetVolumeLabels($"{basePath}.log", out var volLabels))
VolumeLabels = volLabels;
}
// Extract info based generically on MediaType
switch (mediaType)
{
case MediaType.CDROM:
info.Extras!.PVD = GetPVD($"{basePath}.log") ?? "Disc has no PVD";
info.TracksAndWriteOffsets!.ClrMameProData = GetDatfile($"{basePath}.log");
info.TracksAndWriteOffsets.Cuesheet = ProcessingTool.GetFullFile($"{basePath}.cue") ?? string.Empty;
// Attempt to get the write offset
string cdWriteOffset = GetWriteOffset($"{basePath}.log") ?? string.Empty;
info.CommonDiscInfo!.RingWriteOffset = cdWriteOffset;
info.TracksAndWriteOffsets.OtherWriteOffsets = cdWriteOffset;
// Attempt to get the error count
if (GetErrorCount($"{basePath}.log", out long redumpErrors, out long c2Errors))
{
@@ -65,25 +106,17 @@ namespace MPF.Processors
info.DumpingInfo.C2ErrorsCount = (c2Errors == -1 ? "Error retrieving error count" : c2Errors.ToString());
}
// Attempt to get multisession data
string cdMultiSessionInfo = GetMultisessionInformation($"{basePath}.log") ?? string.Empty;
if (!string.IsNullOrEmpty(cdMultiSessionInfo))
info.CommonDiscInfo.CommentsSpecialFields![SiteCode.Multisession] = cdMultiSessionInfo;
// Attempt to get the universal hash, if it's an audio disc
if (System.IsAudio())
// Attempt to get extra metadata if it's an audio disc
if (IsAudio(info.TracksAndWriteOffsets.Cuesheet))
{
string universalHash = GetUniversalHash($"{basePath}.log") ?? string.Empty;
info.CommonDiscInfo.CommentsSpecialFields![SiteCode.UniversalHash] = universalHash;
}
// Attempt to get the non-zero data start, if it's an audio disc
if (System.IsAudio())
{
string ringNonZeroDataStart = GetRingNonZeroDataStart($"{basePath}.log") ?? string.Empty;
info.CommonDiscInfo.CommentsSpecialFields![SiteCode.RingNonZeroDataStart] = ringNonZeroDataStart;
info.CommonDiscInfo.CommentsSpecialFields![SiteCode.RingNonZeroDataStart] = ringNonZeroDataStart!;
string ringPerfectAudioOffset = GetRingPerfectAudioOffset($"{basePath}.log") ?? string.Empty;
info.CommonDiscInfo.CommentsSpecialFields![SiteCode.RingPerfectAudioOffset] = ringPerfectAudioOffset;
info.CommonDiscInfo.CommentsSpecialFields![SiteCode.RingPerfectAudioOffset] = ringPerfectAudioOffset!;
}
break;
@@ -91,9 +124,9 @@ namespace MPF.Processors
case MediaType.DVD:
case MediaType.HDDVD:
case MediaType.BluRay:
info.Extras!.PVD = GetPVD($"{basePath}.log") ?? "Disc has no PVD";
info.TracksAndWriteOffsets!.ClrMameProData = GetDatfile($"{basePath}.log");
case MediaType.NintendoGameCubeGameDisc:
case MediaType.NintendoWiiOpticalDisc:
case MediaType.NintendoWiiUOpticalDisc:
// Get the individual hash data, as per internal
if (ProcessingTool.GetISOHashValues(info.TracksAndWriteOffsets.ClrMameProData, out long size, out var crc32, out var md5, out var sha1))
{
@@ -113,10 +146,10 @@ namespace MPF.Processors
// Attempt to get the error count
long scsiErrors = GetSCSIErrorCount($"{basePath}.log");
info.CommonDiscInfo!.ErrorsCount = (scsiErrors == -1 ? "Error retrieving error count" : scsiErrors.ToString());;
info.CommonDiscInfo!.ErrorsCount = (scsiErrors == -1 ? "Error retrieving error count" : scsiErrors.ToString());
// Bluray-specific options
if (Type == MediaType.BluRay)
if (mediaType == MediaType.BluRay || mediaType == MediaType.NintendoWiiUOpticalDisc)
{
int trimLength = -1;
switch (System)
@@ -181,82 +214,62 @@ namespace MPF.Processors
break;
case RedumpSystem.MicrosoftXbox:
// If .dmi / .pfi / .ss don't already exist, create them
if (!File.Exists($"{basePath}.dmi"))
RemoveHeader($"{basePath}.manufacturer", $"{basePath}.dmi");
if (!File.Exists($"{basePath}.pfi"))
RemoveHeader($"{basePath}.physical", $"{basePath}.pfi");
if (!File.Exists($"{basePath}.ss"))
ProcessingTool.CleanSS($"{basePath}.security", $"{basePath}.ss");
string xmidString = ProcessingTool.GetXMID($"{basePath}.dmi");
var xmid = SabreTools.Serialization.Wrappers.XMID.Create(xmidString);
if (xmid != null)
{
info.CommonDiscInfo!.CommentsSpecialFields![SiteCode.XMID] = xmidString?.TrimEnd('\0') ?? string.Empty;
info.CommonDiscInfo.Serial = xmid.Serial ?? string.Empty;
if (!redumpCompat)
{
info.VersionAndEditions!.Version = xmid.Version ?? string.Empty;
info.CommonDiscInfo.Region = ProcessingTool.GetXGDRegion(xmid.Model.RegionIdentifier);
}
}
string? dmi1Crc = HashTool.GetFileHash($"{basePath}.dmi", HashType.CRC32);
if (dmi1Crc != null)
info.CommonDiscInfo!.CommentsSpecialFields![SiteCode.DMIHash] = dmi1Crc.ToUpperInvariant();
string? pfi1Crc = HashTool.GetFileHash($"{basePath}.pfi", HashType.CRC32);
if (pfi1Crc != null)
info.CommonDiscInfo!.CommentsSpecialFields![SiteCode.PFIHash] = pfi1Crc.ToUpperInvariant();
string? ss1Crc = HashTool.GetFileHash($"{basePath}.ss", HashType.CRC32);
if (ss1Crc != null)
info.CommonDiscInfo!.CommentsSpecialFields![SiteCode.SSHash] = ss1Crc.ToUpperInvariant();
string? ranges1 = ProcessingTool.GetSSRanges($"{basePath}.ss");
if (!string.IsNullOrEmpty(ranges1))
info.Extras!.SecuritySectorRanges = ranges1;
break;
case RedumpSystem.MicrosoftXbox360:
// If .dmi / .pfi / .ss don't already exist, create them
if (!File.Exists($"{basePath}.dmi"))
RemoveHeader($"{basePath}.manufacturer", $"{basePath}.dmi");
RemoveHeaderAndTrim($"{basePath}.manufacturer", $"{basePath}.dmi");
if (!File.Exists($"{basePath}.pfi"))
RemoveHeader($"{basePath}.physical", $"{basePath}.pfi");
RemoveHeaderAndTrim($"{basePath}.physical", $"{basePath}.pfi");
if (!File.Exists($"{basePath}.ss"))
ProcessingTool.CleanSS($"{basePath}.security", $"{basePath}.ss");
string xemidString = ProcessingTool.GetXeMID($"{basePath}.dmi");
var xemid = SabreTools.Serialization.Wrappers.XeMID.Create(xemidString);
if (xemid != null)
string xmidString = ProcessingTool.GetXMID($"{basePath}.dmi").Trim('\0');
if (!string.IsNullOrEmpty(xmidString))
{
info.CommonDiscInfo!.CommentsSpecialFields![SiteCode.XeMID] = xemidString?.TrimEnd('\0') ?? string.Empty;
info.CommonDiscInfo.Serial = xemid.Serial ?? string.Empty;
info.CommonDiscInfo!.CommentsSpecialFields![SiteCode.XMID] = xmidString;
var xmid = SabreTools.Serialization.Wrappers.XMID.Create(xmidString);
info.CommonDiscInfo.Serial = xmid?.Serial ?? string.Empty;
if (!redumpCompat)
info.VersionAndEditions!.Version = xemid.Version ?? string.Empty;
info.CommonDiscInfo.Region = ProcessingTool.GetXGDRegion(xemid.Model.RegionIdentifier);
{
info.VersionAndEditions!.Version = xmid?.Version ?? string.Empty;
info.CommonDiscInfo.Region = ProcessingTool.GetXGDRegion(xmid?.Model.RegionIdentifier);
}
}
string? dmi23Crc = HashTool.GetFileHash($"{basePath}.dmi", HashType.CRC32);
if (dmi23Crc != null)
info.CommonDiscInfo!.CommentsSpecialFields![SiteCode.DMIHash] = dmi23Crc.ToUpperInvariant();
string? pfi23Crc = HashTool.GetFileHash($"{basePath}.pfi", HashType.CRC32);
if (pfi23Crc != null)
info.CommonDiscInfo!.CommentsSpecialFields![SiteCode.PFIHash] = pfi23Crc.ToUpperInvariant();
string? ss23Crc = HashTool.GetFileHash($"{basePath}.ss", HashType.CRC32);
if (ss23Crc != null)
info.CommonDiscInfo!.CommentsSpecialFields![SiteCode.SSHash] = ss23Crc.ToUpperInvariant();
string xemidString = ProcessingTool.GetXeMID($"{basePath}.dmi").Trim('\0');
if (!string.IsNullOrEmpty(xemidString))
{
info.CommonDiscInfo!.CommentsSpecialFields![SiteCode.XeMID] = xemidString;
var xemid = SabreTools.Serialization.Wrappers.XeMID.Create(xemidString);
info.CommonDiscInfo.Serial = xemid?.Serial ?? string.Empty;
if (!redumpCompat)
{
info.VersionAndEditions!.Version = xemid?.Version ?? string.Empty;
info.CommonDiscInfo.Region = ProcessingTool.GetXGDRegion(xemid?.Model.RegionIdentifier);
}
}
string? ranges23 = ProcessingTool.GetSSRanges($"{basePath}.ss");
if (!string.IsNullOrEmpty(ranges23))
info.Extras!.SecuritySectorRanges = ranges23;
string? dmiCrc = HashTool.GetFileHash($"{basePath}.dmi", HashType.CRC32);
if (dmiCrc != null)
info.CommonDiscInfo!.CommentsSpecialFields![SiteCode.DMIHash] = dmiCrc.ToUpperInvariant();
string? pfiCrc = HashTool.GetFileHash($"{basePath}.pfi", HashType.CRC32);
if (pfiCrc != null)
info.CommonDiscInfo!.CommentsSpecialFields![SiteCode.PFIHash] = pfiCrc.ToUpperInvariant();
if (ProcessingTool.IsValidSS($"{basePath}.ss") && !ProcessingTool.IsValidPartialSS($"{basePath}.ss"))
{
string? ssCrc = HashTool.GetFileHash($"{basePath}.ss", HashType.CRC32);
if (ssCrc != null)
info.CommonDiscInfo!.CommentsSpecialFields![SiteCode.SSHash] = ssCrc.ToUpperInvariant();
}
string? ssRanges = ProcessingTool.GetSSRanges($"{basePath}.ss");
if (!string.IsNullOrEmpty(ssRanges))
info.Extras!.SecuritySectorRanges = ssRanges;
break;
case RedumpSystem.NamcoSegaNintendoTriforce:
if (Type == MediaType.CDROM)
if (mediaType == MediaType.CDROM)
{
info.Extras!.Header = GetGDROMHeader($"{basePath}.log",
out string? buildDate,
@@ -278,7 +291,7 @@ namespace MPF.Processors
break;
case RedumpSystem.SegaChihiro:
if (Type == MediaType.CDROM)
if (mediaType == MediaType.CDROM)
{
info.Extras!.Header = GetGDROMHeader($"{basePath}.log",
out string? buildDate,
@@ -293,7 +306,7 @@ namespace MPF.Processors
break;
case RedumpSystem.SegaDreamcast:
if (Type == MediaType.CDROM)
if (mediaType == MediaType.CDROM)
{
info.Extras!.Header = GetGDROMHeader($"{basePath}.log",
out string? buildDate,
@@ -308,7 +321,7 @@ namespace MPF.Processors
break;
case RedumpSystem.SegaNaomi:
if (Type == MediaType.CDROM)
if (mediaType == MediaType.CDROM)
{
info.Extras!.Header = GetGDROMHeader($"{basePath}.log",
out string? buildDate,
@@ -323,7 +336,7 @@ namespace MPF.Processors
break;
case RedumpSystem.SegaNaomi2:
if (Type == MediaType.CDROM)
if (mediaType == MediaType.CDROM)
{
info.Extras!.Header = GetGDROMHeader($"{basePath}.log",
out string? buildDate,
@@ -373,7 +386,7 @@ namespace MPF.Processors
string? ps2Protection = GetPlayStation2Protection($"{basePath}.log");
if (ps2Protection != null)
info.CommonDiscInfo!.Comments = $"<b>Protection</b>: {ps2Protection}" + Environment.NewLine;
break;
case RedumpSystem.SonyPlayStation3:
@@ -406,33 +419,36 @@ namespace MPF.Processors
}
/// <inheritdoc/>
internal override List<OutputFile> GetOutputFiles(string? outputDirectory, string outputFilename)
internal override List<OutputFile> GetOutputFiles(MediaType? mediaType, string? outputDirectory, string outputFilename)
{
// Remove the extension by default
outputFilename = Path.GetFileNameWithoutExtension(outputFilename);
// Get the base path
string basePath;
if (string.IsNullOrEmpty(outputDirectory))
basePath = outputFilename;
else
basePath = Path.Combine(outputDirectory, outputFilename);
// Assemble the base path
string basePath = Path.GetFileNameWithoutExtension(outputFilename);
if (!string.IsNullOrEmpty(outputDirectory))
basePath = Path.Combine(outputDirectory, basePath);
switch (Type)
switch (mediaType)
{
case MediaType.CDROM:
case MediaType.GDROM:
List<OutputFile> cdrom = [
// .asus is obsolete: newer redumper produces .cache instead
new($"{outputFilename}.asus", OutputFileFlags.Binary
| OutputFileFlags.Zippable,
"asus"),
new($"{outputFilename}.atip", OutputFileFlags.Binary
| OutputFileFlags.Zippable,
"atip"),
new($"{outputFilename}.cache", OutputFileFlags.Binary
| OutputFileFlags.Zippable,
"cache"),
new($"{outputFilename}.cdtext", OutputFileFlags.Binary
| OutputFileFlags.Zippable,
"cdtext"),
new($"{outputFilename}.cue", OutputFileFlags.Required),
new($"{outputFilename}.flip", OutputFileFlags.None),
new($"{outputFilename}.fulltoc", OutputFileFlags.Required
| OutputFileFlags.Binary
| OutputFileFlags.Zippable,
@@ -511,9 +527,13 @@ namespace MPF.Processors
case MediaType.NintendoGameCubeGameDisc:
case MediaType.NintendoWiiOpticalDisc:
return [
// .asus is obsolete: newer redumper produces .cache instead
new($"{outputFilename}.asus", OutputFileFlags.Binary
| OutputFileFlags.Zippable,
"asus"),
new($"{outputFilename}.cache", OutputFileFlags.Binary
| OutputFileFlags.Zippable,
"cache"),
new($"{outputFilename}.dmi", OutputFileFlags.Binary
| OutputFileFlags.Zippable,
"dmi"),
@@ -616,15 +636,54 @@ namespace MPF.Processors
/// </summary>
/// <param name="log">Log file location</param>
private static bool DatfileExists(string log)
=> GetDatfile(log) != null;
{
// Uncompressed outputs
if (GetDatfile(log) != null)
return true;
// Check for the log file
string outputFilename = Path.GetFileName(log);
string? outputDirectory = Path.GetDirectoryName(log);
string basePath = Path.GetFileNameWithoutExtension(outputFilename);
if (!string.IsNullOrEmpty(outputDirectory))
basePath = Path.Combine(outputDirectory, basePath);
#if NET20 || NET35 || NET40
// Assume the zipfile has the file in it
return File.Exists($"{basePath}_logs.zip");
#else
// If the zipfile doesn't exist
if (!File.Exists($"{basePath}_logs.zip"))
return false;
try
{
// Try to open the archive
using ZipArchive archive = ZipFile.OpenRead($"{basePath}_logs.zip");
// Get the log entry and check it, if possible
var entry = archive.GetEntry(outputFilename);
if (entry == null)
return false;
using var sr = new StreamReader(entry.Open());
return GetDatfile(sr) != null;
}
catch
{
return false;
}
#endif
}
/// <summary>
/// Copies a file with the header removed
/// Copies a file with the header removed and filesize trimmed
/// </summary>
/// <param name="inputFilename">Filename of file to copy from</param>
/// <param name="outputFilename">Filename of file to copy to</param>
/// <param name="headerLength">Length of header to remove</param>
private static bool RemoveHeader(string inputFilename, string outputFilename, int headerLength = 4)
/// <param name="headerLength">Length of file to trim to</param>
private static bool RemoveHeaderAndTrim(string inputFilename, string outputFilename, int headerLength = 4, int trimLength = 2048)
{
// If the file doesn't exist, we can't copy
if (!File.Exists(inputFilename))
@@ -647,13 +706,9 @@ namespace MPF.Processors
// Skip the header
inputStream.Seek(headerLength, SeekOrigin.Begin);
// inputStream.CopyTo(outputStream);
byte[] buffer = new byte[4096];
int count;
while ((count = inputStream.Read(buffer, 0, buffer.Length)) != 0)
{
outputStream.Write(buffer, 0, count);
}
byte[] buffer = new byte[trimLength];
int count = inputStream.Read(buffer, 0, buffer.Length);
outputStream.Write(buffer, 0, count);
return true;
}
@@ -728,14 +783,16 @@ namespace MPF.Processors
return null;
// Now that we're at the relevant entries, read each line in and concatenate
string? cueString = string.Empty, line = sr.ReadLine()?.Trim();
var sb = new StringBuilder();
string? line = sr.ReadLine()?.Trim();
while (!string.IsNullOrEmpty(line))
{
cueString += line + "\n";
// TODO: Figure out how to use NormalizeShiftJIS here
sb.AppendLine(line);
line = sr.ReadLine()?.Trim();
}
return cueString.TrimEnd('\n');
return sb.ToString().TrimEnd('\n');
}
catch
{
@@ -758,6 +815,24 @@ namespace MPF.Processors
try
{
using var sr = File.OpenText(log);
return GetDatfile(sr);
}
catch
{
// We don't care what the exception is right now
return null;
}
}
/// <summary>
/// Get the datfile from the input file, if possible
/// </summary>
/// <param name="sr">StreamReader representing the input file</param>
/// <returns>Newline-delimited datfile if possible, null on error</returns>
internal static string? GetDatfile(StreamReader sr)
{
try
{
string? datString = null;
// Find all occurrences of the hash information
@@ -791,14 +866,14 @@ namespace MPF.Processors
}
/// <summary>
/// Get reported disc type information, if possible
/// Get reported disc profile information, if possible
/// </summary>
/// <param name="log">Log file location</param>
/// <returns>True if disc type info was set, false otherwise</returns>
internal static bool GetDiscType(string log, out string? discTypeOrBookType)
/// <returns>True if disc profile information was set, false otherwise</returns>
internal static bool GetDiscProfile(string log, out string? discProfile)
{
// Set the default values
discTypeOrBookType = null;
discProfile = null;
// If the file doesn't exist, we can't get the info
if (string.IsNullOrEmpty(log))
@@ -819,7 +894,7 @@ namespace MPF.Processors
if (line.StartsWith("current profile:"))
{
// current profile: <discType>
discTypeOrBookType = line.Substring("current profile: ".Length);
discProfile = line.Substring("current profile: ".Length);
}
line = sr.ReadLine();
@@ -830,11 +905,121 @@ namespace MPF.Processors
catch
{
// We don't care what the exception is right now
discTypeOrBookType = null;
discProfile = null;
return false;
}
}
/// <summary>
/// Get reported disc type, if possible
/// </summary>
/// <param name="log">Log file location</param>
/// <returns>True if disc type was set, false otherwise</returns>
internal static bool GetDiscType(string log, out MediaType? discType)
{
// Set the default values
discType = null;
// If the file doesn't exist, we can't get the info
if (string.IsNullOrEmpty(log))
return false;
if (!File.Exists(log))
return false;
try
{
using var sr = File.OpenText(log);
var line = sr.ReadLine()?.TrimEnd();
while (line != null)
{
// If the line isn't the non-embedded disc type, skip
if (!line.StartsWith("disc type:"))
{
line = sr.ReadLine()?.TrimEnd();
continue;
}
// disc type: <discType>
string discTypeStr = line.Substring("disc type: ".Length);
// Set the media type based on the string
discType = discTypeStr switch
{
"CD" => MediaType.CDROM,
"DVD" => MediaType.DVD,
"BLURAY" => MediaType.BluRay,
"BLURAY-R" => MediaType.BluRay,
"HD-DVD" => MediaType.HDDVD,
_ => null,
};
return discType != null;
}
return false;
}
catch
{
// We don't care what the exception is right now
discType = null;
return false;
}
}
/// <summary>
/// Convert the profile to a media type, if possible
/// </summary>
/// <param name="profile">Profile string to check</param>
/// <returns>Media type on success, null otherwise</returns>
internal static MediaType? GetDiscTypeFromProfile(string? profile)
{
return profile switch
{
"reserved" => null,
"non removable disk" => null,
"removable disk" => null,
"MO erasable" => null,
"MO write once" => null,
"AS MO" => null,
"CD-ROM" => MediaType.CDROM,
"CD-R" => MediaType.CDROM,
"CD-RW" => MediaType.CDROM,
"DVD-ROM" => MediaType.DVD,
"DVD-R" => MediaType.DVD,
"DVD-RAM" => MediaType.DVD,
"DVD-RW RO" => MediaType.DVD,
"DVD-RW" => MediaType.DVD,
"DVD-R DL" => MediaType.DVD,
"DVD-R DL LJR" => MediaType.DVD,
"DVD+RW" => MediaType.DVD,
"DVD+R" => MediaType.DVD,
"DDCD-ROM" => MediaType.CDROM,
"DDCD-R" => MediaType.CDROM,
"DDCD-RW" => MediaType.CDROM,
"DVD+RW DL" => MediaType.DVD,
"DVD+R DL" => MediaType.DVD,
"BD-ROM" => MediaType.BluRay,
"BD-R" => MediaType.BluRay,
"BD-R RRM" => MediaType.BluRay,
"BD-RW" => MediaType.BluRay,
"HD DVD-ROM" => MediaType.HDDVD,
"HD DVD-R" => MediaType.HDDVD,
"HD DVD-RAM" => MediaType.HDDVD,
"HD DVD-RW" => MediaType.HDDVD,
"HD DVD-R DL" => MediaType.HDDVD,
"HD DVD-RW DL" => MediaType.HDDVD,
"NON STANDARD" => null,
_ => null,
};
}
/// <summary>
/// Get the DVD protection information, if possible
/// </summary>
@@ -966,28 +1151,69 @@ namespace MPF.Processors
break;
// C2: <error count>
// C2: <error count> samples
if (line.StartsWith("C2:"))
{
// Ensure there are the correct number of parts
string[] parts = line.Split(' ');
if (long.TryParse(parts[1], out long c2TrackErrors))
c2Errors += c2TrackErrors;
else
if (parts.Length < 2)
{
c2Errors = -1;
break;
}
// If there is a parsing error, return
if (!long.TryParse(parts[1], out long c2TrackErrors))
{
c2Errors = -1;
break;
}
// Standard error counts always add sectors
if (parts.Length == 2)
{
c2Errors += c2TrackErrors;
}
// Correction counts are ignored for now
else if (parts.Length > 2)
{
// No-op
}
}
// REDUMP.ORG errors: <error count>
else if (line.StartsWith("REDUMP.ORG errors:"))
{
// Ensure there are the correct number of parts
string[] parts = line!.Split(' ');
if (long.TryParse(parts[2], out long redumpTrackErrors))
redumpErrors += redumpTrackErrors;
else
if (parts.Length < 3)
{
redumpErrors = -1;
break;
}
// If there is a parsing error, return
if (!long.TryParse(parts[2], out long redumpTrackErrors))
{
redumpErrors = -1;
break;
}
// Always add Redump errors
redumpErrors += redumpTrackErrors;
}
// If either value is -1, exit the loop
if (c2Errors == -1 || redumpErrors == -1)
break;
// Reset C2 errors when a media errors section is found
else if (line.StartsWith("media errors:"))
{
c2Errors = 0;
}
// Reset Redump errors when an INFO block is found
else if (line.StartsWith("*** INFO"))
{
redumpErrors = 0;
}
}
// If either error count is -1, then an issue occurred
@@ -1624,12 +1850,22 @@ namespace MPF.Processors
try
{
// If we have a perfect audio offset, return
bool perfectAudioOffsetApplied = false;
using var sr = File.OpenText(log);
while (!sr.EndOfStream)
{
string? line = sr.ReadLine()?.TrimStart();
if (line?.StartsWith("Perfect Audio Offset applied") == true)
return "+0";
{
perfectAudioOffsetApplied = true;
}
else if (line?.StartsWith("disc write offset: +0") == true)
{
if (perfectAudioOffsetApplied)
return "+0";
else
return null;
}
}
// We couldn't detect it then
@@ -1777,6 +2013,7 @@ namespace MPF.Processors
try
{
long errorCount = 0;
using var sr = File.OpenText(log);
// Find the error counts
@@ -1787,16 +2024,45 @@ namespace MPF.Processors
break;
// SCSI: <error count>
if (line.StartsWith("SCSI: ") && !line.EndsWith("samples"))
// SCSI: <error count> samples
if (line.StartsWith("SCSI: "))
{
// Ensure there are the correct number of parts
string[] parts = line.Split(' ');
if (long.TryParse(parts[1], out long scsiErrors))
return scsiErrors;
if (parts.Length < 2)
{
errorCount = -1;
break;
}
// If there is a parsing error, return
if (!long.TryParse(parts[1], out long scsiErrors))
{
errorCount = -1;
break;
}
// Standard error counts always add sectors
if (parts.Length == 2)
{
errorCount += scsiErrors;
}
// Correction counts are ignored for now
else if (parts.Length > 2)
{
// No-op
}
}
// Reset SCSI errors when a media errors section is found
else if (line.StartsWith("media errors:"))
{
errorCount = 0;
}
}
// We couldn't detect it then
return -1;
// Return error count, default -1 if no SCSI error count found
return errorCount;
}
catch
{
@@ -1987,6 +2253,7 @@ namespace MPF.Processors
// Samples:
// redumper v2022.10.28 [Oct 28 2022, 05:41:43] (print usage: --help,-h)
// redumper v2022.12.22 build_87 [Dec 22 2022, 01:56:26]
// redumper v2025.03.29 build_481
try
{
@@ -2001,7 +2268,7 @@ namespace MPF.Processors
// Generate regex
// Permissive
var regex = new Regex(@"^redumper (v.+) \[.+\]", RegexOptions.Compiled);
var regex = new Regex(@"^redumper (v.+)", RegexOptions.Compiled);
// Strict
//var regex = new Regex(@"^redumper (v\d{4}\.\d{2}\.\d{2}(| build_\d+)) \[.+\]", RegexOptions.Compiled);

View File

@@ -14,106 +14,100 @@ namespace MPF.Processors
public sealed class UmdImageCreator : BaseProcessor
{
/// <inheritdoc/>
public UmdImageCreator(RedumpSystem? system, MediaType? type) : base(system, type) { }
public UmdImageCreator(RedumpSystem? system) : base(system) { }
#region BaseProcessor Implementations
/// <inheritdoc/>
public override void GenerateSubmissionInfo(SubmissionInfo info, string basePath, bool redumpCompat)
public override MediaType? DetermineMediaType(string? outputDirectory, string outputFilename)
=> MediaType.UMD;
/// <inheritdoc/>
public override void GenerateSubmissionInfo(SubmissionInfo info, MediaType? mediaType, string basePath, bool redumpCompat)
{
// Ensure that required sections exist
info = Builder.EnsureAllSections(info);
// TODO: Determine if there's a UMDImageCreator version anywhere
info.DumpingInfo!.DumpingDate = ProcessingTool.GetFileModifiedDate(basePath + "_disc.txt")?.ToString("yyyy-MM-dd HH:mm:ss");
info.DumpingInfo!.DumpingDate = ProcessingTool.GetFileModifiedDate($"{basePath}_disc.txt")?.ToString("yyyy-MM-dd HH:mm:ss");
// Get the PVD, if it exists
info.Extras!.PVD = GetPVD($"{basePath}_mainInfo.txt") ?? string.Empty;
// Get the Datafile information
if (HashTool.GetStandardHashes($"{basePath}.iso", out long filesize, out var crc32, out var md5, out var sha1))
{
// Create a Datafile from the hashes
var datafile = new Datafile
{
Game = [new Game { Rom = [new Rom { Name = string.Empty, Size = filesize.ToString(), CRC = crc32, MD5 = md5, SHA1 = sha1 }] }]
};
// Fill in the hash data
info.TracksAndWriteOffsets!.ClrMameProData = ProcessingTool.GenerateDatfile(datafile);
info.SizeAndChecksums!.Size = filesize;
info.SizeAndChecksums.CRC32 = crc32;
info.SizeAndChecksums.MD5 = md5;
info.SizeAndChecksums.SHA1 = sha1;
}
// Get internal information
if (GetUMDAuxInfo($"{basePath}_disc.txt",
out var title,
out DiscCategory? category,
out string? serial,
out var version,
out var layer,
out long size))
{
info.CommonDiscInfo!.Title = title ?? string.Empty;
info.CommonDiscInfo.Category = category ?? DiscCategory.Games;
info.CommonDiscInfo.CommentsSpecialFields![SiteCode.InternalSerialName] = serial ?? string.Empty;
info.VersionAndEditions!.Version = version ?? string.Empty;
info.SizeAndChecksums!.Size = size;
if (!string.IsNullOrEmpty(layer))
info.SizeAndChecksums.Layerbreak = long.Parse(layer ?? "-1");
}
// Fill in the volume labels
if (GetVolumeLabels($"{basePath}_volDesc.txt", out var volLabels))
VolumeLabels = volLabels;
// Extract info based generically on MediaType
switch (Type)
{
case MediaType.UMD:
info.Extras!.PVD = GetPVD(basePath + "_mainInfo.txt") ?? string.Empty;
if (HashTool.GetStandardHashes(basePath + ".iso", out long filesize, out var crc32, out var md5, out var sha1))
{
// Get the Datafile information
var datafile = new Datafile
{
Game = [new Game { Rom = [new Rom { Name = string.Empty, Size = filesize.ToString(), CRC = crc32, MD5 = md5, SHA1 = sha1 }] }]
};
// Fill in the hash data
info.TracksAndWriteOffsets!.ClrMameProData = ProcessingTool.GenerateDatfile(datafile);
info.SizeAndChecksums!.Size = filesize;
info.SizeAndChecksums.CRC32 = crc32;
info.SizeAndChecksums.MD5 = md5;
info.SizeAndChecksums.SHA1 = sha1;
}
if (GetUMDAuxInfo(basePath + "_disc.txt",
out var title,
out DiscCategory? category,
out string? serial,
out var version,
out var layer,
out long size))
{
info.CommonDiscInfo!.Title = title ?? string.Empty;
info.CommonDiscInfo.Category = category ?? DiscCategory.Games;
info.CommonDiscInfo.CommentsSpecialFields![SiteCode.InternalSerialName] = serial ?? string.Empty;
info.VersionAndEditions!.Version = version ?? string.Empty;
info.SizeAndChecksums!.Size = size;
if (!string.IsNullOrEmpty(layer))
info.SizeAndChecksums.Layerbreak = long.Parse(layer ?? "-1");
}
break;
}
}
/// <inheritdoc/>
internal override List<OutputFile> GetOutputFiles(string? outputDirectory, string outputFilename)
internal override List<OutputFile> GetOutputFiles(MediaType? mediaType, string? outputDirectory, string outputFilename)
{
// Remove the extension by default
outputFilename = Path.GetFileNameWithoutExtension(outputFilename);
switch (Type)
{
case MediaType.UMD:
return [
new($"{outputFilename}.iso", OutputFileFlags.Required),
return [
new($"{outputFilename}.iso", OutputFileFlags.Required),
new($"{outputFilename}_disc.txt", OutputFileFlags.Required
| OutputFileFlags.Artifact
| OutputFileFlags.Zippable,
"disc"),
new($"{outputFilename}_drive.txt", OutputFileFlags.Artifact
| OutputFileFlags.Zippable,
"drive"),
new($"{outputFilename}_mainError.txt", OutputFileFlags.Required
| OutputFileFlags.Artifact
| OutputFileFlags.Zippable,
"main_error"),
new($"{outputFilename}_mainInfo.txt", OutputFileFlags.Required
| OutputFileFlags.Artifact
| OutputFileFlags.Zippable,
"main_info"),
new($"{outputFilename}_PFI.bin", OutputFileFlags.Binary
| OutputFileFlags.Zippable,
"pfi"),
new($"{outputFilename}_volDesc.txt", OutputFileFlags.Required
| OutputFileFlags.Artifact
| OutputFileFlags.Zippable,
"vol_desc"),
];
}
return [];
new($"{outputFilename}_disc.txt", OutputFileFlags.Required
| OutputFileFlags.Artifact
| OutputFileFlags.Zippable,
"disc"),
new($"{outputFilename}_drive.txt", OutputFileFlags.Artifact
| OutputFileFlags.Zippable,
"drive"),
new($"{outputFilename}_mainError.txt", OutputFileFlags.Required
| OutputFileFlags.Artifact
| OutputFileFlags.Zippable,
"main_error"),
new($"{outputFilename}_mainInfo.txt", OutputFileFlags.Required
| OutputFileFlags.Artifact
| OutputFileFlags.Zippable,
"main_info"),
new($"{outputFilename}_PFI.bin", OutputFileFlags.Binary
| OutputFileFlags.Zippable,
"pfi"),
new($"{outputFilename}_volDesc.txt", OutputFileFlags.Required
| OutputFileFlags.Artifact
| OutputFileFlags.Zippable,
"vol_desc"),
];
}
#endregion

View File

@@ -14,12 +14,16 @@ namespace MPF.Processors
public sealed class XboxBackupCreator : BaseProcessor
{
/// <inheritdoc/>
public XboxBackupCreator(RedumpSystem? system, MediaType? type) : base(system, type) { }
public XboxBackupCreator(RedumpSystem? system) : base(system) { }
#region BaseProcessor Implementations
/// <inheritdoc/>
public override void GenerateSubmissionInfo(SubmissionInfo info, string basePath, bool redumpCompat)
public override MediaType? DetermineMediaType(string? outputDirectory, string outputFilename)
=> MediaType.DVD;
/// <inheritdoc/>
public override void GenerateSubmissionInfo(SubmissionInfo info, MediaType? mediaType, string basePath, bool redumpCompat)
{
// Ensure that required sections exist
info = Builder.EnsureAllSections(info);
@@ -38,152 +42,131 @@ namespace MPF.Processors
info.DumpingInfo.DumpingDate = ProcessingTool.GetFileModifiedDate(logPath)?.ToString("yyyy-MM-dd HH:mm:ss");
info.DumpingInfo.Model = GetDrive(logPath) ?? "Unknown Drive";
// Get the Datafile information
Datafile? datafile = GenerateDatafile($"{basePath}.iso");
info.TracksAndWriteOffsets!.ClrMameProData = ProcessingTool.GenerateDatfile(datafile);
// Get the individual hash data, as per internal
if (ProcessingTool.GetISOHashValues(datafile, out long size, out var crc32, out var md5, out var sha1))
{
info.SizeAndChecksums!.Size = size;
info.SizeAndChecksums.CRC32 = crc32;
info.SizeAndChecksums.MD5 = md5;
info.SizeAndChecksums.SHA1 = sha1;
}
// Get Layerbreak from .dvd file if possible
if (GetLayerbreak($"{basePath}.dvd", out long layerbreak))
info.SizeAndChecksums!.Layerbreak = layerbreak;
// Look for read errors
if (GetReadErrors(logPath, out long readErrors))
info.CommonDiscInfo!.ErrorsCount = readErrors == -1 ? "Error retrieving error count" : readErrors.ToString();
// Extract info based generically on MediaType
switch (Type)
switch (System)
{
case MediaType.DVD:
// Get Layerbreak from .dvd file if possible
if (GetLayerbreak($"{basePath}.dvd", out long layerbreak))
info.SizeAndChecksums!.Layerbreak = layerbreak;
// Hash data
if (HashTool.GetStandardHashes(basePath + ".iso", out long filesize, out var crc32, out var md5, out var sha1))
case RedumpSystem.MicrosoftXbox:
string xmidString = ProcessingTool.GetXMID(Path.Combine(outputDirectory, "DMI.bin"));
var xmid = SabreTools.Serialization.Wrappers.XMID.Create(xmidString);
if (xmid != null)
{
// Get the Datafile information
var datafile = new Datafile
info.CommonDiscInfo!.CommentsSpecialFields![SiteCode.XMID] = xmidString?.TrimEnd('\0') ?? string.Empty;
info.CommonDiscInfo.Serial = xmid.Serial ?? string.Empty;
if (!redumpCompat)
{
Game = [new Game { Rom = [new Rom { Name = string.Empty, Size = filesize.ToString(), CRC = crc32, MD5 = md5, SHA1 = sha1 }] }]
};
// Fill in the hash data
info.TracksAndWriteOffsets!.ClrMameProData = ProcessingTool.GenerateDatfile(datafile);
info.SizeAndChecksums!.Size = filesize;
info.SizeAndChecksums.CRC32 = crc32;
info.SizeAndChecksums.MD5 = md5;
info.SizeAndChecksums.SHA1 = sha1;
info.VersionAndEditions!.Version = xmid.Version ?? string.Empty;
info.CommonDiscInfo.Region = ProcessingTool.GetXGDRegion(xmid.Model.RegionIdentifier);
}
}
switch (System)
break;
case RedumpSystem.MicrosoftXbox360:
// Get PVD from ISO
if (GetPVD($"{basePath}.iso", out string? pvd))
info.Extras!.PVD = pvd;
// Parse Media ID
//string? mediaID = GetMediaID(logPath);
// Parse DMI.bin
string xemidString = ProcessingTool.GetXeMID(Path.Combine(outputDirectory, "DMI.bin"));
var xemid = SabreTools.Serialization.Wrappers.XeMID.Create(xemidString);
if (xemid != null)
{
case RedumpSystem.MicrosoftXbox:
info.CommonDiscInfo!.CommentsSpecialFields![SiteCode.XeMID] = xemidString?.TrimEnd('\0') ?? string.Empty;
info.CommonDiscInfo.Serial = xemid.Serial ?? string.Empty;
if (!redumpCompat)
info.VersionAndEditions!.Version = xemid.Version ?? string.Empty;
// Parse DMI.bin
string xmidString = ProcessingTool.GetXMID(Path.Combine(outputDirectory, "DMI.bin"));
var xmid = SabreTools.Serialization.Wrappers.XMID.Create(xmidString);
if (xmid != null)
{
info.CommonDiscInfo!.CommentsSpecialFields![SiteCode.XMID] = xmidString?.TrimEnd('\0') ?? string.Empty;
info.CommonDiscInfo.Serial = xmid.Serial ?? string.Empty;
if (!redumpCompat)
{
info.VersionAndEditions!.Version = xmid.Version ?? string.Empty;
info.CommonDiscInfo.Region = ProcessingTool.GetXGDRegion(xmid.Model.RegionIdentifier);
}
}
break;
case RedumpSystem.MicrosoftXbox360:
// Get PVD from ISO
if (GetPVD(basePath + ".iso", out string? pvd))
info.Extras!.PVD = pvd;
// Parse Media ID
//string? mediaID = GetMediaID(logPath);
// Parse DMI.bin
string xemidString = ProcessingTool.GetXeMID(Path.Combine(outputDirectory, "DMI.bin"));
var xemid = SabreTools.Serialization.Wrappers.XeMID.Create(xemidString);
if (xemid != null)
{
info.CommonDiscInfo!.CommentsSpecialFields![SiteCode.XeMID] = xemidString?.TrimEnd('\0') ?? string.Empty;
info.CommonDiscInfo.Serial = xemid.Serial ?? string.Empty;
if (!redumpCompat)
info.VersionAndEditions!.Version = xemid.Version ?? string.Empty;
info.CommonDiscInfo.Region = ProcessingTool.GetXGDRegion(xemid.Model.RegionIdentifier);
}
break;
info.CommonDiscInfo.Region = ProcessingTool.GetXGDRegion(xemid.Model.RegionIdentifier);
}
// Get the output file paths
string dmiPath = Path.Combine(outputDirectory, "DMI.bin");
string pfiPath = Path.Combine(outputDirectory, "PFI.bin");
string ssPath = Path.Combine(outputDirectory, "SS.bin");
// Deal with SS.bin
if (File.Exists(ssPath))
{
// Save security sector ranges
string? ranges = ProcessingTool.GetSSRanges(ssPath);
if (!string.IsNullOrEmpty(ranges))
info.Extras!.SecuritySectorRanges = ranges;
// Recreate RawSS.bin
RecreateSS(logPath!, ssPath, Path.Combine(outputDirectory, "RawSS.bin"));
// Run ss_sector_range to get repeatable SS hash
ProcessingTool.CleanSS(ssPath, ssPath);
}
// DMI/PFI/SS CRC32 hashes
if (File.Exists(dmiPath))
info.CommonDiscInfo!.CommentsSpecialFields![SiteCode.DMIHash] = HashTool.GetFileHash(dmiPath, HashType.CRC32)?.ToUpperInvariant() ?? string.Empty;
if (File.Exists(pfiPath))
info.CommonDiscInfo!.CommentsSpecialFields![SiteCode.PFIHash] = HashTool.GetFileHash(pfiPath, HashType.CRC32)?.ToUpperInvariant() ?? string.Empty;
if (File.Exists(ssPath))
info.CommonDiscInfo!.CommentsSpecialFields![SiteCode.SSHash] = HashTool.GetFileHash(ssPath, HashType.CRC32)?.ToUpperInvariant() ?? string.Empty;
break;
}
// Get the output file paths
string dmiPath = Path.Combine(outputDirectory, "DMI.bin");
string pfiPath = Path.Combine(outputDirectory, "PFI.bin");
string ssPath = Path.Combine(outputDirectory, "SS.bin");
// Deal with SS.bin
if (File.Exists(ssPath))
{
// Save security sector ranges
string? ranges = ProcessingTool.GetSSRanges(ssPath);
if (!string.IsNullOrEmpty(ranges))
info.Extras!.SecuritySectorRanges = ranges;
// Recreate RawSS.bin
RecreateSS(logPath!, ssPath, Path.Combine(outputDirectory, "RawSS.bin"));
// Run ss_sector_range to get repeatable SS hash
ProcessingTool.CleanSS(ssPath, ssPath);
}
// DMI/PFI/SS CRC32 hashes
if (File.Exists(dmiPath))
info.CommonDiscInfo!.CommentsSpecialFields![SiteCode.DMIHash] = HashTool.GetFileHash(dmiPath, HashType.CRC32)?.ToUpperInvariant() ?? string.Empty;
if (File.Exists(pfiPath))
info.CommonDiscInfo!.CommentsSpecialFields![SiteCode.PFIHash] = HashTool.GetFileHash(pfiPath, HashType.CRC32)?.ToUpperInvariant() ?? string.Empty;
if (File.Exists(ssPath))
info.CommonDiscInfo!.CommentsSpecialFields![SiteCode.SSHash] = HashTool.GetFileHash(ssPath, HashType.CRC32)?.ToUpperInvariant() ?? string.Empty;
}
/// <inheritdoc/>
internal override List<OutputFile> GetOutputFiles(string? outputDirectory, string outputFilename)
internal override List<OutputFile> GetOutputFiles(MediaType? mediaType, string? outputDirectory, string outputFilename)
{
// Remove the extension by default
outputFilename = Path.GetFileNameWithoutExtension(outputFilename);
switch (Type)
{
case MediaType.DVD:
return [
new($"{outputFilename}.dvd", OutputFileFlags.Artifact
| OutputFileFlags.Zippable,
"dvd"),
new($"{outputFilename}.iso", OutputFileFlags.Required),
new("DMI.bin", OutputFileFlags.Required
| OutputFileFlags.Binary
| OutputFileFlags.Zippable,
"dmi"),
new RegexOutputFile("[lL]og.txt", OutputFileFlags.Required
| OutputFileFlags.Artifact
| OutputFileFlags.Zippable,
"log"),
new("PFI.bin", OutputFileFlags.Required
| OutputFileFlags.Binary
| OutputFileFlags.Zippable,
"pfi"),
new("RawSS.bin", OutputFileFlags.Binary
| OutputFileFlags.Zippable,
"raw_ss"),
new("SS.bin", OutputFileFlags.Required
| OutputFileFlags.Binary
| OutputFileFlags.Zippable,
"ss"),
];
}
return [
new($"{outputFilename}.dvd", OutputFileFlags.Artifact
| OutputFileFlags.Zippable,
"dvd"),
new($"{outputFilename}.iso", OutputFileFlags.Required),
return [];
new("DMI.bin", OutputFileFlags.Required
| OutputFileFlags.Binary
| OutputFileFlags.Zippable,
"dmi"),
new RegexOutputFile("[lL]og\\.txt", OutputFileFlags.Required
| OutputFileFlags.Artifact
| OutputFileFlags.Zippable,
"log"),
new("PFI.bin", OutputFileFlags.Required
| OutputFileFlags.Binary
| OutputFileFlags.Zippable,
"pfi"),
new("RawSS.bin", OutputFileFlags.Binary
| OutputFileFlags.Zippable,
"raw_ss"),
new("SS.bin", OutputFileFlags.Required
| OutputFileFlags.Binary
| OutputFileFlags.Zippable,
"ss"),
];
}
#endregion

View File

@@ -4,6 +4,7 @@ using System.Windows.Data;
using MPF.Frontend;
using MPF.Frontend.ComboBoxItems;
using SabreTools.RedumpLib.Data;
using RedumperDriveType = MPF.ExecutionContexts.Redumper.DriveType;
using RedumperReadMethod = MPF.ExecutionContexts.Redumper.ReadMethod;
using RedumperSectorOrder = MPF.ExecutionContexts.Redumper.SectorOrder;
@@ -20,6 +21,7 @@ namespace MPF.UI
MediaType mediaType => new Element<MediaType>(mediaType),
RedumperReadMethod readMethod => new Element<RedumperReadMethod>(readMethod),
RedumperSectorOrder sectorOrder => new Element<RedumperSectorOrder>(sectorOrder),
RedumperDriveType driveType => new Element<RedumperDriveType>(driveType),
RedumpSystem redumpSystem => new RedumpSystemComboBoxItem(redumpSystem),
Region region => new Element<Region>(region),
@@ -41,6 +43,7 @@ namespace MPF.UI
Element<MediaType> mtElement => mtElement.Value,
Element<RedumperReadMethod> rmElement => rmElement.Value,
Element<RedumperSectorOrder> soElement => soElement.Value,
Element<RedumperDriveType> dtElement => dtElement.Value,
RedumpSystemComboBoxItem rsElement => rsElement.Value,
Element<Region> reValue => reValue.Value,
_ => null,

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

After

Width:  |  Height:  |  Size: 184 KiB

View File

@@ -18,7 +18,7 @@
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<UseWindowsForms>true</UseWindowsForms>
<UseWPF>true</UseWPF>
<VersionPrefix>3.3.0</VersionPrefix>
<VersionPrefix>3.3.3</VersionPrefix>
<!-- Package Properties -->
<AssemblyName>MPF</AssemblyName>
@@ -70,14 +70,14 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="SabreTools.RedumpLib" Version="1.6.4" />
<PackageReference Include="SabreTools.RedumpLib" Version="1.6.8" />
</ItemGroup>
<ItemGroup>
<Page Update="UserControls\UserInput.xaml">
<XamlRuntime>$(DefaultXamlRuntime)</XamlRuntime>
</Page>
<Page Update="Windows\DiscInformationWindow.xaml">
<Page Update="Windows\MediaInformationWindow.xaml">
<XamlRuntime>$(DefaultXamlRuntime)</XamlRuntime>
</Page>
<Page Update="Windows\RingCodeGuideWindow.xaml">

View File

@@ -110,6 +110,32 @@
</Grid>
</GroupBox>
<GroupBox Margin="5,5,5,5" HorizontalAlignment="Stretch" Header="Status">
<UniformGrid Margin="5,5,5,5" Grid.ColumnSpan="2">
<TextBlock x:Name="StatusLabel" VerticalAlignment="Center" HorizontalAlignment="Center"
ToolTipService.ToolTip="{Binding Status, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Text="{Binding StatusFirstLine}" />
</UniformGrid>
</GroupBox>
<GroupBox Margin="5,5,5,5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<GroupBox.Template>
<ControlTemplate TargetType="GroupBox">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="5">
<ContentPresenter Content="{TemplateBinding Content}" Margin="{TemplateBinding Padding}" />
</Border>
</ControlTemplate>
</GroupBox.Template>
<Label>
<Label.Content>
<TextBlock TextWrapping="Wrap">
<Run FontWeight="Bold" Foreground="Red" Text="WARNING:" />
<Run Text="Check will overwrite both any existing submission information files as well as any log archives. Please make backups of those if you need to before running Check." />
</TextBlock>
</Label.Content>
</Label>
</GroupBox>
<!-- Check Dump / Cancel -->
<GroupBox Margin="5,5,5,5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<GroupBox.Template>

View File

@@ -125,14 +125,14 @@ namespace MPF.UI.Windows
}
/// <summary>
/// Show the disc information window
/// Show the media information window
/// </summary>
/// <param name="options">Options set to pass to the information window</param>
/// <param name="submissionInfo">SubmissionInfo object to display and possibly change</param>
/// <returns>Dialog open result</returns>
public bool? ShowDiscInformationWindow(Options? options, ref SubmissionInfo? submissionInfo)
public bool? ShowMediaInformationWindow(Options? options, ref SubmissionInfo? submissionInfo)
{
var discInformationWindow = new DiscInformationWindow(options ?? new Options(), submissionInfo)
var mediaInformationWindow = new MediaInformationWindow(options ?? new Options(), submissionInfo)
{
Focusable = true,
Owner = this,
@@ -141,12 +141,12 @@ namespace MPF.UI.Windows
WindowStartupLocation = WindowStartupLocation.CenterOwner,
};
discInformationWindow.Closed += delegate { Activate(); };
bool? result = discInformationWindow.ShowDialog();
mediaInformationWindow.Closed += delegate { Activate(); };
bool? result = mediaInformationWindow.ShowDialog();
// Copy back the submission info changes, if necessary
if (result == true)
submissionInfo = (discInformationWindow.DiscInformationViewModel.SubmissionInfo.Clone() as SubmissionInfo)!;
submissionInfo = (mediaInformationWindow.MediaInformationViewModel.SubmissionInfo.Clone() as SubmissionInfo)!;
return result;
}
@@ -160,12 +160,14 @@ namespace MPF.UI.Windows
/// </summary>
private async void OnCheckDumpClick(object sender, EventArgs e)
{
string? errorMessage = await CheckDumpViewModel.CheckDump(ShowDiscInformationWindow);
string? errorMessage = await CheckDumpViewModel.CheckDump(ShowMediaInformationWindow);
if (string.IsNullOrEmpty(errorMessage))
{
bool? checkAgain = DisplayUserMessage("Check Complete", "The dump has been processed successfully! Would you like to check another dump?", 2, false);
if (checkAgain == false)
Close();
else
CheckDumpViewModel.Status = string.Empty;
}
else
{

View File

@@ -1,4 +1,5 @@
using System;
using System.ComponentModel;
using System.IO;
#if NET40
using System.Threading.Tasks;
@@ -74,6 +75,7 @@ namespace MPF.UI.Windows
{
#if NET40_OR_GREATER || NETCOREAPP
InitializeComponent();
this.Closing += MainWindowClosing;
#endif
#if NET452_OR_GREATER || NETCOREAPP
@@ -106,7 +108,7 @@ namespace MPF.UI.Windows
if (MainViewModel.Options.ShowDebugViewMenuItem)
DebugViewMenuItem!.Visibility = Visibility.Visible;
MainViewModel.Init(LogOutput!.EnqueueLog, DisplayUserMessage, ShowDiscInformationWindow);
MainViewModel.Init(LogOutput!.EnqueueLog, DisplayUserMessage, ShowMediaInformationWindow);
// Set the UI color scheme according to the options
ApplyTheme();
@@ -210,28 +212,41 @@ namespace MPF.UI.Windows
CustomMessageBox.Show(this, message, "Version Update Check", MessageBoxButton.OK, different ? MessageBoxImage.Exclamation : MessageBoxImage.Information);
}
/// <summary>
/// Ask to confirm quitting, when an operation is running
/// </summary>
public void MainWindowClosing(object? sender, CancelEventArgs e)
{
if (MainViewModel.AskBeforeQuit)
{
MessageBoxResult result = CustomMessageBox.Show(this, "A dump is still being processed, are you sure you want to quit?", "Quit", MessageBoxButton.YesNo, MessageBoxImage.Exclamation);
if (result == MessageBoxResult.No)
e.Cancel = true;
}
}
/// <summary>
/// Build a dummy SubmissionInfo and display it for testing
/// </summary>
public void ShowDebugDiscInfoWindow()
{
var submissionInfo = MainViewModel.CreateDebugSubmissionInfo();
_ = ShowDiscInformationWindow(MainViewModel.Options, ref submissionInfo);
_ = ShowMediaInformationWindow(MainViewModel.Options, ref submissionInfo);
Formatter.ProcessSpecialFields(submissionInfo!);
}
/// <summary>
/// Show the disc information window
/// Show the media information window
/// </summary>
/// <param name="options">Options set to pass to the information window</param>
/// <param name="submissionInfo">SubmissionInfo object to display and possibly change</param>
/// <returns>Dialog open result</returns>
public bool? ShowDiscInformationWindow(Options? options, ref SubmissionInfo? submissionInfo)
public bool? ShowMediaInformationWindow(Options? options, ref SubmissionInfo? submissionInfo)
{
if (options?.ShowDiscEjectReminder == true)
CustomMessageBox.Show(this, "It is now safe to eject the disc", "Eject", MessageBoxButton.OK, MessageBoxImage.Information);
var discInformationWindow = new DiscInformationWindow(options ?? new Options(), submissionInfo)
var mediaInformationWindow = new MediaInformationWindow(options ?? new Options(), submissionInfo)
{
Focusable = true,
Owner = this,
@@ -240,12 +255,12 @@ namespace MPF.UI.Windows
WindowStartupLocation = WindowStartupLocation.CenterOwner,
};
discInformationWindow.Closed += delegate { Activate(); };
bool? result = discInformationWindow.ShowDialog();
mediaInformationWindow.Closed += delegate { Activate(); };
bool? result = mediaInformationWindow.ShowDialog();
// Copy back the submission info changes, if necessary
if (result == true)
submissionInfo = (discInformationWindow.DiscInformationViewModel.SubmissionInfo.Clone() as SubmissionInfo)!;
submissionInfo = (mediaInformationWindow.MediaInformationViewModel.SubmissionInfo.Clone() as SubmissionInfo)!;
return result;
}
@@ -500,7 +515,7 @@ namespace MPF.UI.Windows
public void DriveSpeedComboBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (MainViewModel.CanExecuteSelectionChanged)
MainViewModel.EnsureDiscInformation();
MainViewModel.EnsureMediaInformation();
}
/// <summary>
@@ -542,7 +557,7 @@ namespace MPF.UI.Windows
public void OutputPathBrowseButtonClick(object sender, RoutedEventArgs e)
{
BrowseFile();
MainViewModel.EnsureDiscInformation();
MainViewModel.EnsureMediaInformation();
}
/// <summary>
@@ -551,7 +566,7 @@ namespace MPF.UI.Windows
public void OutputPathTextBoxTextChanged(object sender, TextChangedEventArgs e)
{
if (MainViewModel.CanExecuteSelectionChanged)
MainViewModel.EnsureDiscInformation();
MainViewModel.EnsureMediaInformation();
}
/// <summary>

View File

@@ -1,4 +1,4 @@
<coreWindows:WindowBase x:Class="MPF.UI.Windows.DiscInformationWindow"
<coreWindows:WindowBase x:Class="MPF.UI.Windows.MediaInformationWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
@@ -8,7 +8,7 @@
xmlns:redump="clr-namespace:SabreTools.RedumpLib.Data;assembly=SabreTools.RedumpLib"
xmlns:coreWindows="clr-namespace:MPF.UI.Windows"
mc:Ignorable="d"
Title="Disc Information" Width="600" WindowStyle="None"
Title="Media Information" Width="600" WindowStyle="None"
WindowStartupLocation="CenterOwner" ResizeMode="CanMinimize" SizeToContent="Height"
AllowsTransparency="True" Background="Transparent">
@@ -32,7 +32,7 @@
<Image Grid.Column="0" Source="/Images/Icon.ico" Height="20" Width="20" Margin="1" MouseDown="TitleMouseDown" />
<Label Grid.Column="1" Grid.ColumnSpan="4" HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" MouseDown="TitleMouseDown">
<Label.Content>
<Run FontWeight="Bold" Text="Disc Information" />
<Run FontWeight="Bold" Text="Media Information" />
</Label.Content>
<Label.ContextMenu>
<ContextMenu Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"
@@ -72,7 +72,7 @@
<TabItem x:Name="CommonInfo" Header="Common Info" Style="{DynamicResource CustomTabItemStyle}">
<ScrollViewer CanContentScroll="False" VerticalScrollBarVisibility="Auto" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" MaxHeight="500">
<StackPanel Orientation="Vertical">
<GroupBox Header="Common Disc Information" Margin="5" Padding="5" BorderThickness="1" BorderBrush="LightGray"
<GroupBox Header="Common Media Information" Margin="5" Padding="5" BorderThickness="1" BorderBrush="LightGray"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<StackPanel Orientation="Vertical">
<controls:UserInput Label="Title"
@@ -85,8 +85,10 @@
Text="{Binding Path=SubmissionInfo.CommonDiscInfo.CommentsSpecialFields[(redump:SiteCode)AlternativeForeignTitle], Mode=TwoWay}"/>
<controls:UserInput Label="Disc Number / Letter"
Text="{Binding SubmissionInfo.CommonDiscInfo.DiscNumberLetter, Mode=TwoWay}"/>
<controls:UserInput Label="Disc Title"
<controls:UserInput x:Name="DiscTitleTextBox" Label="Disc Title"
Text="{Binding SubmissionInfo.CommonDiscInfo.DiscTitle, Mode=TwoWay}"/>
<controls:UserInput x:Name="DiscTitleNonLatinTextBox" Label="Disc Title (non-Latin)"
Text="{Binding Path=SubmissionInfo.CommonDiscInfo.CommentsSpecialFields[(redump:SiteCode)DiscTitleNonLatin], Mode=TwoWay}"/>
<Grid>
<Grid.ColumnDefinitions>
@@ -157,7 +159,9 @@
HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<StackPanel Orientation="Vertical">
<controls:UserInput Label="Version" Text="{Binding SubmissionInfo.VersionAndEditions.Version, Mode=TwoWay}"/>
<controls:UserInput Label="Edition" Text="{Binding SubmissionInfo.VersionAndEditions.OtherEditions, Mode=TwoWay}"/>
<controls:UserInput x:Name="EditionTextBox" Label="Edition" Text="{Binding SubmissionInfo.VersionAndEditions.OtherEditions, Mode=TwoWay}"/>
<controls:UserInput x:Name="EditionNonLatinTextBox" Label="Edition (non-Latin)"
Text="{Binding Path=SubmissionInfo.CommonDiscInfo.CommentsSpecialFields[(redump:SiteCode)EditionNonLatin], Mode=TwoWay}"/>
</StackPanel>
</GroupBox>
</StackPanel>
@@ -170,6 +174,16 @@
<GroupBox Header="Extras" Margin="5" Padding="5" BorderThickness="1" BorderBrush="LightGray"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<StackPanel Orientation="Vertical">
<Grid x:Name="PCMacHybridGrid" Visibility="Collapsed">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.75*" />
<ColumnDefinition Width="1.75*" />
</Grid.ColumnDefinitions>
<Label/>
<CheckBox Grid.Column="1" x:Name="PCMacHybridCheckBox" Content="PC/Mac Hybrid" Margin="0,4"
IsChecked="{Binding Path=SubmissionInfo.CommonDiscInfo.CommentsSpecialFields[(redump:SiteCode)PCMacHybrid], Mode=TwoWay}"/>
</Grid>
<controls:UserInput x:Name="CommentsTextBox" Label="Comments"
Text="{Binding SubmissionInfo.CommonDiscInfo.Comments, Mode=TwoWay}" TextHeight="50"
Enter="True" TextWrapping="Wrap" VerticalContentAlignmentValue="Top" />
@@ -179,33 +193,9 @@
Text="{Binding Path=SubmissionInfo.Extras.DiscKey, Mode=TwoWay}"/>
<controls:UserInput x:Name="DiscIDTextBox" Label="Disc ID" Visibility="Collapsed"
Text="{Binding Path=SubmissionInfo.Extras.DiscID, Mode=TwoWay}"/>
<controls:UserInput x:Name="GenreTextBox" Label="Genre"
Text="{Binding Path=SubmissionInfo.CommonDiscInfo.CommentsSpecialFields[(redump:SiteCode)Genre], Mode=TwoWay}"/>
<controls:UserInput x:Name="ProtectionTextBox" Label="Protection" ToolTip="CAUTION: Only edit if you know what you are doing!"
Text="{Binding SubmissionInfo.CopyProtection.Protection, Mode=TwoWay}" TextHeight="75" TextWrapping="Wrap"
VerticalContentAlignmentValue="Top" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"/>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.75*" />
<ColumnDefinition Width="1.75*" />
</Grid.ColumnDefinitions>
<Label/>
<CheckBox Grid.Column="1" x:Name="PostgapTypeCheckBox" Content="Postgap type (Form 2)" Margin="0,4"
IsChecked="{Binding Path=SubmissionInfo.CommonDiscInfo.CommentsSpecialFields[(redump:SiteCode)PostgapType], Mode=TwoWay}"/>
</Grid>
<controls:UserInput x:Name="SeriesTextBox" Label="Series"
Text="{Binding Path=SubmissionInfo.CommonDiscInfo.CommentsSpecialFields[(redump:SiteCode)Series], Mode=TwoWay}"/>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.75*" />
<ColumnDefinition Width="1.75*" />
</Grid.ColumnDefinitions>
<Label/>
<CheckBox Grid.Column="1" x:Name="VCDCheckBox" Content="V-CD" Margin="0,4"
IsChecked="{Binding Path=SubmissionInfo.CommonDiscInfo.CommentsSpecialFields[(redump:SiteCode)VCD], Mode=TwoWay}"/>
</Grid>
</StackPanel>
</GroupBox>
@@ -316,7 +306,7 @@
<controls:UserInput x:Name="GamesTextBox" Label="Games" TextHeight="50"
Enter="True" TextWrapping="Wrap" VerticalContentAlignmentValue="Top"
Text="{Binding Path=SubmissionInfo.CommonDiscInfo.ContentsSpecialFields[(redump:SiteCode)Games], Mode=TwoWay}"/>
<controls:UserInput x:Name="NetYarozeGamesTextBox" Label="Net Yaroze Games" TextHeight="50"
<controls:UserInput x:Name="NetYarozeGamesTextBox" Label="Net Yaroze Games" Visibility="Collapsed" TextHeight="50"
Enter="True" TextWrapping="Wrap" VerticalContentAlignmentValue="Top"
Text="{Binding Path=SubmissionInfo.CommonDiscInfo.ContentsSpecialFields[(redump:SiteCode)NetYarozeGames], Mode=TwoWay}"/>

View File

@@ -6,9 +6,9 @@ using SabreTools.RedumpLib.Data;
namespace MPF.UI.Windows
{
/// <summary>
/// Interaction logic for DiscInformationWindow.xaml
/// Interaction logic for MediaInformationWindow.xaml
/// </summary>
public partial class DiscInformationWindow : WindowBase
public partial class MediaInformationWindow : WindowBase
{
#if NET35
@@ -20,11 +20,18 @@ namespace MPF.UI.Windows
#region Additional Info
private Grid? PCMacHybridGrid => ItemHelper.FindChild<Grid>(this, "PCMacHybridGrid");
private UserInput? DiscIDTextBox => ItemHelper.FindChild<UserInput>(this, "DiscIDTextBox");
private UserInput? DiscKeyTextBox => ItemHelper.FindChild<UserInput>(this, "DiscKeyTextBox");
#endregion
#region Contents
private UserInput? NetYarozeGamesTextBox => ItemHelper.FindChild<UserInput>(this, "NetYarozeGamesTextBox");
#endregion
#region Ringcodes
private GroupBox? L0Info => ItemHelper.FindChild<GroupBox>(this, "L0Info");
@@ -102,14 +109,14 @@ namespace MPF.UI.Windows
#endif
/// <summary>
/// Read-only access to the current disc information view model
/// Read-only access to the current media information view model
/// </summary>
public DiscInformationViewModel DiscInformationViewModel => DataContext as DiscInformationViewModel ?? new DiscInformationViewModel(new Options(), new SubmissionInfo());
public MediaInformationViewModel MediaInformationViewModel => DataContext as MediaInformationViewModel ?? new MediaInformationViewModel(new Options(), new SubmissionInfo());
/// <summary>
/// Constructor
/// </summary>
public DiscInformationWindow(Options options, SubmissionInfo? submissionInfo)
public MediaInformationWindow(Options options, SubmissionInfo? submissionInfo)
{
#if NET40_OR_GREATER || NETCOREAPP
InitializeComponent();
@@ -124,14 +131,14 @@ namespace MPF.UI.Windows
System.Windows.Shell.WindowChrome.SetWindowChrome(this, chrome);
#endif
DataContext = new DiscInformationViewModel(options, submissionInfo);
DiscInformationViewModel.Load();
DataContext = new MediaInformationViewModel(options, submissionInfo);
MediaInformationViewModel.Load();
// Limit lists, if necessary
if (options.EnableRedumpCompatibility)
{
DiscInformationViewModel.SetRedumpRegions();
DiscInformationViewModel.SetRedumpLanguages();
MediaInformationViewModel.SetRedumpRegions();
MediaInformationViewModel.SetRedumpLanguages();
}
// Add handlers
@@ -232,7 +239,7 @@ namespace MPF.UI.Windows
AntiModchip!.Visibility = Visibility.Collapsed;
if (submissionInfo.TracksAndWriteOffsets?.OtherWriteOffsets == null)
DiscOffset!.Visibility = Visibility.Collapsed;
if (submissionInfo.CommonDiscInfo?.CommentsSpecialFields?.ContainsKey(SiteCode.DMIHash) != true)
if (ShouldCollapseComment(submissionInfo, SiteCode.DMIHash))
DMIHash!.Visibility = Visibility.Collapsed;
if (submissionInfo.EDC?.EDC == null)
EDC!.Visibility = Visibility.Collapsed;
@@ -240,45 +247,45 @@ namespace MPF.UI.Windows
ErrorsCount!.Visibility = Visibility.Collapsed;
if (string.IsNullOrEmpty(submissionInfo.CommonDiscInfo?.EXEDateBuildDate))
EXEDateBuildDate!.Visibility = Visibility.Collapsed;
if (submissionInfo.CommonDiscInfo?.CommentsSpecialFields?.ContainsKey(SiteCode.Filename) != true)
if (ShouldCollapseComment(submissionInfo, SiteCode.Filename))
Filename!.Visibility = Visibility.Collapsed;
if (string.IsNullOrEmpty(submissionInfo.Extras?.Header))
Header!.Visibility = Visibility.Collapsed;
if (submissionInfo.CommonDiscInfo?.CommentsSpecialFields?.ContainsKey(SiteCode.InternalName) != true)
if (ShouldCollapseComment(submissionInfo, SiteCode.InternalName))
InternalName!.Visibility = Visibility.Collapsed;
if (submissionInfo.CommonDiscInfo?.CommentsSpecialFields?.ContainsKey(SiteCode.InternalSerialName) != true)
if (ShouldCollapseComment(submissionInfo, SiteCode.InternalSerialName))
InternalSerialName!.Visibility = Visibility.Collapsed;
if (submissionInfo.CommonDiscInfo?.CommentsSpecialFields?.ContainsKey(SiteCode.Multisession) != true)
if (ShouldCollapseComment(submissionInfo, SiteCode.Multisession))
Multisession!.Visibility = Visibility.Collapsed;
if (submissionInfo.CopyProtection?.LibCrypt == null)
LibCrypt!.Visibility = Visibility.Collapsed;
if (string.IsNullOrEmpty(submissionInfo.CopyProtection?.LibCryptData))
LibCryptData!.Visibility = Visibility.Collapsed;
if (submissionInfo.CommonDiscInfo?.CommentsSpecialFields?.ContainsKey(SiteCode.PFIHash) != true)
if (ShouldCollapseComment(submissionInfo, SiteCode.PFIHash))
PFIHash!.Visibility = Visibility.Collapsed;
if (string.IsNullOrEmpty(submissionInfo.Extras?.PIC))
PIC!.Visibility = Visibility.Collapsed;
if (string.IsNullOrEmpty(submissionInfo.Extras?.PVD))
PVD!.Visibility = Visibility.Collapsed;
if (submissionInfo.CommonDiscInfo?.CommentsSpecialFields?.ContainsKey(SiteCode.RingNonZeroDataStart) != true)
if (ShouldCollapseComment(submissionInfo, SiteCode.RingNonZeroDataStart))
RingNonZeroDataStart!.Visibility = Visibility.Collapsed;
if (submissionInfo.CommonDiscInfo?.CommentsSpecialFields?.ContainsKey(SiteCode.RingPerfectAudioOffset) != true)
if (ShouldCollapseComment(submissionInfo, SiteCode.RingPerfectAudioOffset))
RingPerfectAudioOffset!.Visibility = Visibility.Collapsed;
if (string.IsNullOrEmpty(submissionInfo.CopyProtection?.SecuROMData))
SecuROMData!.Visibility = Visibility.Collapsed;
if (submissionInfo.CommonDiscInfo?.CommentsSpecialFields?.ContainsKey(SiteCode.SSHash) != true)
if (ShouldCollapseComment(submissionInfo, SiteCode.SSHash))
SSHash!.Visibility = Visibility.Collapsed;
if (string.IsNullOrEmpty(submissionInfo.Extras?.SecuritySectorRanges))
SecuritySectorRanges!.Visibility = Visibility.Collapsed;
if (submissionInfo.CommonDiscInfo?.CommentsSpecialFields?.ContainsKey(SiteCode.SSVersion) != true)
if (ShouldCollapseComment(submissionInfo, SiteCode.SSVersion))
SSVersion!.Visibility = Visibility.Collapsed;
if (submissionInfo.CommonDiscInfo?.CommentsSpecialFields?.ContainsKey(SiteCode.UniversalHash) != true)
if (ShouldCollapseComment(submissionInfo, SiteCode.UniversalHash))
UniversalHash!.Visibility = Visibility.Collapsed;
if (submissionInfo.CommonDiscInfo?.CommentsSpecialFields?.ContainsKey(SiteCode.VolumeLabel) != true)
if (ShouldCollapseComment(submissionInfo, SiteCode.VolumeLabel))
VolumeLabel!.Visibility = Visibility.Collapsed;
if (submissionInfo.CommonDiscInfo?.CommentsSpecialFields?.ContainsKey(SiteCode.XeMID) != true)
if (ShouldCollapseComment(submissionInfo, SiteCode.XeMID))
XeMID!.Visibility = Visibility.Collapsed;
if (submissionInfo.CommonDiscInfo?.CommentsSpecialFields?.ContainsKey(SiteCode.XMID) != true)
if (ShouldCollapseComment(submissionInfo, SiteCode.XMID))
XMID!.Visibility = Visibility.Collapsed;
}
@@ -306,7 +313,7 @@ namespace MPF.UI.Windows
L1Info!.Header = "Label Side";
L1MasteringRing!.Label = "Mastering Ring";
L1MasteringSID!.Label = "Mastering SID";
L1Toolstamp!.Label = "Mastering SID";
L1Toolstamp!.Label = "Toolstamp/Mastering Code";
L1MouldSID!.Label = "Mould SID";
L1AdditionalMould!.Label = "Additional Mould";
break;
@@ -440,10 +447,22 @@ namespace MPF.UI.Windows
var system = submissionInfo?.CommonDiscInfo?.System;
switch (system)
{
case RedumpSystem.AppleMacintosh:
PCMacHybridGrid!.Visibility = Visibility.Visible;
break;
case RedumpSystem.IBMPCcompatible:
PCMacHybridGrid!.Visibility = Visibility.Visible;
break;
case RedumpSystem.NintendoWiiU:
DiscKeyTextBox!.Visibility = Visibility.Visible;
break;
case RedumpSystem.SonyPlayStation:
NetYarozeGamesTextBox!.Visibility = Visibility.Visible;
break;
case RedumpSystem.SonyPlayStation2:
LanguageSelectionGrid!.Visibility = Visibility.Visible;
break;
@@ -455,6 +474,23 @@ namespace MPF.UI.Windows
}
}
/// <summary>
/// Determine if a comment field should be collapsed in read-only view
/// </summary>
private static bool ShouldCollapseComment(SubmissionInfo? submissionInfo, SiteCode siteCode)
{
// If the special fields don't exist
if (submissionInfo?.CommonDiscInfo?.CommentsSpecialFields == null)
return true;
// If the key doesn't exist
if (!submissionInfo.CommonDiscInfo.CommentsSpecialFields.TryGetValue(siteCode, out string? value))
return true;
// Collapse if the value doesn't exist
return string.IsNullOrEmpty(value);
}
#endregion
#region Event Handlers
@@ -464,7 +500,7 @@ namespace MPF.UI.Windows
/// </summary>
private void OnAcceptClick(object sender, RoutedEventArgs e)
{
DiscInformationViewModel.Save();
MediaInformationViewModel.Save();
DialogResult = true;
Close();
}

View File

@@ -105,8 +105,7 @@
IsChecked="{Binding Options.IgnoreFixedDrives}"
ToolTip="Ignore hard drives and other fixed drives" Margin="0,4"
/>
<Label/>
<!-- Empty label for padding -->
<Label/> <!-- Empty label for padding -->
<Label VerticalAlignment="Center" Content="Default System:" HorizontalAlignment="Right" />
<ComboBox x:Name="DefaultSystemComboBox" Height="22" Width="200" HorizontalAlignment="Left"
@@ -196,12 +195,12 @@
<UniformGrid Columns="2" Rows="6">
<CheckBox VerticalAlignment="Center" Content="Show Disc Info"
IsChecked="{Binding Options.PromptForDiscInformation}"
ToolTip="Enable showing the disc information output after dumping" Margin="0,4"
ToolTip="Enable showing the media information output after dumping" Margin="0,4"
/>
<CheckBox VerticalAlignment="Center" Content="Pull All Information"
IsChecked="{Binding Options.PullAllInformation}"
ToolTip="Enable pulling all comment and content data after dumping" Margin="0,4"
ToolTip="Instead of pulling a safe subset of data after dumping, enable pulling all comment and content data" Margin="0,4"
/>
<CheckBox VerticalAlignment="Center" Content="Enable Tab Input"
@@ -234,9 +233,9 @@
ToolTip="Enable outputting a compressed JSON version of the submission info" Margin="0,4"
/>
<CheckBox VerticalAlignment="Center" Content="Include Artifacts"
<CheckBox VerticalAlignment="Center" Content="[DEBUG] Include Artifacts"
IsChecked="{Binding Options.IncludeArtifacts}" IsEnabled="{Binding Options.OutputSubmissionJSON}"
ToolTip="Include log files in serialized JSON data"
ToolTip="Include log files in serialized JSON data [NOT RECOMMENDED TO USE]"
ToolTipService.ShowOnDisabled="True" Margin="0,4"
/>
@@ -297,28 +296,28 @@
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0" Content="CD" />
<Slider x:Name="DumpSpeedCDSlider" Grid.Row="0" Grid.Column="1" Minimum="1" Maximum="72" IsSnapToTickEnabled="True" TickPlacement="BottomRight"
<Slider x:Name="DumpSpeedCDSlider" Grid.Row="0" Grid.Column="1" Minimum="0" Maximum="72" IsSnapToTickEnabled="True" TickPlacement="BottomRight"
Ticks="{Binding Source={x:Static core:Constants.SpeedsForCDAsCollection}}"
Value="{Binding Options.PreferredDumpSpeedCD}" />
<TextBox x:Name="DumpSpeedCDTextBox" Grid.Row="0" Grid.Column="2" Width="22" Height="22" TextAlignment="Center" IsReadOnly="True" VerticalAlignment="Center"
Text="{Binding ElementName=DumpSpeedCDSlider, Path=Value, UpdateSourceTrigger=PropertyChanged}" Background="LightGray" Foreground="Gray"/>
<Label Grid.Row="1" Grid.Column="0" Content="DVD" />
<Slider x:Name="DumpSpeedDVDSlider" Grid.Row="1" Grid.Column="1" Minimum="1" Maximum="24" IsSnapToTickEnabled="True" TickPlacement="BottomRight"
<Slider x:Name="DumpSpeedDVDSlider" Grid.Row="1" Grid.Column="1" Minimum="0" Maximum="24" IsSnapToTickEnabled="True" TickPlacement="BottomRight"
Ticks="{Binding Source={x:Static core:Constants.SpeedsForDVDAsCollection}}"
Value="{Binding Options.PreferredDumpSpeedDVD}" />
<TextBox x:Name="DumpSpeedDVDTextBox" Grid.Row="1" Grid.Column="2" Width="22" Height="22" TextAlignment="Center" IsReadOnly="True" VerticalAlignment="Center"
Text="{Binding ElementName=DumpSpeedDVDSlider, Path=Value, UpdateSourceTrigger=PropertyChanged}" Background="LightGray" Foreground="Gray"/>
<Label Grid.Row="2" Grid.Column="0" Content="HD-DVD" />
<Slider x:Name="DumpSpeedHDDVDSlider" Grid.Row="2" Grid.Column="1" Minimum="1" Maximum="24" IsSnapToTickEnabled="True" TickPlacement="BottomRight"
<Slider x:Name="DumpSpeedHDDVDSlider" Grid.Row="2" Grid.Column="1" Minimum="0" Maximum="24" IsSnapToTickEnabled="True" TickPlacement="BottomRight"
Ticks="{Binding Source={x:Static core:Constants.SpeedsForHDDVDAsCollection}}"
Value="{Binding Options.PreferredDumpSpeedHDDVD}" />
<TextBox x:Name="DumpSpeedHDDVDTextBox" Grid.Row="2" Grid.Column="2" Width="22" Height="22" TextAlignment="Center" IsReadOnly="True" VerticalAlignment="Center"
Text="{Binding ElementName=DumpSpeedHDDVDSlider, Path=Value, UpdateSourceTrigger=PropertyChanged}" Background="LightGray" Foreground="Gray"/>
<Label Grid.Row="3" Grid.Column="0" Content="BD" />
<Slider x:Name="DumpSpeedBDSlider" Grid.Row="3" Grid.Column="1" Minimum="1" Maximum="16" IsSnapToTickEnabled="True" TickPlacement="BottomRight"
<Slider x:Name="DumpSpeedBDSlider" Grid.Row="3" Grid.Column="1" Minimum="0" Maximum="16" IsSnapToTickEnabled="True" TickPlacement="BottomRight"
Ticks="{Binding Source={x:Static core:Constants.SpeedsForBDAsCollection}}"
Value="{Binding Options.PreferredDumpSpeedBD}" />
<TextBox x:Name="DumpSpeedBDTextBox" Grid.Row="3" Grid.Column="2" Width="22" Height="22" TextAlignment="Center" IsReadOnly="True" VerticalAlignment="Center"
@@ -405,15 +404,11 @@
<GroupBox Margin="5,5,5,5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Header="Redumper">
<UniformGrid Columns="2" Rows="7">
<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/> <!-- Empty label for padding -->
<Label Content="Reread Tries:" VerticalAlignment="Center" HorizontalAlignment="Right"/>
<TextBox VerticalAlignment="Center" VerticalContentAlignment="Center" Width="200" HorizontalAlignment="Left"
@@ -421,16 +416,9 @@
ToolTip="Specifies how many rereads are attempted on read error"
/>
<CheckBox VerticalAlignment="Center" Content="Set Default Plextor Lead-in Retries"
IsChecked="{Binding Options.RedumperEnableLeadinRetry}"
ToolTip="Enable custom lead-in retries for Plextor drives" Margin="0,4"
/>
<Label/>
<!-- Empty label for padding -->
<Label Content="Plextor Lead-in Retries:" VerticalAlignment="Center" HorizontalAlignment="Right"/>
<TextBox VerticalAlignment="Center" VerticalContentAlignment="Center" Width="200" HorizontalAlignment="Left"
Text="{Binding Options.RedumperLeadinRetryCount}" IsEnabled ="{Binding Options.RedumperEnableLeadinRetry}"
Text="{Binding Options.RedumperLeadinRetryCount}"
ToolTip="Specifies how many retries are attempted for lead-in on Plextor drives"
ToolTipService.ShowOnDisabled="True"
/>
@@ -439,12 +427,7 @@
IsChecked="{Binding Options.RedumperNonRedumpMode}"
ToolTip="Enable non-redump options" Margin="0,4"
/>
<CheckBox VerticalAlignment="Center" Content="Set Generic Drive Type"
IsChecked="{Binding Options.RedumperUseGenericDriveType}" IsEnabled="{Binding Options.RedumperNonRedumpMode}"
ToolTip="Enable setting drive type to Generic by default"
ToolTipService.ShowOnDisabled="True" Margin="0,4"
/>
<Label/> <!-- Empty label for padding -->
<Label VerticalAlignment="Center" Content="Default Read Method:" HorizontalAlignment="Right" />
<ComboBox x:Name="DefaultRedumperReadMethodComboBox" Height="22" Width="200" HorizontalAlignment="Left"
@@ -457,6 +440,12 @@
ItemsSource="{Binding RedumperSectorOrders}" SelectedItem="{Binding Options.RedumperSectorOrder, Converter={StaticResource ElementConverter}, Mode=TwoWay}"
Style="{DynamicResource CustomComboBoxStyle}" IsEnabled="{Binding Options.RedumperNonRedumpMode}"
/>
<Label VerticalAlignment="Center" Content="Default Drive Type:" HorizontalAlignment="Right" />
<ComboBox x:Name="DefaultRedumperDriveTypeComboBox" Height="22" Width="200" HorizontalAlignment="Left"
ItemsSource="{Binding RedumperDriveTypes}" SelectedItem="{Binding Options.RedumperDriveType, Converter={StaticResource ElementConverter}, Mode=TwoWay}"
Style="{DynamicResource CustomComboBoxStyle}" IsEnabled="{Binding Options.RedumperNonRedumpMode}"
/>
</UniformGrid>
</GroupBox>
</StackPanel>
@@ -464,17 +453,30 @@
<TabItem Header="Login Info" Style="{DynamicResource CustomTabItemStyle}">
<StackPanel>
<GroupBox Margin="5,5,5,5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Header="Retrieval">
<UniformGrid Columns="2" Rows="1">
<CheckBox VerticalAlignment="Center" Content="Retrieve Match Information"
IsChecked="{Binding Options.RetrieveMatchInformation}"
ToolTip="Attempts to retrieve match information from Redump"
Margin="0,4"
/>
<Label/> <!-- Empty label for padding -->
</UniformGrid>
</GroupBox>
<GroupBox Margin="5,5,5,5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Header="Redump">
<UniformGrid Columns="5">
<Label VerticalAlignment="Center" HorizontalAlignment="Right" Content="Username" />
<TextBox x:Name="RedumpUsernameTextBox" Height="22" HorizontalAlignment="Stretch"
Text="{Binding Options.RedumpUsername}" />
Text="{Binding Options.RedumpUsername}"
IsEnabled="{Binding Options.RetrieveMatchInformation}" />
<Label VerticalAlignment="Center" HorizontalAlignment="Right" Content="Password" />
<PasswordBox x:Name="RedumpPasswordBox" Height="22" HorizontalAlignment="Stretch" PasswordChar="*" />
<Button x:Name="RedumpLoginTestButton" Height="22" Width="80" Content="Test Login"
Style="{DynamicResource CustomButtonStyle}" />
Style="{DynamicResource CustomButtonStyle}"
IsEnabled="{Binding Options.RetrieveMatchInformation}" />
</UniformGrid>
</GroupBox>
@@ -500,14 +502,12 @@
</ControlTemplate>
</GroupBox.Template>
<UniformGrid Columns="4" Margin="5,5,5,5" Height="27">
<Label/>
<!-- Empty label for padding -->
<Label/> <!-- Empty label for padding -->
<Button Name="AcceptButton" Height="25" Width="80" IsDefault="True" Content="Accept"
Style="{DynamicResource CustomButtonStyle}" />
<Button Name="CancelButton" Height="25" Width="80" IsCancel="True" Content="Cancel"
Style="{DynamicResource CustomButtonStyle}" />
<Label/>
<!-- Empty label for padding -->
<Label/> <!-- Empty label for padding -->
</UniformGrid>
</GroupBox>
</StackPanel>

View File

@@ -56,7 +56,6 @@ namespace MPF.UI.Windows
{
1 => MessageBoxButton.OK,
2 => MessageBoxButton.YesNo,
3 => MessageBoxButton.YesNoCancel,
// This should not happen, but default to "OK"
_ => MessageBoxButton.OK,

View File

@@ -54,6 +54,10 @@ The main CLI has some known limitations that are documented in code and in some
MPF.Check is a commandline-only program that allows users to generate submission information from their personal rips. This program supports the outputs from Redumper, Aaru, DiscImageCreator, Cleanrip, and UmdImageCreator. Running this program without any parameters will display the help text, including all supported parameters.
**WARNING:** Both the standalone Check executable and the Check functionality in the UI will overwrite both any existing submission information files as well as any log archives. Please make backups of those if you need to before running Check.
**WARNING:** Both the standalone Check executable and the Check functionality in the UI assume that the output files are what were output by the original dumping program. If you need to reparse any outputs that have already been processed by MPF, you will need to unzip all files as if it were the original folder layout.
## System Requirements
MPF.UI, MPF.CLI, and MPF.Check have the same system requirements for running, with the exception that MPF.UI is Windows-only.

View File

@@ -74,6 +74,140 @@ VALID_APPLE_FRAMEWORKS=("net6.0" "net7.0" "net8.0" "net9.0")
VALID_CROSS_PLATFORM_FRAMEWORKS=("netcoreapp3.1" "net5.0" "net6.0" "net7.0" "net8.0" "net9.0")
VALID_CROSS_PLATFORM_RUNTIMES=("win-arm64" "linux-x64" "linux-arm64" "osx-x64" "osx-arm64")
# Download programs step
function download_programs() {
# Define download constants
DL_PREFIXES=("Aaru" "Creator" "Redumper")
declare -A DL_MAP
# Aaru
DL_MAP["Aaru_linux-arm64"]="https://github.com/aaru-dps/Aaru/releases/download/v5.3.2/aaru-5.3.2_linux_arm64.tar.gz"
DL_MAP["Aaru_linux-x64"]="https://github.com/aaru-dps/Aaru/releases/download/v5.3.2/aaru-5.3.2_linux_amd64.tar.gz"
DL_MAP["Aaru_osx-arm64"]="https://github.com/aaru-dps/Aaru/releases/download/v5.3.2/aaru-5.3.2_macos.zip"
DL_MAP["Aaru_osx-x64"]="https://github.com/aaru-dps/Aaru/releases/download/v5.3.2/aaru-5.3.2_macos.zip"
DL_MAP["Aaru_win-arm64"]="https://github.com/aaru-dps/Aaru/releases/download/v5.3.2/aaru-5.3.2_windows_aarch64.zip"
DL_MAP["Aaru_win-x86"]="https://github.com/aaru-dps/Aaru/releases/download/v5.3.2/aaru-5.3.2_windows_x86.zip"
DL_MAP["Aaru_win-x64"]="https://github.com/aaru-dps/Aaru/releases/download/v5.3.2/aaru-5.3.2_windows_x64.zip"
# DiscImageCreator
DL_MAP["Creator_linux-arm64"]=""
DL_MAP["Creator_linux-x64"]="https://github.com/user-attachments/files/20000183/DiscImageCreator_20250501.tar.gz"
DL_MAP["Creator_osx-arm64"]="https://github.com/user-attachments/files/20000184/DiscImageCreator_20250501.zip"
DL_MAP["Creator_osx-x64"]="https://github.com/user-attachments/files/20000184/DiscImageCreator_20250501.zip"
DL_MAP["Creator_win-arm64"]=""
DL_MAP["Creator_win-x86"]="https://github.com/user-attachments/files/20000181/DiscImageCreator_20250501.zip"
DL_MAP["Creator_win-x64"]="https://github.com/user-attachments/files/20000181/DiscImageCreator_20250501.zip"
# Redumper
DL_MAP["Redumper_linux-arm64"]=""
DL_MAP["Redumper_linux-x64"]="https://github.com/superg/redumper/releases/download/build_631/redumper-2025.07.14_build631-Linux64.zip"
DL_MAP["Redumper_osx-arm64"]="https://github.com/superg/redumper/releases/download/build_631/redumper-2025.07.14_build631-Darwin64.zip"
DL_MAP["Redumper_osx-x64"]="https://github.com/superg/redumper/releases/download/build_631/redumper-2025.07.14_build631-Darwin64.zip"
DL_MAP["Redumper_win-arm64"]=""
DL_MAP["Redumper_win-x86"]="https://github.com/superg/redumper/releases/download/build_631/redumper-2025.07.14_build631-Windows32.zip"
DL_MAP["Redumper_win-x64"]="https://github.com/superg/redumper/releases/download/build_631/redumper-2025.07.14_build631-Windows64.zip"
# Download and extract files
echo "===== Downloading Required Programs ====="
for PREFIX in "${DL_PREFIXES[@]}"; do
for RUNTIME in "${CHECK_RUNTIMES[@]}"; do
# Check for a valid URL
DL_KEY=$PREFIX"_"$RUNTIME
URL=${DL_MAP[$DL_KEY]}
if [ -z "$URL" ]; then
continue
fi
# Download the file to a predictable local file
EXT=${URL##*.}
OUTNAME=$PREFIX"_"$RUNTIME.$EXT
wget $URL -O $OUTNAME
TEMPDIR=$PREFIX"_"$RUNTIME-temp
OUTDIR=$PREFIX"_"$RUNTIME-dir
# Handle gzipped files separately
if [[ $URL =~ \.tar\.gz$ ]]; then
mkdir $TEMPDIR
tar -xvf $OUTNAME -C $TEMPDIR
else
unzip -u $OUTNAME -d $TEMPDIR
fi
# Create the proper structure
mkdir $OUTDIR
mv $TEMPDIR/*/** $OUTDIR/
mv $TEMPDIR/** $OUTDIR/
rm -rf $TEMPDIR
if [ -d "$OUTDIR/bin" ]; then
mv $OUTDIR/bin/* $OUTDIR/
fi
# Remove empty subdirectories
find . -empty -type d -delete
done
done
# Create UI directories and copy data
for FRAMEWORK in "${UI_FRAMEWORKS[@]}"; do
for RUNTIME in "${UI_RUNTIMES[@]}"; do
for PREFIX in "${DL_PREFIXES[@]}"; do
OUTDIR=$PREFIX"_"$RUNTIME-dir
if [ ! -d "$OUTDIR" ]; then
continue
fi
if [ $INCLUDE_DEBUG = true ]; then
mkdir -p MPF.UI/bin/Debug/${FRAMEWORK}/${RUNTIME}/publish/Programs/${PREFIX}
cp -rfp $OUTDIR/* MPF.UI/bin/Debug/${FRAMEWORK}/${RUNTIME}/publish/Programs/${PREFIX}/
fi
mkdir -p MPF.UI/bin/Release/${FRAMEWORK}/${RUNTIME}/publish/Programs/${PREFIX}
cp -rfp $OUTDIR/* MPF.UI/bin/Release/${FRAMEWORK}/${RUNTIME}/publish/Programs/${PREFIX}/
done
done
done
# Create CLI directories and copy data
for FRAMEWORK in "${CHECK_FRAMEWORKS[@]}"; do
for RUNTIME in "${CHECK_RUNTIMES[@]}"; do
for PREFIX in "${DL_PREFIXES[@]}"; do
OUTDIR=$PREFIX"_"$RUNTIME-dir
if [ ! -d "$OUTDIR" ]; then
continue
fi
if [ $INCLUDE_DEBUG = true ]; then
mkdir -p MPF.CLI/bin/Debug/${FRAMEWORK}/${RUNTIME}/publish/Programs/${PREFIX}
cp -rfp $OUTDIR/* MPF.CLI/bin/Debug/${FRAMEWORK}/${RUNTIME}/publish/Programs/${PREFIX}/
fi
mkdir -p MPF.CLI/bin/Release/${FRAMEWORK}/${RUNTIME}/publish/Programs/${PREFIX}
cp -rfp $OUTDIR/* MPF.CLI/bin/Release/${FRAMEWORK}/${RUNTIME}/publish/Programs/${PREFIX}/
done
done
done
# Clean up the downloaded files and directories
for PREFIX in "${DL_PREFIXES[@]}"; do
for RUNTIME in "${CHECK_RUNTIMES[@]}"; do
DL_KEY=$PREFIX"_"$RUNTIME
URL=${DL_MAP[$DL_KEY]}
if [ -z "$URL" ]; then
continue
fi
EXT=${URL##*.}
OUTNAME=$PREFIX"_"$RUNTIME.$EXT
OUTDIR=$PREFIX"_"$RUNTIME-dir
rm $OUTNAME
rm -rf $OUTDIR
done
done
}
# Only build if requested
if [ $NO_BUILD = false ]; then
# Restore Nuget packages for all builds
@@ -206,43 +340,7 @@ fi
if [ $NO_ARCHIVE = false ]; then
# Download and extract, if needed
if [ $INCLUDE_PROGRAMS = true ]; then
echo "===== Downloading Required Programs ====="
# Aaru
# --- Skipped for now ---
# DiscImageCreator
wget https://github.com/user-attachments/files/18287520/DiscImageCreator_20250101.zip
unzip -u DiscImageCreator_20250101.zip
# Redumper
wget https://github.com/superg/redumper/releases/download/build_438/redumper-2024.11.03_build438-win64.zip
unzip redumper-2024.11.03_build438-win64.zip
# Create directories and copy data
for FRAMEWORK in "${UI_FRAMEWORKS[@]}"; do
for RUNTIME in "${UI_RUNTIMES[@]}"; do
if [ $INCLUDE_DEBUG = true ]; then
mkdir -p MPF.UI/bin/Debug/${FRAMEWORK}/${RUNTIME}/publish/Programs/Creator
cp -rfp Release_ANSI/* MPF.UI/bin/Debug/${FRAMEWORK}/${RUNTIME}/publish/Programs/Creator/
mkdir -p MPF.UI/bin/Debug/${FRAMEWORK}/${RUNTIME}/publish/Programs/Redumper
cp -rfp redumper-2024.11.03_build438-win64/bin/redumper.exe MPF.UI/bin/Debug/${FRAMEWORK}/${RUNTIME}/publish/Programs/Redumper/
fi
mkdir -p MPF.UI/bin/Release/${FRAMEWORK}/${RUNTIME}/publish/Programs/Creator
cp -rfp Release_ANSI/* MPF.UI/bin/Release/${FRAMEWORK}/${RUNTIME}/publish/Programs/Creator/
mkdir -p MPF.UI/bin/Release/${FRAMEWORK}/${RUNTIME}/publish/Programs/Redumper
cp -rfp redumper-2024.11.03_build438-win64/bin/redumper.exe MPF.UI/bin/Release/${FRAMEWORK}/${RUNTIME}/publish/Programs/Redumper/
done
done
# Clean up the downloaded files and directories
rm DiscImageCreator_20250101.zip
rm -r Release_ANSI
rm redumper-2024.11.03_build438-win64.zip
rm -r redumper-2024.11.03_build438-win64
download_programs
fi
# Create UI archives
@@ -310,10 +408,18 @@ if [ $NO_ARCHIVE = false ]; then
# Only include Debug if set
if [ $INCLUDE_DEBUG = true ]; then
cd $BUILD_FOLDER/MPF.CLI/bin/Debug/${FRAMEWORK}/${RUNTIME}/publish/
zip -r $BUILD_FOLDER/MPF.CLI_${FRAMEWORK}_${RUNTIME}_debug.zip .
if [ $INCLUDE_PROGRAMS = true ]; then
zip -r $BUILD_FOLDER/MPF.CLI_${FRAMEWORK}_${RUNTIME}_debug.zip .
else
zip -r $BUILD_FOLDER/MPF.CLI_${FRAMEWORK}_${RUNTIME}_debug.zip . -x 'Programs/*'
fi
fi
cd $BUILD_FOLDER/MPF.CLI/bin/Release/${FRAMEWORK}/${RUNTIME}/publish/
zip -r $BUILD_FOLDER/MPF.CLI_${FRAMEWORK}_${RUNTIME}_release.zip .
if [ $INCLUDE_PROGRAMS = true ]; then
zip -r $BUILD_FOLDER/MPF.CLI_${FRAMEWORK}_${RUNTIME}_release.zip .
else
zip -r $BUILD_FOLDER/MPF.CLI_${FRAMEWORK}_${RUNTIME}_release.zip . -x 'Programs/*'
fi
done
done

View File

@@ -64,6 +64,142 @@ $VALID_APPLE_FRAMEWORKS = @('net6.0', 'net7.0', 'net8.0', 'net9.0')
$VALID_CROSS_PLATFORM_FRAMEWORKS = @('netcoreapp3.1', 'net5.0', 'net6.0', 'net7.0', 'net8.0', 'net9.0')
$VALID_CROSS_PLATFORM_RUNTIMES = @('win-arm64', 'linux-x64', 'linux-arm64', 'osx-x64', 'osx-arm64')
# Download programs step
function Download-Programs {
# Define download constants
$DL_PREFIXES = ("Aaru", "Creator", "Redumper")
$DL_MAP = @{
# Aaru
"Aaru_linux-arm64" = "https://github.com/aaru-dps/Aaru/releases/download/v5.3.2/aaru-5.3.2_linux_arm64.tar.gz"
"Aaru_linux-x64" = "https://github.com/aaru-dps/Aaru/releases/download/v5.3.2/aaru-5.3.2_linux_amd64.tar.gz"
"Aaru_osx-arm64" = "https://github.com/aaru-dps/Aaru/releases/download/v5.3.2/aaru-5.3.2_macos.zip"
"Aaru_osx-x64" = "https://github.com/aaru-dps/Aaru/releases/download/v5.3.2/aaru-5.3.2_macos.zip"
"Aaru_win-arm64" = "https://github.com/aaru-dps/Aaru/releases/download/v5.3.2/aaru-5.3.2_windows_aarch64.zip"
"Aaru_win-x86" = "https://github.com/aaru-dps/Aaru/releases/download/v5.3.2/aaru-5.3.2_windows_x86.zip"
"Aaru_win-x64" = "https://github.com/aaru-dps/Aaru/releases/download/v5.3.2/aaru-5.3.2_windows_x64.zip"
# DiscImageCreator
"Creator_linux-arm64" = ""
"Creator_linux-x64" = "https://github.com/user-attachments/files/20000183/DiscImageCreator_20250501.tar.gz"
"Creator_osx-arm64" = "https://github.com/user-attachments/files/20000184/DiscImageCreator_20250501.zip"
"Creator_osx-x64" = "https://github.com/user-attachments/files/20000184/DiscImageCreator_20250501.zip"
"Creator_win-arm64" = ""
"Creator_win-x86" = "https://github.com/user-attachments/files/20000181/DiscImageCreator_20250501.zip"
"Creator_win-x64" = "https://github.com/user-attachments/files/20000181/DiscImageCreator_20250501.zip"
# Redumper
"Redumper_linux-arm64" = ""
"Redumper_linux-x64" = "https://github.com/superg/redumper/releases/download/build_631/redumper-2025.07.14_build631-Linux64.zip"
"Redumper_osx-arm64" = "https://github.com/superg/redumper/releases/download/build_631/redumper-2025.07.14_build631-Darwin64.zip"
"Redumper_osx-x64" = "https://github.com/superg/redumper/releases/download/build_631/redumper-2025.07.14_build631-Darwin64.zip"
"Redumper_win-arm64" = ""
"Redumper_win-x86" = "https://github.com/superg/redumper/releases/download/build_631/redumper-2025.07.14_build631-Windows32.zip"
"Redumper_win-x64" = "https://github.com/superg/redumper/releases/download/build_631/redumper-2025.07.14_build631-Windows64.zip"
}
# Download and extract files
Write-Host "===== Downloading Required Programs ====="
foreach ($PREFIX in $DL_PREFIXES) {
foreach ($RUNTIME in $CHECK_RUNTIMES) {
# Check for a valid URL
$DL_KEY = $PREFIX + "_" + $RUNTIME
$URL = $DL_MAP[$DL_KEY]
if ( [string]::IsNullOrEmpty($URL) ) {
continue
}
# Download the file to a predictable local file
$EXT = [System.IO.Path]::GetExtension($URL)
$OUTNAME = $PREFIX + "_" + $RUNTIME + $EXT
Invoke-WebRequest -Uri $URL -OutFile $OUTNAME
$TEMPDIR = $PREFIX + "_" + $RUNTIME + "-temp"
$OUTDIR = $PREFIX + "_" + $RUNTIME + "-dir"
# Handle gzipped files separately
if ($EXT -eq ".gz") {
mkdir $TEMPDIR
tar -xvf $OUTNAME -C $TEMPDIR
}
else {
Expand-Archive -LiteralPath $OUTNAME -DestinationPath "$TEMPDIR"
}
# Create the proper structure
Move-Item -Path "$BUILD_FOLDER/$TEMPDIR/*" -Destination "$BUILD_FOLDER/$OUTDIR"
Remove-Item -Path "$TEMPDIR" -Recurse -Force
if ([System.IO.Directory]::Exists("$OUTDIR/bin")) {
Move-Item -Path "$BUILD_FOLDER/$OUTDIR/bin/*" -Destination "$BUILD_FOLDER/$OUTDIR"
}
# Remove empty subdirectories
$EMPTY = Get-ChildItem $OUTDIR -directory -recurse | Where-Object { (Get-ChildItem $_.fullName).count -eq 0 } | Select-Object -expandproperty FullName
$EMPTY | Foreach-Object { Remove-Item $_ }
}
}
# Create UI directories and copy data
foreach ($FRAMEWORK in $UI_FRAMEWORKS) {
foreach ($RUNTIME in $UI_RUNTIMES) {
foreach ($PREFIX in $DL_PREFIXES) {
$OUTDIR = $BUILD_FOLDER + "/" + $PREFIX + "_" + $RUNTIME + "-dir"
if (![System.IO.Directory]::Exists($PREFIX + "_" + $RUNTIME + "-dir")) {
continue
}
if ($INCLUDE_DEBUG.IsPresent) {
New-Item -Name "MPF.UI/bin/Debug/${FRAMEWORK}/${RUNTIME}/publish/Programs/$PREFIX" -Type Directory -ErrorAction SilentlyContinue
Copy-Item -Path "$OUTDIR/*" -Destination "MPF.UI/bin/Debug/${FRAMEWORK}/${RUNTIME}/publish/Programs/$PREFIX/" -Recurse -Force
}
New-Item -Name "MPF.UI/bin/Release/${FRAMEWORK}/${RUNTIME}/publish/Programs/$PREFIX" -Type Directory -ErrorAction SilentlyContinue
Copy-Item -Path "$OUTDIR/*" -Destination "MPF.UI/bin/Release/${FRAMEWORK}/${RUNTIME}/publish/Programs/$PREFIX/" -Recurse -Force
}
}
}
# Create CLI directories and copy data
foreach ($FRAMEWORK in $CHECK_FRAMEWORKS) {
foreach ($RUNTIME in $CHECK_RUNTIMES) {
foreach ($PREFIX in $DL_PREFIXES) {
$OUTDIR = $BUILD_FOLDER + "/" + $PREFIX + "_" + $RUNTIME + "-dir"
if (![System.IO.Directory]::Exists($OUTDIR)) {
continue
}
if ($INCLUDE_DEBUG.IsPresent) {
New-Item -Name "MPF.CLI/bin/Debug/${FRAMEWORK}/${RUNTIME}/publish/Programs/$PREFIX" -Type Directory -ErrorAction SilentlyContinue
Copy-Item -Path "$OUTDIR/*" -Destination "MPF.CLI/bin/Debug/${FRAMEWORK}/${RUNTIME}/publish/Programs/$PREFIX/" -Recurse -Force
}
New-Item -Name "MPF.CLI/bin/Release/${FRAMEWORK}/${RUNTIME}/publish/Programs/$PREFIX" -Type Directory -ErrorAction SilentlyContinue
Copy-Item -Path "$OUTDIR/*" -Destination "MPF.CLI/bin/Release/${FRAMEWORK}/${RUNTIME}/publish/Programs/$PREFIX/" -Recurse -Force
}
}
}
# Clean up the downloaded files and directories
foreach ($PREFIX in $DL_PREFIXES) {
foreach ($RUNTIME in $CHECK_RUNTIMES) {
$DL_KEY = $PREFIX + "_" + $RUNTIME
$URL = $DL_MAP[$DL_KEY]
if ( [string]::IsNullOrEmpty($URL) ) {
continue
}
$EXT = [System.IO.Path]::GetExtension($URL)
$OUTNAME = $PREFIX + "_" + $RUNTIME + $EXT
$OUTDIR = $PREFIX + "_" + $RUNTIME + "-dir"
Remove-Item -Path $OUTNAME
Remove-Item -Path $OUTDIR -Recurse -Force
}
}
}
# Only build if requested
if (!$NO_BUILD.IsPresent) {
# Restore Nuget packages for all builds
@@ -187,43 +323,7 @@ if (!$NO_BUILD.IsPresent) {
if (!$NO_ARCHIVE.IsPresent) {
# Download and extract, if needed
if ($INCLUDE_PROGRAMS.IsPresent) {
Write-Host "===== Downloading Required Programs ====="
# Aaru
# --- Skipped for now ---
# DiscImageCreator
Invoke-WebRequest -Uri https://github.com/user-attachments/files/18287520/DiscImageCreator_20250101.zip -OutFile DiscImageCreator_20250101.zip
Expand-Archive -LiteralPath "DiscImageCreator_20250101.zip" -DestinationPath "$BUILD_FOLDER/Creator"
# Redumper
Invoke-WebRequest -Uri https://github.com/superg/redumper/releases/download/build_438/redumper-2024.11.03_build438-win64.zip -OutFile redumper-2024.11.03_build438-win64.zip
Expand-Archive -LiteralPath "redumper-2024.11.03_build438-win64.zip" -DestinationPath "$BUILD_FOLDER/Redumper"
# Create directories and copy data
foreach ($FRAMEWORK in $UI_FRAMEWORKS) {
foreach ($RUNTIME in $UI_RUNTIMES) {
if ($INCLUDE_DEBUG.IsPresent) {
New-Item -Name "MPF.UI/bin/Debug/${FRAMEWORK}/${RUNTIME}/publish/Programs/Creator" -Type Directory -ErrorAction SilentlyContinue
Copy-Item -Path "Creator/Release_ANSI/*" -Destination "MPF.UI/bin/Debug/${FRAMEWORK}/${RUNTIME}/publish/Programs/Creator/" -Recurse -Force
New-Item -Name "MPF.UI/bin/Debug/${FRAMEWORK}/${RUNTIME}/publish/Programs/Redumper" -Type Directory -ErrorAction SilentlyContinue
Copy-Item -Path "Redumper/redumper-2024.11.03_build438-win64/bin/redumper.exe" -Destination "MPF.UI/bin/Debug/${FRAMEWORK}/${RUNTIME}/publish/Programs/Redumper/" -Force
}
New-Item -Name "MPF.UI/bin/Release/${FRAMEWORK}/${RUNTIME}/publish/Programs/Creator" -Type Directory -ErrorAction SilentlyContinue
Copy-Item -Path "Creator/Release_ANSI/*" -Destination "MPF.UI/bin/Release/${FRAMEWORK}/${RUNTIME}/publish/Programs/Creator/" -Recurse -Force
New-Item -Name "MPF.UI/bin/Release/${FRAMEWORK}/${RUNTIME}/publish/Programs/Redumper" -Type Directory -ErrorAction SilentlyContinue
Copy-Item -Path "Redumper/redumper-2024.11.03_build438-win64/bin/redumper.exe" -Destination "MPF.UI/bin/Release/${FRAMEWORK}/${RUNTIME}/publish/Programs/Redumper/" -Force
}
}
# Clean up the downloaded files and directories
Remove-Item -Path "DiscImageCreator_20250101.zip"
Remove-Item -Path "Creator" -Recurse
Remove-Item -Path "redumper-2024.11.03_build438-win64.zip"
Remove-Item -Path "Redumper" -Recurse
Download-Programs
}
# Create UI archives
@@ -286,10 +386,21 @@ if (!$NO_ARCHIVE.IsPresent) {
# Only include Debug if set
if ($INCLUDE_DEBUG.IsPresent) {
Set-Location -Path $BUILD_FOLDER/MPF.CLI/bin/Debug/${FRAMEWORK}/${RUNTIME}/publish/
7z a -tzip $BUILD_FOLDER/MPF.CLI_${FRAMEWORK}_${RUNTIME}_debug.zip *
if ($INCLUDE_PROGRAMS.IsPresent) {
7z a -tzip $BUILD_FOLDER/MPF.CLI_${FRAMEWORK}_${RUNTIME}_debug.zip *
}
else {
7z a -tzip -x!Programs/* $BUILD_FOLDER/MPF.CLI_${FRAMEWORK}_${RUNTIME}_debug.zip *
}
}
Set-Location -Path $BUILD_FOLDER/MPF.CLI/bin/Release/${FRAMEWORK}/${RUNTIME}/publish/
7z a -tzip $BUILD_FOLDER/MPF.CLI_${FRAMEWORK}_${RUNTIME}_release.zip *
if ($INCLUDE_PROGRAMS.IsPresent) {
7z a -tzip $BUILD_FOLDER/MPF.CLI_${FRAMEWORK}_${RUNTIME}_release.zip *
}
else {
7z a -tzip -x!Programs/* $BUILD_FOLDER/MPF.CLI_${FRAMEWORK}_${RUNTIME}_release.zip *
}
}
}