Compare commits

..

127 Commits

Author SHA1 Message Date
Matt Nadareski
39f9199807 Move other conversion method to options loader 2026-02-07 21:30:48 -05:00
Matt Nadareski
7c561deb7b Move conversion method to options loader 2026-02-07 21:17:54 -05:00
Matt Nadareski
195d321bbe Remove passthrough property on Options 2026-02-07 21:13:17 -05:00
Matt Nadareski
918e4bf1d1 Introduce base dump settings type 2026-02-07 21:11:22 -05:00
Matt Nadareski
1da70014b1 Move dump settings next to execution contexts 2026-02-07 20:37:15 -05:00
Matt Nadareski
ff58e48ce9 Further cleanup in Options 2026-02-07 20:24:39 -05:00
Matt Nadareski
90f808b63b Add placeholder CLI media info methods 2026-02-07 18:03:52 -05:00
Matt Nadareski
f673a9baea Clean up options serialization and ordering 2026-02-07 18:03:16 -05:00
Matt Nadareski
56ee536eae Replace original Options object 2026-02-07 15:11:46 -05:00
Matt Nadareski
a4fb368f7e Move dictionary logic to new Options object 2026-02-07 15:09:20 -05:00
Matt Nadareski
abca8b58cf Reduce reach of original Options type 2026-02-07 14:21:11 -05:00
Matt Nadareski
a1eef04706 Fix path assignment from UI 2026-02-07 14:13:29 -05:00
Matt Nadareski
a03809c94c Move InternalProgram up a level in options, fix XAML 2026-02-07 13:59:03 -05:00
Matt Nadareski
e5bf218a42 Fix ListConfig feature with new layout 2026-02-07 13:35:46 -05:00
Matt Nadareski
992fb507e7 Replace Options with SegmentedOptions in most places 2026-02-07 13:23:57 -05:00
Matt Nadareski
9a075ad5de Add conversion method from new options type 2026-02-07 11:54:25 -05:00
Matt Nadareski
5e9ec596ea Add save and load for new options type 2026-02-07 11:40:33 -05:00
Matt Nadareski
059fc4cab5 Check should not default to update checking 2026-02-07 11:26:42 -05:00
Matt Nadareski
1fc1288350 Allow Check and CLI to check for updates on startup 2026-02-07 11:08:30 -05:00
Matt Nadareski
1c1b5059d8 Add currently-unused new options class 2026-02-07 10:49:36 -05:00
Matt Nadareski
299fafe1f8 Update changelog 2026-02-02 16:24:01 -05:00
Matt Nadareski
8f6305a7c4 Extend logging with a new state (fixes #944) 2026-02-02 16:23:48 -05:00
Matt Nadareski
3f61957715 Log the system being used, in case it came from config 2026-01-30 08:45:13 -05:00
Matt Nadareski
57750295fb Validate a system is provided for CLI applications 2026-01-29 20:36:56 -05:00
Matt Nadareski
286ec864ab Add unused Dreamdump execution context 2026-01-27 16:16:34 -05:00
Matt Nadareski
e4fd644c61 Split path creation in OptionsLoader 2026-01-27 15:07:22 -05:00
Matt Nadareski
7502d7e8df Update RedumpLib to 1.9.1 2026-01-27 14:02:54 -05:00
Matt Nadareski
439fb2717c Add MPRESS to packer filters (fixes #938) 2026-01-27 08:40:17 -05:00
Matt Nadareski
089ab1c4a2 Add editorconfig, fix issues 2026-01-25 18:09:00 -05:00
Deterous
89a50ea424 Update Redumper to build 683 (#933) 2026-01-04 20:13:35 -05:00
Matt Nadareski
740d867d7b Update DIC to 20260101 2026-01-03 21:57:14 -05:00
Matt Nadareski
83fa4852c9 Add default subfolder to CLI outputs 2026-01-01 10:21:19 -05:00
Deterous
ecc00a28c2 Update Redumper to build 681 (Dreamcast support) (#930)
* Update redumper to b678

* Update Redumper to build 681 (Dreamcast support)

* build 682
2025-12-26 21:24:02 -05:00
Matt Nadareski
2d90c849e1 Use default media type if not provided (fixes #925) 2025-12-22 10:10:49 -05:00
Deterous
1d065ffd48 Update Redumper to build 676 (rename asus flags to mediatek) (#927)
* Update Redumper to build 676 (rename asus flags to mediatek)

* Fix ToRedumperDriveType enum extension
2025-12-15 09:56:49 -05:00
Deterous
ca885c3b89 Update Redumper to build 671 (#924)
* Update Redumper to build 669

* Fix tests

* Bump to build 670

* Update to build 671

* Bump changelist

* Fix tests
2025-12-10 20:32:08 -05:00
Matt Nadareski
94fd614673 Check range-specific values in layerbreak 2025-12-02 08:36:57 -05:00
Matt Nadareski
9fc5799999 Check for null or empty layerbreak arrays 2025-12-02 08:30:33 -05:00
Matt Nadareski
61f90a635f Bump version 2025-11-28 09:53:54 -05:00
Matt Nadareski
8cc0ff3829 Reenable Zstd PKZIP outputs 2025-11-27 20:09:43 -05:00
Matt Nadareski
cac6bcc4de Add commented fix for Zstd PKZIP 2025-11-26 20:25:51 -05:00
Matt Nadareski
7ac0089e81 Disable Zstd PKZIP outputs 2025-11-25 19:38:30 -05:00
Matt Nadareski
48576b38be Update Redumper to build 665 2025-11-25 18:14:08 -05:00
Matt Nadareski
82dedf1ceb Add support for .NET 10 2025-11-25 09:14:46 -05:00
Matt Nadareski
395cded5ef Clarify the unmounted device case (fixes #921) 2025-11-24 13:14:24 -05:00
Deterous
a48f9d1c83 New Redumper Drive Pregap Start option (#920)
* Pregap start option

* Fix DriveType names

* Fix options window

* Update changelist
2025-11-24 09:18:28 -05:00
Matt Nadareski
3975003686 Update changelog 2025-11-18 18:42:28 -05:00
HeroponRikiBestest
4beae71511 Remove DPM identifier for StarForce Keyless (#918)
* Redump staff does not deem the DPM identifier useful, so clean it from the submissioninfo output

* Add test for sanitization of StarForce Keyless
2025-11-18 18:41:10 -05:00
Matt Nadareski
f0f41c86c5 Ensure volume label is trimmed if used in filenames 2025-11-14 09:14:14 -05:00
Matt Nadareski
b1b6eb2c9d Clean up informational issues 2025-11-11 15:52:26 -05:00
Matt Nadareski
29754b4c0e Name some type parameters 2025-11-11 12:06:30 -05:00
Matt Nadareski
35cda84308 Update Redumper to build 663 2025-11-10 20:37:41 -05:00
Matt Nadareski
a877397fe6 Path scan after image scan 2025-11-10 19:34:17 -05:00
Matt Nadareski
2f0471d596 Move and rename new protection scan method 2025-11-10 13:52:31 -05:00
Matt Nadareski
2037ded792 Scan multi-track images for protection 2025-11-10 13:37:23 -05:00
Matt Nadareski
5f1a68a5f5 Scan disc image if not multi-track 2025-11-10 13:27:54 -05:00
Matt Nadareski
87746c8677 Update packages 2025-11-10 13:17:10 -05:00
Matt Nadareski
2665c29918 Use dated default output filenames 2025-11-09 20:03:46 -05:00
Matt Nadareski
5637cf5201 Update Redumper to build 660 2025-11-07 22:06:20 -05:00
Matt Nadareski
eb1d000e4f Fix tests 2025-11-07 09:58:28 -05:00
Matt Nadareski
8db467128d Add DVD-Video to list of copy protection scanning systems 2025-11-07 09:52:49 -05:00
Deterous
dc90e2609d Pre-compress all skeletons for multi-track CDs (#915)
* Pre-compress all skeletons for multi-track CDs

* Gate behind file existing

* Full track path

* split

* if base path is root
2025-11-06 07:39:41 -05:00
Deterous
e96bd21f1d Update Redumper to build 658 (#914) 2025-11-05 20:04:20 -05:00
Matt Nadareski
693599b986 Clean up submission info use and log link text 2025-11-03 08:08:51 -05:00
Matt Nadareski
d482fe926c Fix issues with path assembly 2025-10-29 20:11:02 -04:00
Deterous
17b5432352 Fix langs (#913)
* Fix langs

* changelist
2025-10-27 12:24:15 -04:00
Deterous
ca480f27ed Add hidden language (NovaAurora) (#912)
* Add hidden language (NovaAurora)

* add test
2025-10-27 10:04:00 -04:00
Matt Nadareski
4bad66e706 Slight tweak to automatic UI links 2025-10-26 22:01:10 -04:00
Matt Nadareski
abe00fe132 Try to add UI links to rolling release 2025-10-26 21:46:39 -04:00
Deterous
ba73479837 Rolling tag fix (#911)
* Rolling tag fix

* Remove recursive pull
2025-10-25 21:40:40 -04:00
Matt Nadareski
f2a28dd36b Update changelog 2025-10-24 09:24:40 -04:00
Piotr Swat
928e30a5de Updated Polish translation (#910) 2025-10-24 09:01:26 -04:00
Matt Nadareski
007fc2f9b9 Stop using long name for default system setting 2025-10-23 08:39:09 -04:00
Matt Nadareski
d2d23ebbdf Limit visibility of Compatible OS text box 2025-10-22 11:45:10 -04:00
Matt Nadareski
e02ab769ec Update RedumpLib to 1.8.0 2025-10-22 09:16:53 -04:00
Matt Nadareski
3df78def00 Minor Spanish cleanup 2025-10-21 10:59:49 -04:00
Matt Nadareski
7eddfc5fed Possibly fix missing options string 2025-10-21 09:50:54 -04:00
Matt Nadareski
f6f154b6db Free disk space for runners 2025-10-21 09:22:10 -04:00
Matt Nadareski
47cd133437 Change CLI first-run wording 2025-10-21 09:01:33 -04:00
Matt Nadareski
74c9641a54 Simplify first-run CLI experience 2025-10-21 08:58:01 -04:00
Matt Nadareski
fc5929db2a Add per-OS executable names 2025-10-21 08:51:24 -04:00
Matt Nadareski
f53b428075 Separate out default program paths 2025-10-21 08:43:52 -04:00
Matt Nadareski
46dc931b3f Readme updates for accuracy 2025-10-21 08:30:53 -04:00
Deterous
9608cfb700 Be selective on which systems to enable skeleton (#909)
* Be selective on which systems to enable skeleton

* Bring back lost brace

* case

* RedumpSystem
2025-10-19 20:41:15 -04:00
Matt Nadareski
3493238849 Make log archive handling more user-apparent 2025-10-19 13:15:48 -04:00
Matt Nadareski
4c364f519e Regex outputs should not name based on pattern 2025-10-19 12:47:21 -04:00
Matt Nadareski
337a7a181c Fix tests broken by last commit 2025-10-19 12:27:50 -04:00
Matt Nadareski
071e3a0024 Redumper state file is not accessed 2025-10-19 12:21:20 -04:00
Matt Nadareski
ff0c742dee Handle log zip path in information extraction 2025-10-19 11:55:37 -04:00
Matt Nadareski
7aba0d1c9c Make .img not required for DIC outputs 2025-10-19 11:53:51 -04:00
Matt Nadareski
ac6a77d9da Allow placeholder files to be used in Check 2025-10-19 11:45:22 -04:00
Matt Nadareski
6eb976c842 Merge pull request #908 from SabreTools/ui-langs
Support UI Languages
2025-10-19 09:51:41 -04:00
Matt Nadareski
ba39a8b22f Update changelog 2025-10-19 09:46:11 -04:00
Deterous
88a6fa71a9 Fix long translated strings (#907)
* Build branch

* Enable debug media info window by default

* Fix bold options window context menu

* Shorten ukr strings

* More shortened strings

* better short ukr

* revert build changes and debug flag

* fix test login button strings
2025-10-19 09:46:00 -04:00
Matt Nadareski
584b8c0109 Allow files to be zipped but not deleted 2025-10-19 09:25:56 -04:00
Matt Nadareski
c6258b5520 Handle a provided log zip in Check operation 2025-10-18 20:15:47 -04:00
Matt Nadareski
d6dbbbe928 Add list configuration commandline feature (fixes #906) 2025-10-18 18:47:27 -04:00
Matt Nadareski
f22b3c4ac0 Add Ukrainian translation (superg) 2025-10-18 18:10:45 -04:00
Matt Nadareski
fae399f8bc Add console print when Check loads from config 2025-10-18 13:08:32 -04:00
Matt Nadareski
d2ed2f81ae Make Check flags toggle if config used 2025-10-18 12:03:37 -04:00
Deterous
7dbcfce46c Add basic translation for 8 more languages (#902)
* Add langs

* Top menu spacing

* need using

* ToInterfaceLanguage

* fix UI strings

* auto menu width

* cleanup strings

* fix spacing

* better strings

* revert CI change

* more translation work

* test remove System.Windows.Forms

* full namespace for WinForms

* WinForms namespace

* App is in System.Windows

* Fix string bugs

* Better swedish

* Update changelog
2025-10-18 21:12:51 +09:00
Matt Nadareski
ebd0552a2a Add 8 more language menu items 2025-10-17 17:36:12 -04:00
Matt Nadareski
343973263c Add skeleton for 8 more languages 2025-10-17 17:26:56 -04:00
Matt Nadareski
e5220a8224 Update changelog 2025-10-17 13:01:51 -04:00
Deterous
146120c210 Complete translation support (#901)
* Translate options window

* build on branch

* ui-langs-dev

* fix dupe string

* Translate Media Information Window

* Revert CI process
2025-10-17 13:01:31 -04:00
Matt Nadareski
807e4655a6 Update changelog 2025-10-17 09:12:37 -04:00
Matt Nadareski
e32ebec197 Ensure readers and writers dispose 2025-10-17 08:50:50 -04:00
Matt Nadareski
8d8886390d Minor formatting cleanup 2025-10-17 08:10:02 -04:00
Deterous
5a2aa9d325 Continue UI translation work (#900)
* No redundant translation

* semicolon

* rename DefaultUILanguage

* finish rename

* Cleanup

* Fix SetInterfaceLanguage

* Fix LanguageMenuItemClick

* Set resources before window loads

* set lang during init

* Update interface language after setting options

* Check language menuitem when updating options

* Clear checks when loading language from options

* SetInterfaceLanguage clears checks

* obj as MenuItem

* safer unchecking

* type naming

* uncheck menuitem

* var

* don't uncheck within setlanguage

* test

* equals

* top left menu margin

* help menu right margin

* Fix title bar

* Margin on help menu item

* margin on stack panel

* more translations

* Translate message boxes

* fix margin

* only change lang if options was saved

* only update language if it has been updated

* smaller negative margin

* padding

* padding on textblock

* Revert GHA changes
2025-10-17 08:02:09 -04:00
Matt Nadareski
37aa1645dd Add UI by default to launch 2025-10-17 07:50:46 -04:00
Matt Nadareski
052d074e92 Fill in some gaps 2025-10-16 23:02:35 -04:00
Matt Nadareski
8c551dc990 Clean up a bit of element work 2025-10-16 22:35:31 -04:00
Matt Nadareski
b2fcc190fd Clean up nullability 2025-10-16 21:09:42 -04:00
Matt Nadareski
2325844bd4 Slight cleanup to main window language handling 2025-10-16 20:33:43 -04:00
Matt Nadareski
f63517bb52 Move to enum-based model for UI language options 2025-10-16 20:28:37 -04:00
Deterous
99d26f177b Initial UI lang code (#899)
* Test using resources

* Include system namespace in resource xaml

* system namespace name

* rename strings

* Default strings

* Window resources

* add keys

* just one key

* Combo box example

* window resources

* Dropdown in menu bar

* nullable

* non nullable

* string list init

* simple

* English default

* Add menu item for language

* parent is menuitem

* fix

* no null lang

* Only build win-x64, GHA storage limit

* Korean

* test

* Set resource strings at app level

* remove lost endif

* Better UI

* Move langs next to buttons

* update

* fix button

* More translations

* Better menu size

* too many semicolons

* top right menu bar

* Tweaks

* Top bar positioning

* title bar width

* try again

* final

* Back to original publish script

* more windows

* pre-merge test

* Test non-latin underscore

* More strings

* fix

* FindResource is a function

* space

* cast spells

* Log about text

* semicolon

* Good

* cast spells

* using System.Windows in Frontend

* Translate in MainViewModel

* Dynamic GetFormattedVolumeLabel

* Nullability

* Fix

* using for dict

* Translate func in MVM

* Don't translate in init

* Update MVM translations

* closing brace

* Deprecate resource string

* test

* test2

* set current system

* trial field

* field is preview

* default empty string

* default null

* fix build

* empty string

* GIve up on no system selected text

* Fix context menu border

* Revert half fix

* Translate more IRD Window strings

* Loose string

* Detect current locale

* fix

* System.Globalization

* Locale detection for default lang

* break on zh case

* default startup lang

* default lang option

* fix

* fix2

* fix3

* nonnullable

* final fix

* final final fix

* default language option

* use default language on startup

* empty entry

* semicolon
2025-10-16 11:47:36 -04:00
Matt Nadareski
d6b28de586 Reduce chance of empty strings 2025-10-12 22:45:54 -04:00
Deterous
e8d1567d07 Parse XboxOne/SX Title IDs (#897)
* Parse XboxOne/SX Title IDs

* Bump RedumpLib

* Fix build

* Don't use lists because net20
2025-10-12 20:14:50 -04:00
Matt Nadareski
cd8b484ae3 Replace "We" comments 2025-10-11 16:06:53 -04:00
Matt Nadareski
65b9735941 Conditionally require state 2025-10-11 09:41:28 -04:00
Matt Nadareski
22f7e2a0ed Move output file implementations to separate namespace 2025-10-11 09:34:00 -04:00
Matt Nadareski
2c5dc7390a Use WriteToFile extension for zip entries 2025-10-11 09:27:55 -04:00
Deterous
c5e01b9578 Support reparsing of MPF-processed outputs (#896)
* Have a go at extracting files from existing log

* no null output dir

* Extract log from archive if it is zipped during mediatype detection

* imports

* fix variable names

* fix null output dir

* Final fixes

* changelist

* assign null

* fix
2025-10-10 22:03:03 -04:00
Matt Nadareski
882243316c Implement file merging in CleanRip 2025-10-10 11:40:02 -04:00
Matt Nadareski
1b62ed0c03 Add file merge method in CleanRip 2025-10-10 11:37:11 -04:00
Matt Nadareski
edb8c08a39 Move Zstd compression helper to base processor 2025-10-10 10:07:32 -04:00
Matt Nadareski
ad93387aea Add BCA to list of files to select in Check UI 2025-10-10 09:05:54 -04:00
172 changed files with 9828 additions and 3737 deletions

View File

@@ -1,4 +1,167 @@
[*.cs]
# top-most EditorConfig file
root = true
# SYSLIB1045: Convert to 'GeneratedRegexAttribute'.
dotnet_diagnostic.SYSLIB1045.severity = silent
# C# files
[*.cs]
# Indentation and spacing
charset = utf-8
indent_size = 4
indent_style = space
tab_width = 4
trim_trailing_whitespace = true
# New line preferences
end_of_line = lf
insert_final_newline = true
max_line_length = unset
# using directive preferences
csharp_using_directive_placement = outside_namespace
dotnet_diagnostic.IDE0005.severity = error
# Code-block preferences
csharp_style_namespace_declarations = block_scoped
csharp_style_prefer_method_group_conversion = true
csharp_style_prefer_top_level_statements = false
# Expression-level preferences
csharp_prefer_simple_default_expression = true
csharp_style_inlined_variable_declaration = true
csharp_style_unused_value_assignment_preference = discard_variable
csharp_style_unused_value_expression_statement_preference = discard_variable
dotnet_diagnostic.IDE0001.severity = warning
dotnet_diagnostic.IDE0002.severity = warning
dotnet_diagnostic.IDE0004.severity = warning
dotnet_diagnostic.IDE0010.severity = error
dotnet_diagnostic.IDE0051.severity = warning
dotnet_diagnostic.IDE0052.severity = warning
dotnet_diagnostic.IDE0072.severity = warning
dotnet_diagnostic.IDE0080.severity = warning
dotnet_diagnostic.IDE0100.severity = error
dotnet_diagnostic.IDE0110.severity = error
dotnet_diagnostic.IDE0120.severity = warning
dotnet_diagnostic.IDE0121.severity = warning
dotnet_diagnostic.IDE0240.severity = error
dotnet_diagnostic.IDE0241.severity = error
dotnet_style_coalesce_expression = true
dotnet_style_namespace_match_folder = false
dotnet_style_null_propagation = true
dotnet_style_prefer_auto_properties = true
dotnet_style_prefer_collection_expression = when_types_loosely_match
dotnet_style_prefer_is_null_check_over_reference_equality_method = true
dotnet_style_prefer_compound_assignment = true
csharp_style_prefer_simple_property_accessors = true
dotnet_style_prefer_simplified_interpolation = true
dotnet_style_prefer_simplified_boolean_expressions = true
csharp_style_prefer_unbound_generic_type_in_nameof = true
# Field preferences
dotnet_diagnostic.IDE0044.severity = warning
dotnet_style_readonly_field = true
# Language keyword vs. framework types preferences
dotnet_diagnostic.IDE0049.severity = error
dotnet_style_predefined_type_for_locals_parameters_members = true
dotnet_style_predefined_type_for_member_access = true
# Modifier preferences
csharp_prefer_static_local_function = true
csharp_style_prefer_readonly_struct = true
dotnet_diagnostic.IDE0036.severity = warning
dotnet_diagnostic.IDE0040.severity = error
dotnet_diagnostic.IDE0380.severity = error
dotnet_style_require_accessibility_modifiers = always
# New-line preferences
dotnet_diagnostic.IDE2000.severity = warning
dotnet_diagnostic.IDE2002.severity = warning
dotnet_diagnostic.IDE2003.severity = warning
dotnet_diagnostic.IDE2004.severity = warning
dotnet_diagnostic.IDE2005.severity = warning
dotnet_diagnostic.IDE2006.severity = warning
csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = false
csharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimental = false
csharp_style_allow_blank_line_after_token_in_conditional_expression_experimental = false
csharp_style_allow_blank_lines_between_consecutive_braces_experimental = false
dotnet_style_allow_multiple_blank_lines_experimental = false
dotnet_style_allow_statement_immediately_after_block_experimental = false
# Null-checking preferences
csharp_style_conditional_delegate_call = true
# Parameter preferences
dotnet_code_quality_unused_parameters = all
dotnet_diagnostic.IDE0280.severity = error
# Parentheses preferences
dotnet_diagnostic.IDE0047.severity = warning
dotnet_diagnostic.IDE0048.severity = warning
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity
dotnet_style_parentheses_in_other_operators = always_for_clarity
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity
# Pattern-matching preferences
dotnet_diagnostic.IDE0019.severity = warning
dotnet_diagnostic.IDE0020.severity = warning
dotnet_diagnostic.IDE0038.severity = warning
dotnet_diagnostic.IDE0066.severity = none
dotnet_diagnostic.IDE0083.severity = warning
dotnet_diagnostic.IDE0260.severity = warning
csharp_style_pattern_matching_over_as_with_null_check = true
csharp_style_pattern_matching_over_is_with_cast_check = true
csharp_style_prefer_not_pattern = true
csharp_style_prefer_pattern_matching = true
# this. and Me. preferences
dotnet_style_qualification_for_event = false
dotnet_style_qualification_for_field = false
dotnet_style_qualification_for_method = false
dotnet_style_qualification_for_property = false
# var preferences
csharp_style_var_for_built_in_types = false
csharp_style_var_when_type_is_apparent = true
# .NET formatting options
dotnet_separate_import_directive_groups = false
dotnet_sort_system_directives_first = true
# C# formatting options
csharp_indent_block_contents = true
csharp_indent_braces = false
csharp_indent_case_contents = true
csharp_indent_case_contents_when_block = false
csharp_indent_labels = one_less_than_current
csharp_indent_switch_labels = true
csharp_new_line_before_catch = true
csharp_new_line_before_else = true
csharp_new_line_before_finally = true
csharp_new_line_before_members_in_anonymous_types = true
csharp_new_line_before_members_in_object_initializers = true
csharp_new_line_before_open_brace = all
csharp_new_line_between_query_expression_clauses = true
csharp_preserve_single_line_blocks = true
csharp_preserve_single_line_statements = true
csharp_space_after_cast = false
csharp_space_after_colon_in_inheritance_clause = true
csharp_space_after_comma = true
csharp_space_after_dot = false
csharp_space_after_keywords_in_control_flow_statements = true
csharp_space_after_semicolon_in_for_statement = true
csharp_space_around_binary_operators = before_and_after
csharp_space_around_declaration_statements = false
csharp_space_before_colon_in_inheritance_clause = true
csharp_space_before_comma = false
csharp_space_before_dot = false
csharp_space_before_open_square_brackets = false
csharp_space_before_semicolon_in_for_statement = false
csharp_space_between_empty_square_brackets = false
csharp_space_between_method_call_empty_parameter_list_parentheses = false
csharp_space_between_method_call_name_and_opening_parenthesis = false
csharp_space_between_method_call_parameter_list_parentheses = false
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
csharp_space_between_method_declaration_parameter_list_parentheses = false
csharp_space_between_parentheses = false
csharp_space_between_square_brackets = false

View File

@@ -25,7 +25,7 @@ What version are you using?
**Build**
What runtime version are you using?
- [ ] .NET 9.0 running on (Operating System)
- [ ] .NET 10 running on (Operating System)
**Describe the issue**
A clear and concise description of what the bug is.

View File

@@ -1,40 +1,59 @@
name: Build and Test
on:
push:
branches: [ "master" ]
push:
branches: ["master"]
jobs:
build:
runs-on: ubuntu-latest
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
6.0.x
8.0.x
9.0.x
- name: Run tests
run: dotnet test
- name: Run publish script
run: ./publish-nix.sh -dp
steps:
- name: Free Disk Space (Ubuntu)
uses: jlumbroso/free-disk-space@v1.3.1
with:
dotnet: false
- name: Upload to rolling
uses: ncipollo/release-action@v1.14.0
with:
allowUpdates: True
artifacts: "*.nupkg,*.snupkg,*.zip"
body: 'Last built commit: ${{ github.sha }}'
name: 'Rolling Release'
prerelease: True
replacesArtifacts: True
tag: "rolling"
updateOnlyUnreleased: True
- uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Setup .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: |
8.0.x
9.0.x
10.0.x
- name: Run tests
run: dotnet test
- name: Run publish script
run: ./publish-nix.sh -dp
- name: Update rolling tag
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git tag -f rolling
git push origin :refs/tags/rolling || true
git push origin rolling --force
- name: Upload to rolling
uses: ncipollo/release-action@v1.20.0
with:
allowUpdates: True
artifacts: "*.nupkg,*.snupkg,*.zip"
body: "Last built commit: ${{ github.sha }}
## UI Builds
[Windows x64 UI Release](https://github.com/SabreTools/MPF/releases/download/rolling/MPF.UI_net10.0-windows_win-x64_release.zip)
[Windows x64 UI Debug](https://github.com/SabreTools/MPF/releases/download/rolling/MPF.UI_net10.0-windows_win-x64_debug.zip)"
name: "Rolling Release"
prerelease: True
replacesArtifacts: True
tag: "rolling"
updateOnlyUnreleased: True

View File

@@ -3,24 +3,29 @@ name: Build PR
on: [pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
build:
runs-on: ubuntu-latest
steps:
- name: Free Disk Space (Ubuntu)
uses: jlumbroso/free-disk-space@v1.3.1
with:
dotnet: false
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
6.0.x
8.0.x
9.0.x
- uses: actions/checkout@v5
- name: Restore dependencies
run: dotnet restore
- name: Setup .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: |
8.0.x
9.0.x
10.0.x
- name: Build
run: dotnet build
- name: Restore dependencies
run: dotnet restore
- name: Test
run: dotnet test
- name: Build
run: dotnet build
- name: Test
run: dotnet test

18
.vscode/launch.json vendored
View File

@@ -10,7 +10,7 @@
"request": "launch",
"preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/MPF.Check/bin/Debug/net9.0/MPF.Check.dll",
"program": "${workspaceFolder}/MPF.Check/bin/Debug/net10.0/MPF.Check.dll",
"args": [],
"cwd": "${workspaceFolder}/MPF.Check",
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
@@ -24,7 +24,7 @@
"request": "launch",
"preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/MPF.CLI/bin/Debug/net9.0/MPF.CLI.dll",
"program": "${workspaceFolder}/MPF.CLI/bin/Debug/net10.0/MPF.CLI.dll",
"args": [],
"cwd": "${workspaceFolder}/MPF.CLI",
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
@@ -32,6 +32,20 @@
"stopAtEntry": false,
"justMyCode": false
},
{
"name": ".NET Core Launch (UI)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/MPF.UI/bin/Debug/net10.0-windows/MPF.dll",
"args": [],
"cwd": "${workspaceFolder}/MPF.UI",
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
"console": "internalConsole",
"stopAtEntry": false,
"justMyCode": false
},
{
"name": ".NET Core Attach",
"type": "coreclr",

View File

@@ -1,3 +1,126 @@
### WIP (xxxx-xx-xx)
- Check for null or empty layerbreak arrays
- Check range-specific values in layerbreak
- Update Redumper to build 671
- Update Redumper to build 676 (rename asus flags to mediatek)
- Use default media type if not provided
- Update Redumper to build 682 (Dreamcast support)
- Add default subfolder to CLI outputs
- Update DIC to 20260101
- Update Redumper to build 683
- Add editorconfig, fix issues
- Add MPRESS to packer filters
- Update RedumpLib to 1.9.1
- Split path creation in OptionsLoader
- Add unused Dreamdump execution context
- Validate a system is provided for CLI applications
- Log the system being used, in case it came from config
- Extend logging with a new state
- Add currently-unused new options class
- Allow Check and CLI to check for updates on startup
- Check should not default to update checking
- Add save and load for new options type
- Add conversion method from new options type
- Replace Options with SegmentedOptions in most places
- Fix ListConfig feature with new layout
- Move InternalProgram up a level in options, fix XAML
- Fix path assignment from UI
- Reduce reach of original Options type
- Move dictionary logic to new Options object
- Replace original Options object
- Clean up options serialization and ordering
- Add placeholder CLI media info methods
- Further cleanup in Options
- Move dump settings next to execution contexts
- Introduce base dump settings type
- Remove passthrough property on Options
- Move conversion method to options loader
- Move other conversion method to options loader
### 3.6.0 (2025-11-28)
- Add BCA to list of files to select in Check UI
- Move Zstd compression helper to base processor
- Add file merge method in CleanRip
- Implement file merging in CleanRip
- Support reparsing of MPF-processed outputs
- Use WriteToFile extension for zip entries
- Move output file implementations to separate namespace
- Conditionally require state
- Replace "We" comments
- Parse XboxOne/SX Title IDs
- Reduce chance of empty strings
- Initial UI lang code
- Move to enum-based model for UI language options
- Slight cleanup to main window language handling
- Clean up nullability
- Clean up a bit of element work
- Fill in some gaps
- Add UI by default to launch
- Continue UI translation work
- Minor formatting cleanup
- Ensure readers and writers dispose
- Complete translation support
- Add skeleton for 8 more languages
- Add 8 more language menu items
- Add basic translation for 8 more languages
- Make Check flags toggle if config used
- Add console print when Check loads from config
- Add Ukrainian translation (superg)
- Add list configuration commandline feature
- Handle a provided log zip in Check operation
- Allow files to be zipped but not deleted
- Fix long translated strings
- Allow placeholder files to be used in Check
- Make .img not required for DIC outputs
- Handle log zip path in information extraction
- Redumper state file is not accessed
- Fix tests broken by last commit
- Regex outputs should not name based on pattern
- Make log archive handling more user-apparent
- Be selective on which systems to enable skeleton
- Readme updates for accuracy
- Separate out default program paths
- Add per-OS executable names
- Simplify first-run CLI experience
- Change CLI first-run wording
- Free disk space for runners
- Possibly fix missing options string
- Minor Spanish cleanup
- Update RedumpLib to 1.8.0
- Limit visibility of Compatible OS text box
- Stop using long name for default system setting
- Updated Polish translation
- Fix rolling tag
- Try to add UI links to rolling release
- Slight tweak to automatic UI links
- Add hidden language (NovaAurora)
- Fix langs
- Fix issues with path assembly
- Clean up submission info use and log link text
- Update Redumper to build 658
- Pre-compress all skeletons for multi-track CDs
- Add DVD-Video to list of copy protection scanning systems
- Update Redumper to build 660
- Use dated default output filenames
- Update packages
- Scan disc image if not multi-track
- Scan multi-track images for protection
- Move and rename new protection scan method
- Path scan after image scan
- Update Redumper to build 663
- Name some type parameters
- Ensure volume label is trimmed if used in filenames
- Remove DPM identifier for StarForce Keyless
- New Redumper Drive Pregap Start option
- Clarify the unmounted device case
- Add support for .NET 10
- Update Redumper to build 665
- Disable Zstd PKZIP outputs
- Add commented fix for Zstd PKZIP
- Reenable Zstd PKZIP outputs
### 3.5.0 (2025-10-10)
- Add failure if media type could not be determined

View File

@@ -65,44 +65,56 @@ namespace MPF.CLI.Features
protected BaseFeature(string name, string[] flags, string description, string? detailed = null)
: base(name, flags, description, detailed)
{
Options = new Options()
{
// Internal Program
InternalProgram = InternalProgram.NONE,
Options = new Options();
// Extra Dumping Options
ScanForProtection = false,
AddPlaceholders = true,
PullAllInformation = false,
AddFilenameSuffix = false,
OutputSubmissionJSON = false,
IncludeArtifacts = false,
CompressLogFiles = false,
LogCompression = LogCompression.DeflateMaximum,
DeleteUnnecessaryFiles = false,
CreateIRDAfterDumping = false,
// Internal Program
Options.InternalProgram = InternalProgram.NONE;
// Protection Scanning Options
ScanArchivesForProtection = true,
IncludeDebugProtectionInformation = false,
HideDriveLetters = false,
// Protection Scanning Options
Options.Processing.ProtectionScanning.ScanForProtection = false;
Options.Processing.ProtectionScanning.ScanArchivesForProtection = true;
Options.Processing.ProtectionScanning.IncludeDebugProtectionInformation = false;
Options.Processing.ProtectionScanning.HideDriveLetters = false;
// Redump Login Information
Options.Processing.Login.PullAllInformation = false;
Options.Processing.Login.RedumpUsername = null;
Options.Processing.Login.RedumpPassword = null;
Options.Processing.Login.RetrieveMatchInformation = true;
// Media Information
Options.Processing.MediaInformation.AddPlaceholders = true;
// Post-Information Options
Options.Processing.AddFilenameSuffix = false;
Options.Processing.CreateIRDAfterDumping = false;
Options.Processing.OutputSubmissionJSON = false;
Options.Processing.IncludeArtifacts = false;
Options.Processing.CompressLogFiles = false;
Options.Processing.LogCompression = LogCompression.DeflateMaximum;
Options.Processing.DeleteUnnecessaryFiles = false;
// Redump Login Information
RetrieveMatchInformation = true,
RedumpUsername = null,
RedumpPassword = null,
};
}
/// <inheritdoc/>
public override bool Execute()
{
// Validate the supplied credentials
if (Options.RetrieveMatchInformation
&& !string.IsNullOrEmpty(Options.RedumpUsername)
&& !string.IsNullOrEmpty(Options.RedumpPassword))
// Validate a system type is provided
if (System == null)
{
bool? validated = RedumpClient.ValidateCredentials(Options.RedumpUsername!, Options.RedumpPassword!).GetAwaiter().GetResult();
Console.Error.WriteLine("A system name needs to be provided");
return false;
}
// Log the system being used, in case it came from config
Console.WriteLine($"Using system: {System.LongName()}");
// Validate the supplied credentials
if (Options.Processing.Login.RetrieveMatchInformation
&& !string.IsNullOrEmpty(Options.Processing.Login.RedumpUsername)
&& !string.IsNullOrEmpty(Options.Processing.Login.RedumpPassword))
{
bool? validated = RedumpClient.ValidateCredentials(Options.Processing.Login.RedumpUsername!, Options.Processing.Login.RedumpPassword!).GetAwaiter().GetResult();
string message = validated switch
{
true => "Redump username and password accepted!",
@@ -114,53 +126,88 @@ namespace MPF.CLI.Features
}
// Validate the internal program
#pragma warning disable IDE0010
switch (Options.InternalProgram)
{
case InternalProgram.Aaru:
if (!File.Exists(Options.AaruPath))
if (!File.Exists(Options.Dumping.AaruPath))
{
Console.Error.WriteLine("A path needs to be supplied in config.json for Aaru, exiting...");
return false;
}
break;
case InternalProgram.DiscImageCreator:
if (!File.Exists(Options.DiscImageCreatorPath))
if (!File.Exists(Options.Dumping.DiscImageCreatorPath))
{
Console.Error.WriteLine("A path needs to be supplied in config.json for DIC, exiting...");
return false;
}
break;
// case InternalProgram.Dreamdump:
// if (!File.Exists(Options.Dumping.DreamdumpPath))
// {
// Console.Error.WriteLine("A path needs to be supplied in config.json for Dreamdump, exiting...");
// return false;
// }
// break;
case InternalProgram.Redumper:
if (!File.Exists(Options.RedumperPath))
if (!File.Exists(Options.Dumping.RedumperPath))
{
Console.Error.WriteLine("A path needs to be supplied in config.json for Redumper, exiting...");
return false;
}
break;
default:
Console.Error.WriteLine($"{Options.InternalProgram} is not a supported dumping program, exiting...");
break;
}
#pragma warning restore IDE0010
// Ensure we have the values we need
if (CustomParams == null && (DevicePath == null || FilePath == null))
if (CustomParams is null && DevicePath is null)
{
Console.Error.WriteLine("Both a device path and file path need to be supplied, exiting...");
Console.Error.WriteLine("Either custom parameters or a device path need to be provided, exiting...");
return false;
}
if (Options.InternalProgram == InternalProgram.DiscImageCreator
&& CustomParams == null
&& (MediaType == null || MediaType == SabreTools.RedumpLib.Data.MediaType.NONE))
&& CustomParams is null
&& (MediaType is null || MediaType == SabreTools.RedumpLib.Data.MediaType.NONE))
{
Console.Error.WriteLine("Media type is required for DiscImageCreator, exiting...");
return false;
}
// If no media type is provided, use a default
if (CustomParams is null && (MediaType is null || MediaType == SabreTools.RedumpLib.Data.MediaType.NONE))
{
// Get reasonable default values based on the current system
var mediaTypes = System.MediaTypes();
MediaType = mediaTypes.Count > 0 ? mediaTypes[0] : SabreTools.RedumpLib.Data.MediaType.CDROM;
if (MediaType == SabreTools.RedumpLib.Data.MediaType.NONE)
MediaType = SabreTools.RedumpLib.Data.MediaType.CDROM;
Console.WriteLine($"No media type was provided, using {MediaType.LongName()}");
}
// Normalize the file path
if (FilePath != null)
if (DevicePath is not null && FilePath is null)
{
string defaultFileName = $"track_{DateTime.Now:yyyyMMdd-HHmm}";
FilePath = Path.Combine(defaultFileName, $"{defaultFileName}.bin");
if (Options.Dumping.DefaultOutputPath is not null)
FilePath = Path.Combine(Options.Dumping.DefaultOutputPath, FilePath);
}
if (FilePath is not null)
FilePath = FrontendTool.NormalizeOutputPaths(FilePath, getFullPath: true);
// Get the speed from the options
@@ -190,7 +237,7 @@ namespace MPF.CLI.Features
Console.WriteLine($"Invoking {Options.InternalProgram} using '{paramStr}'");
var dumpResult = env.Run(MediaType).GetAwaiter().GetResult();
Console.WriteLine(dumpResult.Message);
if (!dumpResult)
if (dumpResult == false)
return false;
// If it was not a dumping command
@@ -202,7 +249,7 @@ namespace MPF.CLI.Features
}
// If we have a mounted path, replace the environment
if (MountedPath != null && Directory.Exists(MountedPath))
if (MountedPath is not null && Directory.Exists(MountedPath))
{
drive = Drive.Create(null, MountedPath);
env = new DumpEnvironment(Options,
@@ -215,7 +262,7 @@ namespace MPF.CLI.Features
}
// Finally, attempt to do the output dance
var verifyResult = env.VerifyAndSaveDumpOutput()
var verifyResult = env.VerifyAndSaveDumpOutput(processUserInfo: ProcessUserInfo)
.ConfigureAwait(false).GetAwaiter().GetResult();
Console.WriteLine(verifyResult.Message);
@@ -235,6 +282,7 @@ namespace MPF.CLI.Features
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("lo, listconfig List current configuration values");
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");
@@ -246,7 +294,7 @@ namespace MPF.CLI.Features
Console.WriteLine("-t, --mediatype <mediatype> Set media type for dumping (Required for DIC)");
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)");
Console.WriteLine("-f, --file \"<filepath>\" Output file path (Recommended, uses defaults otherwise)");
Console.WriteLine("-s, --speed <speed> Override default dumping speed");
Console.WriteLine("-c, --custom \"<params>\" Custom parameters to use");
Console.WriteLine();
@@ -258,12 +306,28 @@ namespace MPF.CLI.Features
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.");
Console.WriteLine("Otherwise, a drive path is required.");
Console.WriteLine();
Console.WriteLine("Mounted filesystem path is only recommended on OSes that require block");
Console.WriteLine("device dumping, usually Linux and macOS.");
Console.WriteLine();
}
/// <summary>
/// Determines how user information is processed, if at all
/// </summary>
/// <param name="options">Options set that may impact processing</params>
/// <param name="info">Submission info that may be overwritten</param>
/// <returns>True for successful updating, false or null otherwise</returns>
public bool? ProcessUserInfo(Options? options, ref SubmissionInfo? submissionInfo)
{
// TODO: Somehow use the GUI strings here instead of hardcoding English
if (options?.Processing?.ShowDiscEjectReminder == true)
Console.WriteLine("It is now safe to eject the disc");
// TODO: Implement some sort of CLI-based processing of user information
return null;
}
}
}

View File

@@ -38,11 +38,16 @@ namespace MPF.CLI.Features
// Create return values
MediaType = SabreTools.RedumpLib.Data.MediaType.NONE;
FilePath = Path.Combine(Options.DefaultOutputPath ?? "ISO", "track.bin");
System = Options.DefaultSystem;
string defaultFileName = $"track_{DateTime.Now:yyyyMMdd-HHmm}";
#if NET20 || NET35
FilePath = Path.Combine(Options.Dumping.DefaultOutputPath ?? "ISO", Path.Combine(defaultFileName, $"{defaultFileName}.bin"));
#else
FilePath = Path.Combine(Options.Dumping.DefaultOutputPath ?? "ISO", defaultFileName, $"{defaultFileName}.bin");
#endif
System = Options.Dumping.DefaultSystem;
// Create state values
string? result = string.Empty;
string? result;
root:
Console.Clear();
@@ -115,9 +120,10 @@ namespace MPF.CLI.Features
dumpingProgram:
Console.WriteLine();
Console.WriteLine("Options:");
Console.WriteLine($"{InternalProgram.Redumper.ToString().ToLowerInvariant().PadRight(15)} => {InternalProgram.Redumper.LongName()}");
Console.WriteLine($"{InternalProgram.DiscImageCreator.ToString().ToLowerInvariant().PadRight(15)} => {InternalProgram.DiscImageCreator.LongName()}");
Console.WriteLine($"{InternalProgram.Aaru.ToString().ToLowerInvariant().PadRight(15)} => {InternalProgram.Aaru.LongName()}");
Console.WriteLine($"{InternalProgram.Redumper.ToString().ToLowerInvariant(),-15} => {InternalProgram.Redumper.LongName()}");
Console.WriteLine($"{InternalProgram.DiscImageCreator.ToString().ToLowerInvariant(),-15} => {InternalProgram.DiscImageCreator.LongName()}");
Console.WriteLine($"{InternalProgram.Aaru.ToString().ToLowerInvariant(),-15} => {InternalProgram.Aaru.LongName()}");
// Console.WriteLine($"{InternalProgram.Dreamdump.ToString().ToLowerInvariant(),-15} => {InternalProgram.Dreamdump.LongName()}");
Console.WriteLine();
Console.WriteLine("Input the dumping program and press Enter:");
Console.Write("> ");

View File

@@ -61,7 +61,7 @@ namespace MPF.CLI.Features
public override bool ProcessArgs(string[] args, int index)
{
// If we have no arguments, just return
if (args == null || args.Length == 0)
if (args is null || args.Length == 0)
return true;
// Read the options from config, if possible

View File

@@ -2,7 +2,7 @@
<PropertyGroup>
<!-- Assembly Properties -->
<TargetFrameworks>net20;net35;net40;net452;net462;net472;net48;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0;net9.0</TargetFrameworks>
<TargetFrameworks>net20;net35;net40;net452;net462;net472;net48;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0;net9.0;net10.0</TargetFrameworks>
<OutputType>Exe</OutputType>
<CheckEolTargetFramework>false</CheckEolTargetFramework>
<IncludeNativeLibrariesForSelfExtract>true</IncludeNativeLibrariesForSelfExtract>
@@ -12,7 +12,7 @@
<Nullable>enable</Nullable>
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<VersionPrefix>3.5.0</VersionPrefix>
<VersionPrefix>3.6.0</VersionPrefix>
<!-- Package Properties -->
<Title>MPF CLI</Title>
@@ -31,11 +31,11 @@
<PropertyGroup Condition="$(TargetFramework.StartsWith(`netcoreapp`)) OR $(TargetFramework.StartsWith(`net5`))">
<RuntimeIdentifiers>win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64</RuntimeIdentifiers>
</PropertyGroup>
<PropertyGroup Condition="$(TargetFramework.StartsWith(`net6`)) OR $(TargetFramework.StartsWith(`net7`)) OR $(TargetFramework.StartsWith(`net8`)) OR $(TargetFramework.StartsWith(`net9`))">
<PropertyGroup Condition="$(TargetFramework.StartsWith(`net6`)) OR $(TargetFramework.StartsWith(`net7`)) OR $(TargetFramework.StartsWith(`net8`)) OR $(TargetFramework.StartsWith(`net9`)) OR $(TargetFramework.StartsWith(`net10`))">
<RuntimeIdentifiers>win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64;osx-arm64</RuntimeIdentifiers>
</PropertyGroup>
<PropertyGroup Condition="$(RuntimeIdentifier.StartsWith(`osx-arm`))">
<TargetFrameworks>net6.0;net7.0;net8.0;net9.0</TargetFrameworks>
<TargetFrameworks>net6.0;net7.0;net8.0;net9.0;net10.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
@@ -43,8 +43,8 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="SabreTools.CommandLine" Version="[1.3.2]" />
<PackageReference Include="SabreTools.RedumpLib" Version="[1.7.4]" />
<PackageReference Include="SabreTools.CommandLine" Version="[1.4.0]" />
<PackageReference Include="SabreTools.RedumpLib" Version="[1.9.1]" />
</ItemGroup>
</Project>

View File

@@ -4,7 +4,6 @@ using System.Collections.Generic;
using System.Threading.Tasks;
#endif
using MPF.CLI.Features;
using MPF.Frontend;
using MPF.Frontend.Features;
using MPF.Frontend.Tools;
using SabreTools.CommandLine;
@@ -20,19 +19,12 @@ namespace MPF.CLI
var options = OptionsLoader.LoadFromConfig();
if (options.FirstRun)
{
// Application paths
options.AaruPath = "FILL ME IN";
options.DiscImageCreatorPath = "FILL ME IN";
options.RedumperPath = "FILL ME IN";
options.InternalProgram = InternalProgram.NONE;
// Reset first run
options.FirstRun = false;
OptionsLoader.SaveToConfig(options);
// Display non-error message
Console.WriteLine("First-run detected! Please fill out config.json and run again.");
BaseFeature.DisplayHelp();
Console.WriteLine("First-run detected! Please verify the generated config.json and run again.");
return;
}
@@ -41,7 +33,7 @@ namespace MPF.CLI
var commandSet = CreateCommands(mainFeature);
// If we have no args, show the help and quit
if (args == null || args.Length == 0)
if (args is null || args.Length == 0)
{
BaseFeature.DisplayHelp();
return;
@@ -58,17 +50,22 @@ namespace MPF.CLI
case Help: BaseFeature.DisplayHelp(); return;
case VersionFeature version: version.Execute(); return;
case ListCodesFeature lc: lc.Execute(); return;
case ListConfigFeature lc: lc.Execute(); return;
case ListMediaTypesFeature lm: lm.Execute(); return;
case ListProgramsFeature lp: lp.Execute(); return;
case ListSystemsFeature ls: ls.Execute(); return;
// Interactive Mode
case InteractiveFeature interactive:
if (interactive.Options.CheckForUpdatesOnStartup)
CheckForUpdates();
if (!interactive.ProcessArgs(args, 0))
{
BaseFeature.DisplayHelp();
return;
}
if (!interactive.Execute())
{
BaseFeature.DisplayHelp();
@@ -79,11 +76,15 @@ namespace MPF.CLI
// Default Behavior
default:
if (mainFeature.Options.CheckForUpdatesOnStartup)
CheckForUpdates();
if (!mainFeature.ProcessArgs(args, 0))
{
BaseFeature.DisplayHelp();
return;
}
if (!mainFeature.Execute())
{
BaseFeature.DisplayHelp();
@@ -94,6 +95,24 @@ namespace MPF.CLI
}
}
/// <summary>
/// Check for available updates
/// </summary>
private static void CheckForUpdates()
{
FrontendTool.CheckForNewVersion(out bool different, out string message, out string? url);
if (url is null)
message = $"An exception occurred while checking for remote versions:{Environment.NewLine}{message}";
Console.WriteLine(message);
if (different && url is not null)
Console.WriteLine($"Update URL: {url}");
else if (!different && url is not null)
Console.WriteLine("You have the newest version!");
Console.WriteLine();
}
/// <summary>
/// Create the command set for the program
/// </summary>
@@ -127,6 +146,7 @@ namespace MPF.CLI
commandSet.Add(new Help());
commandSet.Add(new VersionFeature());
commandSet.Add(new ListCodesFeature());
commandSet.Add(new ListConfigFeature());
commandSet.Add(new ListMediaTypesFeature());
commandSet.Add(new ListSystemsFeature());
commandSet.Add(new ListProgramsFeature());

View File

@@ -40,38 +40,50 @@ namespace MPF.Check.Features
protected BaseFeature(string name, string[] flags, string description, string? detailed = null)
: base(name, flags, description, detailed)
{
Options = new Options()
{
// Internal Program
InternalProgram = InternalProgram.NONE,
Options = new Options();
// Extra Dumping Options
ScanForProtection = false,
AddPlaceholders = true,
PullAllInformation = false,
AddFilenameSuffix = false,
OutputSubmissionJSON = false,
IncludeArtifacts = false,
CompressLogFiles = false,
LogCompression = LogCompression.DeflateMaximum,
DeleteUnnecessaryFiles = false,
CreateIRDAfterDumping = false,
// Internal Program
Options.InternalProgram = InternalProgram.NONE;
// Protection Scanning Options
ScanArchivesForProtection = true,
IncludeDebugProtectionInformation = false,
HideDriveLetters = false,
// Protection Scanning Options
Options.Processing.ProtectionScanning.ScanForProtection = false;
Options.Processing.ProtectionScanning.ScanArchivesForProtection = true;
Options.Processing.ProtectionScanning.IncludeDebugProtectionInformation = false;
Options.Processing.ProtectionScanning.HideDriveLetters = false;
// Redump Login Information
RetrieveMatchInformation = true,
RedumpUsername = null,
RedumpPassword = null,
};
// Redump Login Information
Options.Processing.Login.PullAllInformation = false;
Options.Processing.Login.RedumpUsername = null;
Options.Processing.Login.RedumpPassword = null;
Options.Processing.Login.RetrieveMatchInformation = true;
// Media Information
Options.Processing.MediaInformation.AddPlaceholders = true;
// Post-Information Options
Options.Processing.AddFilenameSuffix = false;
Options.Processing.CreateIRDAfterDumping = false;
Options.Processing.OutputSubmissionJSON = false;
Options.Processing.IncludeArtifacts = false;
Options.Processing.CompressLogFiles = false;
Options.Processing.LogCompression = LogCompression.DeflateMaximum;
Options.Processing.DeleteUnnecessaryFiles = false;
}
/// <inheritdoc/>
public override bool Execute()
{
// Validate a system type is provided
if (System == null)
{
Console.Error.WriteLine("A system name needs to be provided");
return false;
}
// Log the system being used, in case it came from config
Console.WriteLine($"Using system: {System.LongName()}");
// Validate a program is provided
if (Options.InternalProgram == InternalProgram.NONE)
{
Console.Error.WriteLine("A program name needs to be provided");
@@ -79,11 +91,11 @@ namespace MPF.Check.Features
}
// Validate the supplied credentials
if (Options.RetrieveMatchInformation
&& !string.IsNullOrEmpty(Options.RedumpUsername)
&& !string.IsNullOrEmpty(Options.RedumpPassword))
if (Options.Processing.Login.RetrieveMatchInformation
&& !string.IsNullOrEmpty(Options.Processing.Login.RedumpUsername)
&& !string.IsNullOrEmpty(Options.Processing.Login.RedumpPassword))
{
bool? validated = RedumpClient.ValidateCredentials(Options.RedumpUsername!, Options.RedumpPassword!).GetAwaiter().GetResult();
bool? validated = RedumpClient.ValidateCredentials(Options.Processing.Login.RedumpUsername!, Options.Processing.Login.RedumpPassword!).GetAwaiter().GetResult();
string message = validated switch
{
true => "Redump username and password accepted!",
@@ -97,13 +109,6 @@ namespace MPF.Check.Features
// Loop through all the rest of the args
for (int i = 0; i < Inputs.Count; i++)
{
// Check for a file
if (!File.Exists(Inputs[i].Trim('"')))
{
Console.Error.WriteLine($"{Inputs[i].Trim('"')} does not exist");
return false;
}
// Get the full file path
string filepath = Path.GetFullPath(Inputs[i].Trim('"'));
@@ -120,7 +125,7 @@ namespace MPF.Check.Features
env.SetProcessor();
// Finally, attempt to do the output dance
var result = env.VerifyAndSaveDumpOutput(seedInfo: Seed)
var result = env.VerifyAndSaveDumpOutput(processUserInfo: ProcessUserInfo, seedInfo: Seed)
.ConfigureAwait(false).GetAwaiter().GetResult();
Console.WriteLine(result.Message);
}
@@ -135,12 +140,13 @@ namespace MPF.Check.Features
public static void DisplayHelp()
{
Console.WriteLine("Usage:");
Console.WriteLine("MPF.Check <system> [options] </path/to/output.cue/iso> ...");
Console.WriteLine("MPF.Check <system> [options] </path/to/output.cue|iso|_logs.zip> ...");
Console.WriteLine();
Console.WriteLine("Standalone Options:");
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("lo, listconfig List current configuration values");
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");
@@ -166,12 +172,33 @@ namespace MPF.Check.Features
Console.WriteLine("-j, --json Enable submission JSON output");
Console.WriteLine(" --include-artifacts Include artifacts in JSON (requires --json)");
Console.WriteLine("-z, --zip Enable log file compression");
Console.WriteLine(" --log-compression Set the log compression type (requires --zip)");
Console.WriteLine(" --log-compression Set the log compression type (requires compression enabled)");
Console.WriteLine("-d, --delete Enable unnecessary file deletion");
Console.WriteLine();
Console.WriteLine("WARNING: If using a configuration file alongside any of the above options");
Console.WriteLine("then flag options will act as toggles instead of always enabling.");
Console.WriteLine("For example, if log compression is enabled in your configuration file, then");
Console.WriteLine("providing the --zip option would disable compression.");
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>
/// Determines how user information is processed, if at all
/// </summary>
/// <param name="options">Options set that may impact processing</params>
/// <param name="info">Submission info that may be overwritten</param>
/// <returns>True for successful updating, false or null otherwise</returns>
public bool? ProcessUserInfo(Options? options, ref SubmissionInfo? submissionInfo)
{
// TODO: Somehow use the GUI strings here instead of hardcoding English
if (options?.Processing?.ShowDiscEjectReminder == true)
Console.WriteLine("It is now safe to eject the disc");
// TODO: Implement some sort of CLI-based processing of user information
return null;
}
}
}

View File

@@ -38,33 +38,34 @@ namespace MPF.Check.Features
Options = OptionsLoader.LoadFromConfig();
if (Options.FirstRun)
{
Options = new Options()
{
// Internal Program
InternalProgram = InternalProgram.NONE,
Options = new Options();
// Extra Dumping Options
ScanForProtection = false,
AddPlaceholders = true,
PullAllInformation = false,
AddFilenameSuffix = false,
OutputSubmissionJSON = false,
IncludeArtifacts = false,
CompressLogFiles = false,
LogCompression = LogCompression.DeflateMaximum,
DeleteUnnecessaryFiles = false,
CreateIRDAfterDumping = false,
// Internal Program
Options.InternalProgram = InternalProgram.NONE;
// Protection Scanning Options
ScanArchivesForProtection = true,
IncludeDebugProtectionInformation = false,
HideDriveLetters = false,
// Protection Scanning Options
Options.Processing.ProtectionScanning.ScanForProtection = false;
Options.Processing.ProtectionScanning.ScanArchivesForProtection = true;
Options.Processing.ProtectionScanning.IncludeDebugProtectionInformation = false;
Options.Processing.ProtectionScanning.HideDriveLetters = false;
// Redump Login Information
RetrieveMatchInformation = true,
RedumpUsername = null,
RedumpPassword = null,
};
// Redump Login Information
Options.Processing.Login.PullAllInformation = false;
Options.Processing.Login.RedumpUsername = null;
Options.Processing.Login.RedumpPassword = null;
Options.Processing.Login.RetrieveMatchInformation = true;
// Media Information
Options.Processing.MediaInformation.AddPlaceholders = true;
// Post-Information Options
Options.Processing.AddFilenameSuffix = false;
Options.Processing.CreateIRDAfterDumping = false;
Options.Processing.OutputSubmissionJSON = false;
Options.Processing.IncludeArtifacts = false;
Options.Processing.CompressLogFiles = false;
Options.Processing.LogCompression = LogCompression.DeflateMaximum;
Options.Processing.DeleteUnnecessaryFiles = false;
}
// Create return values
@@ -77,7 +78,7 @@ namespace MPF.Check.Features
hideDriveLetters = false;
// Create state values
string? result = string.Empty;
string? result;
root:
Console.Clear();
@@ -87,22 +88,22 @@ namespace MPF.Check.Features
Console.WriteLine($"1) Set system (Currently '{System}')");
Console.WriteLine($"2) Set dumping program (Currently '{Options.InternalProgram}')");
Console.WriteLine($"3) Set seed path (Currently '{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($"4) Add placeholders (Currently '{Options.Processing.MediaInformation.AddPlaceholders}')");
Console.WriteLine($"5) Create IRD (Currently '{Options.Processing.CreateIRDAfterDumping}')");
Console.WriteLine($"6) Attempt Redump matches (Currently '{Options.Processing.Login.RetrieveMatchInformation}')");
Console.WriteLine($"7) Redump credentials (Currently '{Options.Processing.Login.RedumpUsername}')");
Console.WriteLine($"8) Pull all information (Currently '{Options.Processing.Login.PullAllInformation}')");
Console.WriteLine($"9) Set device path (Currently '{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) Log compression (Currently '{Options.LogCompression.LongName()}')");
Console.WriteLine($"J) Delete unnecessary files (Currently '{Options.DeleteUnnecessaryFiles}')");
Console.WriteLine($"E) Hide filename suffix (Currently '{Options.Processing.AddFilenameSuffix}')");
Console.WriteLine($"F) Output submission JSON (Currently '{Options.Processing.OutputSubmissionJSON}')");
Console.WriteLine($"G) Include JSON artifacts (Currently '{Options.Processing.IncludeArtifacts}')");
Console.WriteLine($"H) Compress logs (Currently '{Options.Processing.CompressLogFiles}')");
Console.WriteLine($"I) Log compression (Currently '{Options.Processing.LogCompression.LongName()}')");
Console.WriteLine($"J) Delete unnecessary files (Currently '{Options.Processing.DeleteUnnecessaryFiles}')");
Console.WriteLine();
Console.WriteLine($"Q) Exit the program");
Console.WriteLine($"X) Start checking");
@@ -118,18 +119,18 @@ namespace MPF.Check.Features
case "3":
goto seedPath;
case "4":
Options.AddPlaceholders = !Options.AddPlaceholders;
Options.Processing.MediaInformation.AddPlaceholders = !Options.Processing.MediaInformation.AddPlaceholders;
goto root;
case "5":
Options.CreateIRDAfterDumping = !Options.CreateIRDAfterDumping;
Options.Processing.CreateIRDAfterDumping = !Options.Processing.CreateIRDAfterDumping;
goto root;
case "6":
Options.RetrieveMatchInformation = !Options.RetrieveMatchInformation;
Options.Processing.Login.RetrieveMatchInformation = !Options.Processing.Login.RetrieveMatchInformation;
goto root;
case "7":
goto redumpCredentials;
case "8":
Options.PullAllInformation = !Options.PullAllInformation;
Options.Processing.Login.PullAllInformation = !Options.Processing.Login.PullAllInformation;
goto root;
case "9":
goto devicePath;
@@ -151,26 +152,26 @@ namespace MPF.Check.Features
goto root;
case "e":
case "E":
Options.AddFilenameSuffix = !Options.AddFilenameSuffix;
Options.Processing.AddFilenameSuffix = !Options.Processing.AddFilenameSuffix;
goto root;
case "f":
case "F":
Options.OutputSubmissionJSON = !Options.OutputSubmissionJSON;
Options.Processing.OutputSubmissionJSON = !Options.Processing.OutputSubmissionJSON;
goto root;
case "g":
case "G":
Options.IncludeArtifacts = !Options.IncludeArtifacts;
Options.Processing.IncludeArtifacts = !Options.Processing.IncludeArtifacts;
goto root;
case "h":
case "H":
Options.CompressLogFiles = !Options.CompressLogFiles;
Options.Processing.CompressLogFiles = !Options.Processing.CompressLogFiles;
goto root;
case "i":
case "I":
goto logCompression;
case "j":
case "J":
Options.DeleteUnnecessaryFiles = !Options.DeleteUnnecessaryFiles;
Options.Processing.DeleteUnnecessaryFiles = !Options.Processing.DeleteUnnecessaryFiles;
goto root;
case "q":
@@ -212,7 +213,7 @@ namespace MPF.Check.Features
if (program == InternalProgram.NONE)
continue;
Console.WriteLine($"{program.ToString().ToLowerInvariant().PadRight(15)} => {program.LongName()}");
Console.WriteLine($"{program.ToString().ToLowerInvariant(),-15} => {program.LongName()}");
}
Console.WriteLine();
@@ -234,18 +235,18 @@ namespace MPF.Check.Features
Console.WriteLine();
Console.WriteLine("Enter your Redump username and press Enter:");
Console.Write("> ");
Options.RedumpUsername = Console.ReadLine();
Options.Processing.Login.RedumpUsername = Console.ReadLine();
Console.WriteLine("Enter your Redump password (hidden) and press Enter:");
Console.Write("> ");
Options.RedumpPassword = string.Empty;
Options.Processing.Login.RedumpPassword = string.Empty;
while (true)
{
var key = Console.ReadKey(true);
if (key.Key == ConsoleKey.Enter)
break;
Options.RedumpPassword += key.KeyChar;
Options.Processing.Login.RedumpPassword += key.KeyChar;
}
goto root;
@@ -262,22 +263,22 @@ namespace MPF.Check.Features
Console.WriteLine("Options:");
foreach (var compressionType in (LogCompression[])Enum.GetValues(typeof(LogCompression)))
{
Console.WriteLine($"{compressionType.ToString().ToLowerInvariant().PadRight(15)} => {compressionType.LongName()}");
Console.WriteLine($"{compressionType.ToString().ToLowerInvariant(),-15} => {compressionType.LongName()}");
}
Console.WriteLine();
Console.WriteLine("Input the log compression type and press Enter:");
Console.Write("> ");
result = Console.ReadLine();
Options.LogCompression = result.ToLogCompression();
Options.Processing.LogCompression = result.ToLogCompression();
goto root;
exit:
// Now deal with the complex options
Options.ScanForProtection = scan && !string.IsNullOrEmpty(DevicePath);
Options.ScanArchivesForProtection = enableArchives && scan && !string.IsNullOrEmpty(DevicePath);
Options.IncludeDebugProtectionInformation = enableDebug && scan && !string.IsNullOrEmpty(DevicePath);
Options.HideDriveLetters = hideDriveLetters && scan && !string.IsNullOrEmpty(DevicePath);
Options.Processing.ProtectionScanning.ScanForProtection = scan && !string.IsNullOrEmpty(DevicePath);
Options.Processing.ProtectionScanning.ScanArchivesForProtection = enableArchives && scan && !string.IsNullOrEmpty(DevicePath);
Options.Processing.ProtectionScanning.IncludeDebugProtectionInformation = enableDebug && scan && !string.IsNullOrEmpty(DevicePath);
Options.Processing.ProtectionScanning.HideDriveLetters = hideDriveLetters && scan && !string.IsNullOrEmpty(DevicePath);
return true;
}

View File

@@ -1,3 +1,4 @@
using System;
using MPF.Frontend;
using MPF.Frontend.Tools;
using SabreTools.CommandLine.Inputs;
@@ -48,7 +49,7 @@ namespace MPF.Check.Features
internal readonly StringInput LoadSeedInput = new(_loadSeedName, "--load-seed", "Load a seed submission JSON for user information");
private const string _logCompressionName = "log-compression";
internal readonly StringInput LogCompressionInput = new(_logCompressionName, "--log-compression", "Set the log compression type (requires --zip)");
internal readonly StringInput LogCompressionInput = new(_logCompressionName, "--log-compression", "Set the log compression type (requires compression enabled)");
private const string _noPlaceholdersName = "no-placeholders";
internal readonly FlagInput NoPlaceholdersInput = new(_noPlaceholdersName, "--no-placeholders", "Disable placeholder values in submission info");
@@ -115,40 +116,45 @@ namespace MPF.Check.Features
hideDriveLetters = false;
// If we have no arguments, just return
if (args == null || args.Length == 0)
if (args is null || args.Length == 0)
return true;
// Read the options from config, if possible
Options = OptionsLoader.LoadFromConfig();
if (Options.FirstRun)
{
Options = new Options()
{
// Internal Program
InternalProgram = InternalProgram.NONE,
Options = new Options();
// Extra Dumping Options
ScanForProtection = false,
AddPlaceholders = true,
PullAllInformation = false,
AddFilenameSuffix = false,
OutputSubmissionJSON = false,
IncludeArtifacts = false,
CompressLogFiles = false,
LogCompression = LogCompression.DeflateMaximum,
DeleteUnnecessaryFiles = false,
CreateIRDAfterDumping = false,
// Internal Program
Options.InternalProgram = InternalProgram.NONE;
// Protection Scanning Options
ScanArchivesForProtection = true,
IncludeDebugProtectionInformation = false,
HideDriveLetters = false,
// Protection Scanning Options
Options.Processing.ProtectionScanning.ScanForProtection = false;
Options.Processing.ProtectionScanning.ScanArchivesForProtection = true;
Options.Processing.ProtectionScanning.IncludeDebugProtectionInformation = false;
Options.Processing.ProtectionScanning.HideDriveLetters = false;
// Redump Login Information
RetrieveMatchInformation = true,
RedumpUsername = null,
RedumpPassword = null,
};
// Redump Login Information
Options.Processing.Login.PullAllInformation = false;
Options.Processing.Login.RedumpUsername = null;
Options.Processing.Login.RedumpPassword = null;
Options.Processing.Login.RetrieveMatchInformation = true;
// Media Information
Options.Processing.MediaInformation.AddPlaceholders = true;
// Post-Information Options
Options.Processing.AddFilenameSuffix = false;
Options.Processing.CreateIRDAfterDumping = false;
Options.Processing.OutputSubmissionJSON = false;
Options.Processing.IncludeArtifacts = false;
Options.Processing.CompressLogFiles = false;
Options.Processing.LogCompression = LogCompression.DeflateMaximum;
Options.Processing.DeleteUnnecessaryFiles = false;
}
else
{
Console.WriteLine("Options will be loaded from found configuration file!");
}
// The first argument is the system type
@@ -167,45 +173,45 @@ namespace MPF.Check.Features
// Disable placeholder values in submission info
else if (NoPlaceholdersInput.ProcessInput(args, ref index))
Options.AddPlaceholders = false;
Options.Processing.MediaInformation.AddPlaceholders = !Options.Processing.MediaInformation.AddPlaceholders;
// Create IRD from output files (PS3 only)
else if (CreateIrdInput.ProcessInput(args, ref index))
Options.CreateIRDAfterDumping = true;
Options.Processing.CreateIRDAfterDumping = !Options.Processing.CreateIRDAfterDumping;
// Set the log compression type (requires --zip)
// Set the log compression type (requires compression enabled)
else if (LogCompressionInput.ProcessInput(args, ref index))
Options.LogCompression = LogCompressionInput.Value.ToLogCompression();
Options.Processing.LogCompression = LogCompressionInput.Value.ToLogCompression();
// Retrieve Redump match information
else if (NoRetrieveInput.ProcessInput(args, ref index))
Options.RetrieveMatchInformation = false;
Options.Processing.Login.RetrieveMatchInformation = !Options.Processing.Login.RetrieveMatchInformation;
// Redump login
else if (args[index].StartsWith("-c=") || args[index].StartsWith("--credentials="))
{
string[] credentials = args[index].Split('=')[1].Split(';');
Options.RedumpUsername = credentials[0];
Options.RedumpPassword = credentials[1];
Options.Processing.Login.RedumpUsername = credentials[0];
Options.Processing.Login.RedumpPassword = credentials[1];
}
else if (args[index] == "-c" || args[index] == "--credentials")
{
Options.RedumpUsername = args[index + 1];
Options.RedumpPassword = args[index + 2];
Options.Processing.Login.RedumpUsername = args[index + 1];
Options.Processing.Login.RedumpPassword = args[index + 2];
index += 2;
}
// Redump username
else if (UsernameInput.ProcessInput(args, ref index))
Options.RedumpUsername = UsernameInput.Value;
Options.Processing.Login.RedumpUsername = UsernameInput.Value;
// Redump password
else if (PasswordInput.ProcessInput(args, ref index))
Options.RedumpPassword = PasswordInput.Value;
Options.Processing.Login.RedumpPassword = PasswordInput.Value;
// Pull all information (requires Redump login)
else if (PullAllInput.ProcessInput(args, ref index))
Options.PullAllInformation = true;
Options.Processing.Login.PullAllInformation = !Options.Processing.Login.PullAllInformation;
// Use a device path for physical checks
else if (PathInput.ProcessInput(args, ref index))
@@ -229,23 +235,23 @@ namespace MPF.Check.Features
// Add filename suffix
else if (SuffixInput.ProcessInput(args, ref index))
Options.AddFilenameSuffix = true;
Options.Processing.AddFilenameSuffix = !Options.Processing.AddFilenameSuffix;
// Output submission JSON
else if (JsonInput.ProcessInput(args, ref index))
Options.OutputSubmissionJSON = true;
Options.Processing.OutputSubmissionJSON = !Options.Processing.OutputSubmissionJSON;
// Include JSON artifacts
else if (IncludeArtifactsInput.ProcessInput(args, ref index))
Options.IncludeArtifacts = true;
Options.Processing.IncludeArtifacts = !Options.Processing.IncludeArtifacts;
// Compress log and extraneous files
else if (ZipInput.ProcessInput(args, ref index))
Options.CompressLogFiles = true;
Options.Processing.CompressLogFiles = !Options.Processing.CompressLogFiles;
// Delete unnecessary files
else if (DeleteInput.ProcessInput(args, ref index))
Options.DeleteUnnecessaryFiles = true;
Options.Processing.DeleteUnnecessaryFiles = !Options.Processing.DeleteUnnecessaryFiles;
// Default, add to inputs
else
@@ -253,10 +259,10 @@ namespace MPF.Check.Features
}
// Now deal with the complex options
Options.ScanForProtection = scan && !string.IsNullOrEmpty(DevicePath);
Options.ScanArchivesForProtection = enableArchives && scan && !string.IsNullOrEmpty(DevicePath);
Options.IncludeDebugProtectionInformation = enableDebug && scan && !string.IsNullOrEmpty(DevicePath);
Options.HideDriveLetters = hideDriveLetters && scan && !string.IsNullOrEmpty(DevicePath);
Options.Processing.ProtectionScanning.ScanForProtection = scan && !string.IsNullOrEmpty(DevicePath);
Options.Processing.ProtectionScanning.ScanArchivesForProtection = enableArchives && scan && !string.IsNullOrEmpty(DevicePath);
Options.Processing.ProtectionScanning.IncludeDebugProtectionInformation = enableDebug && scan && !string.IsNullOrEmpty(DevicePath);
Options.Processing.ProtectionScanning.HideDriveLetters = hideDriveLetters && scan && !string.IsNullOrEmpty(DevicePath);
return true;
}

View File

@@ -2,7 +2,7 @@
<PropertyGroup>
<!-- Assembly Properties -->
<TargetFrameworks>net20;net35;net40;net452;net462;net472;net48;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0;net9.0</TargetFrameworks>
<TargetFrameworks>net20;net35;net40;net452;net462;net472;net48;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0;net9.0;net10.0</TargetFrameworks>
<OutputType>Exe</OutputType>
<CheckEolTargetFramework>false</CheckEolTargetFramework>
<IncludeNativeLibrariesForSelfExtract>true</IncludeNativeLibrariesForSelfExtract>
@@ -12,7 +12,7 @@
<Nullable>enable</Nullable>
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<VersionPrefix>3.5.0</VersionPrefix>
<VersionPrefix>3.6.0</VersionPrefix>
<!-- Package Properties -->
<Title>MPF Check</Title>
@@ -31,11 +31,11 @@
<PropertyGroup Condition="$(TargetFramework.StartsWith(`netcoreapp`)) OR $(TargetFramework.StartsWith(`net5`))">
<RuntimeIdentifiers>win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64</RuntimeIdentifiers>
</PropertyGroup>
<PropertyGroup Condition="$(TargetFramework.StartsWith(`net6`)) OR $(TargetFramework.StartsWith(`net7`)) OR $(TargetFramework.StartsWith(`net8`)) OR $(TargetFramework.StartsWith(`net9`))">
<PropertyGroup Condition="$(TargetFramework.StartsWith(`net6`)) OR $(TargetFramework.StartsWith(`net7`)) OR $(TargetFramework.StartsWith(`net8`)) OR $(TargetFramework.StartsWith(`net9`)) OR $(TargetFramework.StartsWith(`net10`))">
<RuntimeIdentifiers>win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64;osx-arm64</RuntimeIdentifiers>
</PropertyGroup>
<PropertyGroup Condition="$(RuntimeIdentifier.StartsWith(`osx-arm`))">
<TargetFrameworks>net6.0;net7.0;net8.0;net9.0</TargetFrameworks>
<TargetFrameworks>net6.0;net7.0;net8.0;net9.0;net10.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
@@ -43,8 +43,8 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="SabreTools.CommandLine" Version="[1.3.2]" />
<PackageReference Include="SabreTools.RedumpLib" Version="[1.7.4]" />
<PackageReference Include="SabreTools.CommandLine" Version="[1.4.0]" />
<PackageReference Include="SabreTools.RedumpLib" Version="[1.9.1]" />
</ItemGroup>
</Project>

View File

@@ -5,6 +5,7 @@ using System.Threading.Tasks;
#endif
using MPF.Check.Features;
using MPF.Frontend.Features;
using MPF.Frontend.Tools;
using SabreTools.CommandLine;
using SabreTools.CommandLine.Features;
@@ -19,7 +20,7 @@ namespace MPF.Check
var commandSet = CreateCommands(mainFeature);
// If we have no args, show the help and quit
if (args == null || args.Length == 0)
if (args is null || args.Length == 0)
{
BaseFeature.DisplayHelp();
return;
@@ -36,23 +37,29 @@ namespace MPF.Check
case Help: BaseFeature.DisplayHelp(); return;
case VersionFeature version: version.Execute(); return;
case ListCodesFeature lc: lc.Execute(); return;
case ListConfigFeature lc: lc.Execute(); return;
case ListMediaTypesFeature lm: lm.Execute(); return;
case ListProgramsFeature lp: lp.Execute(); return;
case ListSystemsFeature ls: ls.Execute(); return;
// Interactive Mode
case InteractiveFeature interactive:
if (interactive.Options.CheckForUpdatesOnStartup)
CheckForUpdates();
if (!interactive.ProcessArgs(args, 0))
{
BaseFeature.DisplayHelp();
return;
}
if (!interactive.VerifyInputs())
{
Console.Error.WriteLine("At least one input is required");
BaseFeature.DisplayHelp();
return;
}
if (!interactive.Execute())
{
BaseFeature.DisplayHelp();
@@ -63,17 +70,22 @@ namespace MPF.Check
// Default Behavior
default:
if (mainFeature.Options.CheckForUpdatesOnStartup)
CheckForUpdates();
if (!mainFeature.ProcessArgs(args, 0))
{
BaseFeature.DisplayHelp();
return;
}
if (!mainFeature.VerifyInputs())
{
Console.Error.WriteLine("At least one input is required");
BaseFeature.DisplayHelp();
return;
}
if (!mainFeature.Execute())
{
BaseFeature.DisplayHelp();
@@ -84,6 +96,24 @@ namespace MPF.Check
}
}
/// <summary>
/// Check for available updates
/// </summary>
private static void CheckForUpdates()
{
FrontendTool.CheckForNewVersion(out bool different, out string message, out string? url);
if (url is null)
message = $"An exception occurred while checking for remote versions:{Environment.NewLine}{message}";
Console.WriteLine(message);
if (different && url is not null)
Console.WriteLine($"Update URL: {url}");
else if (!different && url is not null)
Console.WriteLine("You have the newest version!");
Console.WriteLine();
}
/// <summary>
/// Create the command set for the program
/// </summary>
@@ -107,6 +137,7 @@ namespace MPF.Check
commandSet.Add(new Help());
commandSet.Add(new VersionFeature());
commandSet.Add(new ListCodesFeature());
commandSet.Add(new ListConfigFeature());
commandSet.Add(new ListMediaTypesFeature());
commandSet.Add(new ListSystemsFeature());
commandSet.Add(new ListProgramsFeature());

View File

@@ -1,4 +1,3 @@
using System.Collections.Generic;
using MPF.ExecutionContexts.Aaru;
using SabreTools.RedumpLib.Data;
using Xunit;
@@ -29,13 +28,13 @@ namespace MPF.ExecutionContexts.Test
#region Default Values
private static Dictionary<string, string?> AllOptions = new()
private static readonly BaseDumpSettings AllOptions = new DumpSettings()
{
[SettingConstants.EnableDebug] = "true",
[SettingConstants.EnableVerbose] = "true",
[SettingConstants.ForceDumping] = "true",
[SettingConstants.RereadCount] = "1000",
[SettingConstants.StripPersonalData] = "true",
EnableDebug = true,
EnableVerbose = true,
ForceDumping = true,
RereadCount = 1000,
StripPersonalData = true,
};
[Theory]
@@ -514,4 +513,4 @@ namespace MPF.ExecutionContexts.Test
#endregion
}
}
}

View File

@@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Xunit;
@@ -7,193 +6,6 @@ namespace MPF.ExecutionContexts.Test
{
public class BaseExecutionContextTests
{
#region GetBooleanSetting
[Fact]
public void GetBooleanSetting_InvalidDict_Default()
{
Dictionary<string, string?> settings = [];
string key = "key";
bool defaultValue = false;
bool actual = BaseExecutionContext.GetBooleanSetting(settings, key, defaultValue);
Assert.False(actual);
}
[Fact]
public void GetBooleanSetting_InvalidKey_Default()
{
Dictionary<string, string?> settings = new()
{
["key2"] = "true",
};
string key = "key";
bool defaultValue = false;
bool actual = BaseExecutionContext.GetBooleanSetting(settings, key, defaultValue);
Assert.False(actual);
}
[Fact]
public void GetBooleanSetting_NullValue_Default()
{
Dictionary<string, string?> settings = new()
{
["key"] = null,
};
string key = "key";
bool defaultValue = false;
bool actual = BaseExecutionContext.GetBooleanSetting(settings, key, defaultValue);
Assert.False(actual);
}
[Fact]
public void GetBooleanSetting_InvalidValue_Default()
{
Dictionary<string, string?> settings = new()
{
["key"] = "invalid",
};
string key = "key";
bool defaultValue = false;
bool actual = BaseExecutionContext.GetBooleanSetting(settings, key, defaultValue);
Assert.False(actual);
}
[Fact]
public void GetBooleanSetting_ValidValue_Parsed()
{
Dictionary<string, string?> settings = new()
{
["key"] = "true",
};
string key = "key";
bool defaultValue = false;
bool actual = BaseExecutionContext.GetBooleanSetting(settings, key, defaultValue);
Assert.True(actual);
}
#endregion
#region GetInt32Setting
[Fact]
public void GetInt32Setting_InvalidDict_Default()
{
Dictionary<string, string?> settings = [];
string key = "key";
int defaultValue = -1;
int actual = BaseExecutionContext.GetInt32Setting(settings, key, defaultValue);
Assert.Equal(-1, actual);
}
[Fact]
public void GetInt32Setting_InvalidKey_Default()
{
Dictionary<string, string?> settings = new()
{
["key2"] = "12345",
};
string key = "key";
int defaultValue = -1;
int actual = BaseExecutionContext.GetInt32Setting(settings, key, defaultValue);
Assert.Equal(-1, actual);
}
[Fact]
public void GetInt32Setting_NullValue_Default()
{
Dictionary<string, string?> settings = new()
{
["key"] = null,
};
string key = "key";
int defaultValue = -1;
int actual = BaseExecutionContext.GetInt32Setting(settings, key, defaultValue);
Assert.Equal(-1, actual);
}
[Fact]
public void GetInt32Setting_InvalidValue_Default()
{
Dictionary<string, string?> settings = new()
{
["key"] = "invalid",
};
string key = "key";
int defaultValue = -1;
int actual = BaseExecutionContext.GetInt32Setting(settings, key, defaultValue);
Assert.Equal(-1, actual);
}
[Fact]
public void GetInt32Setting_ValidValue_Parsed()
{
int expected = 12345;
Dictionary<string, string?> settings = new()
{
["key"] = "12345",
};
string key = "key";
int defaultValue = -1;
int actual = BaseExecutionContext.GetInt32Setting(settings, key, defaultValue);
Assert.Equal(expected, actual);
}
#endregion
#region GetStringSetting
[Fact]
public void GetStringSetting_InvalidDict_Default()
{
Dictionary<string, string?> settings = [];
string key = "key";
string? defaultValue = null;
string? actual = BaseExecutionContext.GetStringSetting(settings, key, defaultValue);
Assert.Null(actual);
}
[Fact]
public void GetStringSetting_InvalidKey_Default()
{
Dictionary<string, string?> settings = new()
{
["key2"] = "12345",
};
string key = "key";
string? defaultValue = null;
string? actual = BaseExecutionContext.GetStringSetting(settings, key, defaultValue);
Assert.Null(actual);
}
[Fact]
public void GetStringSetting_ValidValue_Rturned()
{
string expected = "expected";
Dictionary<string, string?> settings = new()
{
["key"] = "expected",
};
string key = "key";
string? defaultValue = null;
string? actual = BaseExecutionContext.GetStringSetting(settings, key, defaultValue);
Assert.Equal(expected, actual);
}
#endregion
#region SplitParameterString
[Fact]
@@ -461,4 +273,4 @@ namespace MPF.ExecutionContexts.Test
#endregion
}
}
}

View File

@@ -1,5 +1,4 @@
using System.Collections.Generic;
using MPF.ExecutionContexts.DiscImageCreator;
using MPF.ExecutionContexts.DiscImageCreator;
using SabreTools.RedumpLib.Data;
using Xunit;
@@ -42,15 +41,15 @@ namespace MPF.ExecutionContexts.Test
#region Default Values
private static Dictionary<string, string?> AllOptions = new()
private static readonly BaseDumpSettings AllOptions = new DumpSettings()
{
[SettingConstants.DVDRereadCount] = "1000",
[SettingConstants.MultiSectorRead] = "true",
[SettingConstants.MultiSectorReadValue] = "1000",
[SettingConstants.ParanoidMode] = "true",
[SettingConstants.QuietMode] = "true",
[SettingConstants.RereadCount] = "1000",
[SettingConstants.UseCMIFlag] = "true",
DVDRereadCount = 1000,
MultiSectorRead = true,
MultiSectorReadValue = 1000,
ParanoidMode = true,
QuietMode = true,
RereadCount = 1000,
UseCMIFlag = true,
};
[Theory]
@@ -102,6 +101,21 @@ namespace MPF.ExecutionContexts.Test
#endregion
#region AuthPS3
[Theory]
[InlineData("authps3 f")]
public void AuthPS3Test(string parameters)
{
string? expected = "authps3 f";
var context = new ExecutionContext(parameters);
string? actual = context.GenerateParameters();
Assert.Equal(expected, actual);
Assert.False(context.IsDumpingCommand());
}
#endregion
#region BluRay
[Theory]

View File

@@ -0,0 +1,67 @@
using MPF.ExecutionContexts.Dreamdump;
using SabreTools.RedumpLib.Data;
using Xunit;
namespace MPF.ExecutionContexts.Test
{
public class DreamdumpTests
{
#region Default Values
private static readonly BaseDumpSettings AllOptions = new DumpSettings()
{
RereadCount = 50,
SectorOrder = SectorOrder.DATA_C2_SUB,
};
// None of these scenarios are actually supported as all are treated like GD-ROM
[Theory]
[InlineData(null, null, null, "filename.bin", null, "--retries=50 --image-name=\"filename\" --sector-order=DATA_C2_SUB")]
[InlineData(RedumpSystem.IBMPCcompatible, MediaType.CDROM, "/dev/sr0", "path/filename.bin", 2, "--retries=50 --image-name=\"filename\" --image-path=\"path\" --speed=2 --sector-order=DATA_C2_SUB --drive=/dev/sr0")]
[InlineData(RedumpSystem.IBMPCcompatible, MediaType.DVD, "/dev/sr0", "path/filename.bin", 2, "--retries=50 --image-name=\"filename\" --image-path=\"path\" --speed=2 --sector-order=DATA_C2_SUB --drive=/dev/sr0")]
[InlineData(RedumpSystem.NintendoGameCube, MediaType.NintendoGameCubeGameDisc, "/dev/sr0", "path/filename.bin", 2, "--retries=50 --image-name=\"filename\" --image-path=\"path\" --speed=2 --sector-order=DATA_C2_SUB --drive=/dev/sr0")]
[InlineData(RedumpSystem.NintendoWii, MediaType.NintendoWiiOpticalDisc, "/dev/sr0", "path/filename.bin", 2, "--retries=50 --image-name=\"filename\" --image-path=\"path\" --speed=2 --sector-order=DATA_C2_SUB --drive=/dev/sr0")]
[InlineData(RedumpSystem.HDDVDVideo, MediaType.HDDVD, "/dev/sr0", "path/filename.bin", 2, "--retries=50 --image-name=\"filename\" --image-path=\"path\" --speed=2 --sector-order=DATA_C2_SUB --drive=/dev/sr0")]
[InlineData(RedumpSystem.BDVideo, MediaType.BluRay, "/dev/sr0", "path/filename.bin", 2, "--retries=50 --image-name=\"filename\" --image-path=\"path\" --speed=2 --sector-order=DATA_C2_SUB --drive=/dev/sr0")]
[InlineData(RedumpSystem.NintendoWiiU, MediaType.NintendoWiiUOpticalDisc, "/dev/sr0", "path/filename.bin", 2, "--retries=50 --image-name=\"filename\" --image-path=\"path\" --speed=2 --sector-order=DATA_C2_SUB --drive=/dev/sr0")]
public void DefaultValueTest(RedumpSystem? system,
MediaType? type,
string? drivePath,
string filename,
int? driveSpeed,
string? expected)
{
var context = new ExecutionContext(system, type, drivePath, filename, driveSpeed, AllOptions);
string? actual = context.GenerateParameters();
Assert.Equal(expected, actual);
}
#endregion
#region Default
[Theory]
[InlineData("--force-qtoc --train --retries=50 --image-name=image --image-path=path --read-offset=0 --read-at-once=0 --speed=8 --sector-order=so --drive=/dev/sr0")]
public void DiscTest(string parameters)
{
string? expected = "--force-qtoc --train --retries=50 --image-name=\"image\" --image-path=\"path\" --read-offset=0 --read-at-once=0 --speed=8 --sector-order=so --drive=/dev/sr0";
var context = new ExecutionContext(parameters);
string? actual = context.GenerateParameters();
Assert.Equal(expected, actual);
Assert.True(context.IsDumpingCommand());
}
[Theory]
[InlineData("--image-name=\"image name.bin\" --image-path=\"directory name\"")]
public void SpacesTest(string parameters)
{
string? expected = "--image-name=\"image name.bin\" --image-path=\"directory name\"";
var context = new ExecutionContext(parameters);
string? actual = context.GenerateParameters();
Assert.Equal(expected, actual);
Assert.True(context.IsDumpingCommand());
}
#endregion
}
}

View File

@@ -20,7 +20,7 @@ namespace MPF.ExecutionContexts.Test
[InlineData("flag", new string[] { "flag" }, 0, true, true)]
public void FlagInputTest(string name, string[] parts, int index, bool success, bool expected)
{
FlagInput input = new FlagInput(name);
var input = new FlagInput(name);
bool actual = input.Process(parts, ref index);
Assert.Equal(success, actual);
@@ -55,7 +55,7 @@ namespace MPF.ExecutionContexts.Test
[InlineData("flag", true, new string[] { "flag=false" }, 0, true, false)]
public void BooleanInputTest(string name, bool required, string[] parts, int index, bool success, bool? expected)
{
BooleanInput input = new BooleanInput(name, required);
var input = new BooleanInput(name, required);
bool actual = input.Process(parts, ref index);
Assert.Equal(success, actual);
@@ -90,7 +90,7 @@ namespace MPF.ExecutionContexts.Test
[InlineData("flag", true, new string[] { "flag=-1" }, 0, true, (sbyte)-1)]
public void Int8InputTest(string name, bool required, string[] parts, int index, bool success, sbyte? expected)
{
Int8Input input = new Int8Input(name, required);
var input = new Int8Input(name, required);
bool actual = input.Process(parts, ref index);
Assert.Equal(success, actual);
@@ -123,7 +123,7 @@ namespace MPF.ExecutionContexts.Test
[InlineData("flag", true, new string[] { "flag=1" }, 0, true, (byte)1)]
public void UInt8InputTest(string name, bool required, string[] parts, int index, bool success, byte? expected)
{
UInt8Input input = new UInt8Input(name, required);
var input = new UInt8Input(name, required);
bool actual = input.Process(parts, ref index);
Assert.Equal(success, actual);
@@ -158,7 +158,7 @@ namespace MPF.ExecutionContexts.Test
[InlineData("flag", true, new string[] { "flag=-1" }, 0, true, (short)-1)]
public void Int16InputTest(string name, bool required, string[] parts, int index, bool success, short? expected)
{
Int16Input input = new Int16Input(name, required);
var input = new Int16Input(name, required);
bool actual = input.Process(parts, ref index);
Assert.Equal(success, actual);
@@ -191,7 +191,7 @@ namespace MPF.ExecutionContexts.Test
[InlineData("flag", true, new string[] { "flag=1" }, 0, true, (ushort)1)]
public void UInt16InputTest(string name, bool required, string[] parts, int index, bool success, ushort? expected)
{
UInt16Input input = new UInt16Input(name, required);
var input = new UInt16Input(name, required);
bool actual = input.Process(parts, ref index);
Assert.Equal(success, actual);
@@ -226,7 +226,7 @@ namespace MPF.ExecutionContexts.Test
[InlineData("flag", true, new string[] { "flag=-1" }, 0, true, (int)-1)]
public void Int32InputTest(string name, bool required, string[] parts, int index, bool success, int? expected)
{
Int32Input input = new Int32Input(name, required);
var input = new Int32Input(name, required);
bool actual = input.Process(parts, ref index);
Assert.Equal(success, actual);
@@ -259,7 +259,7 @@ namespace MPF.ExecutionContexts.Test
[InlineData("flag", true, new string[] { "flag=1" }, 0, true, (uint)1)]
public void UInt32InputTest(string name, bool required, string[] parts, int index, bool success, uint? expected)
{
UInt32Input input = new UInt32Input(name, required);
var input = new UInt32Input(name, required);
bool actual = input.Process(parts, ref index);
Assert.Equal(success, actual);
@@ -294,7 +294,7 @@ namespace MPF.ExecutionContexts.Test
[InlineData("flag", true, new string[] { "flag=-1" }, 0, true, (long)-1)]
public void Int64InputTest(string name, bool required, string[] parts, int index, bool success, long? expected)
{
Int64Input input = new Int64Input(name, required);
var input = new Int64Input(name, required);
bool actual = input.Process(parts, ref index);
Assert.Equal(success, actual);
@@ -327,7 +327,7 @@ namespace MPF.ExecutionContexts.Test
[InlineData("flag", true, new string[] { "flag=1" }, 0, true, (ulong)1)]
public void UInt64InputTest(string name, bool required, string[] parts, int index, bool success, ulong? expected)
{
UInt64Input input = new UInt64Input(name, required);
var input = new UInt64Input(name, required);
bool actual = input.Process(parts, ref index);
Assert.Equal(success, actual);
@@ -355,7 +355,7 @@ namespace MPF.ExecutionContexts.Test
[InlineData("flag", true, new string[] { "flag=value" }, 0, true, "value")]
public void StringInputTest(string name, bool required, string[] parts, int index, bool success, string? expected)
{
StringInput input = new StringInput(name, required);
var input = new StringInput(name, required);
bool actual = input.Process(parts, ref index);
Assert.Equal(success, actual);
@@ -407,4 +407,4 @@ namespace MPF.ExecutionContexts.Test
#endregion
}
}
}

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net8.0;net9.0</TargetFrameworks>
<TargetFrameworks>net8.0;net9.0;net10.0</TargetFrameworks>
<CheckEolTargetFramework>false</CheckEolTargetFramework>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
@@ -14,13 +14,13 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeCoverage" Version="17.14.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
<PackageReference Include="Microsoft.CodeCoverage" Version="18.0.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.0.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
<PackageReference Include="SabreTools.RedumpLib" Version="[1.7.4]" />
<PackageReference Include="SabreTools.RedumpLib" Version="[1.9.1]" />
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.abstractions" Version="2.0.3" />
<PackageReference Include="xunit.analyzers" Version="1.24.0" />
<PackageReference Include="xunit.analyzers" Version="1.27.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" />

View File

@@ -1,4 +1,3 @@
using System.Collections.Generic;
using MPF.ExecutionContexts.Redumper;
using SabreTools.RedumpLib.Data;
using Xunit;
@@ -27,17 +26,17 @@ namespace MPF.ExecutionContexts.Test
}
#endregion
#region Default Values
private static Dictionary<string, string?> AllOptions = new()
private static readonly BaseDumpSettings AllOptions = new DumpSettings()
{
[SettingConstants.EnableVerbose] = "true",
[SettingConstants.LeadinRetryCount] = "1000",
[SettingConstants.ReadMethod] = "BE",
[SettingConstants.RereadCount] = "1000",
[SettingConstants.SectorOrder] = "DATA_C2_SUB",
[SettingConstants.DriveType] = "GENERIC",
EnableVerbose = true,
LeadinRetryCount = 1000,
ReadMethod = ReadMethod.BE,
RereadCount = 1000,
SectorOrder = SectorOrder.DATA_C2_SUB,
DriveType = DriveType.GENERIC,
};
[Theory]
@@ -66,11 +65,11 @@ namespace MPF.ExecutionContexts.Test
#region Disc
[Theory]
[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")]
[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 --mediatek-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 --filesystem-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 --mediatek-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 --filesystem-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 = "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";
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 --mediatek-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 --filesystem-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);
@@ -93,11 +92,11 @@ namespace MPF.ExecutionContexts.Test
#region Rings
[Theory]
[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")]
[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 --mediatek-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 --filesystem-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 --mediatek-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 --filesystem-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 --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";
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 --mediatek-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 --filesystem-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);
@@ -109,11 +108,11 @@ namespace MPF.ExecutionContexts.Test
#region Dump
[Theory]
[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")]
[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 --mediatek-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 --filesystem-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 --mediatek-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 --filesystem-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 --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";
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 --mediatek-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 --filesystem-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);
@@ -125,11 +124,11 @@ namespace MPF.ExecutionContexts.Test
#region DumpExtra
[Theory]
[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")]
[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 --mediatek-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 --filesystem-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 --mediatek-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 --filesystem-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 = "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";
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 --mediatek-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 --filesystem-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);
@@ -141,11 +140,11 @@ namespace MPF.ExecutionContexts.Test
#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")]
[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 --mediatek-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 --filesystem-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 --mediatek-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 --filesystem-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";
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 --mediatek-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 --filesystem-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);
@@ -157,11 +156,11 @@ namespace MPF.ExecutionContexts.Test
#region Verify
[Theory]
[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")]
[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 --mediatek-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 --filesystem-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 --mediatek-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 --filesystem-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 --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";
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 --mediatek-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 --filesystem-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);
@@ -173,11 +172,11 @@ namespace MPF.ExecutionContexts.Test
#region DVDKey
[Theory]
[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")]
[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 --mediatek-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 --filesystem-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 --mediatek-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 --filesystem-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 --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";
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 --mediatek-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 --filesystem-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);
@@ -189,11 +188,11 @@ namespace MPF.ExecutionContexts.Test
#region Eject
[Theory]
[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")]
[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 --mediatek-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 --filesystem-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 --mediatek-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 --filesystem-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 --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";
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 --mediatek-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 --filesystem-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);
@@ -205,11 +204,11 @@ namespace MPF.ExecutionContexts.Test
#region DVDIsoKey
[Theory]
[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")]
[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 --mediatek-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 --filesystem-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 --mediatek-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 --filesystem-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 --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";
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 --mediatek-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 --filesystem-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,11 +220,11 @@ namespace MPF.ExecutionContexts.Test
#region Protection
[Theory]
[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")]
[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 --mediatek-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 --filesystem-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 --mediatek-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 --filesystem-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 --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";
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 --mediatek-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 --filesystem-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);
@@ -237,11 +236,11 @@ namespace MPF.ExecutionContexts.Test
#region Split
[Theory]
[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")]
[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 --mediatek-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 --filesystem-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 --mediatek-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 --filesystem-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 --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";
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 --mediatek-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 --filesystem-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);
@@ -253,11 +252,11 @@ namespace MPF.ExecutionContexts.Test
#region Hash
[Theory]
[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")]
[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 --mediatek-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 --filesystem-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 --mediatek-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 --filesystem-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 --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";
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 --mediatek-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 --filesystem-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);
@@ -269,11 +268,11 @@ namespace MPF.ExecutionContexts.Test
#region Info
[Theory]
[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")]
[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 --mediatek-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 --filesystem-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 --mediatek-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 --filesystem-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 --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";
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 --mediatek-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 --filesystem-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);
@@ -285,11 +284,11 @@ namespace MPF.ExecutionContexts.Test
#region Skeleton
[Theory]
[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")]
[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 --mediatek-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 --filesystem-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 --mediatek-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 --filesystem-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 --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";
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 --mediatek-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 --filesystem-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);
@@ -301,11 +300,11 @@ namespace MPF.ExecutionContexts.Test
#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")]
[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 --mediatek-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 --filesystem-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 --mediatek-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 --filesystem-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";
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 --mediatek-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 --filesystem-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);
@@ -317,11 +316,11 @@ namespace MPF.ExecutionContexts.Test
#region Debug
[Theory]
[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")]
[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 --mediatek-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 --filesystem-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 --mediatek-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 --filesystem-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 --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";
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 --mediatek-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 --filesystem-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);
@@ -333,11 +332,11 @@ namespace MPF.ExecutionContexts.Test
#region FixMSF
[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")]
[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 --mediatek-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 --filesystem-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 --mediatek-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 --filesystem-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";
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 --mediatek-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 --filesystem-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);
@@ -348,11 +347,11 @@ namespace MPF.ExecutionContexts.Test
#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")]
[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 --mediatek-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 --filesystem-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 --mediatek-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 --filesystem-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";
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 --mediatek-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 --filesystem-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);
@@ -363,11 +362,11 @@ namespace MPF.ExecutionContexts.Test
#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")]
[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 --mediatek-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 --filesystem-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 --mediatek-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 --filesystem-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";
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 --mediatek-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 --filesystem-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);

View File

@@ -86,4 +86,4 @@ namespace MPF.ExecutionContexts.Aaru
#endregion
}
}
}

View File

@@ -0,0 +1,38 @@
namespace MPF.ExecutionContexts.Aaru
{
/// <summary>
/// Context-specific settings that can be used by caller
/// </summary>
public class DumpSettings : BaseDumpSettings
{
/// <summary>
/// Enable debug output while dumping by default
/// </summary>
/// <remarks>Version 1 and greater</remarks>
public bool EnableDebug { get; set; } = SettingConstants.EnableDebugDefault;
/// <summary>
/// Enable verbose output while dumping by default
/// </summary>
/// <remarks>Version 1 and greater</remarks>
public bool EnableVerbose { get; set; } = SettingConstants.EnableVerboseDefault;
/// <summary>
/// Enable force dumping of media by default
/// </summary>
/// <remarks>Version 1 and greater</remarks>
public bool ForceDumping { get; set; } = SettingConstants.ForceDumpingDefault;
/// <summary>
/// Default number of sector/subchannel rereads
/// </summary>
/// <remarks>Version 1 and greater</remarks>
public int RereadCount { get; set; } = SettingConstants.RereadCountDefault;
/// <summary>
/// Strip personal data information from Aaru metadata by default
/// </summary>
/// <remarks>Version 1 and greater</remarks>
public bool StripPersonalData { get; set; } = SettingConstants.StripPersonalDataDefault;
}
}

View File

@@ -40,4 +40,4 @@ namespace MPF.ExecutionContexts.Aaru
public const string WesternEuropeanMac = "macintosh";
public const string WesternEuropeanRadix50 = "radix50";
}
}
}

View File

@@ -168,8 +168,8 @@ namespace MPF.ExecutionContexts.Aaru
string? drivePath,
string filename,
int? driveSpeed,
Dictionary<string, string?> options)
: base(system, type, drivePath, filename, driveSpeed, options)
BaseDumpSettings baseDumpSettings)
: base(system, type, drivePath, filename, driveSpeed, baseDumpSettings)
{
}
@@ -511,6 +511,7 @@ namespace MPF.ExecutionContexts.Aaru
}
// Handle filenames based on command, if necessary
#pragma warning disable IDE0010
switch (BaseCommand)
{
// Input value only (file path)
@@ -538,7 +539,11 @@ namespace MPF.ExecutionContexts.Aaru
if (string.IsNullOrEmpty(InputValue))
return null;
#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER
if (InputValue!.Contains(' '))
#else
if (InputValue!.Contains(" "))
#endif
parameters.Append($"\"{InputValue!.TrimEnd('\\')}\" ");
else
parameters.Append($"{InputValue!.TrimEnd('\\')} ");
@@ -582,6 +587,7 @@ namespace MPF.ExecutionContexts.Aaru
parameters.Append($"\"{RemoteHostValue}\" ");
break;
}
#pragma warning restore IDE0010
return parameters.ToString().TrimEnd();
}
@@ -625,44 +631,49 @@ namespace MPF.ExecutionContexts.Aaru
protected override void SetDefaultParameters(string? drivePath,
string filename,
int? driveSpeed,
Dictionary<string, string?> options)
BaseDumpSettings baseDumpSettings)
{
// Get the base settings, if possible
var dumpSettings = baseDumpSettings as DumpSettings ?? new DumpSettings();
BaseCommand = $"{CommandStrings.MediaPrefixLong} {CommandStrings.MediaDump}";
InputValue = drivePath;
OutputValue = filename;
if (driveSpeed != null)
if (driveSpeed is not null)
{
this[FlagStrings.SpeedLong] = true;
(_inputs[FlagStrings.SpeedLong] as Int8Input)?.SetValue((sbyte)driveSpeed);
}
// Set retry count
int rereadCount = GetInt32Setting(options, SettingConstants.RereadCount, SettingConstants.RereadCountDefault);
if (rereadCount > 0)
if (dumpSettings.RereadCount > 0)
{
this[FlagStrings.RetryPassesLong] = true;
(_inputs[FlagStrings.RetryPassesLong] as Int16Input)?.SetValue((short)rereadCount);
(_inputs[FlagStrings.RetryPassesLong] as Int16Input)?.SetValue((short)dumpSettings.RereadCount);
}
// Set user-defined options
if (GetBooleanSetting(options, SettingConstants.EnableDebug, SettingConstants.EnableDebugDefault))
if (dumpSettings.EnableDebug)
{
this[FlagStrings.DebugLong] = true;
_preCommandInputs[FlagStrings.DebugLong].SetValue(true);
}
if (GetBooleanSetting(options, SettingConstants.EnableVerbose, SettingConstants.EnableVerboseDefault))
if (dumpSettings.EnableVerbose)
{
this[FlagStrings.VerboseLong] = true;
_preCommandInputs[FlagStrings.VerboseLong].SetValue(true);
}
if (GetBooleanSetting(options, SettingConstants.ForceDumping, SettingConstants.ForceDumpingDefault))
if (dumpSettings.ForceDumping)
{
this[FlagStrings.ForceLong] = true;
(_inputs[FlagStrings.ForceLong] as BooleanInput)?.SetValue(true);
}
if (GetBooleanSetting(options, SettingConstants.StripPersonalData, SettingConstants.StripPersonalDataDefault))
if (dumpSettings.StripPersonalData)
{
this[FlagStrings.PrivateLong] = true;
(_inputs[FlagStrings.PrivateLong] as BooleanInput)?.SetValue(true);
@@ -753,6 +764,7 @@ namespace MPF.ExecutionContexts.Aaru
}
// Handle filenames based on command, if necessary
#pragma warning disable IDE0010
switch (BaseCommand)
{
// Input value only
@@ -819,6 +831,7 @@ namespace MPF.ExecutionContexts.Aaru
i++;
break;
}
#pragma warning restore IDE0010
// If we didn't reach the end for some reason, it failed
if (i != parts.Length)
@@ -850,7 +863,7 @@ namespace MPF.ExecutionContexts.Aaru
var normalized = NormalizeCommand($"{partOne} {partTwo}".Trim());
// Null normalization means invalid command
if (normalized == null)
if (normalized is null)
return null;
// Determine if start should be incremented

View File

@@ -170,4 +170,4 @@ namespace MPF.ExecutionContexts.Aaru
#endregion
}
}
}

View File

@@ -166,4 +166,4 @@ namespace MPF.ExecutionContexts.Aaru
public const string XboxPartitioning = "Xbox partitioning";
public const string XENIX = "XENIX";
}
}
}

View File

@@ -24,4 +24,4 @@ namespace MPF.ExecutionContexts.Aaru
public const string WindowsNT83MixedCase = "nt";
public const string OS2Extended = "os2";
}
}
}

View File

@@ -40,4 +40,4 @@ namespace MPF.ExecutionContexts.Aaru
public const string VMwareDiskImageSparse = "sparse"; // boolean, default false
public const string VMwareDiskImageSplit = "split"; // boolean, default false
}
}
}

View File

@@ -17,4 +17,4 @@ namespace MPF.ExecutionContexts.Aaru
public const string StripPersonalData = "AaruStripPersonalData";
public const bool StripPersonalDataDefault = false;
}
}
}

View File

@@ -0,0 +1,9 @@
namespace MPF.ExecutionContexts
{
/// <summary>
/// Base class for all dump settings objects, representing an
/// arbitrary set of values that can be passed in to change
/// default dumping behavior.
/// </summary>
public abstract class BaseDumpSettings { }
}

View File

@@ -110,17 +110,17 @@ namespace MPF.ExecutionContexts
/// <param name="drivePath">Drive path to use</param>
/// <param name="filename">Filename to use</param>
/// <param name="driveSpeed">Drive speed to use</param>
/// <param name="options">Dictionary object containing all settings that may be used for setting parameters</param>
/// <param name="baseDumpSettings">BaseDumpSettings object containing all settings that may be used for setting parameters</param>
public BaseExecutionContext(RedumpSystem? system,
MediaType? type,
string? drivePath,
string filename,
int? driveSpeed,
Dictionary<string, string?> options)
BaseDumpSettings baseDumpSettings)
{
RedumpSystem = system;
MediaType = type;
SetDefaultParameters(drivePath, filename, driveSpeed, options);
SetDefaultParameters(drivePath, filename, driveSpeed, baseDumpSettings);
}
#region Abstract Methods
@@ -160,7 +160,7 @@ namespace MPF.ExecutionContexts
/// Returns if the current Parameter object is valid
/// </summary>
/// <returns></returns>
public bool IsValid() => GenerateParameters() != null;
public bool IsValid() => GenerateParameters() is not null;
/// <summary>
/// Reset all special variables to have default values
@@ -173,11 +173,11 @@ namespace MPF.ExecutionContexts
/// <param name="drivePath">Drive path to use</param>
/// <param name="filename">Filename to use</param>
/// <param name="driveSpeed">Drive speed to use</param>
/// <param name="options">Dictionary containing all settings that may be used for setting parameters</param>
/// <param name="baseDumpSettings">BaseDumpSettings containing all settings that may be used for setting parameters</param>
protected abstract void SetDefaultParameters(string? drivePath,
string filename,
int? driveSpeed,
Dictionary<string, string?> options);
BaseDumpSettings baseDumpSettings);
/// <summary>
/// Scan a possible parameter string and populate whatever possible
@@ -222,7 +222,7 @@ namespace MPF.ExecutionContexts
{
try
{
while (process != null && !process.HasExited)
while (process is not null && !process.HasExited)
{
process.Kill();
}
@@ -233,69 +233,6 @@ namespace MPF.ExecutionContexts
#endregion
#region Option Processing
/// <summary>
/// Get a Boolean setting from a settings, dictionary
/// </summary>
/// <param name="settings">Dictionary representing the settings</param>
/// <param name="key">Setting key to get a value for</param>
/// <param name="defaultValue">Default value to return if no value is found</param>
/// <returns>Setting value if possible, default value otherwise</returns>
internal static bool GetBooleanSetting(Dictionary<string, string?> settings, string key, bool defaultValue)
{
if (settings.ContainsKey(key))
{
if (bool.TryParse(settings[key], out bool value))
return value;
else
return defaultValue;
}
else
{
return defaultValue;
}
}
/// <summary>
/// Get an Int32 setting from a settings, dictionary
/// </summary>
/// <param name="settings">Dictionary representing the settings</param>
/// <param name="key">Setting key to get a value for</param>
/// <param name="defaultValue">Default value to return if no value is found</param>
/// <returns>Setting value if possible, default value otherwise</returns>
internal static int GetInt32Setting(Dictionary<string, string?> settings, string key, int defaultValue)
{
if (settings.ContainsKey(key))
{
if (int.TryParse(settings[key], out int value))
return value;
else
return defaultValue;
}
else
{
return defaultValue;
}
}
/// <summary>
/// Get a String setting from a settings, dictionary
/// </summary>
/// <param name="settings">Dictionary representing the settings</param>
/// <param name="key">Setting key to get a value for</param>
/// <param name="defaultValue">Default value to return if no value is found</param>
/// <returns>Setting value if possible, default value otherwise</returns>
internal static string? GetStringSetting(Dictionary<string, string?> settings, string key, string? defaultValue)
{
if (settings.ContainsKey(key))
return settings[key];
else
return defaultValue;
}
#endregion
#region Parameter Parsing
/// <summary>
@@ -331,9 +268,9 @@ namespace MPF.ExecutionContexts
/// <returns>True if the flag value is supported, false otherwise</returns>
protected bool IsFlagSupported(string flag)
{
if (CommandSupport == null)
if (CommandSupport is null)
return false;
if (BaseCommand == null)
if (BaseCommand is null)
return false;
if (!CommandSupport.TryGetValue(BaseCommand, out var supported))
return false;
@@ -360,9 +297,9 @@ namespace MPF.ExecutionContexts
string value = ExtractFactorFromValue(parameter, out _);
if (!sbyte.TryParse(value, out sbyte temp))
return false;
else if (lowerBound != null && temp < lowerBound)
else if (lowerBound is not null && temp < lowerBound)
return false;
else if (upperBound != null && temp > upperBound)
else if (upperBound is not null && temp > upperBound)
return false;
return true;
@@ -380,9 +317,9 @@ namespace MPF.ExecutionContexts
string value = ExtractFactorFromValue(parameter, out _);
if (!short.TryParse(value, out short temp))
return false;
else if (lowerBound != null && temp < lowerBound)
else if (lowerBound is not null && temp < lowerBound)
return false;
else if (upperBound != null && temp > upperBound)
else if (upperBound is not null && temp > upperBound)
return false;
return true;
@@ -400,9 +337,9 @@ namespace MPF.ExecutionContexts
string value = ExtractFactorFromValue(parameter, out _);
if (!int.TryParse(value, out int temp))
return false;
else if (lowerBound != null && temp < lowerBound)
else if (lowerBound is not null && temp < lowerBound)
return false;
else if (upperBound != null && temp > upperBound)
else if (upperBound is not null && temp > upperBound)
return false;
return true;
@@ -420,9 +357,9 @@ namespace MPF.ExecutionContexts
string value = ExtractFactorFromValue(parameter, out _);
if (!long.TryParse(value, out long temp))
return false;
else if (lowerBound != null && temp < lowerBound)
else if (lowerBound is not null && temp < lowerBound)
return false;
else if (upperBound != null && temp > upperBound)
else if (upperBound is not null && temp > upperBound)
return false;
return true;
@@ -448,7 +385,7 @@ namespace MPF.ExecutionContexts
/// <returns>True if the parameter was processed successfully or skipped, false otherwise</returns>
protected bool ProcessFlagParameter(string[] parts, string? shortFlagString, string longFlagString, ref int i)
{
if (parts == null)
if (parts is null)
return false;
if (parts[i] == shortFlagString || parts[i] == longFlagString)
@@ -484,7 +421,7 @@ namespace MPF.ExecutionContexts
/// <returns>True if the parameter was processed successfully or skipped, false otherwise</returns>
protected bool ProcessBooleanParameter(string[] parts, string? shortFlagString, string longFlagString, ref int i, bool missingAllowed = false)
{
if (parts == null)
if (parts is null)
return false;
if (parts[i] == shortFlagString || parts[i] == longFlagString)
@@ -559,7 +496,7 @@ namespace MPF.ExecutionContexts
/// <returns>SByte value if success, SByte.MinValue if skipped, null on error/returns>
protected sbyte? ProcessInt8Parameter(string[] parts, string? shortFlagString, string longFlagString, ref int i, bool missingAllowed = false)
{
if (parts == null)
if (parts is null)
return null;
if (parts[i] == shortFlagString || parts[i] == longFlagString)
@@ -622,7 +559,7 @@ namespace MPF.ExecutionContexts
return null;
}
return SByte.MinValue;
return sbyte.MinValue;
}
/// <summary>
@@ -647,7 +584,7 @@ namespace MPF.ExecutionContexts
/// <returns>Int16 value if success, Int16.MinValue if skipped, null on error/returns>
protected short? ProcessInt16Parameter(string[] parts, string? shortFlagString, string longFlagString, ref int i, bool missingAllowed = false)
{
if (parts == null)
if (parts is null)
return null;
if (parts[i] == shortFlagString || parts[i] == longFlagString)
@@ -709,7 +646,7 @@ namespace MPF.ExecutionContexts
return null;
}
return Int16.MinValue;
return short.MinValue;
}
/// <summary>
@@ -734,7 +671,7 @@ namespace MPF.ExecutionContexts
/// <returns>Int32 value if success, Int32.MinValue if skipped, null on error/returns>
protected int? ProcessInt32Parameter(string[] parts, string? shortFlagString, string longFlagString, ref int i, bool missingAllowed = false)
{
if (parts == null)
if (parts is null)
return null;
if (parts[i] == shortFlagString || parts[i] == longFlagString)
@@ -821,7 +758,7 @@ namespace MPF.ExecutionContexts
/// <returns>Int64 value if success, Int64.MinValue if skipped, null on error/returns>
protected long? ProcessInt64Parameter(string[] parts, string? shortFlagString, string longFlagString, ref int i, bool missingAllowed = false)
{
if (parts == null)
if (parts is null)
return null;
if (parts[i] == shortFlagString || parts[i] == longFlagString)
@@ -856,10 +793,10 @@ namespace MPF.ExecutionContexts
i++;
string value = ExtractFactorFromValue(parts[i], out long factor);
if (long.TryParse(value, out long longValue))
return (long)(longValue * factor);
return longValue * factor;
string hexValue = RemoveHexIdentifier(value);
if (long.TryParse(hexValue, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out long longHexValue))
return (long)(longHexValue * factor);
return longHexValue * factor;
return null;
}
else if (parts[i].StartsWith(shortFlagString + "=") || parts[i].StartsWith(longFlagString + "="))
@@ -876,10 +813,10 @@ namespace MPF.ExecutionContexts
this[longFlagString] = true;
string value = ExtractFactorFromValue(valuePart, out long factor);
if (long.TryParse(value, out long longValue))
return (long)(longValue * factor);
return longValue * factor;
string hexValue = RemoveHexIdentifier(value);
if (long.TryParse(hexValue, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out long longHexValue))
return (long)(longHexValue * factor);
return longHexValue * factor;
return null;
}
@@ -908,7 +845,7 @@ namespace MPF.ExecutionContexts
/// <returns>String value if possible, string.Empty on missing, null on error</returns>
protected string? ProcessStringParameter(string[] parts, string? shortFlagString, string longFlagString, ref int i, bool missingAllowed = false)
{
if (parts == null)
if (parts is null)
return null;
if (parts[i] == shortFlagString || parts[i] == longFlagString)
@@ -981,7 +918,7 @@ namespace MPF.ExecutionContexts
/// <returns>Byte value if success, Byte.MinValue if skipped, null on error/returns>
protected byte? ProcessUInt8Parameter(string[] parts, string? shortFlagString, string longFlagString, ref int i, bool missingAllowed = false)
{
if (parts == null)
if (parts is null)
return null;
if (parts[i] == shortFlagString || parts[i] == longFlagString)
@@ -1044,7 +981,7 @@ namespace MPF.ExecutionContexts
return null;
}
return Byte.MinValue;
return byte.MinValue;
}
/// <summary>

View File

@@ -40,7 +40,7 @@ namespace MPF.ExecutionContexts.Data
public override string Format(bool useEquals)
{
// Do not output if there is no value
if (Value == null)
if (Value is null)
return string.Empty;
// Build the output format
@@ -51,9 +51,9 @@ namespace MPF.ExecutionContexts.Data
// Separator
if (useEquals)
builder.Append("=");
builder.Append('=');
else
builder.Append(" ");
builder.Append(' ');
// Value
builder.Append(Value.ToString());
@@ -120,4 +120,4 @@ namespace MPF.ExecutionContexts.Data
return false;
}
}
}
}

View File

@@ -40,7 +40,7 @@ namespace MPF.ExecutionContexts.Data
public override string Format(bool useEquals)
{
// Do not output if there is no value
if (Value == false)
if (!Value)
return string.Empty;
// Build the output format
@@ -70,4 +70,4 @@ namespace MPF.ExecutionContexts.Data
return false;
}
}
}
}

View File

@@ -1,5 +1,3 @@
using System;
namespace MPF.ExecutionContexts.Data
{
/// <summary>
@@ -124,49 +122,77 @@ namespace MPF.ExecutionContexts.Data
factor = 1;
// Characters
if (value.EndsWith("c", StringComparison.Ordinal))
#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER
if (value.EndsWith('c'))
#else
if (value.EndsWith("c", System.StringComparison.Ordinal))
#endif
{
factor = 1;
value = value.TrimEnd('c');
}
// Words
else if (value.EndsWith("w", StringComparison.Ordinal))
#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER
else if (value.EndsWith('w'))
#else
else if (value.EndsWith("w", System.StringComparison.Ordinal))
#endif
{
factor = 2;
value = value.TrimEnd('w');
}
// Double Words
else if (value.EndsWith("d", StringComparison.Ordinal))
#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER
else if (value.EndsWith('d'))
#else
else if (value.EndsWith("d", System.StringComparison.Ordinal))
#endif
{
factor = 4;
value = value.TrimEnd('d');
}
// Quad Words
else if (value.EndsWith("q", StringComparison.Ordinal))
#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER
else if (value.EndsWith('q'))
#else
else if (value.EndsWith("q", System.StringComparison.Ordinal))
#endif
{
factor = 8;
value = value.TrimEnd('q');
}
// Kilobytes
else if (value.EndsWith("k", StringComparison.Ordinal))
#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER
else if (value.EndsWith('k'))
#else
else if (value.EndsWith("k", System.StringComparison.Ordinal))
#endif
{
factor = 1024;
value = value.TrimEnd('k');
}
// Megabytes
else if (value.EndsWith("M", StringComparison.Ordinal))
#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER
else if (value.EndsWith('M'))
#else
else if (value.EndsWith("M", System.StringComparison.Ordinal))
#endif
{
factor = 1024 * 1024;
value = value.TrimEnd('M');
}
// Gigabytes
else if (value.EndsWith("G", StringComparison.Ordinal))
#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER
else if (value.EndsWith('G'))
#else
else if (value.EndsWith("G", System.StringComparison.Ordinal))
#endif
{
factor = 1024 * 1024 * 1024;
value = value.TrimEnd('G');
@@ -189,7 +215,11 @@ namespace MPF.ExecutionContexts.Data
if (value[1] != 'x' && value[1] != 'X')
return value;
#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER
return value[2..];
#else
return value.Substring(2);
#endif
}
#endregion
@@ -208,7 +238,7 @@ namespace MPF.ExecutionContexts.Data
public T? Value { get; protected set; }
/// <inheritdoc/>
public override bool ValueSet => Value != null;
public override bool ValueSet => Value is not null;
#endregion
@@ -258,4 +288,4 @@ namespace MPF.ExecutionContexts.Data
#endregion
}
}
}

View File

@@ -55,7 +55,7 @@ namespace MPF.ExecutionContexts.Data
public override string Format(bool useEquals)
{
// Do not output if there is no value
if (Value == null)
if (Value is null)
return string.Empty;
// Build the output format
@@ -69,9 +69,9 @@ namespace MPF.ExecutionContexts.Data
{
// Separator
if (useEquals)
builder.Append("=");
builder.Append('=');
else
builder.Append(" ");
builder.Append(' ');
// Value
builder.Append(Value.ToString());
@@ -95,25 +95,25 @@ namespace MPF.ExecutionContexts.Data
if (index + 1 >= parts.Length)
{
Value = _required ? null : short.MinValue;
Value = (MinValue != null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue != null && Value > MaxValue) ? MaxValue : Value;
Value = (MinValue is not null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue is not null && Value > MaxValue) ? MaxValue : Value;
return !_required;
}
// If the next value is valid
if (ParseValue(parts[index + 1], out short? value) && value != null)
if (ParseValue(parts[index + 1], out short? value) && value is not null)
{
index++;
Value = value;
Value = (MinValue != null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue != null && Value > MaxValue) ? MaxValue : Value;
Value = (MinValue is not null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue is not null && Value > MaxValue) ? MaxValue : Value;
return true;
}
// Return value based on required flag
Value = _required ? null : short.MinValue;
Value = (MinValue != null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue != null && Value > MaxValue) ? MaxValue : Value;
Value = (MinValue is not null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue is not null && Value > MaxValue) ? MaxValue : Value;
return !_required;
}
@@ -129,24 +129,24 @@ namespace MPF.ExecutionContexts.Data
if (string.IsNullOrEmpty(val))
{
Value = _required ? null : short.MinValue;
Value = (MinValue != null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue != null && Value > MaxValue) ? MaxValue : Value;
Value = (MinValue is not null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue is not null && Value > MaxValue) ? MaxValue : Value;
return !_required;
}
// If the next value is valid
if (ParseValue(val, out short? value) && value != null)
if (ParseValue(val, out short? value) && value is not null)
{
Value = value;
Value = (MinValue != null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue != null && Value > MaxValue) ? MaxValue : Value;
Value = (MinValue is not null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue is not null && Value > MaxValue) ? MaxValue : Value;
return true;
}
// Return value based on required flag
Value = _required ? null : short.MinValue;
Value = (MinValue != null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue != null && Value > MaxValue) ? MaxValue : Value;
Value = (MinValue is not null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue is not null && Value > MaxValue) ? MaxValue : Value;
return !_required;
}
@@ -186,4 +186,4 @@ namespace MPF.ExecutionContexts.Data
return false;
}
}
}
}

View File

@@ -60,7 +60,7 @@ namespace MPF.ExecutionContexts.Data
public override string Format(bool useEquals)
{
// Do not output if there is no value
if (Value == null)
if (Value is null)
return string.Empty;
// Build the output format
@@ -70,16 +70,16 @@ namespace MPF.ExecutionContexts.Data
builder.Append(Name);
// Only output separator and value if needed
if (_required || (!_required && Value != null))
if (_required || (!_required && Value is not null))
{
// Separator
if (useEquals)
builder.Append("=");
builder.Append('=');
else
builder.Append(" ");
builder.Append(' ');
// Value
int?[] nonNull = Array.FindAll(Value, i => i != null);
int?[] nonNull = Array.FindAll(Value, i => i is not null);
string[] stringValues = Array.ConvertAll(nonNull, i => i.ToString() ?? string.Empty);
builder.Append(string.Join(" ", stringValues));
}
@@ -106,12 +106,12 @@ namespace MPF.ExecutionContexts.Data
return !_required;
// If the next value is valid
if (ParseValue(parts[index + 1], out int? value) && value != null)
if (ParseValue(parts[index + 1], out int? value) && value is not null)
{
index++;
Value[i] = value;
Value[i] = (MinValue != null && Value[i] < MinValue) ? MinValue : Value[i];
Value[i] = (MaxValue != null && Value[i] > MaxValue) ? MaxValue : Value[i];
Value[i] = (MinValue is not null && Value[i] < MinValue) ? MinValue : Value[i];
Value[i] = (MaxValue is not null && Value[i] > MaxValue) ? MaxValue : Value[i];
continue;
}
@@ -158,4 +158,4 @@ namespace MPF.ExecutionContexts.Data
return false;
}
}
}
}

View File

@@ -55,7 +55,7 @@ namespace MPF.ExecutionContexts.Data
public override string Format(bool useEquals)
{
// Do not output if there is no value
if (Value == null)
if (Value is null)
return string.Empty;
// Build the output format
@@ -69,9 +69,9 @@ namespace MPF.ExecutionContexts.Data
{
// Separator
if (useEquals)
builder.Append("=");
builder.Append('=');
else
builder.Append(" ");
builder.Append(' ');
// Value
builder.Append(Value.ToString());
@@ -95,25 +95,25 @@ namespace MPF.ExecutionContexts.Data
if (index + 1 >= parts.Length)
{
Value = _required ? null : int.MinValue;
Value = (MinValue != null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue != null && Value > MaxValue) ? MaxValue : Value;
Value = (MinValue is not null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue is not null && Value > MaxValue) ? MaxValue : Value;
return !_required;
}
// If the next value is valid
if (ParseValue(parts[index + 1], out int? value) && value != null)
if (ParseValue(parts[index + 1], out int? value) && value is not null)
{
index++;
Value = value;
Value = (MinValue != null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue != null && Value > MaxValue) ? MaxValue : Value;
Value = (MinValue is not null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue is not null && Value > MaxValue) ? MaxValue : Value;
return true;
}
// Return value based on required flag
Value = _required ? null : int.MinValue;
Value = (MinValue != null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue != null && Value > MaxValue) ? MaxValue : Value;
Value = (MinValue is not null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue is not null && Value > MaxValue) ? MaxValue : Value;
return !_required;
}
@@ -129,24 +129,24 @@ namespace MPF.ExecutionContexts.Data
if (string.IsNullOrEmpty(val))
{
Value = _required ? null : int.MinValue;
Value = (MinValue != null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue != null && Value > MaxValue) ? MaxValue : Value;
Value = (MinValue is not null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue is not null && Value > MaxValue) ? MaxValue : Value;
return !_required;
}
// If the next value is valid
if (ParseValue(val, out int? value) && value != null)
if (ParseValue(val, out int? value) && value is not null)
{
Value = value;
Value = (MinValue != null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue != null && Value > MaxValue) ? MaxValue : Value;
Value = (MinValue is not null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue is not null && Value > MaxValue) ? MaxValue : Value;
return true;
}
// Return value based on required flag
Value = _required ? null : int.MinValue;
Value = (MinValue != null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue != null && Value > MaxValue) ? MaxValue : Value;
Value = (MinValue is not null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue is not null && Value > MaxValue) ? MaxValue : Value;
return !_required;
}
@@ -186,4 +186,4 @@ namespace MPF.ExecutionContexts.Data
return false;
}
}
}
}

View File

@@ -55,7 +55,7 @@ namespace MPF.ExecutionContexts.Data
public override string Format(bool useEquals)
{
// Do not output if there is no value
if (Value == null)
if (Value is null)
return string.Empty;
// Build the output format
@@ -69,9 +69,9 @@ namespace MPF.ExecutionContexts.Data
{
// Separator
if (useEquals)
builder.Append("=");
builder.Append('=');
else
builder.Append(" ");
builder.Append(' ');
// Value
builder.Append(Value.ToString());
@@ -95,25 +95,25 @@ namespace MPF.ExecutionContexts.Data
if (index + 1 >= parts.Length)
{
Value = _required ? null : long.MinValue;
Value = (MinValue != null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue != null && Value > MaxValue) ? MaxValue : Value;
Value = (MinValue is not null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue is not null && Value > MaxValue) ? MaxValue : Value;
return !_required;
}
// If the next value is valid
if (ParseValue(parts[index + 1], out long? value) && value != null)
if (ParseValue(parts[index + 1], out long? value) && value is not null)
{
index++;
Value = value;
Value = (MinValue != null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue != null && Value > MaxValue) ? MaxValue : Value;
Value = (MinValue is not null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue is not null && Value > MaxValue) ? MaxValue : Value;
return true;
}
// Return value based on required flag
Value = _required ? null : long.MinValue;
Value = (MinValue != null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue != null && Value > MaxValue) ? MaxValue : Value;
Value = (MinValue is not null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue is not null && Value > MaxValue) ? MaxValue : Value;
return !_required;
}
@@ -129,24 +129,24 @@ namespace MPF.ExecutionContexts.Data
if (string.IsNullOrEmpty(val))
{
Value = _required ? null : long.MinValue;
Value = (MinValue != null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue != null && Value > MaxValue) ? MaxValue : Value;
Value = (MinValue is not null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue is not null && Value > MaxValue) ? MaxValue : Value;
return !_required;
}
// If the next value is valid
if (ParseValue(val, out long? value) && value != null)
if (ParseValue(val, out long? value) && value is not null)
{
Value = value;
Value = (MinValue != null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue != null && Value > MaxValue) ? MaxValue : Value;
Value = (MinValue is not null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue is not null && Value > MaxValue) ? MaxValue : Value;
return true;
}
// Return value based on required flag
Value = _required ? null : long.MinValue;
Value = (MinValue != null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue != null && Value > MaxValue) ? MaxValue : Value;
Value = (MinValue is not null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue is not null && Value > MaxValue) ? MaxValue : Value;
return !_required;
}
@@ -169,7 +169,7 @@ namespace MPF.ExecutionContexts.Data
string baseVal = ExtractFactorFromValue(str, out long factor);
if (long.TryParse(baseVal, out value))
{
output = (long)(value * factor);
output = value * factor;
return true;
}
@@ -177,7 +177,7 @@ namespace MPF.ExecutionContexts.Data
string hexValue = RemoveHexIdentifier(baseVal);
if (long.TryParse(hexValue, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out value))
{
output = (long)(value * factor);
output = value * factor;
return true;
}
@@ -186,4 +186,4 @@ namespace MPF.ExecutionContexts.Data
return false;
}
}
}
}

View File

@@ -55,7 +55,7 @@ namespace MPF.ExecutionContexts.Data
public override string Format(bool useEquals)
{
// Do not output if there is no value
if (Value == null)
if (Value is null)
return string.Empty;
// Build the output format
@@ -69,9 +69,9 @@ namespace MPF.ExecutionContexts.Data
{
// Separator
if (useEquals)
builder.Append("=");
builder.Append('=');
else
builder.Append(" ");
builder.Append(' ');
// Value
builder.Append(Value.ToString());
@@ -95,25 +95,25 @@ namespace MPF.ExecutionContexts.Data
if (index + 1 >= parts.Length)
{
Value = _required ? null : sbyte.MinValue;
Value = (MinValue != null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue != null && Value > MaxValue) ? MaxValue : Value;
Value = (MinValue is not null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue is not null && Value > MaxValue) ? MaxValue : Value;
return !_required;
}
// If the next value is valid
if (ParseValue(parts[index + 1], out sbyte? value) && value != null)
if (ParseValue(parts[index + 1], out sbyte? value) && value is not null)
{
index++;
Value = value;
Value = (MinValue != null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue != null && Value > MaxValue) ? MaxValue : Value;
Value = (MinValue is not null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue is not null && Value > MaxValue) ? MaxValue : Value;
return true;
}
// Return value based on required flag
Value = _required ? null : sbyte.MinValue;
Value = (MinValue != null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue != null && Value > MaxValue) ? MaxValue : Value;
Value = (MinValue is not null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue is not null && Value > MaxValue) ? MaxValue : Value;
return !_required;
}
@@ -129,24 +129,24 @@ namespace MPF.ExecutionContexts.Data
if (string.IsNullOrEmpty(val))
{
Value = _required ? null : sbyte.MinValue;
Value = (MinValue != null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue != null && Value > MaxValue) ? MaxValue : Value;
Value = (MinValue is not null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue is not null && Value > MaxValue) ? MaxValue : Value;
return !_required;
}
// If the next value is valid
if (ParseValue(val, out sbyte? value) && value != null)
if (ParseValue(val, out sbyte? value) && value is not null)
{
Value = value;
Value = (MinValue != null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue != null && Value > MaxValue) ? MaxValue : Value;
Value = (MinValue is not null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue is not null && Value > MaxValue) ? MaxValue : Value;
return true;
}
// Return value based on required flag
Value = _required ? null : sbyte.MinValue;
Value = (MinValue != null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue != null && Value > MaxValue) ? MaxValue : Value;
Value = (MinValue is not null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue is not null && Value > MaxValue) ? MaxValue : Value;
return !_required;
}
@@ -186,4 +186,4 @@ namespace MPF.ExecutionContexts.Data
return false;
}
}
}
}

View File

@@ -50,7 +50,7 @@ namespace MPF.ExecutionContexts.Data
public override string Format(bool useEquals)
{
// Do not output if there is no value
if (Value == null)
if (Value is null)
return string.Empty;
// Build the output format
@@ -64,9 +64,9 @@ namespace MPF.ExecutionContexts.Data
{
// Separator
if (useEquals)
builder.Append("=");
builder.Append('=');
else
builder.Append(" ");
builder.Append(' ');
// Value
if (Quotes)
@@ -123,4 +123,4 @@ namespace MPF.ExecutionContexts.Data
return false;
}
}
}
}

View File

@@ -55,7 +55,7 @@ namespace MPF.ExecutionContexts.Data
public override string Format(bool useEquals)
{
// Do not output if there is no value
if (Value == null)
if (Value is null)
return string.Empty;
// Build the output format
@@ -69,9 +69,9 @@ namespace MPF.ExecutionContexts.Data
{
// Separator
if (useEquals)
builder.Append("=");
builder.Append('=');
else
builder.Append(" ");
builder.Append(' ');
// Value
builder.Append(Value.ToString());
@@ -95,25 +95,25 @@ namespace MPF.ExecutionContexts.Data
if (index + 1 >= parts.Length)
{
Value = _required ? null : ushort.MinValue;
Value = (MinValue != null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue != null && Value > MaxValue) ? MaxValue : Value;
Value = (MinValue is not null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue is not null && Value > MaxValue) ? MaxValue : Value;
return !_required;
}
// If the next value is valid
if (ParseValue(parts[index + 1], out ushort? value) && value != null)
if (ParseValue(parts[index + 1], out ushort? value) && value is not null)
{
index++;
Value = value;
Value = (MinValue != null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue != null && Value > MaxValue) ? MaxValue : Value;
Value = (MinValue is not null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue is not null && Value > MaxValue) ? MaxValue : Value;
return true;
}
// Return value based on required flag
Value = _required ? null : ushort.MinValue;
Value = (MinValue != null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue != null && Value > MaxValue) ? MaxValue : Value;
Value = (MinValue is not null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue is not null && Value > MaxValue) ? MaxValue : Value;
return !_required;
}
@@ -129,24 +129,24 @@ namespace MPF.ExecutionContexts.Data
if (string.IsNullOrEmpty(val))
{
Value = _required ? null : ushort.MinValue;
Value = (MinValue != null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue != null && Value > MaxValue) ? MaxValue : Value;
Value = (MinValue is not null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue is not null && Value > MaxValue) ? MaxValue : Value;
return !_required;
}
// If the next value is valid
if (ParseValue(val, out ushort? value) && value != null)
if (ParseValue(val, out ushort? value) && value is not null)
{
Value = value;
Value = (MinValue != null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue != null && Value > MaxValue) ? MaxValue : Value;
Value = (MinValue is not null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue is not null && Value > MaxValue) ? MaxValue : Value;
return true;
}
// Return value based on required flag
Value = _required ? null : ushort.MinValue;
Value = (MinValue != null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue != null && Value > MaxValue) ? MaxValue : Value;
Value = (MinValue is not null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue is not null && Value > MaxValue) ? MaxValue : Value;
return !_required;
}
@@ -186,4 +186,4 @@ namespace MPF.ExecutionContexts.Data
return false;
}
}
}
}

View File

@@ -55,7 +55,7 @@ namespace MPF.ExecutionContexts.Data
public override string Format(bool useEquals)
{
// Do not output if there is no value
if (Value == null)
if (Value is null)
return string.Empty;
// Build the output format
@@ -69,9 +69,9 @@ namespace MPF.ExecutionContexts.Data
{
// Separator
if (useEquals)
builder.Append("=");
builder.Append('=');
else
builder.Append(" ");
builder.Append(' ');
// Value
builder.Append(Value.ToString());
@@ -95,25 +95,25 @@ namespace MPF.ExecutionContexts.Data
if (index + 1 >= parts.Length)
{
Value = _required ? null : uint.MinValue;
Value = (MinValue != null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue != null && Value > MaxValue) ? MaxValue : Value;
Value = (MinValue is not null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue is not null && Value > MaxValue) ? MaxValue : Value;
return !_required;
}
// If the next value is valid
if (ParseValue(parts[index + 1], out uint? value) && value != null)
if (ParseValue(parts[index + 1], out uint? value) && value is not null)
{
index++;
Value = value;
Value = (MinValue != null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue != null && Value > MaxValue) ? MaxValue : Value;
Value = (MinValue is not null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue is not null && Value > MaxValue) ? MaxValue : Value;
return true;
}
// Return value based on required flag
Value = _required ? null : uint.MinValue;
Value = (MinValue != null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue != null && Value > MaxValue) ? MaxValue : Value;
Value = (MinValue is not null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue is not null && Value > MaxValue) ? MaxValue : Value;
return !_required;
}
@@ -129,24 +129,24 @@ namespace MPF.ExecutionContexts.Data
if (string.IsNullOrEmpty(val))
{
Value = _required ? null : uint.MinValue;
Value = (MinValue != null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue != null && Value > MaxValue) ? MaxValue : Value;
Value = (MinValue is not null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue is not null && Value > MaxValue) ? MaxValue : Value;
return !_required;
}
// If the next value is valid
if (ParseValue(val, out uint? value) && value != null)
if (ParseValue(val, out uint? value) && value is not null)
{
Value = value;
Value = (MinValue != null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue != null && Value > MaxValue) ? MaxValue : Value;
Value = (MinValue is not null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue is not null && Value > MaxValue) ? MaxValue : Value;
return true;
}
// Return value based on required flag
Value = _required ? null : uint.MinValue;
Value = (MinValue != null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue != null && Value > MaxValue) ? MaxValue : Value;
Value = (MinValue is not null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue is not null && Value > MaxValue) ? MaxValue : Value;
return !_required;
}
@@ -186,4 +186,4 @@ namespace MPF.ExecutionContexts.Data
return false;
}
}
}
}

View File

@@ -55,7 +55,7 @@ namespace MPF.ExecutionContexts.Data
public override string Format(bool useEquals)
{
// Do not output if there is no value
if (Value == null)
if (Value is null)
return string.Empty;
// Build the output format
@@ -69,9 +69,9 @@ namespace MPF.ExecutionContexts.Data
{
// Separator
if (useEquals)
builder.Append("=");
builder.Append('=');
else
builder.Append(" ");
builder.Append(' ');
// Value
builder.Append(Value.ToString());
@@ -95,25 +95,25 @@ namespace MPF.ExecutionContexts.Data
if (index + 1 >= parts.Length)
{
Value = _required ? null : ulong.MinValue;
Value = (MinValue != null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue != null && Value > MaxValue) ? MaxValue : Value;
Value = (MinValue is not null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue is not null && Value > MaxValue) ? MaxValue : Value;
return !_required;
}
// If the next value is valid
if (ParseValue(parts[index + 1], out ulong? value) && value != null)
if (ParseValue(parts[index + 1], out ulong? value) && value is not null)
{
index++;
Value = value;
Value = (MinValue != null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue != null && Value > MaxValue) ? MaxValue : Value;
Value = (MinValue is not null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue is not null && Value > MaxValue) ? MaxValue : Value;
return true;
}
// Return value based on required flag
Value = _required ? null : ulong.MinValue;
Value = (MinValue != null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue != null && Value > MaxValue) ? MaxValue : Value;
Value = (MinValue is not null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue is not null && Value > MaxValue) ? MaxValue : Value;
return !_required;
}
@@ -129,24 +129,24 @@ namespace MPF.ExecutionContexts.Data
if (string.IsNullOrEmpty(val))
{
Value = _required ? null : ulong.MinValue;
Value = (MinValue != null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue != null && Value > MaxValue) ? MaxValue : Value;
Value = (MinValue is not null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue is not null && Value > MaxValue) ? MaxValue : Value;
return !_required;
}
// If the next value is valid
if (ParseValue(val, out ulong? value) && value != null)
if (ParseValue(val, out ulong? value) && value is not null)
{
Value = value;
Value = (MinValue != null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue != null && Value > MaxValue) ? MaxValue : Value;
Value = (MinValue is not null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue is not null && Value > MaxValue) ? MaxValue : Value;
return true;
}
// Return value based on required flag
Value = _required ? null : ulong.MinValue;
Value = (MinValue != null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue != null && Value > MaxValue) ? MaxValue : Value;
Value = (MinValue is not null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue is not null && Value > MaxValue) ? MaxValue : Value;
return !_required;
}
@@ -169,7 +169,7 @@ namespace MPF.ExecutionContexts.Data
string baseVal = ExtractFactorFromValue(str, out long factor);
if (ulong.TryParse(baseVal, out value))
{
output = (ulong)(value * (ulong)factor);
output = value * (ulong)factor;
return true;
}
@@ -177,7 +177,7 @@ namespace MPF.ExecutionContexts.Data
string hexValue = RemoveHexIdentifier(baseVal);
if (ulong.TryParse(hexValue, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out value))
{
output = (ulong)(value * (ulong)factor);
output = value * (ulong)factor;
return true;
}
@@ -186,4 +186,4 @@ namespace MPF.ExecutionContexts.Data
return false;
}
}
}
}

View File

@@ -55,7 +55,7 @@ namespace MPF.ExecutionContexts.Data
public override string Format(bool useEquals)
{
// Do not output if there is no value
if (Value == null)
if (Value is null)
return string.Empty;
// Build the output format
@@ -69,9 +69,9 @@ namespace MPF.ExecutionContexts.Data
{
// Separator
if (useEquals)
builder.Append("=");
builder.Append('=');
else
builder.Append(" ");
builder.Append(' ');
// Value
builder.Append(Value.ToString());
@@ -95,25 +95,25 @@ namespace MPF.ExecutionContexts.Data
if (index + 1 >= parts.Length)
{
Value = _required ? null : byte.MinValue;
Value = (MinValue != null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue != null && Value > MaxValue) ? MaxValue : Value;
Value = (MinValue is not null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue is not null && Value > MaxValue) ? MaxValue : Value;
return !_required;
}
// If the next value is valid
if (ParseValue(parts[index + 1], out byte? value) && value != null)
if (ParseValue(parts[index + 1], out byte? value) && value is not null)
{
index++;
Value = value;
Value = (MinValue != null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue != null && Value > MaxValue) ? MaxValue : Value;
Value = (MinValue is not null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue is not null && Value > MaxValue) ? MaxValue : Value;
return true;
}
// Return value based on required flag
Value = _required ? null : byte.MinValue;
Value = (MinValue != null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue != null && Value > MaxValue) ? MaxValue : Value;
Value = (MinValue is not null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue is not null && Value > MaxValue) ? MaxValue : Value;
return !_required;
}
@@ -129,24 +129,24 @@ namespace MPF.ExecutionContexts.Data
if (string.IsNullOrEmpty(val))
{
Value = _required ? null : byte.MinValue;
Value = (MinValue != null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue != null && Value > MaxValue) ? MaxValue : Value;
Value = (MinValue is not null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue is not null && Value > MaxValue) ? MaxValue : Value;
return !_required;
}
// If the next value is valid
if (ParseValue(val, out byte? value) && value != null)
if (ParseValue(val, out byte? value) && value is not null)
{
Value = value;
Value = (MinValue != null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue != null && Value > MaxValue) ? MaxValue : Value;
Value = (MinValue is not null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue is not null && Value > MaxValue) ? MaxValue : Value;
return true;
}
// Return value based on required flag
Value = _required ? null : byte.MinValue;
Value = (MinValue != null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue != null && Value > MaxValue) ? MaxValue : Value;
Value = (MinValue is not null && Value < MinValue) ? MinValue : Value;
Value = (MaxValue is not null && Value > MaxValue) ? MaxValue : Value;
return !_required;
}
@@ -186,4 +186,4 @@ namespace MPF.ExecutionContexts.Data
return false;
}
}
}
}

View File

@@ -7,6 +7,7 @@ namespace MPF.ExecutionContexts.DiscImageCreator
{
public const string NONE = "";
public const string Audio = "audio";
public const string AuthPS3 = "authps3";
public const string BluRay = "bd";
public const string Close = "close";
public const string CompactDisc = "cd";
@@ -32,4 +33,4 @@ namespace MPF.ExecutionContexts.DiscImageCreator
public const string XGD2Swap = "xgd2swap";
public const string XGD3Swap = "xgd3swap";
}
}
}

View File

@@ -72,6 +72,7 @@ namespace MPF.ExecutionContexts.DiscImageCreator
/// <returns>Valid extension (with leading '.'), null on error</returns>
public static string? Extension(MediaType? type)
{
#pragma warning disable IDE0072
return type switch
{
MediaType.CDROM
@@ -93,8 +94,9 @@ namespace MPF.ExecutionContexts.DiscImageCreator
MediaType.Cassette => ".wav",
_ => null,
};
#pragma warning restore IDE0072
}
#endregion
}
}
}

View File

@@ -0,0 +1,55 @@
namespace MPF.ExecutionContexts.DiscImageCreator
{
/// <summary>
/// Context-specific settings that can be used by caller
/// </summary>
public class DumpSettings : BaseDumpSettings
{
/// <summary>
/// Enable multi-sector read flag by default
/// </summary>
/// <remarks>Version 1 and greater</remarks>
public bool MultiSectorRead { get; set; } = SettingConstants.MultiSectorReadDefault;
/// <summary>
/// Include a default multi-sector read value
/// </summary>
/// <remarks>Version 1 and greater</remarks>
public int MultiSectorReadValue { get; set; } = SettingConstants.MultiSectorReadValueDefault;
/// <summary>
/// Enable overly-secure dumping flags by default
/// </summary>
/// <remarks>
/// Version 1 and greater
/// Split this into component parts later. Currently does:
/// - Scan sector protection and set subchannel read level to 2 for CD
/// - Set scan file protect flag for DVD
/// </remarks>
public bool ParanoidMode { get; set; } = SettingConstants.ParanoidModeDefault;
/// <summary>
/// Enable the Quiet flag by default
/// </summary>
/// <remarks>Version 1 and greater</remarks>
public bool QuietMode { get; set; } = SettingConstants.QuietModeDefault;
/// <summary>
/// Default number of C2 rereads
/// </summary>
/// <remarks>Version 1 and greater</remarks>
public int RereadCount { get; set; } = SettingConstants.RereadCountDefault;
/// <summary>
/// Default number of DVD/HD-DVD/BD rereads
/// </summary>
/// <remarks>Version 1 and greater</remarks>
public int DVDRereadCount { get; set; } = SettingConstants.DVDRereadCountDefault;
/// <summary>
/// Use the CMI flag for supported disc types
/// </summary>
/// <remarks>Version 1 and greater</remarks>
public bool UseCMIFlag { get; set; } = SettingConstants.UseCMIFlagDefault;
}
}

View File

@@ -1,5 +1,4 @@
using System.Collections.Generic;
using System.IO;
using System.Collections.Generic;
using System.Text;
using SabreTools.RedumpLib.Data;
@@ -176,8 +175,8 @@ namespace MPF.ExecutionContexts.DiscImageCreator
string? drivePath,
string filename,
int? driveSpeed,
Dictionary<string, string?> options)
: base(system, type, drivePath, filename, driveSpeed, options)
BaseDumpSettings baseDumpSettings)
: base(system, type, drivePath, filename, driveSpeed, baseDumpSettings)
{
}
@@ -209,6 +208,8 @@ namespace MPF.ExecutionContexts.DiscImageCreator
FlagStrings.Tages,
],
[CommandStrings.AuthPS3] = [],
[CommandStrings.BluRay] =
[
FlagStrings.DatExpand,
@@ -419,6 +420,7 @@ namespace MPF.ExecutionContexts.DiscImageCreator
// Drive Letter
if (BaseCommand == CommandStrings.Audio
|| BaseCommand == CommandStrings.AuthPS3
|| BaseCommand == CommandStrings.BluRay
|| BaseCommand == CommandStrings.Close
|| BaseCommand == CommandStrings.CompactDisc
@@ -439,9 +441,13 @@ namespace MPF.ExecutionContexts.DiscImageCreator
|| BaseCommand == CommandStrings.XGD2Swap
|| BaseCommand == CommandStrings.XGD3Swap)
{
if (DrivePath != null)
if (DrivePath is not null)
{
#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER
if (DrivePath.Contains(' '))
#else
if (DrivePath.Contains(" "))
#endif
parameters.Append($"\"{DrivePath}\" ");
else
parameters.Append($"{DrivePath} ");
@@ -472,7 +478,7 @@ namespace MPF.ExecutionContexts.DiscImageCreator
|| BaseCommand == CommandStrings.XGD2Swap
|| BaseCommand == CommandStrings.XGD3Swap)
{
if (Filename != null)
if (Filename is not null)
parameters.Append($"\"{Filename.Trim('"')}\" ");
else
return null;
@@ -481,7 +487,7 @@ namespace MPF.ExecutionContexts.DiscImageCreator
// Optiarc Filename
if (BaseCommand == CommandStrings.Merge)
{
if (OptiarcFilename != null)
if (OptiarcFilename is not null)
parameters.Append($"\"{OptiarcFilename.Trim('"')}\" ");
else
return null;
@@ -501,7 +507,7 @@ namespace MPF.ExecutionContexts.DiscImageCreator
|| BaseCommand == CommandStrings.XGD2Swap
|| BaseCommand == CommandStrings.XGD3Swap)
{
if (DriveSpeed != null)
if (DriveSpeed is not null)
parameters.Append($"{DriveSpeed} ");
else
return null;
@@ -511,7 +517,7 @@ namespace MPF.ExecutionContexts.DiscImageCreator
if (BaseCommand == CommandStrings.Audio
|| BaseCommand == CommandStrings.Data)
{
if (StartLBAValue != null && EndLBAValue != null)
if (StartLBAValue is not null && EndLBAValue is not null)
{
parameters.Append($"{StartLBAValue} ");
parameters.Append($"{EndLBAValue} ");
@@ -526,7 +532,7 @@ namespace MPF.ExecutionContexts.DiscImageCreator
if (this[FlagStrings.AddOffset] == true)
{
parameters.Append($"{FlagStrings.AddOffset} ");
if (AddOffsetValue != null)
if (AddOffsetValue is not null)
parameters.Append($"{AddOffsetValue} ");
}
}
@@ -551,7 +557,7 @@ namespace MPF.ExecutionContexts.DiscImageCreator
if (this[FlagStrings.BEOpcode] == true)
{
parameters.Append($"{FlagStrings.BEOpcode} ");
if (BEOpcodeValue != null)
if (BEOpcodeValue is not null)
parameters.Append($"{BEOpcodeValue} ");
}
}
@@ -562,22 +568,25 @@ namespace MPF.ExecutionContexts.DiscImageCreator
if (this[FlagStrings.C2Opcode] == true)
{
parameters.Append($"{FlagStrings.C2Opcode} ");
if (C2OpcodeValue[0] != null)
if (C2OpcodeValue[0] is not null)
{
if (C2OpcodeValue[0] > 0)
parameters.Append($"{C2OpcodeValue[0]} ");
else
return null;
}
if (C2OpcodeValue[1] != null)
if (C2OpcodeValue[1] is not null)
{
parameters.Append($"{C2OpcodeValue[1]} ");
}
if (C2OpcodeValue[2] != null)
if (C2OpcodeValue[2] is not null)
{
parameters.Append($"{C2OpcodeValue[2]} ");
}
if (C2OpcodeValue[3] != null)
if (C2OpcodeValue[3] is not null)
{
if (C2OpcodeValue[3] == 0)
{
@@ -586,7 +595,7 @@ namespace MPF.ExecutionContexts.DiscImageCreator
else if (C2OpcodeValue[3] == 1)
{
parameters.Append($"{C2OpcodeValue[3]} ");
if (C2OpcodeValue[4] != null && C2OpcodeValue[5] != null)
if (C2OpcodeValue[4] is not null && C2OpcodeValue[5] is not null)
{
if (C2OpcodeValue[4] > 0 && C2OpcodeValue[5] > 0)
{
@@ -613,7 +622,7 @@ namespace MPF.ExecutionContexts.DiscImageCreator
if (this[FlagStrings.C2OpcodeNew] == true)
{
parameters.Append($"{FlagStrings.C2OpcodeNew} ");
if (C2OpcodeValue[0] != null)
if (C2OpcodeValue[0] is not null)
{
if (C2OpcodeValue[0] > 0)
parameters.Append($"{C2OpcodeValue[0]} ");
@@ -657,7 +666,7 @@ namespace MPF.ExecutionContexts.DiscImageCreator
if (this[FlagStrings.DVDReread] == true)
{
parameters.Append($"{FlagStrings.DVDReread} ");
if (DVDRereadValue != null)
if (DVDRereadValue is not null)
parameters.Append($"{DVDRereadValue} ");
}
}
@@ -675,7 +684,7 @@ namespace MPF.ExecutionContexts.DiscImageCreator
if (this[FlagStrings.Fix] == true)
{
parameters.Append($"{FlagStrings.Fix} ");
if (FixValue != null)
if (FixValue is not null)
parameters.Append($"{FixValue} ");
else
return null;
@@ -688,7 +697,7 @@ namespace MPF.ExecutionContexts.DiscImageCreator
if (this[FlagStrings.ForceDescrambleSector] == true)
{
parameters.Append($"{FlagStrings.ForceDescrambleSector} ");
if (ForceDescrambleSectorValue != null)
if (ForceDescrambleSectorValue is not null)
parameters.Append($"{ForceDescrambleSectorValue} ");
else
return null;
@@ -701,7 +710,7 @@ namespace MPF.ExecutionContexts.DiscImageCreator
if (this[FlagStrings.ForceUnitAccess] == true)
{
parameters.Append($"{FlagStrings.ForceUnitAccess} ");
if (ForceUnitAccessValue != null)
if (ForceUnitAccessValue is not null)
parameters.Append($"{ForceUnitAccessValue} ");
}
}
@@ -719,7 +728,7 @@ namespace MPF.ExecutionContexts.DiscImageCreator
if (this[FlagStrings.MultiSectorRead] == true)
{
parameters.Append($"{FlagStrings.MultiSectorRead} ");
if (MultiSectorReadValue != null)
if (MultiSectorReadValue is not null)
parameters.Append($"{MultiSectorReadValue} ");
}
}
@@ -765,7 +774,7 @@ namespace MPF.ExecutionContexts.DiscImageCreator
if (this[FlagStrings.NoSkipSS] == true)
{
parameters.Append($"{FlagStrings.NoSkipSS} ");
if (NoSkipSecuritySectorValue != null)
if (NoSkipSecuritySectorValue is not null)
parameters.Append($"{NoSkipSecuritySectorValue} ");
}
}
@@ -776,7 +785,7 @@ namespace MPF.ExecutionContexts.DiscImageCreator
if (this[FlagStrings.PadSector] == true)
{
parameters.Append($"{FlagStrings.PadSector} ");
if (PadSectorValue != null)
if (PadSectorValue is not null)
parameters.Append($"{PadSectorValue} ");
}
}
@@ -790,7 +799,7 @@ namespace MPF.ExecutionContexts.DiscImageCreator
if (BaseCommand == CommandStrings.DigitalVideoDisc)
{
if (RangeStartLBAValue == null || RangeEndLBAValue == null)
if (RangeStartLBAValue is null || RangeEndLBAValue is null)
return null;
parameters.Append($"{RangeStartLBAValue} ");
@@ -822,7 +831,7 @@ namespace MPF.ExecutionContexts.DiscImageCreator
if (BaseCommand == CommandStrings.DigitalVideoDisc)
{
if (ReverseStartLBAValue == null || ReverseEndLBAValue == null)
if (ReverseStartLBAValue is null || ReverseEndLBAValue is null)
return null;
parameters.Append($"{ReverseStartLBAValue} ");
@@ -844,7 +853,7 @@ namespace MPF.ExecutionContexts.DiscImageCreator
if (this[FlagStrings.ScanFileProtect] == true)
{
parameters.Append($"{FlagStrings.ScanFileProtect} ");
if (ScanFileProtectValue != null)
if (ScanFileProtectValue is not null)
{
if (ScanFileProtectValue > 0)
parameters.Append($"{ScanFileProtectValue} ");
@@ -874,14 +883,15 @@ namespace MPF.ExecutionContexts.DiscImageCreator
if (this[FlagStrings.SkipSector] == true)
{
parameters.Append($"{FlagStrings.SkipSector} ");
if (SkipSectorValue[0] != null)
if (SkipSectorValue[0] is not null)
{
if (SkipSectorValue[0] > 0)
parameters.Append($"{SkipSectorValue[0]} ");
else
return null;
}
if (SkipSectorValue[1] != null)
if (SkipSectorValue[1] is not null)
{
if (SkipSectorValue[1] == 0)
parameters.Append($"{SkipSectorValue[1]} ");
@@ -895,7 +905,7 @@ namespace MPF.ExecutionContexts.DiscImageCreator
if (this[FlagStrings.SubchannelReadLevel] == true)
{
parameters.Append($"{FlagStrings.SubchannelReadLevel} ");
if (SubchannelReadLevelValue != null)
if (SubchannelReadLevelValue is not null)
{
if (SubchannelReadLevelValue >= 0 && SubchannelReadLevelValue <= 2)
parameters.Append($"{SubchannelReadLevelValue} ");
@@ -939,7 +949,7 @@ namespace MPF.ExecutionContexts.DiscImageCreator
if (this[FlagStrings.VideoNow] == true)
{
parameters.Append($"{FlagStrings.VideoNow} ");
if (VideoNowValue != null)
if (VideoNowValue is not null)
{
if (VideoNowValue >= 0)
parameters.Append($"{VideoNowValue} ");
@@ -1028,8 +1038,11 @@ namespace MPF.ExecutionContexts.DiscImageCreator
protected override void SetDefaultParameters(string? drivePath,
string filename,
int? driveSpeed,
Dictionary<string, string?> options)
BaseDumpSettings baseDumpSettings)
{
// Get the base settings, if possible
var dumpSettings = baseDumpSettings as DumpSettings ?? new DumpSettings();
SetBaseCommand(RedumpSystem, MediaType);
DrivePath = drivePath;
@@ -1042,35 +1055,34 @@ namespace MPF.ExecutionContexts.DiscImageCreator
return;
// Set disable beep flag, if needed
if (GetBooleanSetting(options, SettingConstants.QuietMode, SettingConstants.QuietModeDefault))
if (dumpSettings.QuietMode)
this[FlagStrings.DisableBeep] = true;
// Set the C2 reread count
int cdRereadCount = GetInt32Setting(options, SettingConstants.RereadCount, SettingConstants.RereadCountDefault);
C2OpcodeValue[0] = cdRereadCount switch
C2OpcodeValue[0] = dumpSettings.RereadCount switch
{
-1 => null,
0 => 20,
_ => cdRereadCount,
_ => dumpSettings.RereadCount,
};
// Set the DVD/HD-DVD/BD reread count
int dvdRereadCount = GetInt32Setting(options, SettingConstants.DVDRereadCount, SettingConstants.DVDRereadCountDefault);
DVDRereadValue = dvdRereadCount switch
DVDRereadValue = dumpSettings.DVDRereadCount switch
{
-1 => null,
0 => 10,
_ => dvdRereadCount,
_ => dumpSettings.DVDRereadCount,
};
// Now sort based on disc type
#pragma warning disable IDE0010
switch (MediaType)
{
case SabreTools.RedumpLib.Data.MediaType.CDROM:
this[FlagStrings.C2Opcode] = true;
this[FlagStrings.MultiSectorRead] = GetBooleanSetting(options, SettingConstants.MultiSectorRead, SettingConstants.MultiSectorReadDefault);
if (this[FlagStrings.MultiSectorRead] == true)
MultiSectorReadValue = GetInt32Setting(options, SettingConstants.MultiSectorReadValue, SettingConstants.MultiSectorReadValueDefault);
this[FlagStrings.MultiSectorRead] = dumpSettings.MultiSectorRead;
if (dumpSettings.MultiSectorRead)
MultiSectorReadValue = dumpSettings.MultiSectorReadValue;
switch (RedumpSystem)
{
@@ -1078,8 +1090,8 @@ namespace MPF.ExecutionContexts.DiscImageCreator
case SabreTools.RedumpLib.Data.RedumpSystem.IBMPCcompatible:
this[FlagStrings.NoFixSubQSecuROM] = true;
this[FlagStrings.ScanFileProtect] = true;
this[FlagStrings.ScanSectorProtect] = GetBooleanSetting(options, SettingConstants.ParanoidMode, SettingConstants.ParanoidModeDefault);
this[FlagStrings.SubchannelReadLevel] = GetBooleanSetting(options, SettingConstants.ParanoidMode, SettingConstants.ParanoidModeDefault);
this[FlagStrings.ScanSectorProtect] = dumpSettings.ParanoidMode;
this[FlagStrings.SubchannelReadLevel] = dumpSettings.ParanoidMode;
if (this[FlagStrings.SubchannelReadLevel] == true)
SubchannelReadLevelValue = 2;
@@ -1099,17 +1111,18 @@ namespace MPF.ExecutionContexts.DiscImageCreator
this[FlagStrings.NoFixSubQLibCrypt] = true;
break;
}
break;
case SabreTools.RedumpLib.Data.MediaType.DVD:
this[FlagStrings.CopyrightManagementInformation] = GetBooleanSetting(options, SettingConstants.UseCMIFlag, SettingConstants.UseCMIFlagDefault);
this[FlagStrings.ScanFileProtect] = GetBooleanSetting(options, SettingConstants.ParanoidMode, SettingConstants.ParanoidModeDefault);
this[FlagStrings.CopyrightManagementInformation] = dumpSettings.UseCMIFlag;
this[FlagStrings.ScanFileProtect] = dumpSettings.ParanoidMode;
this[FlagStrings.DVDReread] = true;
break;
case SabreTools.RedumpLib.Data.MediaType.GDROM:
this[FlagStrings.C2Opcode] = true;
break;
case SabreTools.RedumpLib.Data.MediaType.HDDVD:
this[FlagStrings.CopyrightManagementInformation] = GetBooleanSetting(options, SettingConstants.UseCMIFlag, SettingConstants.UseCMIFlagDefault);
this[FlagStrings.CopyrightManagementInformation] = dumpSettings.UseCMIFlag;
this[FlagStrings.DVDReread] = true;
break;
case SabreTools.RedumpLib.Data.MediaType.BluRay:
@@ -1132,6 +1145,7 @@ namespace MPF.ExecutionContexts.DiscImageCreator
// Currently no defaults set
break;
}
#pragma warning restore IDE0010
}
/// <inheritdoc/>
@@ -1183,6 +1197,14 @@ namespace MPF.ExecutionContexts.DiscImageCreator
index = 6;
break;
case CommandStrings.AuthPS3:
if (parts.Length != 2)
return false;
// Blindly assume the path exists
DrivePath = parts[1];
break;
case CommandStrings.BluRay:
if (parts.Length < 4)
return false;
@@ -1529,7 +1551,7 @@ namespace MPF.ExecutionContexts.DiscImageCreator
// Add Offset
intValue = ProcessInt32Parameter(parts, FlagStrings.AddOffset, ref i, missingAllowed: true);
if (intValue != null && intValue != int.MinValue)
if (intValue is not null && intValue != int.MinValue)
AddOffsetValue = intValue;
// AMSF
@@ -1607,7 +1629,7 @@ namespace MPF.ExecutionContexts.DiscImageCreator
// DVD/HD-DVD/BD Reread
intValue = ProcessInt32Parameter(parts, FlagStrings.DVDReread, ref i, missingAllowed: true);
if (intValue != null && intValue != int.MinValue)
if (intValue is not null && intValue != int.MinValue)
DVDRereadValue = intValue;
// Extract MS-CAB
@@ -1615,7 +1637,7 @@ namespace MPF.ExecutionContexts.DiscImageCreator
// Fix
intValue = ProcessInt32Parameter(parts, FlagStrings.Fix, ref i);
if (intValue != null && intValue != int.MinValue)
if (intValue is not null && intValue != int.MinValue)
FixValue = intValue;
// Force Descramble Sector
@@ -1677,7 +1699,7 @@ namespace MPF.ExecutionContexts.DiscImageCreator
// Force Unit Access
intValue = ProcessInt32Parameter(parts, FlagStrings.ForceUnitAccess, ref i, missingAllowed: true);
if (intValue != null && intValue != int.MinValue && intValue >= 0)
if (intValue is not null && intValue != int.MinValue && intValue >= 0)
ForceUnitAccessValue = intValue;
// Full TOC
@@ -1685,7 +1707,7 @@ namespace MPF.ExecutionContexts.DiscImageCreator
// Multi-Sector Read
intValue = ProcessInt32Parameter(parts, FlagStrings.MultiSectorRead, ref i, missingAllowed: true);
if (intValue != null && intValue != int.MinValue && intValue >= 0)
if (intValue is not null && intValue != int.MinValue && intValue >= 0)
MultiSectorReadValue = intValue;
// NoFixSubP
@@ -1705,12 +1727,12 @@ namespace MPF.ExecutionContexts.DiscImageCreator
// NoSkipSS
intValue = ProcessInt32Parameter(parts, FlagStrings.NoSkipSS, ref i, missingAllowed: true);
if (intValue != null && intValue != int.MinValue && intValue >= 0)
if (intValue is not null && intValue != int.MinValue && intValue >= 0)
NoSkipSecuritySectorValue = intValue;
// PadSector
byteValue = ProcessUInt8Parameter(parts, FlagStrings.PadSector, ref i, missingAllowed: true);
if (byteValue != null)
if (byteValue is not null)
PadSectorValue = byteValue;
// Range
@@ -1762,7 +1784,7 @@ namespace MPF.ExecutionContexts.DiscImageCreator
// ScanFileProtect
intValue = ProcessInt32Parameter(parts, FlagStrings.ScanFileProtect, ref i, missingAllowed: true);
if (intValue != null && intValue != int.MinValue && intValue >= 0)
if (intValue is not null && intValue != int.MinValue && intValue >= 0)
ScanFileProtectValue = intValue;
// ScanSectorProtect
@@ -1803,7 +1825,7 @@ namespace MPF.ExecutionContexts.DiscImageCreator
// SubchannelReadLevel
intValue = ProcessInt32Parameter(parts, FlagStrings.SubchannelReadLevel, ref i, missingAllowed: true);
if (intValue != null && intValue != int.MinValue && intValue >= 0 && intValue <= 2)
if (intValue is not null && intValue != int.MinValue && intValue >= 0 && intValue <= 2)
SubchannelReadLevelValue = intValue;
// Tages
@@ -1820,7 +1842,7 @@ namespace MPF.ExecutionContexts.DiscImageCreator
// VideoNow
intValue = ProcessInt32Parameter(parts, FlagStrings.VideoNow, ref i, missingAllowed: true);
if (intValue != null && intValue != int.MinValue && intValue >= 0)
if (intValue is not null && intValue != int.MinValue && intValue >= 0)
VideoNowValue = intValue;
// VideoNowColor
@@ -1852,6 +1874,7 @@ namespace MPF.ExecutionContexts.DiscImageCreator
return;
}
#pragma warning disable IDE0010
switch (type)
{
case SabreTools.RedumpLib.Data.MediaType.CDROM:
@@ -1867,6 +1890,7 @@ namespace MPF.ExecutionContexts.DiscImageCreator
BaseCommand = CommandStrings.XBOX;
return;
}
BaseCommand = CommandStrings.DigitalVideoDisc;
return;
case SabreTools.RedumpLib.Data.MediaType.GDROM:
@@ -1901,6 +1925,7 @@ namespace MPF.ExecutionContexts.DiscImageCreator
BaseCommand = null;
return;
}
#pragma warning restore IDE0010
}
#endregion

View File

@@ -47,4 +47,4 @@ namespace MPF.ExecutionContexts.DiscImageCreator
public const string VideoNowColor = "/vnc";
public const string VideoNowXP = "/vnx";
}
}
}

View File

@@ -23,4 +23,4 @@ namespace MPF.ExecutionContexts.DiscImageCreator
public const string UseCMIFlag = "DICUseCMIFlag";
public const bool UseCMIFlagDefault = false;
}
}
}

View File

@@ -0,0 +1,10 @@
namespace MPF.ExecutionContexts.Dreamdump
{
/// <summary>
/// Top-level commands for Dreamdump
/// </summary>
public static class CommandStrings
{
public const string NONE = "";
}
}

View File

@@ -0,0 +1,26 @@
namespace MPF.ExecutionContexts.Dreamdump
{
/// <summary>
/// Context-specific settings that can be used by caller
/// </summary>
public class DumpSettings : BaseDumpSettings
{
/// <summary>
/// Enable options incompatible with redump submissions
/// </summary>
/// <remarks>Version 1 and greater</remarks>
public bool NonRedumpMode { get; set; } = false;
/// <summary>
/// Currently selected default Dreamdump sector order
/// </summary>
/// <remarks>Version 1 and greater</remarks>
public SectorOrder SectorOrder { get; set; } = SettingConstants.SectorOrderDefault;
/// <summary>
/// Default number of rereads
/// </summary>
/// <remarks>Version 1 and greater</remarks>
public int RereadCount { get; set; } = SettingConstants.RereadCountDefault;
}
}

View File

@@ -0,0 +1,15 @@
namespace MPF.ExecutionContexts.Dreamdump
{
/// <summary>
/// Drive sector order option
/// </summary>
public enum SectorOrder
{
NONE = 0,
DATA_C2,
DATA_SUB,
DATA_C2_SUB,
DATA_SUB_C2,
}
}

View File

@@ -0,0 +1,258 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using MPF.ExecutionContexts.Data;
using SabreTools.RedumpLib.Data;
namespace MPF.ExecutionContexts.Dreamdump
{
/// <summary>
/// Represents a generic set of Dreamdump parameters
/// </summary>
public sealed class ExecutionContext : BaseExecutionContext
{
#region Generic Dumping Information
/// <inheritdoc/>
public override string? InputPath
=> (_inputs[FlagStrings.Drive] as StringInput)?.Value?.Trim('"');
/// <inheritdoc/>
public override string? OutputPath => Path.Combine(
(_inputs[FlagStrings.ImagePath] as StringInput)?.Value?.Trim('"') ?? string.Empty,
(_inputs[FlagStrings.ImageName] as StringInput)?.Value?.Trim('"') ?? string.Empty)
+ GetDefaultExtension(MediaType);
/// <inheritdoc/>
public override int? Speed
{
get
{
return (_inputs[FlagStrings.Speed] as Int32Input)?.Value;
}
set
{
if (value is not 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);
}
}
}
#endregion
#region Flag Values
/// <summary>
/// Set of all command flags
/// </summary>
private readonly Dictionary<string, Input> _inputs = new()
{
// Special
[FlagStrings.ForceQTOC] = new FlagInput(FlagStrings.ForceQTOC),
[FlagStrings.Train] = new FlagInput(FlagStrings.Train),
[FlagStrings.Retries] = new UInt8Input(FlagStrings.Retries),
// Paths
[FlagStrings.ImageName] = new StringInput(FlagStrings.ImageName) { Quotes = true },
[FlagStrings.ImagePath] = new StringInput(FlagStrings.ImagePath) { Quotes = true },
// Drive Part
[FlagStrings.ReadOffset] = new Int16Input(FlagStrings.ReadOffset),
[FlagStrings.ReadAtOnce] = new UInt8Input(FlagStrings.ReadAtOnce),
[FlagStrings.Speed] = new UInt16Input(FlagStrings.Speed),
[FlagStrings.SectorOrder] = new StringInput(FlagStrings.SectorOrder),
[FlagStrings.Drive] = new StringInput(FlagStrings.Drive),
};
#endregion
/// <inheritdoc/>
public ExecutionContext(string? parameters) : base(parameters) { }
/// <inheritdoc/>
public ExecutionContext(RedumpSystem? system,
MediaType? type,
string? drivePath,
string filename,
int? driveSpeed,
BaseDumpSettings baseDumpSettings)
: base(system, type, drivePath, filename, driveSpeed, baseDumpSettings)
{
}
#region BaseExecutionContext Implementations
/// <inheritdoc/>
/// <remarks>Command support is irrelevant for Dreamdump</remarks>
public override Dictionary<string, List<string>> GetCommandSupport()
{
return new Dictionary<string, List<string>>()
{
[CommandStrings.NONE] =
[
// Special
FlagStrings.ForceQTOC,
FlagStrings.Train,
FlagStrings.Retries,
// Paths
FlagStrings.ImageName,
FlagStrings.ImagePath,
// Drive Part
FlagStrings.ReadOffset,
FlagStrings.ReadAtOnce,
FlagStrings.Speed,
FlagStrings.SectorOrder,
FlagStrings.Drive,
],
};
}
/// <inheritdoc/>
public override string GenerateParameters()
{
var parameters = new StringBuilder();
// Loop though and append all existing
foreach (var kvp in _inputs)
{
// If the value doesn't exist
string formatted = kvp.Value.Format(useEquals: true);
if (formatted.Length == 0)
continue;
// Append the parameter
parameters.Append($"{formatted} ");
}
return parameters.ToString().TrimEnd();
}
/// <inheritdoc/>
public override string? GetDefaultExtension(MediaType? mediaType) => ".bin";
/// <inheritdoc/>
public override MediaType? GetMediaType() => SabreTools.RedumpLib.Data.MediaType.GDROM;
/// <inheritdoc/>
public override bool IsDumpingCommand() => true;
/// <inheritdoc/>
protected override void ResetValues()
{
BaseCommand = CommandStrings.NONE;
flags = [];
foreach (var kvp in _inputs)
kvp.Value.ClearValue();
}
/// <inheritdoc/>
protected override void SetDefaultParameters(string? drivePath,
string filename,
int? driveSpeed,
BaseDumpSettings baseDumpSettings)
{
// Get the base settings, if possible
var dumpSettings = baseDumpSettings as DumpSettings ?? new DumpSettings();
BaseCommand = CommandStrings.NONE;
if (drivePath is not null)
{
this[FlagStrings.Drive] = true;
(_inputs[FlagStrings.Drive] as StringInput)?.SetValue(drivePath);
}
if (driveSpeed is not null && driveSpeed > 0)
{
this[FlagStrings.Speed] = true;
(_inputs[FlagStrings.Speed] as UInt16Input)?.SetValue((ushort)driveSpeed);
}
else
{
this[FlagStrings.Speed] = false;
(_inputs[FlagStrings.Speed] as UInt16Input)?.SetValue(null);
}
// Set user-defined options
if (dumpSettings.SectorOrder != SectorOrder.NONE)
{
this[FlagStrings.SectorOrder] = true;
(_inputs[FlagStrings.SectorOrder] as StringInput)?.SetValue(dumpSettings.SectorOrder.ToString());
}
// Set the output paths
if (!string.IsNullOrEmpty(filename))
{
var imagePath = Path.GetDirectoryName(filename);
if (!string.IsNullOrEmpty(imagePath))
{
this[FlagStrings.ImagePath] = true;
(_inputs[FlagStrings.ImagePath] as StringInput)?.SetValue(imagePath!);
}
string imageName = Path.GetFileNameWithoutExtension(filename);
if (!string.IsNullOrEmpty(imageName))
{
this[FlagStrings.ImageName] = true;
(_inputs[FlagStrings.ImageName] as StringInput)?.SetValue(imageName!);
}
}
if (dumpSettings.RereadCount > 0)
{
this[FlagStrings.Retries] = true;
(_inputs[FlagStrings.Retries] as UInt8Input)?.SetValue((byte)dumpSettings.RereadCount);
}
}
/// <inheritdoc/>
protected override bool ValidateAndSetParameters(string? parameters)
{
// The string has to be valid by itself first
if (string.IsNullOrEmpty(parameters))
return false;
// Now split the string into parts for easier validation
string[] parts = SplitParameterString(parameters!);
// Setup the modes
BaseCommand = null;
// Loop through all auxiliary flags, if necessary
int index = 0;
for (int i = index; i < parts.Length; i++)
{
// Match all possible flags
foreach (var kvp in _inputs)
{
// If the value was not a match
if (!kvp.Value.Process(parts, ref i))
continue;
// Set the flag
this[kvp.Key] = true;
}
}
// If the image name was not set, set it with a default value
if (string.IsNullOrEmpty((_inputs[FlagStrings.ImageName] as StringInput)?.Value))
(_inputs[FlagStrings.ImageName] as StringInput)?.SetValue($"track_{DateTime.Now:yyyyMMdd-HHmm}");
return true;
}
#endregion
}
}

View File

@@ -0,0 +1,33 @@
namespace MPF.ExecutionContexts.Dreamdump
{
/// <summary>
/// Dumping flags for Dreamdump
/// </summary>
public static class FlagStrings
{
#region Special
public const string ForceQTOC = "--force-qtoc";
public const string Train = "--train";
public const string Retries = "--retries";
#endregion
#region Paths
public const string ImageName = "--image-name";
public const string ImagePath = "--image-path";
#endregion
#region Drive Part
public const string ReadOffset = "--read-offset";
public const string ReadAtOnce = "--read-at-once"; // [0,40] (Linux), [0,20] (Windows)
public const string Speed = "--speed";
public const string SectorOrder = "--sector-order";
public const string Drive = "--drive";
#endregion
}
}

View File

@@ -0,0 +1,11 @@
namespace MPF.ExecutionContexts.Dreamdump
{
public static class SettingConstants
{
public const string RereadCount = "DreamdumpRereadCount";
public const int RereadCountDefault = 20;
public const string SectorOrder = "DreamdumpSectorOrder";
public static readonly SectorOrder SectorOrderDefault = Dreamdump.SectorOrder.NONE;
}
}

View File

@@ -2,7 +2,7 @@
<PropertyGroup>
<!-- Assembly Properties -->
<TargetFrameworks>net20;net35;net40;net452;net462;net472;net48;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0;net9.0</TargetFrameworks>
<TargetFrameworks>net20;net35;net40;net452;net462;net472;net48;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0;net9.0;net10.0</TargetFrameworks>
<CheckEolTargetFramework>false</CheckEolTargetFramework>
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
<IncludeSymbols>true</IncludeSymbols>
@@ -11,7 +11,7 @@
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<VersionPrefix>3.5.0</VersionPrefix>
<VersionPrefix>3.6.0</VersionPrefix>
<WarningsNotAsErrors>NU5104</WarningsNotAsErrors>
<!-- Package Properties -->
@@ -32,7 +32,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="SabreTools.RedumpLib" Version="[1.7.4]" />
<PackageReference Include="SabreTools.RedumpLib" Version="[1.9.1]" />
</ItemGroup>
</Project>

View File

@@ -29,4 +29,4 @@ namespace MPF.ExecutionContexts.Redumper
public const string DebugFlip = "debug::flip";
public const string DriveTest = "drive::test";
}
}
}

View File

@@ -13,6 +13,7 @@ namespace MPF.ExecutionContexts.Redumper
/// <returns>Valid extension (with leading '.'), null on error</returns>
public static string? Extension(MediaType? type)
{
#pragma warning disable IDE0072
return type switch
{
MediaType.CDROM
@@ -25,8 +26,9 @@ namespace MPF.ExecutionContexts.Redumper
MediaType.NintendoWiiUOpticalDisc => ".wud",
_ => null,
};
#pragma warning restore IDE0072
}
#endregion
}
}
}

View File

@@ -0,0 +1,68 @@
namespace MPF.ExecutionContexts.Redumper
{
/// <summary>
/// Context-specific settings that can be used by caller
/// </summary>
public class DumpSettings : BaseDumpSettings
{
/// <summary>
/// Enable skeleton output while dumping by default
/// </summary>
/// <remarks>Version 1 and greater; This is a hidden setting</remarks>
public bool EnableSkeleton { get; set; } = SettingConstants.EnableSkeletonDefault;
/// <summary>
/// Enable verbose output while dumping by default
/// </summary>
/// <remarks>Version 1 and greater</remarks>
public bool EnableVerbose { get; set; } = SettingConstants.EnableVerboseDefault;
/// <summary>
/// Default number of redumper Plextor leadin retries
/// </summary>
/// <remarks>Version 1 and greater</remarks>
public int LeadinRetryCount { get; set; } = SettingConstants.LeadinRetryCountDefault;
/// <summary>
/// Enable options incompatible with redump submissions
/// </summary>
/// <remarks>Version 1 and greater</remarks>
public bool NonRedumpMode { get; set; } = false;
/// <summary>
/// Currently selected default redumper drive type
/// </summary>
/// <remarks>Version 1 and greater</remarks>
public DriveType DriveType { get; set; } = SettingConstants.DriveTypeDefault;
/// <summary>
/// Currently selected default redumper drive pregap start sector
/// </summary>
/// <remarks>Version 1 and greater</remarks>
public int DrivePregapStart { get; set; } = SettingConstants.DrivePregapStartDefault;
/// <summary>
/// Currently selected default redumper read method
/// </summary>
/// <remarks>Version 1 and greater</remarks>
public ReadMethod ReadMethod { get; set; } = SettingConstants.ReadMethodDefault;
/// <summary>
/// Currently selected default redumper sector order
/// </summary>
/// <remarks>Version 1 and greater</remarks>
public SectorOrder SectorOrder { get; set; } = SettingConstants.SectorOrderDefault;
/// <summary>
/// Default number of rereads
/// </summary>
/// <remarks>Version 1 and greater</remarks>
public int RereadCount { get; set; } = SettingConstants.RereadCountDefault;
/// <summary>
/// Enable the refine sector mode flag by default
/// </summary>
/// <remarks>Version 1 and greater</remarks>
public bool RefineSectorMode { get; set; } = SettingConstants.RefineSectorModeDefault;
}
}

View File

@@ -9,11 +9,11 @@ namespace MPF.ExecutionContexts.Redumper
GENERIC,
PLEXTOR,
LG_ASU8A,
LG_ASU8B,
LG_ASU8C,
LG_ASU3,
LG_ASU2,
MTK8A,
MTK8B,
MTK8C,
MTK3,
MTK2,
}
/// <summary>

View File

@@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
@@ -32,7 +33,7 @@ namespace MPF.ExecutionContexts.Redumper
}
set
{
if (value != null && value > 0)
if (value is not null && value > 0)
{
this[FlagStrings.Speed] = true;
(_inputs[FlagStrings.Speed] as Int32Input)?.SetValue(value);
@@ -83,8 +84,8 @@ namespace MPF.ExecutionContexts.Redumper
[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.MediatekSkipLeadout] = new FlagInput(FlagStrings.MediatekSkipLeadout),
[FlagStrings.MediatekLeadoutRetries] = new Int32Input(FlagStrings.MediatekLeadoutRetries),
[FlagStrings.DisableCDText] = new FlagInput(FlagStrings.DisableCDText),
// Offset
@@ -98,7 +99,7 @@ namespace MPF.ExecutionContexts.Redumper
[FlagStrings.LeaveUnchanged] = new FlagInput(FlagStrings.LeaveUnchanged),
[FlagStrings.ForceQTOC] = new FlagInput(FlagStrings.ForceQTOC),
[FlagStrings.SkipFill] = new UInt8Input(FlagStrings.SkipFill),
[FlagStrings.ISO9660Trim] = new FlagInput(FlagStrings.ISO9660Trim),
[FlagStrings.FilesystemTrim] = new FlagInput(FlagStrings.FilesystemTrim),
// Drive Test
[FlagStrings.DriveTestSkipPlextorLeadin] = new FlagInput(FlagStrings.DriveTestSkipPlextorLeadin),
@@ -108,6 +109,7 @@ namespace MPF.ExecutionContexts.Redumper
[FlagStrings.Continue] = new StringInput(FlagStrings.Continue),
[FlagStrings.LBAStart] = new Int32Input(FlagStrings.LBAStart),
[FlagStrings.LBAEnd] = new Int32Input(FlagStrings.LBAEnd),
[FlagStrings.LBAEndBySubcode] = new Int32Input(FlagStrings.LBAEndBySubcode),
[FlagStrings.RefineSubchannel] = new FlagInput(FlagStrings.RefineSubchannel),
[FlagStrings.RefineSectorMode] = new FlagInput(FlagStrings.RefineSectorMode),
[FlagStrings.Skip] = new StringInput(FlagStrings.Skip),
@@ -117,8 +119,10 @@ namespace MPF.ExecutionContexts.Redumper
[FlagStrings.ForceUnscrambled] = new FlagInput(FlagStrings.ForceUnscrambled),
[FlagStrings.ForceRefine] = new FlagInput(FlagStrings.ForceRefine),
//[FlagStrings.Firmware] = new StringInput(FlagStrings.Firmware) { Quotes = true },
[FlagStrings.ForceFlash] = new FlagInput(FlagStrings.ForceFlash),
[FlagStrings.SkipSubcodeDesync] = new FlagInput(FlagStrings.SkipSubcodeDesync),
[FlagStrings.Rings] = new FlagInput(FlagStrings.Rings),
[FlagStrings.CdrErrorThreshold] = new Int32Input(FlagStrings.CdrErrorThreshold),
[FlagStrings.ScsiTimeout] = new Int32Input(FlagStrings.ScsiTimeout),
// Undocumented
[FlagStrings.Debug] = new FlagInput(FlagStrings.Debug),
@@ -136,8 +140,8 @@ namespace MPF.ExecutionContexts.Redumper
string? drivePath,
string filename,
int? driveSpeed,
Dictionary<string, string?> options)
: base(system, type, drivePath, filename, driveSpeed, options)
BaseDumpSettings baseDumpSettings)
: base(system, type, drivePath, filename, driveSpeed, baseDumpSettings)
{
}
@@ -181,8 +185,8 @@ namespace MPF.ExecutionContexts.Redumper
FlagStrings.PlextorLeadinRetries,
FlagStrings.PlextorLeadinForceStore,
FlagStrings.KreonPartialSS,
FlagStrings.AsusSkipLeadout,
FlagStrings.AsusLeadoutRetries,
FlagStrings.MediatekSkipLeadout,
FlagStrings.MediatekLeadoutRetries,
FlagStrings.DisableCDText,
// Offset
@@ -196,7 +200,7 @@ namespace MPF.ExecutionContexts.Redumper
FlagStrings.LeaveUnchanged,
FlagStrings.ForceQTOC,
FlagStrings.SkipFill,
FlagStrings.ISO9660Trim,
FlagStrings.FilesystemTrim,
// Drive Test
FlagStrings.DriveTestSkipPlextorLeadin,
@@ -206,6 +210,7 @@ namespace MPF.ExecutionContexts.Redumper
FlagStrings.Continue,
FlagStrings.LBAStart,
FlagStrings.LBAEnd,
FlagStrings.LBAEndBySubcode,
FlagStrings.RefineSubchannel,
FlagStrings.RefineSectorMode,
FlagStrings.Skip,
@@ -215,8 +220,10 @@ namespace MPF.ExecutionContexts.Redumper
FlagStrings.ForceUnscrambled,
FlagStrings.ForceRefine,
//FlagStrings.Firmware,
FlagStrings.ForceFlash,
FlagStrings.SkipSubcodeDesync,
FlagStrings.Rings,
FlagStrings.CdrErrorThreshold,
FlagStrings.ScsiTimeout,
// Undocumented
FlagStrings.Debug,
@@ -284,17 +291,20 @@ namespace MPF.ExecutionContexts.Redumper
protected override void SetDefaultParameters(string? drivePath,
string filename,
int? driveSpeed,
Dictionary<string, string?> options)
BaseDumpSettings baseDumpSettings)
{
// Get the base settings, if possible
var dumpSettings = baseDumpSettings as DumpSettings ?? new DumpSettings();
BaseCommand = CommandStrings.Disc;
if (drivePath != null)
if (drivePath is not null)
{
this[FlagStrings.Drive] = true;
(_inputs[FlagStrings.Drive] as StringInput)?.SetValue(drivePath);
}
if (driveSpeed != null && driveSpeed > 0)
if (driveSpeed is not null && driveSpeed > 0)
{
this[FlagStrings.Speed] = true;
(_inputs[FlagStrings.Speed] as Int32Input)?.SetValue(driveSpeed);
@@ -306,52 +316,80 @@ namespace MPF.ExecutionContexts.Redumper
}
// Set user-defined options
if (GetBooleanSetting(options, SettingConstants.EnableVerbose, SettingConstants.EnableVerboseDefault))
if (dumpSettings.EnableVerbose)
{
this[FlagStrings.Verbose] = true;
(_inputs[FlagStrings.Verbose] as FlagInput)?.SetValue(true);
}
if (GetBooleanSetting(options, SettingConstants.EnableSkeleton, SettingConstants.EnableSkeletonDefault))
{
// Enable skeleton for CD and DVD only, by default
switch (MediaType)
{
case SabreTools.RedumpLib.Data.MediaType.CDROM:
case SabreTools.RedumpLib.Data.MediaType.DVD:
this[FlagStrings.Skeleton] = true;
(_inputs[FlagStrings.Skeleton] as FlagInput)?.SetValue(true);
break;
// If the type is unknown, also enable
case null:
this[FlagStrings.Skeleton] = true;
(_inputs[FlagStrings.Skeleton] as FlagInput)?.SetValue(true);
if (dumpSettings.EnableSkeleton)
{
#pragma warning disable IDE0010
switch (RedumpSystem)
{
// Systems known to have significant data outside the ISO9660 filesystem
case SabreTools.RedumpLib.Data.RedumpSystem.MicrosoftXbox:
case SabreTools.RedumpLib.Data.RedumpSystem.MicrosoftXbox360:
case SabreTools.RedumpLib.Data.RedumpSystem.PlaymajiPolymega:
// Skeletons from newer BD-based consoles unnecessary
case SabreTools.RedumpLib.Data.RedumpSystem.MicrosoftXboxOne:
case SabreTools.RedumpLib.Data.RedumpSystem.MicrosoftXboxSeriesXS:
case SabreTools.RedumpLib.Data.RedumpSystem.SonyPlayStation3:
case SabreTools.RedumpLib.Data.RedumpSystem.SonyPlayStation4:
case SabreTools.RedumpLib.Data.RedumpSystem.SonyPlayStation5:
case SabreTools.RedumpLib.Data.RedumpSystem.NintendoWiiU:
break;
default:
// Enable skeleton for CD and DVD only, by default
switch (MediaType)
{
case SabreTools.RedumpLib.Data.MediaType.CDROM:
case SabreTools.RedumpLib.Data.MediaType.DVD:
{
this[FlagStrings.Skeleton] = true;
(_inputs[FlagStrings.Skeleton] as FlagInput)?.SetValue(true);
}
break;
// If the type is unknown, also enable
case null:
this[FlagStrings.Skeleton] = true;
(_inputs[FlagStrings.Skeleton] as FlagInput)?.SetValue(true);
break;
default:
break;
}
break;
}
#pragma warning restore IDE0010
}
string? readMethod = GetStringSetting(options, SettingConstants.ReadMethod, SettingConstants.ReadMethodDefault);
if (!string.IsNullOrEmpty(readMethod) && readMethod != ReadMethod.NONE.ToString())
if (dumpSettings.ReadMethod != ReadMethod.NONE)
{
this[FlagStrings.DriveReadMethod] = true;
(_inputs[FlagStrings.DriveReadMethod] as StringInput)?.SetValue(readMethod!);
(_inputs[FlagStrings.DriveReadMethod] as StringInput)?.SetValue(dumpSettings.ReadMethod.ToString());
}
string? sectorOrder = GetStringSetting(options, SettingConstants.SectorOrder, SettingConstants.SectorOrderDefault);
if (!string.IsNullOrEmpty(sectorOrder) && sectorOrder != SectorOrder.NONE.ToString())
if (dumpSettings.DrivePregapStart != SettingConstants.DrivePregapStartDefault)
{
this[FlagStrings.DrivePregapStart] = true;
(_inputs[FlagStrings.DrivePregapStart] as Int32Input)?.SetValue(dumpSettings.DrivePregapStart);
}
if (dumpSettings.SectorOrder != SectorOrder.NONE)
{
this[FlagStrings.DriveSectorOrder] = true;
(_inputs[FlagStrings.DriveSectorOrder] as StringInput)?.SetValue(sectorOrder!);
(_inputs[FlagStrings.DriveSectorOrder] as StringInput)?.SetValue(dumpSettings.SectorOrder.ToString());
}
string? driveType = GetStringSetting(options, SettingConstants.DriveType, SettingConstants.DriveTypeDefault);
if (!string.IsNullOrEmpty(driveType) && driveType != DriveType.NONE.ToString())
if (dumpSettings.DriveType != DriveType.NONE)
{
this[FlagStrings.DriveType] = true;
(_inputs[FlagStrings.DriveType] as StringInput)?.SetValue(driveType!);
(_inputs[FlagStrings.DriveType] as StringInput)?.SetValue(dumpSettings.DriveType.ToString());
}
// Set the output paths
@@ -372,21 +410,19 @@ namespace MPF.ExecutionContexts.Redumper
}
}
int retries = GetInt32Setting(options, SettingConstants.RereadCount, SettingConstants.RereadCountDefault);
if (retries > 0)
if (dumpSettings.RereadCount > 0)
{
this[FlagStrings.Retries] = true;
(_inputs[FlagStrings.Retries] as Int32Input)?.SetValue(retries);
(_inputs[FlagStrings.Retries] as Int32Input)?.SetValue(dumpSettings.RereadCount);
}
int leadinRetries = GetInt32Setting(options, SettingConstants.LeadinRetryCount, SettingConstants.LeadinRetryCountDefault);
if (leadinRetries != SettingConstants.LeadinRetryCountDefault)
if (dumpSettings.LeadinRetryCount != SettingConstants.LeadinRetryCountDefault)
{
this[FlagStrings.PlextorLeadinRetries] = true;
(_inputs[FlagStrings.PlextorLeadinRetries] as Int32Input)?.SetValue(leadinRetries);
(_inputs[FlagStrings.PlextorLeadinRetries] as Int32Input)?.SetValue(dumpSettings.LeadinRetryCount);
}
if (GetBooleanSetting(options, SettingConstants.RefineSectorMode, SettingConstants.RefineSectorModeDefault))
if (dumpSettings.RefineSectorMode)
{
this[FlagStrings.RefineSectorMode] = true;
(_inputs[FlagStrings.RefineSectorMode] as FlagInput)?.SetValue(true);
@@ -439,7 +475,7 @@ namespace MPF.ExecutionContexts.Redumper
case CommandStrings.DebugFlip:
case CommandStrings.DriveTest:
// Only allow one mode per command
if (BaseCommand != null)
if (BaseCommand is not null)
continue;
BaseCommand = part;
@@ -447,7 +483,11 @@ namespace MPF.ExecutionContexts.Redumper
// Default is either a flag or an invalid mode
default:
#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER
if (part.StartsWith('-'))
#else
if (part.StartsWith("-"))
#endif
{
isFlag = true;
break;
@@ -480,7 +520,7 @@ namespace MPF.ExecutionContexts.Redumper
// If the image name was not set, set it with a default value
if (string.IsNullOrEmpty((_inputs[FlagStrings.ImageName] as StringInput)?.Value))
(_inputs[FlagStrings.ImageName] as StringInput)?.SetValue("track");
(_inputs[FlagStrings.ImageName] as StringInput)?.SetValue($"track_{DateTime.Now:yyyyMMdd-HHmm}");
return true;
}

View File

@@ -42,8 +42,8 @@ namespace MPF.ExecutionContexts.Redumper
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 MediatekSkipLeadout = "--mediatek-skip-leadout";
public const string MediatekLeadoutRetries = "--mediatek-leadout-retries";
public const string DisableCDText = "--disable-cdtext";
#endregion
@@ -63,7 +63,7 @@ namespace MPF.ExecutionContexts.Redumper
public const string LeaveUnchanged = "--leave-unchanged";
public const string ForceQTOC = "--force-qtoc";
public const string SkipFill = "--skip-fill";
public const string ISO9660Trim = "--iso9660-trim";
public const string FilesystemTrim = "--filesystem-trim";
#endregion
@@ -79,6 +79,7 @@ namespace MPF.ExecutionContexts.Redumper
public const string Continue = "--continue";
public const string LBAStart = "--lba-start";
public const string LBAEnd = "--lba-end";
public const string LBAEndBySubcode = "--lba-end-by-subcode";
public const string RefineSubchannel = "--refine-subchannel";
public const string RefineSectorMode = "--refine-sector-mode";
public const string Skip = "--skip";
@@ -88,8 +89,10 @@ namespace MPF.ExecutionContexts.Redumper
public const string ForceUnscrambled = "--force-unscrambled";
public const string ForceRefine = "--force-refine";
public const string Firmware = "--firmware";
public const string ForceFlash = "--force-flash";
public const string SkipSubcodeDesync = "--skip-subcode-desync";
public const string Rings = "--rings";
public const string CdrErrorThreshold = "--cdr-error-threshold";
public const string ScsiTimeout = "--scsi-timeout";
#endregion

View File

@@ -3,7 +3,7 @@ namespace MPF.ExecutionContexts.Redumper
public static class SettingConstants
{
public const string DriveType = "RedumperDriveType";
public static readonly string DriveTypeDefault = Redumper.DriveType.NONE.ToString();
public static readonly DriveType DriveTypeDefault = Redumper.DriveType.NONE;
public const string EnableSkeleton = "RedumperEnableSkeleton";
public const bool EnableSkeletonDefault = true;
@@ -14,8 +14,11 @@ namespace MPF.ExecutionContexts.Redumper
public const string LeadinRetryCount = "RedumperLeadinRetryCount";
public const int LeadinRetryCountDefault = 4;
public const string DrivePregapStart = "RedumperDrivePregapStart";
public const int DrivePregapStartDefault = 0;
public const string ReadMethod = "RedumperReadMethod";
public static readonly string ReadMethodDefault = Redumper.ReadMethod.NONE.ToString();
public static readonly ReadMethod ReadMethodDefault = Redumper.ReadMethod.NONE;
public const string RefineSectorMode = "RedumperRefineSectorMode";
public const bool RefineSectorModeDefault = false;
@@ -24,6 +27,6 @@ namespace MPF.ExecutionContexts.Redumper
public const int RereadCountDefault = 20;
public const string SectorOrder = "RedumperSectorOrder";
public static readonly string SectorOrderDefault = Redumper.SectorOrder.NONE.ToString();
public static readonly SectorOrder SectorOrderDefault = Redumper.SectorOrder.NONE;
}
}

View File

@@ -43,7 +43,7 @@ namespace MPF.Frontend.Test
public static List<object?[]> GenerateDriveTypeMappingTestData()
{
var testData = new List<object?[]>() { new object?[] { null, true } };
foreach (DriveType driveType in Enum.GetValues(typeof(DriveType)))
foreach (DriveType driveType in Enum.GetValues<DriveType>())
{
if (Array.IndexOf(_mappableDriveTypes, driveType) > -1)
testData.Add([driveType, false]);

View File

@@ -13,9 +13,10 @@ namespace MPF.Frontend.Test
[InlineData("fd A test.img", 'A', true, MediaType.FloppyDisk, true)]
[InlineData("dvd X test.iso 8 /raw", 'X', false, MediaType.FloppyDisk, false)]
[InlineData("stop D", 'D', false, MediaType.DVD, true)]
public void ParametersValidTest(string? parameters, char letter, bool isFloppy, MediaType? mediaType, bool expected)
public void ParametersValidSegmentedTest(string? parameters, char letter, bool isFloppy, MediaType? mediaType, bool expected)
{
var options = new Options() { InternalProgram = InternalProgram.DiscImageCreator };
var options = new Options();
options.InternalProgram = InternalProgram.DiscImageCreator;
// TODO: This relies on creating real objects for the drive. Can we mock this out instead?
var drive = isFloppy

View File

@@ -14,11 +14,39 @@ namespace MPF.Frontend.Test
{
#region Long Name
[Theory]
[InlineData(null, "Unknown")]
[InlineData(InterfaceLanguage.AutoDetect, "Auto Detect")]
[InlineData(InterfaceLanguage.English, "English")]
[InlineData(InterfaceLanguage.French, "Français")]
[InlineData(InterfaceLanguage.German, "Deutsch")]
[InlineData(InterfaceLanguage.Italian, "Italiano")]
[InlineData(InterfaceLanguage.Japanese, "日本語")]
[InlineData(InterfaceLanguage.Korean, "한국어")]
[InlineData(InterfaceLanguage.Polish, "Polski")]
[InlineData(InterfaceLanguage.Russian, "Русский")]
[InlineData(InterfaceLanguage.Spanish, "Español")]
[InlineData(InterfaceLanguage.Swedish, "Svenska")]
[InlineData(InterfaceLanguage.Ukrainian, "Українська")]
[InlineData(InterfaceLanguage.L337, "L337")]
public void LongName_InterfaceLanguage(InterfaceLanguage? lang, string? expected)
{
string? actual = lang.LongName();
Assert.Equal(expected, actual);
if (lang is not null)
{
actual = EnumExtensions.GetLongName(lang);
Assert.Equal(expected, actual);
}
}
[Theory]
[InlineData(null, "Unknown")]
[InlineData(InternalProgram.NONE, "Unknown")]
[InlineData(InternalProgram.Aaru, "Aaru")]
[InlineData(InternalProgram.DiscImageCreator, "DiscImageCreator")]
// [InlineData(InternalProgram.Dreamdump, "Dreamdump")]
[InlineData(InternalProgram.Redumper, "Redumper")]
[InlineData(InternalProgram.CleanRip, "CleanRip")]
[InlineData(InternalProgram.PS3CFW, "PS3 CFW")]
@@ -29,7 +57,7 @@ namespace MPF.Frontend.Test
string? actual = prog.LongName();
Assert.Equal(expected, actual);
if (prog != null)
if (prog is not null)
{
actual = EnumExtensions.GetLongName(prog);
Assert.Equal(expected, actual);
@@ -46,7 +74,7 @@ namespace MPF.Frontend.Test
string? actual = comp.LongName();
Assert.Equal(expected, actual);
if (comp != null)
if (comp is not null)
{
actual = EnumExtensions.GetLongName(comp);
Assert.Equal(expected, actual);
@@ -63,7 +91,7 @@ namespace MPF.Frontend.Test
string? actual = method.LongName();
Assert.Equal(expected, actual);
if (method != null)
if (method is not null)
{
actual = EnumExtensions.GetLongName(method);
Assert.Equal(expected, actual);
@@ -82,7 +110,7 @@ namespace MPF.Frontend.Test
string? actual = order.LongName();
Assert.Equal(expected, actual);
if (order != null)
if (order is not null)
{
actual = EnumExtensions.GetLongName(order);
Assert.Equal(expected, actual);
@@ -94,17 +122,17 @@ namespace MPF.Frontend.Test
[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")]
[InlineData(RedumperDriveType.MTK8A, "MTK8A")]
[InlineData(RedumperDriveType.MTK8B, "MTK8B")]
[InlineData(RedumperDriveType.MTK8C, "MTK8C")]
[InlineData(RedumperDriveType.MTK3, "MTK3")]
[InlineData(RedumperDriveType.MTK2, "MTK2")]
public void LongName_RedumperDriveType(RedumperDriveType? type, string? expected)
{
string? actual = type.LongName();
Assert.Equal(expected, actual);
if (type != null)
if (type is not null)
{
actual = EnumExtensions.GetLongName(type);
Assert.Equal(expected, actual);
@@ -115,11 +143,33 @@ namespace MPF.Frontend.Test
#region Short Name
[Theory]
[InlineData(null, "Unknown")]
[InlineData(InterfaceLanguage.AutoDetect, "auto")]
[InlineData(InterfaceLanguage.English, "eng")]
[InlineData(InterfaceLanguage.French, "fra")]
[InlineData(InterfaceLanguage.German, "deu")]
[InlineData(InterfaceLanguage.Italian, "ita")]
[InlineData(InterfaceLanguage.Japanese, "jpn")]
[InlineData(InterfaceLanguage.Korean, "kor")]
[InlineData(InterfaceLanguage.Polish, "pol")]
[InlineData(InterfaceLanguage.Russian, "rus")]
[InlineData(InterfaceLanguage.Spanish, "spa")]
[InlineData(InterfaceLanguage.Swedish, "swe")]
[InlineData(InterfaceLanguage.Ukrainian, "ukr")]
[InlineData(InterfaceLanguage.L337, "l37")]
public void ShortName_InterfaceLanguage(InterfaceLanguage? lang, string? expected)
{
string? actual = lang.ShortName();
Assert.Equal(expected, actual);
}
[Theory]
[InlineData(null, "Unknown")]
[InlineData(InternalProgram.NONE, "Unknown")]
[InlineData(InternalProgram.Aaru, "aaru")]
[InlineData(InternalProgram.DiscImageCreator, "dic")]
// [InlineData(InternalProgram.Dreamdump, "dreamdump")]
[InlineData(InternalProgram.Redumper, "redumper")]
[InlineData(InternalProgram.CleanRip, "cleanrip")]
[InlineData(InternalProgram.PS3CFW, "ps3cfw")]
@@ -135,11 +185,34 @@ namespace MPF.Frontend.Test
#region From String
[Theory]
[InlineData(null, InterfaceLanguage.AutoDetect)]
[InlineData("", InterfaceLanguage.AutoDetect)]
[InlineData("auto", InterfaceLanguage.AutoDetect)]
[InlineData("eng", InterfaceLanguage.English)]
[InlineData("fra", InterfaceLanguage.French)]
[InlineData("deu", InterfaceLanguage.German)]
[InlineData("ita", InterfaceLanguage.Italian)]
[InlineData("jpn", InterfaceLanguage.Japanese)]
[InlineData("kor", InterfaceLanguage.Korean)]
[InlineData("pol", InterfaceLanguage.Polish)]
[InlineData("rus", InterfaceLanguage.Russian)]
[InlineData("spa", InterfaceLanguage.Spanish)]
[InlineData("swe", InterfaceLanguage.Swedish)]
[InlineData("ukr", InterfaceLanguage.Ukrainian)]
[InlineData("l37", InterfaceLanguage.L337)]
public void ToInterfaceLanguageTest(string? interfaceLanguage, InterfaceLanguage expected)
{
InterfaceLanguage actual = interfaceLanguage.ToInterfaceLanguage();
Assert.Equal(expected, actual);
}
[Theory]
[InlineData(null, InternalProgram.NONE)]
[InlineData("", InternalProgram.NONE)]
[InlineData("aaru", InternalProgram.Aaru)]
[InlineData("dic", InternalProgram.DiscImageCreator)]
// [InlineData("dreamdump", InternalProgram.Dreamdump)]
[InlineData("redumper", InternalProgram.Redumper)]
[InlineData("cleanrip", InternalProgram.CleanRip)]
[InlineData("ps3cfw", InternalProgram.PS3CFW)]
@@ -165,6 +238,7 @@ namespace MPF.Frontend.Test
private static readonly RedumpSystem?[] _copyProtectionSystems =
[
RedumpSystem.AppleMacintosh,
RedumpSystem.DVDVideo,
RedumpSystem.EnhancedCD ,
RedumpSystem.IBMPCcompatible,
RedumpSystem.PalmOS,
@@ -192,7 +266,7 @@ namespace MPF.Frontend.Test
public static List<object?[]> GenerateSupportsAntiModchipScansData()
{
var testData = new List<object?[]>() { new object?[] { null, false } };
foreach (RedumpSystem redumpSystem in Enum.GetValues(typeof(RedumpSystem)))
foreach (RedumpSystem redumpSystem in Enum.GetValues<RedumpSystem>())
{
if (_antiModchipSystems.Contains(redumpSystem))
testData.Add([redumpSystem, true]);
@@ -206,7 +280,7 @@ namespace MPF.Frontend.Test
public static List<object?[]> GenerateSupportsCopyProtectionScansData()
{
var testData = new List<object?[]>() { new object?[] { null, false } };
foreach (RedumpSystem redumpSystem in Enum.GetValues(typeof(RedumpSystem)))
foreach (RedumpSystem redumpSystem in Enum.GetValues<RedumpSystem>())
{
if (_copyProtectionSystems.Contains(redumpSystem))
testData.Add([redumpSystem, true]);

View File

@@ -18,7 +18,7 @@ namespace MPF.Frontend.Test
public void GetAllowedDriveSpeedForMediaTypeTest(MediaType? mediaType, int maxExpected)
{
var actual = InterfaceConstants.GetSpeedsForMediaType(mediaType);
Assert.Equal(maxExpected, actual[actual.Count - 1]);
Assert.Equal(maxExpected, actual[^1]);
}
}
}

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net8.0;net9.0</TargetFrameworks>
<TargetFrameworks>net8.0;net9.0;net10.0</TargetFrameworks>
<CheckEolTargetFramework>false</CheckEolTargetFramework>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
@@ -14,13 +14,13 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeCoverage" Version="17.14.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
<PackageReference Include="Microsoft.CodeCoverage" Version="18.0.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.0.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
<PackageReference Include="SabreTools.RedumpLib" Version="[1.7.4]" />
<PackageReference Include="SabreTools.RedumpLib" Version="[1.9.1]" />
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.abstractions" Version="2.0.3" />
<PackageReference Include="xunit.analyzers" Version="1.24.0" />
<PackageReference Include="xunit.analyzers" Version="1.27.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" />

View File

@@ -1,47 +0,0 @@
using System.Collections.Generic;
using Xunit;
namespace MPF.Frontend.Test
{
public class OptionsTests
{
[Theory]
[InlineData("key2", null, "key", false, false)]
[InlineData("key", null, "key", false, false)]
[InlineData("key", "", "key", false, false)]
[InlineData("key", "INVALID", "key", false, false)]
[InlineData("key", "true", "key", false, true)]
public void GetBooleanSettingTest(string key, string? value, string expectedKey, bool defaultValue, bool expectedValue)
{
Dictionary<string, string?> settings = new() { [key] = value };
bool actual = Options.GetBooleanSetting(settings, expectedKey, defaultValue);
Assert.Equal(expectedValue, actual);
}
[Theory]
[InlineData("key2", null, "key", -1, -1)]
[InlineData("key", null, "key", -1, -1)]
[InlineData("key", "", "key", -1, -1)]
[InlineData("key", "INVALID", "key", -1, -1)]
[InlineData("key", "12345", "key", -1, 12345)]
public void GetInt32SettingTest(string key, string? value, string expectedKey, int defaultValue, int expectedValue)
{
Dictionary<string, string?> settings = new() { [key] = value };
int actual = Options.GetInt32Setting(settings, expectedKey, defaultValue);
Assert.Equal(expectedValue, actual);
}
[Theory]
[InlineData("key2", null, "key", null, null)]
[InlineData("key", null, "key", null, null)]
[InlineData("key", "", "key", null, "")]
[InlineData("key", "INVALID", "key", null, "INVALID")]
[InlineData("key", "String", "key", null, "String")]
public void GetStringSettingTest(string key, string? value, string expectedKey, string? defaultValue, string? expectedValue)
{
Dictionary<string, string?> settings = new() { [key] = value };
string? actual = Options.GetStringSetting(settings, expectedKey, defaultValue);
Assert.Equal(expectedValue, actual);
}
}
}

View File

@@ -4,6 +4,23 @@ namespace MPF.Frontend.Test
{
public class ResultEventArgsTests
{
[Fact]
public void EmptyNeutralTest()
{
var actual = ResultEventArgs.Neutral();
Assert.Null((bool?)actual);
Assert.Empty(actual.Message);
}
[Fact]
public void CustomMessageNeutralTest()
{
string message = "Success!";
var actual = ResultEventArgs.Neutral(message);
Assert.Null((bool?)actual);
Assert.Equal(message, actual.Message);
}
[Fact]
public void EmptySuccessTest()
{

View File

@@ -19,15 +19,13 @@ namespace MPF.Frontend.Test.Tools
[InlineData(MediaType.HDDVD, 24)]
[InlineData(MediaType.BluRay, 16)]
[InlineData(MediaType.NintendoWiiUOpticalDisc, 16)]
public void GetDefaultSpeedForMediaTypeTest(MediaType? mediaType, int expected)
public void GetDefaultSpeedForMediaTypeSegmentedTest(MediaType? mediaType, int expected)
{
Options options = new Options
{
PreferredDumpSpeedCD = 72,
PreferredDumpSpeedDVD = 24,
PreferredDumpSpeedHDDVD = 24,
PreferredDumpSpeedBD = 16,
};
var options = new Options();
options.Dumping.DumpSpeeds.CD = 72;
options.Dumping.DumpSpeeds.DVD = 24;
options.Dumping.DumpSpeeds.HDDVD = 24;
options.Dumping.DumpSpeeds.Bluray = 16;
int actual = FrontendTool.GetDefaultSpeedForMediaType(mediaType, options);
Assert.Equal(expected, actual);
@@ -97,4 +95,4 @@ namespace MPF.Frontend.Test.Tools
#endregion
}
}
}

View File

@@ -1,8 +1,7 @@
using System.Collections.Generic;
using System.IO;
using MPF.Frontend.Tools;
using SabreTools.RedumpLib;
using SabreTools.RedumpLib.Data;
using SabreTools.RedumpLib.Data.Sections;
using Xunit;
namespace MPF.Frontend.Test.Tools
@@ -10,7 +9,7 @@ namespace MPF.Frontend.Test.Tools
public class InfoToolTests
{
[Fact]
public void ProcessSpecialFieldsCompleteTest()
public void ProcessSpecialFields_Complete()
{
// Create a new SubmissionInfo object
var info = new SubmissionInfo()
@@ -36,9 +35,9 @@ namespace MPF.Frontend.Test.Tools
// Validate the basics
Assert.NotNull(info.CommonDiscInfo.Comments);
Assert.Null(info.CommonDiscInfo.CommentsSpecialFields);
Assert.Empty(info.CommonDiscInfo.CommentsSpecialFields);
Assert.NotNull(info.CommonDiscInfo.Contents);
Assert.Null(info.CommonDiscInfo.ContentsSpecialFields);
Assert.Empty(info.CommonDiscInfo.ContentsSpecialFields);
// Split the values
string[] splitComments = info.CommonDiscInfo.Comments.Split('\n');
@@ -50,23 +49,7 @@ namespace MPF.Frontend.Test.Tools
}
[Fact]
public void ProcessSpecialFieldsNullObjectTest()
{
// Create a new SubmissionInfo object
var info = new SubmissionInfo()
{
CommonDiscInfo = null,
};
// Process the special fields
Formatter.ProcessSpecialFields(info);
// Validate
Assert.Null(info.CommonDiscInfo);
}
[Fact]
public void ProcessSpecialFieldsNullCommentsContentsTest()
public void ProcessSpecialFields_NullStrings()
{
// Create a new SubmissionInfo object
var info = new SubmissionInfo()
@@ -92,9 +75,9 @@ namespace MPF.Frontend.Test.Tools
// Validate the basics
Assert.NotNull(info.CommonDiscInfo.Comments);
Assert.Null(info.CommonDiscInfo.CommentsSpecialFields);
Assert.Empty(info.CommonDiscInfo.CommentsSpecialFields);
Assert.NotNull(info.CommonDiscInfo.Contents);
Assert.Null(info.CommonDiscInfo.ContentsSpecialFields);
Assert.Empty(info.CommonDiscInfo.ContentsSpecialFields);
// Split the values
string[] splitComments = info.CommonDiscInfo.Comments.Split('\n');
@@ -106,7 +89,7 @@ namespace MPF.Frontend.Test.Tools
}
[Fact]
public void ProcessSpecialFieldsNullDictionariesTest()
public void ProcessSpecialFields_EmptyDictionaries()
{
// Create a new SubmissionInfo object
var info = new SubmissionInfo()
@@ -114,10 +97,10 @@ namespace MPF.Frontend.Test.Tools
CommonDiscInfo = new CommonDiscInfoSection()
{
Comments = "This is a comments line\n[T:ISBN] ISBN Value",
CommentsSpecialFields = null,
CommentsSpecialFields = [],
Contents = "This is a contents line\n[T:GF] Game Footage",
ContentsSpecialFields = null,
ContentsSpecialFields = [],
}
};
@@ -126,9 +109,9 @@ namespace MPF.Frontend.Test.Tools
// Validate the basics
Assert.NotNull(info.CommonDiscInfo.Comments);
Assert.Null(info.CommonDiscInfo.CommentsSpecialFields);
Assert.Empty(info.CommonDiscInfo.CommentsSpecialFields);
Assert.NotNull(info.CommonDiscInfo.Contents);
Assert.Null(info.CommonDiscInfo.ContentsSpecialFields);
Assert.Empty(info.CommonDiscInfo.ContentsSpecialFields);
// Split the values
string[] splitComments = info.CommonDiscInfo.Comments.Split('\n');

View File

@@ -363,6 +363,19 @@ namespace MPF.Frontend.Test.Tools
Assert.Empty(sanitized);
}
[Fact]
public void SanitizeFoundProtections_MPRESS()
{
List<string> protections =
[
"MPRESS",
"MPRESS ANYTHING",
];
string sanitized = ProtectionTool.SanitizeFoundProtections(protections);
Assert.Empty(sanitized);
}
[Fact]
public void SanitizeFoundProtections_NeoLite()
{
@@ -661,7 +674,7 @@ namespace MPF.Frontend.Test.Tools
throw new ArgumentException("Invalid skip value", nameof(skip));
// The list is in order of preference
protections = protections.Skip(skip).ToList();
protections = [.. protections.Skip(skip)];
string sanitized = ProtectionTool.SanitizeFoundProtections(protections);
Assert.Equal(protections[0], sanitized);
@@ -711,7 +724,7 @@ namespace MPF.Frontend.Test.Tools
throw new ArgumentException("Invalid skip value", nameof(skip));
// The list is in order of preference
protections = protections.Skip(skip).ToList();
protections = [.. protections.Skip(skip)];
string sanitized = ProtectionTool.SanitizeFoundProtections(protections);
Assert.Equal(expected, sanitized);
@@ -770,12 +783,27 @@ namespace MPF.Frontend.Test.Tools
throw new ArgumentException("Invalid skip value", nameof(skip));
// The list is in order of preference
protections = protections.Skip(skip).ToList();
protections = [.. protections.Skip(skip)];
string sanitized = ProtectionTool.SanitizeFoundProtections(protections);
Assert.Equal(protections[0], sanitized);
}
[Fact]
public void SanitizeFoundProtections_StarForce_Keyless()
{
List<string> protections =
[
"StarForce Keyless",
"StarForce Keyless - ",
"StarForce Keyless - ESPY97LS8FHNYR52JDWL8D6FJ",
"StarForce Keyless - UAYA-RPMVHJ-ZRY45G-ETUJ36-WL922B",
];
string sanitized = ProtectionTool.SanitizeFoundProtections(protections);
Assert.Equal("StarForce Keyless", sanitized);
}
[Fact]
public void SanitizeFoundProtections_Sysiphus()
{

View File

@@ -6,18 +6,18 @@ namespace MPF.Frontend.ComboBoxItems
/// <summary>
/// A generic combo box element
/// </summary>
/// <typeparam name="T">Enum type representing the possible values</typeparam>
public class Element<T> : IEquatable<Element<T>>, IElement where T : struct, Enum
/// <typeparam name="TEnum">Enum type representing the possible values</typeparam>
public class Element<TEnum> : IEquatable<Element<TEnum>>, IElement where TEnum : struct, Enum
{
private readonly T Data;
private readonly TEnum Data;
public Element(T data) => Data = data;
public Element(TEnum data) => Data = data;
/// <summary>
/// Allow elements to be used as their internal enum type
/// </summary>
/// <param name="item"></param>
public static implicit operator T? (Element<T> item) => item?.Data;
public static implicit operator TEnum?(Element<TEnum> item) => item?.Data;
/// <inheritdoc/>
public string Name => EnumExtensions.GetLongName(Data);
@@ -27,7 +27,7 @@ namespace MPF.Frontend.ComboBoxItems
/// <summary>
/// Internal enum value
/// </summary>
public T Value => Data;
public TEnum Value => Data;
/// <summary>
/// Determine if the item is selected or not
@@ -39,22 +39,22 @@ namespace MPF.Frontend.ComboBoxItems
/// Generate all elements associated with the data enum type
/// </summary>
/// <returns></returns>
public static List<Element<T>> GenerateElements()
public static List<Element<TEnum>> GenerateElements()
{
var enumArr = (T[])Enum.GetValues(typeof(T));
return [.. Array.ConvertAll(enumArr, e => new Element<T>(e))];
var enumArr = (TEnum[])Enum.GetValues(typeof(TEnum));
return [.. Array.ConvertAll(enumArr, e => new Element<TEnum>(e))];
}
/// <inheritdoc/>
public override bool Equals(object? obj)
{
return Equals(obj as Element<T>);
return Equals(obj as Element<TEnum>);
}
/// <inheritdoc/>
public bool Equals(Element<T>? other)
public bool Equals(Element<TEnum>? other)
{
if (other == null)
if (other is null)
return false;
return Name == other.Name;

View File

@@ -5,6 +5,6 @@
/// <summary>
/// Display name for the combo box element
/// </summary>
string Name { get; }
public string Name { get; }
}
}

View File

@@ -84,7 +84,7 @@ namespace MPF.Frontend.ComboBoxItems
var systemsValues = new List<RedumpSystemComboBoxItem>
{
new RedumpSystemComboBoxItem((RedumpSystem?)null),
new((RedumpSystem?)null),
};
foreach (var group in mapping)
@@ -105,7 +105,7 @@ namespace MPF.Frontend.ComboBoxItems
/// <inheritdoc/>
public bool Equals(RedumpSystemComboBoxItem? other)
{
if (other == null)
if (other is null)
return false;
return Value == other.Value;

View File

@@ -10,7 +10,14 @@ namespace MPF.Frontend
/// </summary>
public static void ProgressUpdated(object? sender, ResultEventArgs value)
{
Console.WriteLine(value.Message);
string prefix = (bool?)value switch
{
true => "SUCCESS: ",
false => "FAILURE: ",
_ => "",
};
Console.WriteLine($"{prefix}{value.Message}");
}
/// <summary>

View File

@@ -86,11 +86,15 @@ namespace MPF.Frontend
// Sanitize a Windows-formatted long device path
if (devicePath.StartsWith("\\\\.\\"))
#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER
devicePath = devicePath["\\\\.\\".Length..];
#else
devicePath = devicePath.Substring("\\\\.\\".Length);
#endif
// Create and validate the drive info object
var driveInfo = new DriveInfo(devicePath);
if (driveInfo == null || driveInfo == default)
if (driveInfo is null || driveInfo == default)
return null;
// Fill in the rest of the data
@@ -106,7 +110,7 @@ namespace MPF.Frontend
private void PopulateFromDriveInfo(DriveInfo? driveInfo)
{
// If we have an invalid DriveInfo, just return
if (driveInfo == null || driveInfo == default)
if (driveInfo is null || driveInfo == default)
return;
// Populate the data fields
@@ -138,8 +142,8 @@ namespace MPF.Frontend
var drives = GetDriveList(ignoreFixedDrives);
drives.Sort((d1, d2) =>
{
string d1Name = d1?.Name == null ? "\0" : d1.Name;
string d2Name = d2?.Name == null ? "\0" : d2.Name;
string d1Name = d1?.Name is null ? "\0" : d1.Name;
string d2Name = d2?.Name is null ? "\0" : d2.Name;
return d1Name.CompareTo(d2Name);
});
return [.. drives];
@@ -152,6 +156,7 @@ namespace MPF.Frontend
/// <returns>The detected media type, if possible</returns>
public MediaType? GetMediaType(RedumpSystem? system)
{
#pragma warning disable IDE0010
// Take care of the non-optical stuff first
switch (InternalDriveType)
{
@@ -211,6 +216,7 @@ namespace MPF.Frontend
case RedumpSystem.SonyPlayStationPortable:
return MediaType.UMD;
}
#pragma warning restore IDE0010
// Handle optical media by size and filesystem
if (TotalSize >= 0 && TotalSize <= 800_000_000 && (DriveFormat == "CDFS" || DriveFormat == "UDF"))
@@ -282,12 +288,12 @@ namespace MPF.Frontend
{
CimKeyedCollection<CimProperty> properties = instance.CimInstanceProperties;
uint? mediaType = properties["MediaType"]?.Value as uint?;
if (mediaType != null && ((mediaType > 0 && mediaType < 11) || (mediaType > 12 && mediaType < 22)))
if (mediaType is not null && ((mediaType > 0 && mediaType < 11) || (mediaType > 12 && mediaType < 22)))
{
char devId = (properties["Caption"].Value as string ?? string.Empty)[0];
Array.ForEach(drives, d =>
{
if (d?.Name != null && d.Name[0] == devId)
if (d?.Name is not null && d.Name[0] == devId)
d.InternalDriveType = Frontend.InternalDriveType.Floppy;
});
}
@@ -309,6 +315,7 @@ namespace MPF.Frontend
/// <returns>InternalDriveType, if possible, null on error</returns>
internal static InternalDriveType? ToInternalDriveType(DriveType driveType)
{
#pragma warning disable IDE0072
return driveType switch
{
DriveType.CDRom => (InternalDriveType?)Frontend.InternalDriveType.Optical,
@@ -316,6 +323,7 @@ namespace MPF.Frontend
DriveType.Removable => (InternalDriveType?)Frontend.InternalDriveType.Removable,
_ => null,
};
#pragma warning restore IDE0072
}
#endregion

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
@@ -81,11 +81,7 @@ namespace MPF.Frontend
public int? Speed
{
get => _executionContext?.Speed;
set
{
if (_executionContext != null)
_executionContext.Speed = value;
}
set => _executionContext?.Speed = value;
}
/// <inheritdoc cref="Extensions.LongName(RedumpSystem?)/>
@@ -117,14 +113,14 @@ namespace MPF.Frontend
InternalProgram? internalProgram)
{
// Set options object
_options = options;
_options = new Options(options);
// Output paths
OutputPath = FrontendTool.NormalizeOutputPaths(outputPath, false);
// UI information
_drive = drive;
_system = system ?? options.DefaultSystem;
_system = system ?? options.Dumping.DefaultSystem;
_internalProgram = internalProgram ?? options.InternalProgram;
}
@@ -137,28 +133,38 @@ namespace MPF.Frontend
{
// If a complete dump exists from a different program
InternalProgram? programFound = null;
if (programFound == null && _internalProgram != InternalProgram.Redumper)
if (programFound is null && _internalProgram != InternalProgram.Redumper)
{
var processor = new Processors.Redumper(_system);
var processor = new Redumper(_system);
var missingFiles = processor.FoundAllFiles(mediaType, outputDirectory, outputFilename);
if (missingFiles.Count == 0)
programFound = InternalProgram.Redumper;
}
if (programFound == null && _internalProgram != InternalProgram.DiscImageCreator)
if (programFound is null && _internalProgram != InternalProgram.DiscImageCreator)
{
var processor = new Processors.DiscImageCreator(_system);
var processor = new DiscImageCreator(_system);
var missingFiles = processor.FoundAllFiles(mediaType, outputDirectory, outputFilename);
if (missingFiles.Count == 0)
programFound = InternalProgram.DiscImageCreator;
}
if (programFound == null && _internalProgram != InternalProgram.Aaru)
if (programFound is null && _internalProgram != InternalProgram.Aaru)
{
var processor = new Processors.Aaru(_system);
var processor = new Aaru(_system);
var missingFiles = processor.FoundAllFiles(mediaType, outputDirectory, outputFilename);
if (missingFiles.Count == 0)
programFound = InternalProgram.Aaru;
}
// if (programFound is null && _internalProgram != InternalProgram.Dreamdump)
// {
// var processor = new Dreamdump(_system);
// var missingFiles = processor.FoundAllFiles(mediaType, outputDirectory, outputFilename);
// if (missingFiles.Count == 0)
// programFound = InternalProgram.Dreamdump;
// }
return programFound;
}
@@ -169,25 +175,34 @@ namespace MPF.Frontend
{
// If a complete dump exists from a different program
InternalProgram? programFound = null;
if (programFound == null && _internalProgram != InternalProgram.Redumper)
if (programFound is null && _internalProgram != InternalProgram.Redumper)
{
var processor = new Processors.Redumper(_system);
var processor = new Redumper(_system);
if (processor.FoundAnyFiles(mediaType, outputDirectory, outputFilename))
programFound = InternalProgram.Redumper;
}
if (programFound == null && _internalProgram != InternalProgram.DiscImageCreator)
if (programFound is null && _internalProgram != InternalProgram.DiscImageCreator)
{
var processor = new Processors.DiscImageCreator(_system);
var processor = new DiscImageCreator(_system);
if (processor.FoundAnyFiles(mediaType, outputDirectory, outputFilename))
programFound = InternalProgram.DiscImageCreator;
}
if (programFound == null && _internalProgram != InternalProgram.Aaru)
if (programFound is null && _internalProgram != InternalProgram.Aaru)
{
var processor = new Processors.Aaru(_system);
var processor = new Aaru(_system);
if (processor.FoundAnyFiles(mediaType, outputDirectory, outputFilename))
programFound = InternalProgram.Aaru;
}
// if (programFound is null && _internalProgram != InternalProgram.Dreamdump)
// {
// var processor = new Dreamdump(_system);
// if (processor.FoundAnyFiles(mediaType, outputDirectory, outputFilename))
// programFound = InternalProgram.Dreamdump;
// }
return programFound;
}
@@ -198,19 +213,22 @@ namespace MPF.Frontend
/// <param name="parameters">String representation of the parameters</param>
public bool SetExecutionContext(MediaType? mediaType, string? parameters)
{
#pragma warning disable IDE0072
_executionContext = _internalProgram switch
{
InternalProgram.Aaru => new ExecutionContexts.Aaru.ExecutionContext(parameters) { ExecutablePath = _options.AaruPath },
InternalProgram.DiscImageCreator => new ExecutionContexts.DiscImageCreator.ExecutionContext(parameters) { ExecutablePath = _options.DiscImageCreatorPath },
InternalProgram.Redumper => new ExecutionContexts.Redumper.ExecutionContext(parameters) { ExecutablePath = _options.RedumperPath },
InternalProgram.Aaru => new ExecutionContexts.Aaru.ExecutionContext(parameters) { ExecutablePath = _options.Dumping.AaruPath },
InternalProgram.DiscImageCreator => new ExecutionContexts.DiscImageCreator.ExecutionContext(parameters) { ExecutablePath = _options.Dumping.DiscImageCreatorPath },
// InternalProgram.Dreamdump => new ExecutionContexts.Dreamdump.ExecutionContext(parameters) { ExecutablePath = _options.Dumping.DreamdumpPath },
InternalProgram.Redumper => new ExecutionContexts.Redumper.ExecutionContext(parameters) { ExecutablePath = _options.Dumping.RedumperPath },
// If no dumping program found, set to null
InternalProgram.NONE => null,
_ => null,
};
#pragma warning restore IDE0072
// Set system, type, and drive
if (_executionContext != null)
if (_executionContext is not null)
{
_executionContext.RedumpSystem = _system;
_executionContext.MediaType = mediaType;
@@ -220,7 +238,7 @@ namespace MPF.Frontend
_drive ??= Drive.Create(InternalDriveType.Optical, _executionContext.InputPath!);
}
return _executionContext != null;
return _executionContext is not null;
}
/// <summary>
@@ -230,9 +248,10 @@ namespace MPF.Frontend
{
_processor = _internalProgram switch
{
InternalProgram.Aaru => new Processors.Aaru(_system),
InternalProgram.Aaru => new Aaru(_system),
InternalProgram.CleanRip => new CleanRip(_system),
InternalProgram.DiscImageCreator => new DiscImageCreator(_system),
// InternalProgram.Dreamdump => new Dreamdump(_system),
InternalProgram.PS3CFW => new PS3CFW(_system),
InternalProgram.Redumper => new Redumper(_system),
InternalProgram.UmdImageCreator => new UmdImageCreator(_system),
@@ -243,7 +262,7 @@ namespace MPF.Frontend
_ => null,
};
return _processor != null;
return _processor is not null;
}
/// <summary>
@@ -255,23 +274,49 @@ namespace MPF.Frontend
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 && mediaType != MediaType.NONE)
if (_system is not null && mediaType != MediaType.NONE)
{
// If drive letter is invalid, skip this
if (_drive == null)
if (_drive is null)
return null;
#pragma warning disable IDE0072
// Set the proper parameters
_executionContext = _internalProgram switch
{
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),
InternalProgram.Aaru => new ExecutionContexts.Aaru.ExecutionContext(_system,
mediaType,
_drive.Name,
OutputPath,
driveSpeed,
_options.Dumping.Aaru),
InternalProgram.DiscImageCreator => new ExecutionContexts.DiscImageCreator.ExecutionContext(_system,
mediaType,
_drive.Name,
OutputPath,
driveSpeed,
_options.Dumping.DIC),
// InternalProgram.Dreamdump => new ExecutionContexts.Dreamdump.ExecutionContext(_system,
// mediaType,
// _drive.Name,
// OutputPath,
// driveSpeed,
// _options.Dumping.Dreamdump),
InternalProgram.Redumper => new ExecutionContexts.Redumper.ExecutionContext(_system,
mediaType,
_drive.Name,
OutputPath,
driveSpeed,
_options.Dumping.Redumper),
// If no dumping program found, set to null
InternalProgram.NONE => null,
_ => null,
};
#pragma warning restore IDE0072
// Generate and return the param string
return _executionContext?.GenerateParameters();
@@ -292,8 +337,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(MediaType? mediaType)
public static bool DoesSupportDriveSpeed(MediaType? mediaType)
{
#pragma warning disable IDE0072
return mediaType switch
{
MediaType.CDROM
@@ -306,12 +352,13 @@ namespace MPF.Frontend
or MediaType.NintendoWiiUOpticalDisc => true,
_ => false,
};
#pragma warning restore IDE0072
}
/// <inheritdoc cref="BaseProcessor.FoundAllFiles(MediaType?, string?, string)"/>
public bool FoundAllFiles(MediaType? mediaType, string? outputDirectory, string outputFilename)
{
if (_processor == null)
if (_processor is null)
return false;
return _processor.FoundAllFiles(mediaType, outputDirectory, outputFilename).Count == 0;
@@ -320,7 +367,7 @@ namespace MPF.Frontend
/// <inheritdoc cref="BaseProcessor.FoundAnyFiles(MediaType?, string?, string)"/>
public bool FoundAnyFiles(MediaType? mediaType, string? outputDirectory, string outputFilename)
{
if (_processor == null)
if (_processor is null)
return false;
return _processor.FoundAnyFiles(mediaType, outputDirectory, outputFilename);
@@ -329,7 +376,7 @@ namespace MPF.Frontend
/// <inheritdoc cref="BaseExecutionContext.GetDefaultExtension(MediaType?)"/>
public string? GetDefaultExtension(MediaType? mediaType)
{
if (_executionContext == null)
if (_executionContext is null)
return null;
return _executionContext.GetDefaultExtension(mediaType);
@@ -338,7 +385,7 @@ namespace MPF.Frontend
/// <inheritdoc cref="BaseExecutionContext.GetMediaType()"/>
public MediaType? GetMediaType()
{
if (_executionContext == null)
if (_executionContext is null)
return null;
return _executionContext.GetMediaType();
@@ -350,9 +397,10 @@ namespace MPF.Frontend
public ResultEventArgs GetSupportStatus(MediaType? mediaType)
{
// No system chosen, update status
if (_system == null)
if (_system is null)
return ResultEventArgs.Failure("Please select a valid system");
#pragma warning disable IDE0072
// If we're on an unsupported type, update the status accordingly
return mediaType switch
{
@@ -385,12 +433,13 @@ namespace MPF.Frontend
// Undumpable but recognized types
_ => ResultEventArgs.Failure($"{mediaType.LongName()} media are not supported for dumping"),
};
#pragma warning restore IDE0072
}
/// <inheritdoc cref="BaseExecutionContext.IsDumpingCommand()"/>
public bool IsDumpingCommand()
{
if (_executionContext == null)
if (_executionContext is null)
return false;
return _executionContext.IsDumpingCommand();
@@ -416,11 +465,11 @@ namespace MPF.Frontend
public async Task<ResultEventArgs> Run(MediaType? mediaType, IProgress<ResultEventArgs>? progress = null)
{
// If we don't have parameters
if (_executionContext == null)
if (_executionContext is null)
return ResultEventArgs.Failure("Error! Current configuration is not supported!");
// Build default console progress indicators if none exist
if (progress == null)
if (progress is null)
{
var temp = new Progress<ResultEventArgs>();
temp.ProgressChanged += ConsoleLogger.ProgressUpdated;
@@ -429,11 +478,11 @@ namespace MPF.Frontend
// Check that we have the basics for dumping
ResultEventArgs result = IsValidForDump(mediaType);
if (!result)
if (result == false)
return result;
// Execute internal tool
progress?.Report(ResultEventArgs.Success($"Executing {_internalProgram}... please wait!"));
progress?.Report(ResultEventArgs.Neutral($"Executing {_internalProgram}... please wait!"));
var directoryName = Path.GetDirectoryName(OutputPath);
if (!string.IsNullOrEmpty(directoryName))
@@ -463,36 +512,48 @@ namespace MPF.Frontend
ProcessUserInfoDelegate? processUserInfo = null,
SubmissionInfo? seedInfo = null)
{
if (_processor == null)
if (_processor is null)
return ResultEventArgs.Failure("Error! Current configuration is not supported!");
// Build default console progress indicators if none exist
if (resultProgress == null)
if (resultProgress is null)
{
var temp = new Progress<ResultEventArgs>();
temp.ProgressChanged += ConsoleLogger.ProgressUpdated;
resultProgress = temp;
}
if (protectionProgress == null)
if (protectionProgress is null)
{
var temp = new Progress<ProtectionProgress>();
temp.ProgressChanged += ConsoleLogger.ProgressUpdated;
protectionProgress = temp;
}
resultProgress.Report(ResultEventArgs.Success("Gathering submission information... please wait!"));
resultProgress.Report(ResultEventArgs.Neutral("Gathering submission information... please wait!"));
// Get the output directory and filename separately
var outputDirectory = Path.GetDirectoryName(OutputPath);
var outputFilename = Path.GetFileName(OutputPath);
// If a standard log zip was provided, replace the suffix with ".tmp" for easier processing
if (outputFilename.EndsWith("_logs.zip", StringComparison.OrdinalIgnoreCase))
{
int zipSuffixIndex = outputFilename.LastIndexOf("_logs.zip", StringComparison.OrdinalIgnoreCase);
#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER
outputFilename = outputFilename[..zipSuffixIndex] + ".tmp";
#else
outputFilename = outputFilename.Substring(0, zipSuffixIndex) + ".tmp";
#endif
}
// Determine the media type from the processor
MediaType? mediaType = _processor.DetermineMediaType(outputDirectory, outputFilename);
if (mediaType == null)
if (mediaType is null)
return ResultEventArgs.Failure("Could not determine the media type from output files...");
// Extract the information from the output files
resultProgress.Report(ResultEventArgs.Success("Extracting output information from output files..."));
resultProgress.Report(ResultEventArgs.Neutral("Extracting output information from output files..."));
var submissionInfo = await SubmissionGenerator.ExtractOutputInformation(
OutputPath,
_drive,
@@ -502,23 +563,23 @@ namespace MPF.Frontend
_processor,
resultProgress,
protectionProgress);
if (submissionInfo == null)
if (submissionInfo is null)
return ResultEventArgs.Failure("There was an issue extracting information!");
else
resultProgress.Report(ResultEventArgs.Success("Extracting information complete!"));
// Inject seed submission info data, if necessary
if (seedInfo != null)
if (seedInfo is not null)
{
resultProgress.Report(ResultEventArgs.Success("Injecting user-supplied information..."));
resultProgress.Report(ResultEventArgs.Neutral("Injecting user-supplied information..."));
submissionInfo = Builder.InjectSubmissionInformation(submissionInfo, seedInfo);
resultProgress.Report(ResultEventArgs.Success("Information injection complete!"));
}
// Get user-modifiable information if configured to
if (_options.PromptForDiscInformation && processUserInfo != null)
if (_options.Processing.MediaInformation.PromptForDiscInformation && processUserInfo is not null)
{
resultProgress.Report(ResultEventArgs.Success("Waiting for additional media information..."));
resultProgress.Report(ResultEventArgs.Neutral("Waiting for additional media information..."));
bool? filledInfo = processUserInfo.Invoke(_options, ref submissionInfo);
if (filledInfo == true)
resultProgress.Report(ResultEventArgs.Success("Additional media information added!"));
@@ -527,23 +588,23 @@ namespace MPF.Frontend
}
// Process special fields for site codes
resultProgress.Report(ResultEventArgs.Success("Processing site codes..."));
resultProgress.Report(ResultEventArgs.Neutral("Processing site codes..."));
Formatter.ProcessSpecialFields(submissionInfo!);
resultProgress.Report(ResultEventArgs.Success("Processing complete!"));
// Format the information for the text output
resultProgress.Report(ResultEventArgs.Success("Formatting information..."));
var formattedValues = Formatter.FormatOutputData(submissionInfo, _options.EnableRedumpCompatibility, out string? formatResult);
if (formattedValues == null)
resultProgress.Report(ResultEventArgs.Neutral("Formatting information..."));
var formattedValues = Formatter.FormatOutputData(submissionInfo, _options.Processing.MediaInformation.EnableRedumpCompatibility, out string? formatResult);
if (formattedValues is null)
resultProgress.Report(ResultEventArgs.Failure(formatResult));
else
resultProgress.Report(ResultEventArgs.Success(formatResult));
// Get the filename suffix for auto-generated files
var filenameSuffix = _options.AddFilenameSuffix ? Path.GetFileNameWithoutExtension(outputFilename) : null;
var filenameSuffix = _options.Processing.AddFilenameSuffix ? Path.GetFileNameWithoutExtension(outputFilename) : null;
// Write the text output
resultProgress.Report(ResultEventArgs.Success("Writing submission information file..."));
resultProgress.Report(ResultEventArgs.Neutral("Writing submission information file..."));
bool txtSuccess = WriteOutputData(outputDirectory, filenameSuffix, formattedValues, out string txtResult);
if (txtSuccess)
resultProgress.Report(ResultEventArgs.Success(txtResult));
@@ -551,12 +612,12 @@ namespace MPF.Frontend
resultProgress.Report(ResultEventArgs.Failure(txtResult));
// Write the copy protection output
if (submissionInfo?.CopyProtection?.FullProtections != null && submissionInfo.CopyProtection.FullProtections.Count > 0)
if (submissionInfo?.CopyProtection?.FullProtections is not null && submissionInfo.CopyProtection.FullProtections.Count > 0)
{
if (_options.ScanForProtection)
if (_options.Processing.ProtectionScanning.ScanForProtection)
{
resultProgress.Report(ResultEventArgs.Success("Writing protection information file..."));
bool scanSuccess = WriteProtectionData(outputDirectory, filenameSuffix, submissionInfo, _options.HideDriveLetters);
resultProgress.Report(ResultEventArgs.Neutral("Writing protection information file..."));
bool scanSuccess = WriteProtectionData(outputDirectory, filenameSuffix, submissionInfo, _options.Processing.ProtectionScanning.HideDriveLetters);
if (scanSuccess)
resultProgress.Report(ResultEventArgs.Success("Writing complete!"));
else
@@ -565,10 +626,10 @@ namespace MPF.Frontend
}
// Write the JSON output, if required
if (_options.OutputSubmissionJSON)
if (_options.Processing.OutputSubmissionJSON)
{
resultProgress.Report(ResultEventArgs.Success($"Writing submission information JSON file{(_options.IncludeArtifacts ? " with artifacts" : string.Empty)}..."));
bool jsonSuccess = WriteOutputData(outputDirectory, filenameSuffix, submissionInfo, _options.IncludeArtifacts);
resultProgress.Report(ResultEventArgs.Neutral($"Writing submission information JSON file{(_options.Processing.IncludeArtifacts ? " with artifacts" : string.Empty)}..."));
bool jsonSuccess = WriteOutputData(outputDirectory, filenameSuffix, submissionInfo, _options.Processing.IncludeArtifacts);
if (jsonSuccess)
resultProgress.Report(ResultEventArgs.Success("Writing complete!"));
else
@@ -576,16 +637,16 @@ namespace MPF.Frontend
}
// Compress the logs, if required
if (_options.CompressLogFiles)
if (_options.Processing.CompressLogFiles)
{
resultProgress.Report(ResultEventArgs.Success("Compressing log files..."));
resultProgress.Report(ResultEventArgs.Neutral("Compressing log files..."));
#if NET40
await Task.Factory.StartNew(() =>
#else
await Task.Run(() =>
#endif
{
bool compressSuccess = _processor.CompressLogFiles(mediaType, _options.LogCompression, outputDirectory, outputFilename, filenameSuffix, out string compressResult);
bool compressSuccess = _processor.CompressLogFiles(mediaType, _options.Processing.LogCompression, outputDirectory, outputFilename, filenameSuffix, out string compressResult);
if (compressSuccess)
resultProgress.Report(ResultEventArgs.Success(compressResult));
else
@@ -596,9 +657,9 @@ namespace MPF.Frontend
}
// Delete unnecessary files, if required
if (_options.DeleteUnnecessaryFiles)
if (_options.Processing.DeleteUnnecessaryFiles)
{
resultProgress.Report(ResultEventArgs.Success("Deleting unnecessary files..."));
resultProgress.Report(ResultEventArgs.Neutral("Deleting unnecessary files..."));
bool deleteSuccess = _processor.DeleteUnnecessaryFiles(mediaType, outputDirectory, outputFilename, out string deleteResult);
if (deleteSuccess)
resultProgress.Report(ResultEventArgs.Success(deleteResult));
@@ -607,10 +668,10 @@ namespace MPF.Frontend
}
// Create PS3 IRD, if required
if (_options.CreateIRDAfterDumping && _system == RedumpSystem.SonyPlayStation3 && mediaType == MediaType.BluRay)
if (_options.Processing.CreateIRDAfterDumping && _system == RedumpSystem.SonyPlayStation3 && mediaType == MediaType.BluRay)
{
resultProgress.Report(ResultEventArgs.Success("Creating IRD... please wait!"));
bool deleteSuccess = await IRDTool.WriteIRD(OutputPath, submissionInfo?.Extras?.DiscKey, submissionInfo?.Extras?.DiscID, submissionInfo?.Extras?.PIC, submissionInfo?.SizeAndChecksums?.Layerbreak, submissionInfo?.SizeAndChecksums?.CRC32);
resultProgress.Report(ResultEventArgs.Neutral("Creating IRD... please wait!"));
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
@@ -628,7 +689,7 @@ namespace MPF.Frontend
internal bool ParametersValid(MediaType? mediaType)
{
// Missing drive means it can never be valid
if (_drive == null)
if (_drive is null)
return false;
bool parametersValid = _executionContext?.IsValid() ?? false;
@@ -648,14 +709,14 @@ namespace MPF.Frontend
private ResultEventArgs IsValidForDump(MediaType? mediaType)
{
// Validate that everything is good
if (_executionContext == null || !ParametersValid(mediaType))
if (_executionContext is null || !ParametersValid(mediaType))
return ResultEventArgs.Failure("Error! Current configuration is not supported!");
// Fix the output paths, just in case
OutputPath = FrontendTool.NormalizeOutputPaths(OutputPath, false);
// Validate that the output path isn't on the dumping drive
if (_drive?.Name != null && OutputPath.StartsWith(_drive.Name))
if (_drive?.Name is not null && OutputPath.StartsWith(_drive.Name))
return ResultEventArgs.Failure("Error! Cannot output to same drive that is being dumped!");
// Validate that the required program exists
@@ -664,7 +725,7 @@ namespace MPF.Frontend
// Validate that the dumping drive doesn't contain the executable
string fullExecutablePath = Path.GetFullPath(_executionContext.ExecutablePath!);
if (_drive?.Name != null && fullExecutablePath.StartsWith(_drive.Name))
if (_drive?.Name is not null && fullExecutablePath.StartsWith(_drive.Name))
return ResultEventArgs.Failure("Error! Cannot dump same drive that executable resides on!");
// Validate that the current configuration is supported
@@ -685,7 +746,7 @@ namespace MPF.Frontend
private static bool WriteOutputData(string? outputDirectory, string? filenameSuffix, string? lines, out string status)
{
// Check to see if the inputs are valid
if (lines == null)
if (lines is null)
{
status = "No formatted data found to write!";
return false;
@@ -730,7 +791,7 @@ namespace MPF.Frontend
private static bool WriteOutputData(string? outputDirectory, string? filenameSuffix, SubmissionInfo? info, bool includedArtifacts)
{
// Check to see if the input is valid
if (info == null)
if (info is null)
return false;
try
@@ -771,7 +832,7 @@ namespace MPF.Frontend
}
catch
{
// We don't care what the error is
// Absorb the exception
return false;
}
@@ -790,7 +851,7 @@ namespace MPF.Frontend
private static bool WriteProtectionData(string? outputDirectory, string? filenameSuffix, SubmissionInfo? info, bool hideDriveLetters)
{
// Check to see if the inputs are valid
if (info?.CopyProtection?.FullProtections == null || info.CopyProtection.FullProtections.Count == 0)
if (info?.CopyProtection?.FullProtections is null || info.CopyProtection.FullProtections.Count == 0)
return true;
// Now write out to a generic file
@@ -815,11 +876,15 @@ namespace MPF.Frontend
{
string scanPath = key;
if (hideDriveLetters)
scanPath = Path.DirectorySeparatorChar + key.Substring((Path.GetPathRoot(key) ?? String.Empty).Length);
#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER
scanPath = Path.DirectorySeparatorChar + key[(Path.GetPathRoot(key) ?? string.Empty).Length..];
#else
scanPath = Path.DirectorySeparatorChar + key.Substring((Path.GetPathRoot(key) ?? string.Empty).Length);
#endif
List<string>? scanResult = info.CopyProtection.FullProtections[key];
if (scanResult == null)
if (scanResult is null)
sw.WriteLine($"{scanPath}: None");
else
sw.WriteLine($"{scanPath}: {string.Join(", ", [.. scanResult])}");
@@ -827,7 +892,7 @@ namespace MPF.Frontend
}
catch
{
// We don't care what the error is
// Absorb the exception
return false;
}

View File

@@ -6,6 +6,7 @@ using System.Collections.Concurrent;
#endif
using System.Reflection;
using SabreTools.RedumpLib.Data;
using DreamdumpSectorOrder = MPF.ExecutionContexts.Dreamdump.SectorOrder;
using LogCompression = MPF.Processors.LogCompression;
using RedumperDriveType = MPF.ExecutionContexts.Redumper.DriveType;
using RedumperReadMethod = MPF.ExecutionContexts.Redumper.ReadMethod;
@@ -50,7 +51,7 @@ namespace MPF.Frontend
#endif
}
if (method != null)
if (method is not null)
return method.Invoke(null, [value]) as string ?? string.Empty;
else
return string.Empty;
@@ -62,6 +63,68 @@ namespace MPF.Frontend
}
}
/// <summary>
/// Get the string representation of the DreamdumpSectorOrder enum values
/// </summary>
/// <param name="order">DreamdumpSectorOrder value to convert</param>
/// <returns>String representing the value, if possible</returns>
public static string LongName(this DreamdumpSectorOrder order)
=> ((DreamdumpSectorOrder?)order).LongName();
/// <summary>
/// Get the string representation of the DreamdumpSectorOrder enum values
/// </summary>
/// <param name="order">DreamdumpSectorOrder value to convert</param>
/// <returns>String representing the value, if possible</returns>
public static string LongName(this DreamdumpSectorOrder? order)
{
return order switch
{
DreamdumpSectorOrder.DATA_C2_SUB => "DATA_C2_SUB",
DreamdumpSectorOrder.DATA_SUB_C2 => "DATA_SUB_C2",
DreamdumpSectorOrder.DATA_SUB => "DATA_SUB",
DreamdumpSectorOrder.DATA_C2 => "DATA_C2",
DreamdumpSectorOrder.NONE => "Default",
_ => "Unknown",
};
}
/// <summary>
/// Get the string representation of the InterfaceLanguage enum values
/// </summary>
/// <param name="lang">InterfaceLanguage value to convert</param>
/// <returns>String representing the value, if possible</returns>
public static string LongName(this InterfaceLanguage lang)
=> ((InterfaceLanguage?)lang).LongName();
/// <summary>
/// Get the string representation of the InterfaceLanguage enum values
/// </summary>
/// <param name="lang">InterfaceLanguage value to convert</param>
/// <returns>String representing the value, if possible</returns>
public static string LongName(this InterfaceLanguage? lang)
{
return lang switch
{
InterfaceLanguage.AutoDetect => "Auto Detect",
InterfaceLanguage.English => "English",
InterfaceLanguage.French => "Français",
InterfaceLanguage.German => "Deutsch",
InterfaceLanguage.Italian => "Italiano",
InterfaceLanguage.Japanese => "日本語",
InterfaceLanguage.Korean => "한국어",
InterfaceLanguage.Polish => "Polski",
InterfaceLanguage.Russian => "Русский",
InterfaceLanguage.Spanish => "Español",
InterfaceLanguage.Swedish => "Svenska",
InterfaceLanguage.Ukrainian => "Українська",
InterfaceLanguage.L337 => "L337",
_ => "Unknown",
};
}
/// <summary>
/// Get the string representation of the InternalProgram enum values
/// </summary>
@@ -83,6 +146,7 @@ namespace MPF.Frontend
InternalProgram.Aaru => "Aaru",
InternalProgram.DiscImageCreator => "DiscImageCreator",
// InternalProgram.Dreamdump => "Dreamdump",
InternalProgram.Redumper => "Redumper",
#endregion
@@ -126,6 +190,14 @@ namespace MPF.Frontend
};
}
/// <summary>
/// Get the string representation of the RedumperReadMethod enum values
/// </summary>
/// <param name="method">RedumperReadMethod value to convert</param>
/// <returns>String representing the value, if possible</returns>
public static string LongName(this RedumperReadMethod method)
=> ((RedumperReadMethod?)method).LongName();
/// <summary>
/// Get the string representation of the RedumperReadMethod enum values
/// </summary>
@@ -143,6 +215,14 @@ namespace MPF.Frontend
};
}
/// <summary>
/// Get the string representation of the RedumperSectorOrder enum values
/// </summary>
/// <param name="order">RedumperSectorOrder value to convert</param>
/// <returns>String representing the value, if possible</returns>
public static string LongName(this RedumperSectorOrder order)
=> ((RedumperSectorOrder?)order).LongName();
/// <summary>
/// Get the string representation of the RedumperSectorOrder enum values
/// </summary>
@@ -162,6 +242,14 @@ namespace MPF.Frontend
};
}
/// <summary>
/// Get the string representation of the RedumperDriveType enum values
/// </summary>
/// <param name="type">RedumperDriveType value to convert</param>
/// <returns>String representing the value, if possible</returns>
public static string LongName(this RedumperDriveType type)
=> ((RedumperDriveType?)type).LongName();
/// <summary>
/// Get the string representation of the RedumperDriveType enum values
/// </summary>
@@ -173,11 +261,11 @@ namespace MPF.Frontend
{
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.MTK8A => "MTK8A",
RedumperDriveType.MTK8B => "MTK8B",
RedumperDriveType.MTK8C => "MTK8C",
RedumperDriveType.MTK3 => "MTK3",
RedumperDriveType.MTK2 => "MTK2",
RedumperDriveType.NONE => "Default",
_ => "Unknown",
@@ -188,6 +276,41 @@ namespace MPF.Frontend
#region Convert to Short Name
/// <summary>
/// Get the short string representation of the InterfaceLanguage enum values
/// </summary>
/// <param name="lang">InterfaceLanguage value to convert</param>
/// <returns>String representing the value, if possible</returns>
public static string ShortName(this InterfaceLanguage lang)
=> ((InterfaceLanguage?)lang).ShortName();
/// <summary>
/// Get the short string representation of the InterfaceLanguage enum values
/// </summary>
/// <param name="lang">InterfaceLanguage value to convert</param>
/// <returns>String representing the value, if possible</returns>
public static string ShortName(this InterfaceLanguage? lang)
{
return lang switch
{
InterfaceLanguage.AutoDetect => "auto",
InterfaceLanguage.English => "eng",
InterfaceLanguage.French => "fra",
InterfaceLanguage.German => "deu",
InterfaceLanguage.Italian => "ita",
InterfaceLanguage.Japanese => "jpn",
InterfaceLanguage.Korean => "kor",
InterfaceLanguage.Polish => "pol",
InterfaceLanguage.Russian => "rus",
InterfaceLanguage.Spanish => "spa",
InterfaceLanguage.Swedish => "swe",
InterfaceLanguage.Ukrainian => "ukr",
InterfaceLanguage.L337 => "l37",
_ => "Unknown",
};
}
/// <summary>
/// Get the short string representation of the InternalProgram enum values
/// </summary>
@@ -201,6 +324,7 @@ namespace MPF.Frontend
InternalProgram.Aaru => "aaru",
InternalProgram.DiscImageCreator => "dic",
// InternalProgram.Dreamdump => "dreamdump",
InternalProgram.Redumper => "redumper",
#endregion
@@ -223,6 +347,63 @@ namespace MPF.Frontend
#region Convert from String
/// <summary>
/// Get the DreamdumpSectorOrder enum value for a given string
/// </summary>
/// <param name="order">String value to convert</param>
/// <returns>DreamdumpSectorOrder represented by the string, if possible</returns>
public static DreamdumpSectorOrder ToDreamdumpSectorOrder(this string? order)
{
return (order?.ToLowerInvariant()) switch
{
"data_c2_sub"
or "data c2 sub"
or "data-c2-sub"
or "datac2sub" => DreamdumpSectorOrder.DATA_C2_SUB,
"data_sub_c2"
or "data sub c2"
or "data-sub-c2"
or "datasubc2" => DreamdumpSectorOrder.DATA_SUB_C2,
"data_sub"
or "data sub"
or "data-sub"
or "datasub" => DreamdumpSectorOrder.DATA_SUB,
"data_c2"
or "data c2"
or "data-c2"
or "datac2" => DreamdumpSectorOrder.DATA_C2,
_ => DreamdumpSectorOrder.NONE,
};
}
/// <summary>
/// Get the InterfaceLanguage enum value for a given string
/// </summary>
/// <param name="internalLanguage">String value to convert</param>
/// <returns>InterfaceLanguage represented by the string, if possible</returns>
public static InterfaceLanguage ToInterfaceLanguage(this string? internalLanguage)
{
return (internalLanguage?.ToLowerInvariant()) switch
{
"auto" or "autodetect" or "auto detect" => InterfaceLanguage.AutoDetect,
"eng" or "english" => InterfaceLanguage.English,
"fra" or "french" or "français" => InterfaceLanguage.French,
"deu" or "german" or "deutsch" => InterfaceLanguage.German,
"ita" or "italian" or "italiano" => InterfaceLanguage.Italian,
"jpn" or "japanese" or "日本語" => InterfaceLanguage.Japanese,
"kor" or "korean" or "한국어" => InterfaceLanguage.Korean,
"pol" or "polish" or "polski" => InterfaceLanguage.Polish,
"rus" or "russian" or "русский" => InterfaceLanguage.Russian,
"spa" or "spanish" or "español" => InterfaceLanguage.Spanish,
"swe" or "swedish" or "svenska" => InterfaceLanguage.Swedish,
"ukr" or "ukranian" or "українська" => InterfaceLanguage.Ukrainian,
"l37" or "l337" => InterfaceLanguage.L337,
_ => InterfaceLanguage.AutoDetect,
};
}
/// <summary>
/// Get the InternalProgram enum value for a given string
/// </summary>
@@ -241,6 +422,7 @@ namespace MPF.Frontend
or "dic"
or "dicreator"
or "discimagecreator" => InternalProgram.DiscImageCreator,
// "dreamdump" => InternalProgram.Dreamdump,
"rd"
or "redumper" => InternalProgram.Redumper,
@@ -270,7 +452,7 @@ namespace MPF.Frontend
/// Get the LogCompression enum value for a given string
/// </summary>
/// <param name="logCompression">String value to convert</param>
/// <returns>LogCompression represented by teh string, if possible</returns>
/// <returns>LogCompression represented by the string, if possible</returns>
public static LogCompression ToLogCompression(this string? logCompression)
{
return (logCompression?.ToLowerInvariant()) switch
@@ -345,31 +527,66 @@ namespace MPF.Frontend
{
"generic" => RedumperDriveType.GENERIC,
"plextor" => RedumperDriveType.PLEXTOR,
"lg_asus8a"
"mtk8a"
or "mtk_8a"
or "lg_asus8a"
or "lg-asus8a"
or "lgasus8a"
or "lg_asus_8a"
or "lg-asus-8a" => RedumperDriveType.LG_ASU8A,
"lg_asus8b"
or "lg-asus-8a"
or "lg_asu8a"
or "lg-asu8a"
or "lgasu8a"
or "lg_asu_8a"
or "lg-asu-8a" => RedumperDriveType.MTK8A,
"mtk8b"
or "mtk_8b"
or "lg_asus8b"
or "lg-asus8b"
or "lgasus8b"
or "lg_asus_8b"
or "lg-asus-8b" => RedumperDriveType.LG_ASU8B,
"lg_asus8c"
or "lg-asus-8b"
or "lg_asu8b"
or "lg-asu8b"
or "lgasu8b"
or "lg_asu_8b"
or "lg-asu-8b" => RedumperDriveType.MTK8B,
"mtk8c"
or "mtk_8c"
or "lg_asus8c"
or "lg-asus8c"
or "lgasus8c"
or "lg_asus_8c"
or "lg-asus-8c" => RedumperDriveType.LG_ASU8C,
"lg_asus3"
or "lg-asus-8c"
or "lg_asu8c"
or "lg-asu8c"
or "lgasu8c"
or "lg_asu_8c"
or "lg-asu-8c" => RedumperDriveType.MTK8C,
"mtk3"
or "mtk3"
or "lg_asus3"
or "lg-asus3"
or "lgasus3"
or "lg_asus_3"
or "lg-asus-3" => RedumperDriveType.LG_ASU3,
"lg_asus2"
or "lg-asus-3"
or "lg_asu3"
or "lg-asu3"
or "lgasu3"
or "lg_asu_3"
or "lg-asu-3" => RedumperDriveType.MTK3,
"mtk2"
or "mtk2"
or "lg_asus2"
or "lg-asus2"
or "lgasus2"
or "lg_asus_2"
or "lg-asus-2" => RedumperDriveType.LG_ASU2,
or "lg-asus-2"
or "lg_asu2"
or "lg-asu2"
or "lgasu2"
or "lg_asu_2"
or "lg-asu-2" => RedumperDriveType.MTK2,
_ => RedumperDriveType.NONE,
};
@@ -384,11 +601,13 @@ namespace MPF.Frontend
/// </summary>
public static bool SupportsAntiModchipScans(this RedumpSystem? system)
{
#pragma warning disable IDE0072
return system switch
{
RedumpSystem.SonyPlayStation => true,
_ => false,
};
#pragma warning restore IDE0072
}
/// <summary>
@@ -396,9 +615,11 @@ namespace MPF.Frontend
/// </summary>
public static bool SupportsCopyProtectionScans(this RedumpSystem? system)
{
#pragma warning disable IDE0072
return system switch
{
RedumpSystem.AppleMacintosh => true,
RedumpSystem.DVDVideo => true,
RedumpSystem.EnhancedCD => true,
RedumpSystem.IBMPCcompatible => true,
RedumpSystem.PalmOS => true,
@@ -407,6 +628,7 @@ namespace MPF.Frontend
RedumpSystem.SonyElectronicBook => true,
_ => false,
};
#pragma warning restore IDE0072
}
#endregion

View File

@@ -1,5 +1,32 @@
namespace MPF.Frontend
{
/// <summary>
/// Interface language
/// </summary>
public enum InterfaceLanguage
{
/// <summary>
/// Default to auto-detecting language
/// </summary>
AutoDetect = 0,
// Selectable languages (in Manual Window dropdown)
English,
French,
German,
Italian,
Japanese,
Korean,
Polish,
Russian,
Spanish,
Swedish,
Ukrainian,
// Hidden languages (not in Main Window dropdown)
L337,
}
/// <summary>
/// Drive type for dumping
/// </summary>
@@ -21,6 +48,7 @@ namespace MPF.Frontend
// Dumping support
Aaru,
DiscImageCreator,
// Dreamdump,
Redumper,
// Verification support only
@@ -35,9 +63,10 @@ namespace MPF.Frontend
/// </summary>
public enum LogLevel
{
USER,
USER_GENERIC,
USER_SUCCESS,
VERBOSE,
ERROR,
SECRET,
}
}
}

View File

@@ -0,0 +1,159 @@
using System;
using MPF.Frontend;
using MPF.Frontend.Tools;
using SabreTools.RedumpLib.Data;
namespace MPF.Frontend.Features
{
public class ListConfigFeature : SabreTools.CommandLine.Feature
{
#region Feature Definition
public const string DisplayName = "listconfig";
private static readonly string[] _flags = ["lo", "listconfig"];
private const string _description = "List current configuration values";
#endregion
public ListConfigFeature()
: base(DisplayName, _flags, _description)
{
}
/// <inheritdoc/>
public override bool Execute()
{
// Try to load the current config
var options = OptionsLoader.LoadFromConfig();
if (options.FirstRun)
{
Console.WriteLine("No valid configuration found!");
return true;
}
// Root-level
Console.WriteLine($"Configuration Version = {options.Version}");
Console.WriteLine($"Check for Updates on Startup = {options.CheckForUpdatesOnStartup}");
Console.WriteLine($"Verbose Logging = {options.VerboseLogging}");
Console.WriteLine();
// GUI
Console.WriteLine("GUI:");
Console.WriteLine($" Copy Update URL to Clipboard = {options.GUI.CopyUpdateUrlToClipboard}");
Console.WriteLine($" Open Log Window at Startup = {options.GUI.OpenLogWindowAtStartup}");
Console.WriteLine($" Default Interface Language = {options.GUI.DefaultInterfaceLanguage.LongName()}");
Console.WriteLine($" Show Debug Menu Item = {options.GUI.ShowDebugViewMenuItem}");
Console.WriteLine(" Theming:");
Console.WriteLine($" Dark Mode = {options.GUI.Theming.EnableDarkMode}");
Console.WriteLine($" Purp Mode = {options.GUI.Theming.EnablePurpMode}");
Console.WriteLine($" Custom Background Color = {options.GUI.Theming.CustomBackgroundColor}");
Console.WriteLine($" Custom Text Color = {options.GUI.Theming.CustomTextColor}");
Console.WriteLine($" Fast Label Update = {options.GUI.FastUpdateLabel}");
Console.WriteLine($" Ignore Fixed Drives = {options.GUI.IgnoreFixedDrives}");
Console.WriteLine($" Skip System Detection = {options.GUI.SkipSystemDetection}");
Console.WriteLine();
// Dump Paths
Console.WriteLine("Dump Paths:");
Console.WriteLine($" Aaru Path = {options.Dumping.AaruPath}");
Console.WriteLine($" DiscImageCreator Path = {options.Dumping.DiscImageCreatorPath}");
Console.WriteLine($" Dreamdump Path = {options.Dumping.DreamdumpPath}");
Console.WriteLine($" Redumper Path = {options.Dumping.RedumperPath}");
Console.WriteLine();
// Dump Defaults
Console.WriteLine("Dump Defaults:");
Console.WriteLine($" Default Program = {options.InternalProgram.LongName()}");
Console.WriteLine($" Default Output Path = {options.Dumping.DefaultOutputPath}");
Console.WriteLine($" Default System = {options.Dumping.DefaultSystem.LongName()}");
Console.WriteLine($" Default CD Speed = {options.Dumping.DumpSpeeds.CD}");
Console.WriteLine($" Default DVD Speed = {options.Dumping.DumpSpeeds.DVD}");
Console.WriteLine($" Default HD-DVD Speed = {options.Dumping.DumpSpeeds.HDDVD}");
Console.WriteLine($" Default Blu-ray Speed = {options.Dumping.DumpSpeeds.Bluray}");
Console.WriteLine();
// Aaru
Console.WriteLine("Aaru-Specific Options:");
Console.WriteLine($" Enable Debug = {options.Dumping.Aaru.EnableDebug}");
Console.WriteLine($" Enable Verbose = {options.Dumping.Aaru.EnableVerbose}");
Console.WriteLine($" Force Dumping = {options.Dumping.Aaru.ForceDumping}");
Console.WriteLine($" Reread Count = {options.Dumping.Aaru.RereadCount}");
Console.WriteLine($" Strip Personal Data = {options.Dumping.Aaru.StripPersonalData}");
Console.WriteLine();
// DiscImageCreator
Console.WriteLine("DiscImageCreator-Specific Options:");
Console.WriteLine($" Multi-Sector Read Flag = {options.Dumping.DIC.MultiSectorRead}");
Console.WriteLine($" Multi-Sector Read Value = {options.Dumping.DIC.MultiSectorReadValue}");
Console.WriteLine($" Overly-Secure Flags = {options.Dumping.DIC.ParanoidMode}");
Console.WriteLine($" Quiet Flag = {options.Dumping.DIC.QuietMode}");
Console.WriteLine($" CD Reread Count = {options.Dumping.DIC.RereadCount}");
Console.WriteLine($" DVD Reread Count = {options.Dumping.DIC.DVDRereadCount}");
Console.WriteLine($" Use CMI Flag = {options.Dumping.DIC.UseCMIFlag}");
Console.WriteLine();
// Dreamdump
Console.WriteLine("Dreamdump-Specific Options:");
Console.WriteLine($" Non-Redump Mode = {options.Dumping.Dreamdump.NonRedumpMode}");
Console.WriteLine($" Sector Order = {options.Dumping.Dreamdump.SectorOrder.LongName()}");
Console.WriteLine($" Reread Count = {options.Dumping.Dreamdump.RereadCount}");
Console.WriteLine();
// Redumper
Console.WriteLine("Redumper-Specific Options:");
Console.WriteLine($" Enable Skeleton = {options.Dumping.Redumper.EnableSkeleton}");
Console.WriteLine($" Enable Verbose = {options.Dumping.Redumper.EnableVerbose}");
Console.WriteLine($" Lead-in Retry Count = {options.Dumping.Redumper.LeadinRetryCount}");
Console.WriteLine($" Non-Redump Mode = {options.Dumping.Redumper.NonRedumpMode}");
Console.WriteLine($" Drive Type = {options.Dumping.Redumper.DriveType.LongName()}");
Console.WriteLine($" Read Method = {options.Dumping.Redumper.ReadMethod.LongName()}");
Console.WriteLine($" Sector Order = {options.Dumping.Redumper.SectorOrder.LongName()}");
Console.WriteLine($" Reread Count = {options.Dumping.Redumper.RereadCount}");
Console.WriteLine($" Refine Sector Mode = {options.Dumping.Redumper.RefineSectorMode}");
Console.WriteLine();
// Protection Scanning Options
Console.WriteLine("Protection Scanning Options:");
Console.WriteLine($" Scan for Protection = {options.Processing.ProtectionScanning.ScanForProtection}");
Console.WriteLine($" Scan Archives for Protection = {options.Processing.ProtectionScanning.ScanArchivesForProtection}");
Console.WriteLine($" Hide Drive Letters = {options.Processing.ProtectionScanning.HideDriveLetters}");
Console.WriteLine($" Include Debug Protection Information = {options.Processing.ProtectionScanning.IncludeDebugProtectionInformation}");
Console.WriteLine();
// Redump Login Information
Console.WriteLine("Redump Login Information:");
Console.WriteLine($" Pull All Information = {options.Processing.Login.PullAllInformation}");
Console.WriteLine($" Redump Username = {options.Processing.Login.RedumpUsername}");
Console.WriteLine($" Redump Password = {(string.IsNullOrEmpty(options.Processing.Login.RedumpPassword) ? "[UNSET]" : "[SET]")}");
Console.WriteLine($" Retrieve Match Information = {options.Processing.Login.RetrieveMatchInformation}");
Console.WriteLine();
// Media Information
Console.WriteLine("Media Information:");
Console.WriteLine($" Add Placeholders = {options.Processing.MediaInformation.AddPlaceholders}");
Console.WriteLine($" Enable Redump Compatibility = {options.Processing.MediaInformation.EnableRedumpCompatibility}");
Console.WriteLine($" Enable Tabs in Input Fields = {options.Processing.MediaInformation.EnableTabsInInputFields}");
Console.WriteLine($" Prompt for Media Information = {options.Processing.MediaInformation.PromptForDiscInformation}");
Console.WriteLine();
// Post-Information Options
Console.WriteLine("Post-Information Options:");
Console.WriteLine($" Add Filename Suffix = {options.Processing.AddFilenameSuffix}");
Console.WriteLine($" Compress Log Files = {options.Processing.CompressLogFiles}");
Console.WriteLine($" Create IRD After Dumping = {options.Processing.CreateIRDAfterDumping}");
Console.WriteLine($" Delete Unnecessary Files = {options.Processing.DeleteUnnecessaryFiles}");
Console.WriteLine($" Include Artifacts = {options.Processing.IncludeArtifacts}");
Console.WriteLine($" Log Compression = {options.Processing.LogCompression.LongName()}");
Console.WriteLine($" Output Submission JSON = {options.Processing.OutputSubmissionJSON}");
Console.WriteLine($" Show Disc Eject Reminder = {options.Processing.ShowDiscEjectReminder}");
Console.WriteLine();
return true;
}
/// <inheritdoc/>
public override bool VerifyInputs() => true;
}
}

View File

@@ -40,6 +40,7 @@ namespace MPF.Frontend
/// <returns>Read-only list of drive speeds</returns>
public static List<int> GetSpeedsForMediaType(MediaType? type)
{
#pragma warning disable IDE0072
return type switch
{
MediaType.CDROM
@@ -54,6 +55,7 @@ namespace MPF.Frontend
// Default to CD speed range
_ => CD,
};
#pragma warning restore IDE0072
}
}
}

View File

@@ -2,7 +2,7 @@
<PropertyGroup>
<!-- Assembly Properties -->
<TargetFrameworks>net20;net35;net40;net452;net462;net472;net48;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0;net9.0</TargetFrameworks>
<TargetFrameworks>net20;net35;net40;net452;net462;net472;net48;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0;net9.0;net10.0</TargetFrameworks>
<CheckEolTargetFramework>false</CheckEolTargetFramework>
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
<LangVersion>latest</LangVersion>
@@ -10,7 +10,7 @@
<Nullable>enable</Nullable>
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<VersionPrefix>3.5.0</VersionPrefix>
<VersionPrefix>3.6.0</VersionPrefix>
<!-- Package Properties -->
<Authors>Matt Nadareski;ReignStumble;Jakz</Authors>
@@ -31,14 +31,14 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="BinaryObjectScanner" Version="[3.4.5]" />
<PackageReference Include="LibIRD" Version="[1.0.0]" />
<PackageReference Include="BinaryObjectScanner" Version="[3.5.0]" />
<PackageReference Include="LibIRD" Version="[1.0.1]" />
<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="MinThreadingBridge" Version="0.11.4" Condition="$(TargetFramework.StartsWith(`net2`)) OR $(TargetFramework.StartsWith(`net3`)) OR $(TargetFramework.StartsWith(`net40`))" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
<PackageReference Include="SabreTools.CommandLine" Version="[1.3.2]" />
<PackageReference Include="SabreTools.RedumpLib" Version="[1.7.4]" />
<PackageReference Include="SabreTools.CommandLine" Version="[1.4.0]" />
<PackageReference Include="SabreTools.RedumpLib" Version="[1.9.1]" />
<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>

View File

@@ -42,4 +42,4 @@ namespace MPF.Frontend
IEnumerator IEnumerable.GetEnumerator() => _queue.GetEnumerator();
}
}
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -9,4 +9,4 @@ namespace MPF.Frontend
/// <param name="info">Submission info that may be overwritten</param>
/// <returns>True for successful updating, false or null otherwise</returns>
public delegate bool? ProcessUserInfoDelegate(Options? options, ref SubmissionInfo? info);
}
}

View File

@@ -36,7 +36,7 @@ namespace MPF.Frontend
// Capture the current synchronization context.
// If there is no current context, we use a default instance targeting the ThreadPool.
_synchronizationContext = SynchronizationContext.Current ?? ProgressStatics.DefaultContext;
Debug.Assert(_synchronizationContext != null);
Debug.Assert(_synchronizationContext is not null);
_invokeHandlers = new SendOrPostCallback(InvokeHandlers);
}
@@ -70,7 +70,7 @@ namespace MPF.Frontend
// an event handler is removed between now and then.
Action<T>? handler = _handler;
EventHandler<T>? changedEvent = ProgressChanged;
if (handler != null || changedEvent != null)
if (handler is not null || changedEvent is not null)
{
// Post the processing to the sync context.
// (If T is a value type, it will get boxed here.)

View File

@@ -10,19 +10,30 @@ namespace MPF.Frontend
/// <summary>
/// Internal representation of success
/// </summary>
private readonly bool _success;
private readonly bool? _success;
/// <summary>
/// Optional message for the result
/// </summary>
public string Message { get; }
private ResultEventArgs(bool success, string message)
private ResultEventArgs(bool? success, string message)
{
_success = success;
Message = message;
}
/// <summary>
/// Create a default neutral result with no message
/// </summary>
public static ResultEventArgs Neutral() => new(null, string.Empty);
/// <summary>
/// Create a neutral result with a custom message
/// </summary>
/// <param name="message">String to add as a message</param>
public static ResultEventArgs Neutral(string? message) => new(null, message ?? string.Empty);
/// <summary>
/// Create a default success result with no message
/// </summary>
@@ -49,7 +60,7 @@ namespace MPF.Frontend
/// <summary>
/// Results can be compared to boolean values based on the success value
/// </summary>
public static implicit operator bool(ResultEventArgs result) => result._success;
public static implicit operator bool?(ResultEventArgs result) => result._success;
/// <summary>
/// Results can be compared to boolean values based on the success value

View File

@@ -49,4 +49,4 @@ namespace MPF.Frontend
/// </summary>
public static implicit operator StringEventArgs(StringBuilder? sb) => new(sb);
}
}
}

View File

@@ -16,27 +16,29 @@ namespace MPF.Frontend.Tools
/// </summary>
public static int GetDefaultSpeedForMediaType(MediaType? mediaType, Options options)
{
#pragma warning disable IDE0072
return mediaType switch
{
// CD dump speed
MediaType.CDROM => options.PreferredDumpSpeedCD,
MediaType.GDROM => options.PreferredDumpSpeedCD,
MediaType.CDROM => options.Dumping.DumpSpeeds.CD,
MediaType.GDROM => options.Dumping.DumpSpeeds.CD,
// DVD dump speed
MediaType.DVD => options.PreferredDumpSpeedDVD,
MediaType.NintendoGameCubeGameDisc => options.PreferredDumpSpeedDVD,
MediaType.NintendoWiiOpticalDisc => options.PreferredDumpSpeedDVD,
MediaType.DVD => options.Dumping.DumpSpeeds.DVD,
MediaType.NintendoGameCubeGameDisc => options.Dumping.DumpSpeeds.DVD,
MediaType.NintendoWiiOpticalDisc => options.Dumping.DumpSpeeds.DVD,
// HD-DVD dump speed
MediaType.HDDVD => options.PreferredDumpSpeedHDDVD,
MediaType.HDDVD => options.Dumping.DumpSpeeds.HDDVD,
// BD dump speed
MediaType.BluRay => options.PreferredDumpSpeedBD,
MediaType.NintendoWiiUOpticalDisc => options.PreferredDumpSpeedBD,
MediaType.BluRay => options.Dumping.DumpSpeeds.Bluray,
MediaType.NintendoWiiUOpticalDisc => options.Dumping.DumpSpeeds.Bluray,
// Default
_ => options.PreferredDumpSpeedCD,
_ => options.Dumping.DumpSpeeds.CD,
};
#pragma warning restore IDE0072
}
/// <summary>
@@ -49,6 +51,9 @@ namespace MPF.Frontend.Tools
if (string.IsNullOrEmpty(volumeLabel))
return null;
// Trim the volume label
volumeLabel = volumeLabel!.Trim();
// Audio CD
if (volumeLabel!.Equals("Audio CD", StringComparison.OrdinalIgnoreCase))
return RedumpSystem.AudioCD;
@@ -114,7 +119,7 @@ namespace MPF.Frontend.Tools
public static string? NormalizeDiscTitle(string? title, Language?[]? languages)
{
// If we have no set languages, then assume English
if (languages == null || languages.Length == 0)
if (languages is null || languages.Length == 0)
languages = [Language.English];
// Loop through all of the given languages
@@ -151,8 +156,7 @@ namespace MPF.Frontend.Tools
return title;
// If we have an invalid language, assume Language.English
if (language == null)
language = Language.English;
language ??= Language.English;
// Get the title split into parts
string[] splitTitle = Array.FindAll(title!.Split(' '), s => !string.IsNullOrEmpty(s));
@@ -496,12 +500,20 @@ namespace MPF.Frontend.Tools
else if (!itemInserted && segment.EndsWith(":"))
{
itemInserted = true;
#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER
newTitleBuilder.Append($" {segment[..^1]}, {firstItem}:");
#else
newTitleBuilder.Append($" {segment.Substring(0, segment.Length - 1)}, {firstItem}:");
#endif
}
else if (!itemInserted && segment.EndsWith("-"))
{
itemInserted = true;
#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER
newTitleBuilder.Append($" {segment[..^1]}, {firstItem}-");
#else
newTitleBuilder.Append($" {segment.Substring(0, segment.Length - 1)}, {firstItem}-");
#endif
}
else
{
@@ -581,7 +593,7 @@ namespace MPF.Frontend.Tools
{
// Get current assembly version
var assemblyVersion = Assembly.GetEntryAssembly()?.GetName()?.Version;
if (assemblyVersion == null)
if (assemblyVersion is null)
{
different = false;
message = "Assembly version could not be determined";
@@ -593,13 +605,8 @@ namespace MPF.Frontend.Tools
// Get the latest tag from GitHub
_ = GetRemoteVersionAndUrl(out string? tag, out url);
different = version != tag && tag != null;
message = $"Local version: {version}"
+ $"{Environment.NewLine}Remote version: {tag}"
+ (different
? $"{Environment.NewLine}The update URL has been added copied to your clipboard"
: $"{Environment.NewLine}You have the newest version!");
different = version != tag && tag is not null;
message = $"Local version: {version}{Environment.NewLine}Remote version: {tag}";
}
catch (Exception ex)
{
@@ -617,7 +624,7 @@ namespace MPF.Frontend.Tools
try
{
var assembly = Assembly.GetEntryAssembly();
if (assembly == null)
if (assembly is null)
return null;
var assemblyVersion = Attribute.GetCustomAttribute(assembly, typeof(AssemblyInformationalVersionAttribute)) as AssemblyInformationalVersionAttribute;
@@ -650,11 +657,11 @@ namespace MPF.Frontend.Tools
message.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:64.0) Gecko/20100101 Firefox/64.0");
var latestReleaseJsonString = hc.SendAsync(message)?.ConfigureAwait(false).GetAwaiter().GetResult()
.Content?.ReadAsStringAsync().ConfigureAwait(false).GetAwaiter().GetResult();
if (latestReleaseJsonString == null)
if (latestReleaseJsonString is null)
return false;
var latestReleaseJson = Newtonsoft.Json.Linq.JObject.Parse(latestReleaseJsonString);
if (latestReleaseJson == null)
if (latestReleaseJson is null)
return false;
tag = latestReleaseJson["tag_name"]?.ToString();
@@ -666,4 +673,4 @@ namespace MPF.Frontend.Tools
#endregion
}
}
}

View File

@@ -36,7 +36,7 @@ namespace MPF.Frontend.Tools
}
catch (Exception)
{
// We don't care what the error is
// Absorb the exception
return false;
}
}
@@ -61,7 +61,7 @@ namespace MPF.Frontend.Tools
try
{
// Fail on a missing disc key
if (discKey == null)
if (discKey is null)
return false;
// Output IRD file path
@@ -79,9 +79,9 @@ namespace MPF.Frontend.Tools
new LibIRD.ReIRD(isoPath, discKey, layerbreak, uid));
// Set optional fields if valid
if (pic != null)
if (pic is not null)
ird.PIC = pic;
if (discID != null && ird.DiscID[15] != 0x00)
if (discID is not null && ird.DiscID[15] != 0x00)
ird.DiscID = discID;
// Write IRD to file
@@ -91,9 +91,9 @@ namespace MPF.Frontend.Tools
}
catch (Exception)
{
// We don't care what the error is
// Absorb the exception
return false;
}
}
}
}
}

View File

@@ -1,9 +1,16 @@
using System;
using System;
using System.Collections.Generic;
using System.IO;
#if NET20 || NET35 || NET40 || NET452
using System.Reflection;
#endif
using Newtonsoft.Json;
using SabreTools.RedumpLib.Data;
using AaruConstants = MPF.ExecutionContexts.Aaru.SettingConstants;
using DiscImageCreatorConstants = MPF.ExecutionContexts.DiscImageCreator.SettingConstants;
using DreamdumpConstants = MPF.ExecutionContexts.Dreamdump.SettingConstants;
using LogCompression = MPF.Processors.LogCompression;
using RedumperConstants = MPF.ExecutionContexts.Redumper.SettingConstants;
namespace MPF.Frontend.Tools
{
@@ -21,7 +28,7 @@ namespace MPF.Frontend.Tools
{
get
{
if (_configPath != null)
if (_configPath is not null)
return _configPath;
_configPath = GetConfigurationPath();
@@ -193,11 +200,36 @@ namespace MPF.Frontend.Tools
return new Options();
var serializer = JsonSerializer.Create();
var stream = File.Open(ConfigurationPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
var reader = new StreamReader(stream);
var stream = File.Open(ConfigurationPath, FileMode.Open, FileAccess.Read, FileShare.None);
using var reader = new StreamReader(stream);
var settings = serializer.Deserialize(reader, typeof(Dictionary<string, string?>)) as Dictionary<string, string?>;
reader.Dispose();
return new Options(settings);
return ConvertFromDictionary(settings);
}
/// <summary>
/// Load the current set of options from the application configuration
/// </summary>
public static Options LoadFromConfigNative()
{
// If no options path can be found
if (string.IsNullOrEmpty(ConfigurationPath))
return new Options();
// If the file does not exist
if (!File.Exists(ConfigurationPath) || new FileInfo(ConfigurationPath).Length == 0)
return new Options();
var serializer = JsonSerializer.Create();
serializer.DefaultValueHandling = DefaultValueHandling.Ignore;
serializer.MissingMemberHandling = MissingMemberHandling.Ignore;
serializer.NullValueHandling = NullValueHandling.Ignore;
var stream = File.Open(ConfigurationPath, FileMode.Open, FileAccess.Read, FileShare.None);
using var sr = new StreamReader(stream);
var reader = new JsonTextReader(sr);
return serializer.Deserialize<Options>(reader) ?? new Options();
}
/// <summary>
@@ -209,30 +241,29 @@ namespace MPF.Frontend.Tools
if (string.IsNullOrEmpty(ConfigurationPath))
return;
// Ensure default values are included
PropertyInfo[] properties = typeof(Options).GetProperties();
foreach (var property in properties)
{
// Skip dictionary properties
if (property.Name == "Item")
continue;
var serializer = JsonSerializer.Create();
var stream = File.Open(ConfigurationPath, FileMode.Create, FileAccess.Write, FileShare.None);
using var sw = new StreamWriter(stream) { AutoFlush = true };
var writer = new JsonTextWriter(sw) { Formatting = Formatting.Indented };
// Skip non-option properties
if (property.Name == "Settings" || property.Name == "HasRedumpLogin")
continue;
serializer.Serialize(writer, ConvertToDictionary(options), typeof(Dictionary<string, string>));
}
var val = property.GetValue(options, null);
property.SetValue(options, val, null);
}
// Handle a very strange edge case
if (!File.Exists(ConfigurationPath))
File.Create(ConfigurationPath).Dispose();
/// <summary>
/// Save the current set of options to the application configuration
/// </summary>
public static void SaveToConfigNative(Options options)
{
// If no options path can be found
if (string.IsNullOrEmpty(ConfigurationPath))
return;
var serializer = JsonSerializer.Create();
var sw = new StreamWriter(ConfigurationPath) { AutoFlush = true };
var stream = File.Open(ConfigurationPath, FileMode.Create, FileAccess.Write, FileShare.None);
using var sw = new StreamWriter(stream) { AutoFlush = true };
var writer = new JsonTextWriter(sw) { Formatting = Formatting.Indented };
serializer.Serialize(writer, options.Settings, typeof(Dictionary<string, string>));
serializer.Serialize(writer, options, typeof(Options));
}
/// <summary>
@@ -240,27 +271,17 @@ namespace MPF.Frontend.Tools
/// </summary>
private static string GetConfigurationPath()
{
// User home directory
#if NET20 || NET35
string homeDir = Environment.ExpandEnvironmentVariables("%HOMEDRIVE%%HOMEPATH%");
homeDir = Path.Combine(Path.Combine(homeDir, ".config"), "mpf");
#else
string homeDir = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
homeDir = Path.Combine(homeDir, ".config", "mpf");
#endif
// User configuration
string homeDir = GetUserConfigurationPath();
if (File.Exists(Path.Combine(homeDir, ConfigurationFileName)))
return Path.Combine(homeDir, ConfigurationFileName);
// Local folder
#if NET20 || NET35 || NET40 || NET452
string runtimeDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
#else
string runtimeDir = AppContext.BaseDirectory;
#endif
// Portable configuration
string runtimeDir = GetRuntimeConfigurationPath();
if (File.Exists(Path.Combine(runtimeDir, ConfigurationFileName)))
return Path.Combine(runtimeDir, ConfigurationFileName);
// Attempt to use local folder
// Attempt portable configuration
try
{
Directory.CreateDirectory(runtimeDir);
@@ -269,7 +290,7 @@ namespace MPF.Frontend.Tools
}
catch { }
// Attempt to use home directory
// Attempt user configuration
try
{
Directory.CreateDirectory(homeDir);
@@ -282,6 +303,294 @@ namespace MPF.Frontend.Tools
return string.Empty;
}
/// <summary>
/// Get the runtime configuration path
/// </summary>
private static string GetRuntimeConfigurationPath()
{
#if NET20 || NET35 || NET40 || NET452
return Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
#else
return AppContext.BaseDirectory;
#endif
}
/// <summary>
/// Get the user configuration path
/// </summary>
/// <remarks>Typically this is located in the profile or home directory</remarks>
private static string GetUserConfigurationPath()
{
#if NET20 || NET35
string homeDir = Environment.ExpandEnvironmentVariables("%HOMEDRIVE%%HOMEPATH%");
homeDir = Path.Combine(Path.Combine(homeDir, ".config"), "mpf");
#else
string homeDir = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
homeDir = Path.Combine(homeDir, ".config", "mpf");
#endif
return homeDir;
}
#endregion
#region Options Helpers
/// <summary>
/// Convert a flat dictionary to an options object
/// </summary>
private static Options ConvertFromDictionary(Dictionary<string, string?>? source)
{
source ??= [];
var options = new Options();
options.FirstRun = GetBooleanSetting(source, "FirstRun", true);
options.CheckForUpdatesOnStartup = GetBooleanSetting(source, "CheckForUpdatesOnStartup", true);
options.VerboseLogging = GetBooleanSetting(source, "VerboseLogging", true);
var valueString = GetStringSetting(source, "InternalProgram", InternalProgram.Redumper.ToString());
var tempInternalProgram = valueString.ToInternalProgram();
options.InternalProgram = tempInternalProgram == InternalProgram.NONE ? InternalProgram.Redumper : tempInternalProgram;
options.GUI.CopyUpdateUrlToClipboard = GetBooleanSetting(source, "CopyUpdateUrlToClipboard", true);
options.GUI.OpenLogWindowAtStartup = GetBooleanSetting(source, "OpenLogWindowAtStartup", true);
valueString = GetStringSetting(source, "DefaultInterfaceLanguage", InterfaceLanguage.AutoDetect.ShortName());
options.GUI.DefaultInterfaceLanguage = valueString.ToInterfaceLanguage();
options.GUI.ShowDebugViewMenuItem = GetBooleanSetting(source, "ShowDebugViewMenuItem", false);
options.GUI.Theming.EnableDarkMode = GetBooleanSetting(source, "EnableDarkMode", false);
options.GUI.Theming.EnablePurpMode = GetBooleanSetting(source, "EnablePurpMode", false);
options.GUI.Theming.CustomBackgroundColor = GetStringSetting(source, "CustomBackgroundColor", null);
options.GUI.Theming.CustomTextColor = GetStringSetting(source, "CustomTextColor", null);
options.GUI.FastUpdateLabel = GetBooleanSetting(source, "FastUpdateLabel", false);
options.GUI.IgnoreFixedDrives = GetBooleanSetting(source, "IgnoreFixedDrives", true);
options.GUI.SkipSystemDetection = GetBooleanSetting(source, "SkipSystemDetection", false);
options.Dumping.AaruPath = GetStringSetting(source, "AaruPath", DumpSettings.DefaultAaruPath) ?? DumpSettings.DefaultAaruPath;
options.Dumping.DiscImageCreatorPath = GetStringSetting(source, "DiscImageCreatorPath", DumpSettings.DefaultDiscImageCreatorPath) ?? DumpSettings.DefaultDiscImageCreatorPath;
options.Dumping.DreamdumpPath = GetStringSetting(source, "DreamdumpPath", DumpSettings.DefaultDreamdumpPath) ?? DumpSettings.DefaultDreamdumpPath;
options.Dumping.RedumperPath = GetStringSetting(source, "RedumperPath", DumpSettings.DefaultRedumperPath) ?? DumpSettings.DefaultRedumperPath;
options.Dumping.DefaultOutputPath = GetStringSetting(source, "DefaultOutputPath", "ISO");
valueString = GetStringSetting(source, "DefaultSystem", RedumpSystem.IBMPCcompatible.ToString());
options.Dumping.DefaultSystem = (valueString ?? string.Empty).ToRedumpSystem();
options.Dumping.DumpSpeeds.CD = GetInt32Setting(source, "PreferredDumpSpeedCD", 24);
options.Dumping.DumpSpeeds.DVD = GetInt32Setting(source, "PreferredDumpSpeedDVD", 16);
options.Dumping.DumpSpeeds.HDDVD = GetInt32Setting(source, "PreferredDumpSpeedHDDVD", 8);
options.Dumping.DumpSpeeds.Bluray = GetInt32Setting(source, "PreferredDumpSpeedBD", 8);
options.Dumping.Aaru.EnableDebug = GetBooleanSetting(source, AaruConstants.EnableDebug, AaruConstants.EnableDebugDefault);
options.Dumping.Aaru.EnableVerbose = GetBooleanSetting(source, AaruConstants.EnableVerbose, AaruConstants.EnableVerboseDefault);
options.Dumping.Aaru.ForceDumping = GetBooleanSetting(source, AaruConstants.ForceDumping, AaruConstants.ForceDumpingDefault);
options.Dumping.Aaru.RereadCount = GetInt32Setting(source, AaruConstants.RereadCount, AaruConstants.RereadCountDefault);
options.Dumping.Aaru.StripPersonalData = GetBooleanSetting(source, AaruConstants.StripPersonalData, AaruConstants.StripPersonalDataDefault);
options.Dumping.DIC.MultiSectorRead = GetBooleanSetting(source, DiscImageCreatorConstants.MultiSectorRead, DiscImageCreatorConstants.MultiSectorReadDefault);
options.Dumping.DIC.MultiSectorReadValue = GetInt32Setting(source, DiscImageCreatorConstants.MultiSectorReadValue, DiscImageCreatorConstants.MultiSectorReadValueDefault);
options.Dumping.DIC.ParanoidMode = GetBooleanSetting(source, DiscImageCreatorConstants.ParanoidMode, DiscImageCreatorConstants.ParanoidModeDefault);
options.Dumping.DIC.QuietMode = GetBooleanSetting(source, DiscImageCreatorConstants.QuietMode, DiscImageCreatorConstants.QuietModeDefault);
options.Dumping.DIC.RereadCount = GetInt32Setting(source, DiscImageCreatorConstants.RereadCount, DiscImageCreatorConstants.RereadCountDefault);
options.Dumping.DIC.DVDRereadCount = GetInt32Setting(source, DiscImageCreatorConstants.DVDRereadCount, DiscImageCreatorConstants.DVDRereadCountDefault);
options.Dumping.DIC.UseCMIFlag = GetBooleanSetting(source, DiscImageCreatorConstants.UseCMIFlag, DiscImageCreatorConstants.UseCMIFlagDefault);
options.Dumping.Dreamdump.NonRedumpMode = GetBooleanSetting(source, "DreamdumpNonRedumpMode", false);
valueString = GetStringSetting(source, DreamdumpConstants.SectorOrder, DreamdumpConstants.SectorOrderDefault.ToString());
options.Dumping.Dreamdump.SectorOrder = valueString.ToDreamdumpSectorOrder();
options.Dumping.Dreamdump.RereadCount = GetInt32Setting(source, DreamdumpConstants.RereadCount, DreamdumpConstants.RereadCountDefault);
options.Dumping.Redumper.EnableSkeleton = GetBooleanSetting(source, RedumperConstants.EnableSkeleton, RedumperConstants.EnableSkeletonDefault);
options.Dumping.Redumper.EnableVerbose = GetBooleanSetting(source, RedumperConstants.EnableVerbose, RedumperConstants.EnableVerboseDefault);
options.Dumping.Redumper.LeadinRetryCount = GetInt32Setting(source, RedumperConstants.LeadinRetryCount, RedumperConstants.LeadinRetryCountDefault);
options.Dumping.Redumper.NonRedumpMode = GetBooleanSetting(source, "RedumperNonRedumpMode", false);
valueString = GetStringSetting(source, RedumperConstants.DriveType, RedumperConstants.DriveTypeDefault.ToString());
options.Dumping.Redumper.DriveType = valueString.ToRedumperDriveType();
options.Dumping.Redumper.DrivePregapStart = GetInt32Setting(source, RedumperConstants.DrivePregapStart, RedumperConstants.DrivePregapStartDefault);
valueString = GetStringSetting(source, RedumperConstants.ReadMethod, RedumperConstants.ReadMethodDefault.ToString());
options.Dumping.Redumper.ReadMethod = valueString.ToRedumperReadMethod();
valueString = GetStringSetting(source, RedumperConstants.SectorOrder, RedumperConstants.SectorOrderDefault.ToString());
options.Dumping.Redumper.SectorOrder = valueString.ToRedumperSectorOrder();
options.Dumping.Redumper.RereadCount = GetInt32Setting(source, RedumperConstants.RereadCount, RedumperConstants.RereadCountDefault);
options.Dumping.Redumper.RefineSectorMode = GetBooleanSetting(source, RedumperConstants.RefineSectorMode, RedumperConstants.RefineSectorModeDefault);
options.Processing.ProtectionScanning.ScanForProtection = GetBooleanSetting(source, "ScanForProtection", true);
options.Processing.ProtectionScanning.ScanArchivesForProtection = GetBooleanSetting(source, "ScanArchivesForProtection", true);
options.Processing.ProtectionScanning.HideDriveLetters = GetBooleanSetting(source, "HideDriveLetters", false);
options.Processing.ProtectionScanning.IncludeDebugProtectionInformation = GetBooleanSetting(source, "IncludeDebugProtectionInformation", false);
options.Processing.Login.PullAllInformation = GetBooleanSetting(source, "PullAllInformation", false);
options.Processing.Login.RedumpUsername = GetStringSetting(source, "RedumpUsername", string.Empty);
options.Processing.Login.RedumpPassword = GetStringSetting(source, "RedumpPassword", string.Empty);
options.Processing.Login.RetrieveMatchInformation = GetBooleanSetting(source, "RetrieveMatchInformation", true);
options.Processing.MediaInformation.AddPlaceholders = GetBooleanSetting(source, "AddPlaceholders", true);
options.Processing.MediaInformation.EnableRedumpCompatibility = GetBooleanSetting(source, "EnableRedumpCompatibility", true);
options.Processing.MediaInformation.EnableTabsInInputFields = GetBooleanSetting(source, "EnableTabsInInputFields", true);
options.Processing.MediaInformation.PromptForDiscInformation = GetBooleanSetting(source, "PromptForDiscInformation", true);
options.Processing.AddFilenameSuffix = GetBooleanSetting(source, "AddFilenameSuffix", false);
options.Processing.CompressLogFiles = GetBooleanSetting(source, "CompressLogFiles", true);
options.Processing.CreateIRDAfterDumping = GetBooleanSetting(source, "CreateIRDAfterDumping", false);
options.Processing.DeleteUnnecessaryFiles = GetBooleanSetting(source, "DeleteUnnecessaryFiles", false);
options.Processing.IncludeArtifacts = GetBooleanSetting(source, "IncludeArtifacts", false);
valueString = GetStringSetting(source, "LogCompression", LogCompression.DeflateMaximum.ToString());
options.Processing.LogCompression = valueString.ToLogCompression();
options.Processing.OutputSubmissionJSON = GetBooleanSetting(source, "OutputSubmissionJSON", false);
options.Processing.ShowDiscEjectReminder = GetBooleanSetting(source, "ShowDiscEjectReminder", true);
return options;
}
/// <summary>
/// Convert options object to a flat dictionary
/// </summary>
private static Dictionary<string, string?> ConvertToDictionary(Options options)
{
return new Dictionary<string, string?>
{
{ "FirstRun", options.FirstRun.ToString()},
{ "AaruPath", options.Dumping.AaruPath },
{ "DiscImageCreatorPath", options.Dumping.DiscImageCreatorPath },
{ "DreamdumpPath", options.Dumping.DreamdumpPath },
{ "RedumperPath", options.Dumping.RedumperPath },
{ "InternalProgram", options.InternalProgram.ToString() },
{ "EnableDarkMode", options.GUI.Theming.EnableDarkMode.ToString() },
{ "EnablePurpMode", options.GUI.Theming.EnablePurpMode.ToString() },
{ "CustomBackgroundColor", options.GUI.Theming.CustomBackgroundColor },
{ "CustomTextColor", options.GUI.Theming.CustomTextColor },
{ "CheckForUpdatesOnStartup", options.CheckForUpdatesOnStartup.ToString() },
{ "CopyUpdateUrlToClipboard", options.GUI.CopyUpdateUrlToClipboard.ToString() },
{ "FastUpdateLabel", options.GUI.FastUpdateLabel.ToString() },
{ "DefaultInterfaceLanguage", options.GUI.DefaultInterfaceLanguage.ShortName() },
{ "DefaultOutputPath", options.Dumping.DefaultOutputPath },
{ "DefaultSystem", options.Dumping.DefaultSystem.ToString() },
{ "ShowDebugViewMenuItem", options.GUI.ShowDebugViewMenuItem.ToString() },
{ "PreferredDumpSpeedCD", options.Dumping.DumpSpeeds.CD.ToString() },
{ "PreferredDumpSpeedDVD", options.Dumping.DumpSpeeds.DVD.ToString() },
{ "PreferredDumpSpeedHDDVD", options.Dumping.DumpSpeeds.HDDVD.ToString() },
{ "PreferredDumpSpeedBD", options.Dumping.DumpSpeeds.Bluray.ToString() },
{ AaruConstants.EnableDebug, options.Dumping.Aaru.EnableDebug.ToString() },
{ AaruConstants.EnableVerbose, options.Dumping.Aaru.EnableVerbose.ToString() },
{ AaruConstants.ForceDumping, options.Dumping.Aaru.ForceDumping.ToString() },
{ AaruConstants.RereadCount, options.Dumping.Aaru.RereadCount.ToString() },
{ AaruConstants.StripPersonalData, options.Dumping.Aaru.StripPersonalData.ToString() },
{ DiscImageCreatorConstants.MultiSectorRead, options.Dumping.DIC.MultiSectorRead.ToString() },
{ DiscImageCreatorConstants.MultiSectorReadValue, options.Dumping.DIC.MultiSectorReadValue.ToString() },
{ DiscImageCreatorConstants.ParanoidMode, options.Dumping.DIC.ParanoidMode.ToString() },
{ DiscImageCreatorConstants.QuietMode, options.Dumping.DIC.QuietMode.ToString() },
{ DiscImageCreatorConstants.RereadCount, options.Dumping.DIC.RereadCount.ToString() },
{ DiscImageCreatorConstants.DVDRereadCount, options.Dumping.DIC.DVDRereadCount.ToString() },
{ DiscImageCreatorConstants.UseCMIFlag, options.Dumping.DIC.UseCMIFlag.ToString() },
{ "DreamdumpNonRedumpMode", options.Dumping.Dreamdump.NonRedumpMode.ToString() },
{ DreamdumpConstants.SectorOrder, options.Dumping.Dreamdump.SectorOrder.ToString() },
{ DreamdumpConstants.RereadCount, options.Dumping.Dreamdump.RereadCount.ToString() },
{ RedumperConstants.EnableSkeleton, options.Dumping.Redumper.EnableSkeleton.ToString() },
{ RedumperConstants.EnableVerbose, options.Dumping.Redumper.EnableVerbose.ToString() },
{ RedumperConstants.LeadinRetryCount, options.Dumping.Redumper.LeadinRetryCount.ToString() },
{ "RedumperNonRedumpMode", options.Dumping.Redumper.NonRedumpMode.ToString() },
{ RedumperConstants.DriveType, options.Dumping.Redumper.DriveType.ToString() },
{ RedumperConstants.DrivePregapStart, options.Dumping.Redumper.DrivePregapStart.ToString() },
{ RedumperConstants.ReadMethod, options.Dumping.Redumper.ReadMethod.ToString() },
{ RedumperConstants.SectorOrder, options.Dumping.Redumper.SectorOrder.ToString() },
{ RedumperConstants.RereadCount, options.Dumping.Redumper.RereadCount.ToString() },
{ RedumperConstants.RefineSectorMode, options.Dumping.Redumper.RefineSectorMode.ToString() },
{ "ScanForProtection", options.Processing.ProtectionScanning.ScanForProtection.ToString() },
{ "AddPlaceholders", options.Processing.MediaInformation.AddPlaceholders.ToString() },
{ "PromptForDiscInformation", options.Processing.MediaInformation.PromptForDiscInformation.ToString() },
{ "PullAllInformation", options.Processing.Login.PullAllInformation.ToString() },
{ "EnableTabsInInputFields", options.Processing.MediaInformation.EnableTabsInInputFields.ToString() },
{ "EnableRedumpCompatibility", options.Processing.MediaInformation.EnableRedumpCompatibility.ToString() },
{ "ShowDiscEjectReminder", options.Processing.ShowDiscEjectReminder.ToString() },
{ "IgnoreFixedDrives", options.GUI.IgnoreFixedDrives.ToString() },
{ "AddFilenameSuffix", options.Processing.AddFilenameSuffix.ToString() },
{ "OutputSubmissionJSON", options.Processing.OutputSubmissionJSON.ToString() },
{ "IncludeArtifacts", options.Processing.IncludeArtifacts.ToString() },
{ "CompressLogFiles", options.Processing.CompressLogFiles.ToString() },
{ "LogCompression", options.Processing.LogCompression.ToString() },
{ "DeleteUnnecessaryFiles", options.Processing.DeleteUnnecessaryFiles.ToString() },
{ "CreateIRDAfterDumping", options.Processing.CreateIRDAfterDumping.ToString() },
{ "SkipSystemDetection", options.GUI.SkipSystemDetection.ToString() },
{ "ScanArchivesForProtection", options.Processing.ProtectionScanning.ScanArchivesForProtection.ToString() },
{ "IncludeDebugProtectionInformation", options.Processing.ProtectionScanning.IncludeDebugProtectionInformation.ToString() },
{ "HideDriveLetters", options.Processing.ProtectionScanning.HideDriveLetters.ToString() },
{ "VerboseLogging", options.VerboseLogging.ToString() },
{ "OpenLogWindowAtStartup", options.GUI.OpenLogWindowAtStartup.ToString() },
{ "RetrieveMatchInformation", options.Processing.Login.RetrieveMatchInformation.ToString() },
{ "RedumpUsername", options.Processing.Login.RedumpUsername },
{ "RedumpPassword", options.Processing.Login.RedumpPassword },
};
}
/// <summary>
/// Get a Boolean setting from a settings, dictionary
/// </summary>
/// <param name="settings">Dictionary representing the settings</param>
/// <param name="key">Setting key to get a value for</param>
/// <param name="defaultValue">Default value to return if no value is found</param>
/// <returns>Setting value if possible, default value otherwise</returns>
private static bool GetBooleanSetting(Dictionary<string, string?> settings, string key, bool defaultValue)
{
if (settings.ContainsKey(key))
{
if (bool.TryParse(settings[key], out bool value))
return value;
else
return defaultValue;
}
else
{
return defaultValue;
}
}
/// <summary>
/// Get an Int32 setting from a settings, dictionary
/// </summary>
/// <param name="settings">Dictionary representing the settings</param>
/// <param name="key">Setting key to get a value for</param>
/// <param name="defaultValue">Default value to return if no value is found</param>
/// <returns>Setting value if possible, default value otherwise</returns>
private static int GetInt32Setting(Dictionary<string, string?> settings, string key, int defaultValue)
{
if (settings.ContainsKey(key))
{
if (int.TryParse(settings[key], out int value))
return value;
else
return defaultValue;
}
else
{
return defaultValue;
}
}
/// <summary>
/// Get a String setting from a settings, dictionary
/// </summary>
/// <param name="settings">Dictionary representing the settings</param>
/// <param name="key">Setting key to get a value for</param>
/// <param name="defaultValue">Default value to return if no value is found</param>
/// <returns>Setting value if possible, default value otherwise</returns>
private static string? GetStringSetting(Dictionary<string, string?> settings, string key, string? defaultValue)
{
if (settings.ContainsKey(key))
return settings[key];
else
return defaultValue;
}
#endregion
}
}

View File

@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
@@ -49,7 +50,7 @@ namespace MPF.Frontend.Tools
// Fix the Y2K timestamp issue, if required
if (fixTwoDigitYear)
year = year >= 1900 && year < 1920 ? 2000 + year % 100 : year;
year = year >= 1900 && year < 1920 ? 2000 + (year % 100) : year;
// Format and return the string
var dt = new DateTime(year, month, day);
@@ -57,7 +58,7 @@ namespace MPF.Frontend.Tools
}
catch
{
// We don't care what the error is
// Absorb the exception
return null;
}
}
@@ -70,7 +71,7 @@ namespace MPF.Frontend.Tools
/// <returns>Byte array of first sector of data, null on error</returns>
public static byte[]? GetFirstBytes(Drive? drive, int numBytes)
{
if (drive == null || drive.Letter == null || drive.Letter == '\0')
if (drive is null || drive.Letter is null || drive.Letter == '\0')
return null;
// Must read between 1 and 2048 bytes
@@ -93,7 +94,7 @@ namespace MPF.Frontend.Tools
}
catch
{
// We don't care what the error is
// Absorb the exception
return null;
}
@@ -149,7 +150,7 @@ namespace MPF.Frontend.Tools
}
catch
{
// We don't care what the error is
// Absorb the exception
return false;
}
}
@@ -205,7 +206,7 @@ namespace MPF.Frontend.Tools
}
catch
{
// We don't care what the error is, assume SYSTEM.CNF doesn't exist
// Absorb the exception, assume SYSTEM.CNF doesn't exist
}
// If the SYSTEM.CNF value can't be found, try PSX.EXE
@@ -274,7 +275,7 @@ namespace MPF.Frontend.Tools
}
catch
{
// We don't care what the error is
// Absorb the exception
return null;
}
}
@@ -306,7 +307,7 @@ namespace MPF.Frontend.Tools
}
catch
{
// We don't care what the error was
// Absorb the exception
return null;
}
}
@@ -327,7 +328,7 @@ namespace MPF.Frontend.Tools
}
catch
{
// We don't care what the error was
// Absorb the exception
return null;
}
}
@@ -364,7 +365,7 @@ namespace MPF.Frontend.Tools
}
catch
{
// We don't care what the error was
// Absorb the exception
return null;
}
}
@@ -385,7 +386,7 @@ namespace MPF.Frontend.Tools
}
catch
{
// We don't care what the error was
// Absorb the exception
return null;
}
}
@@ -430,7 +431,7 @@ namespace MPF.Frontend.Tools
}
catch
{
// We don't care what the error was
// Absorb the exception
return null;
}
}
@@ -468,7 +469,7 @@ namespace MPF.Frontend.Tools
}
catch
{
// We don't care what the error was
// Absorb the exception
return null;
}
}
@@ -506,7 +507,7 @@ namespace MPF.Frontend.Tools
}
catch
{
// We don't care what the error was
// Absorb the exception
return null;
}
}
@@ -548,7 +549,7 @@ namespace MPF.Frontend.Tools
var appPkgHeaderDeserializer = new SabreTools.Serialization.Readers.AppPkgHeader();
var appPkgHeader = appPkgHeaderDeserializer.Deserialize(fileStream);
if (appPkgHeader != null)
if (appPkgHeader is not null)
pkgInfo += $"{appPkgHeader.ContentID}{Environment.NewLine}";
}
@@ -559,7 +560,7 @@ namespace MPF.Frontend.Tools
}
catch
{
// We don't care what the error was
// Absorb the exception
return null;
}
}
@@ -573,7 +574,7 @@ namespace MPF.Frontend.Tools
{
// Attempt to get the param.json file
var json = GetPlayStation5ParamsJsonFromDrive(drive);
if (json == null)
if (json is null)
return null;
try
@@ -582,7 +583,7 @@ namespace MPF.Frontend.Tools
}
catch
{
// We don't care what the error was
// Absorb the exception
return null;
}
}
@@ -596,7 +597,7 @@ namespace MPF.Frontend.Tools
{
// Attempt to get the param.json file
var json = GetPlayStation5ParamsJsonFromDrive(drive);
if (json == null)
if (json is null)
return null;
try
@@ -605,7 +606,7 @@ namespace MPF.Frontend.Tools
}
catch
{
// We don't care what the error was
// Absorb the exception
return null;
}
}
@@ -657,7 +658,7 @@ namespace MPF.Frontend.Tools
}
catch
{
// We don't care what the error was
// Absorb the exception
return null;
}
}
@@ -699,7 +700,7 @@ namespace MPF.Frontend.Tools
var appPkgHeaderDeserializer = new SabreTools.Serialization.Readers.AppPkgHeader();
var appPkgHeader = appPkgHeaderDeserializer.Deserialize(fileStream);
if (appPkgHeader != null)
if (appPkgHeader is not null)
pkgInfo += $"{appPkgHeader.ContentID}{Environment.NewLine}";
}
@@ -710,7 +711,7 @@ namespace MPF.Frontend.Tools
}
catch
{
// We don't care what the error was
// Absorb the exception
return null;
}
}
@@ -726,11 +727,11 @@ namespace MPF.Frontend.Tools
/// <returns>Filenames if possible, null on error</returns>
public static string? GetXboxFilenames(Drive? drive)
{
// If there's no drive path, we can't get BEE flag
// If there's no drive path, can't do anything
if (string.IsNullOrEmpty(drive?.Name))
return null;
// If the folder no longer exists, we can't get exe name
// If the folder no longer exists, can't do anything
if (!Directory.Exists(drive!.Name))
return null;
@@ -747,7 +748,59 @@ namespace MPF.Frontend.Tools
}
catch
{
// We don't care what the error is
// Absorb the exception
return null;
}
}
/// <summary>
/// Get Title ID(s) for Xbox One and Xbox Series X
/// </summary>
/// <param name="drive">Drive to extract information from</param>
/// <returns>Title ID(s) if possible, null on error</returns>
public static string? GetXboxTitleID(Drive? drive)
{
// If there's no drive path, can't do anything
if (string.IsNullOrEmpty(drive?.Name))
return null;
// If the folder no longer exists, can't do anything
if (!Directory.Exists(drive!.Name))
return null;
// Get the catalog.js path
#if NET20 || NET35
string catalogjs = Path.Combine(drive.Name, Path.Combine("MSXC", Path.Combine("Metadata", "catalog.js")));
#else
string catalogjs = Path.Combine(drive.Name, "MSXC", "Metadata", "catalog.js");
#endif
// Check catalog.js exists
if (!File.Exists(catalogjs))
return null;
// Deserialize catalog.js and extract Title ID(s)
try
{
var catalog = new SabreTools.Serialization.Readers.Catalog().Deserialize(catalogjs);
if (catalog is null)
return null;
if (!string.IsNullOrEmpty(catalog.TitleID))
return catalog.TitleID;
if (catalog.Packages is null)
return null;
List<string> titleIDs = [];
foreach (var package in catalog.Packages)
{
if (package?.TitleID is not null)
titleIDs.Add(package.TitleID);
}
return string.Join(", ", [.. titleIDs]);
}
catch
{
// Absorb the exception
return null;
}
}
@@ -763,11 +816,11 @@ namespace MPF.Frontend.Tools
/// <returns>Detected RedumpSystem if detected, null otherwise</returns>
public static RedumpSystem? DetectSegaSystem(Drive? drive)
{
if (drive == null)
if (drive is null)
return null;
byte[]? firstSector = GetFirstBytes(drive, 0x10);
if (firstSector == null || firstSector.Length < 0x10)
if (firstSector is null || firstSector.Length < 0x10)
return null;
string systemType = Encoding.ASCII.GetString(firstSector, 0x00, 0x10);
@@ -797,11 +850,11 @@ namespace MPF.Frontend.Tools
/// <returns>RedumpSystem.Panasonic3DOInteractiveMultiplayer if detected, null otherwise</returns>
public static RedumpSystem? Detect3DOSystem(Drive? drive)
{
if (drive == null)
if (drive is null)
return null;
byte[]? firstSector = GetFirstBytes(drive, 0xC0);
if (firstSector == null || firstSector.Length < 0xC0)
if (firstSector is null || firstSector.Length < 0xC0)
return null;
string systemType = Encoding.ASCII.GetString(firstSector, 0xB0, 0x10);
@@ -815,4 +868,4 @@ namespace MPF.Frontend.Tools
#endregion
}
}
}

View File

@@ -9,6 +9,7 @@ using System.Threading.Tasks;
using BinaryObjectScanner;
using SabreTools.IO.Extensions;
#pragma warning disable SYSLIB1045 // Convert to 'GeneratedRegexAttribute'
namespace MPF.Frontend.Tools
{
public static class ProtectionTool
@@ -42,6 +43,7 @@ namespace MPF.Frontend.Tools
"Installer VISE",
"Intel Installation Framework",
"Microsoft CAB SFX",
"MPRESS",
"NeoLite",
"NSIS",
"PE Compact",
@@ -65,6 +67,72 @@ namespace MPF.Frontend.Tools
#endregion
];
/// <summary>
/// Run comprehensive protection scans based on both the
/// physical media as well as the image
/// </summary>
/// <param name="basePath">Base output image path</param>
/// <param name="drive">Drive object representing the current drive</param>
/// <param name="options">Options object that determines what to scan</param>
/// <param name="progress">Optional progress callback</param>
public static async Task<Dictionary<string, List<string>>> RunCombinedProtectionScans(string basePath,
Drive? drive,
Options options,
IProgress<ProtectionProgress>? protectionProgress = null)
{
// Setup the output protections dictionary
Dictionary<string, List<string>> protections = [];
// Scan the disc image, if possible
if (File.Exists($"{basePath}.iso"))
{
var imageProtections = await RunProtectionScanOnImage($"{basePath}.iso", options, protectionProgress);
MergeDictionaries(protections, imageProtections);
}
else if (File.Exists($"{basePath}.bin"))
{
var imageProtections = await RunProtectionScanOnImage($"{basePath}.bin", options, protectionProgress);
MergeDictionaries(protections, imageProtections);
}
else if (File.Exists($"{basePath}.cue"))
{
string[] cueLines = File.ReadAllLines($"{basePath}.cue");
foreach (string cueLine in cueLines)
{
// Skip all non-FILE lines
if (!cueLine.StartsWith("FILE"))
continue;
// Extract the information
var match = Regex.Match(cueLine, @"FILE ""(.*?)"" BINARY");
if (!match.Success || match.Groups.Count == 0)
continue;
// Get the track name from the matches
string trackName = match.Groups[1].Value;
trackName = Path.GetFileNameWithoutExtension(trackName);
string baseDir = Path.GetDirectoryName(basePath) ?? string.Empty;
string trackPath = Path.Combine(baseDir, trackName);
// Scan the track for protections, if it exists
if (File.Exists($"{trackPath}.bin"))
{
var trackProtections = await RunProtectionScanOnImage($"{trackPath}.bin", options, protectionProgress);
MergeDictionaries(protections, trackProtections);
}
}
}
// Scan the mounted drive path
if (drive?.Name is not null)
{
var driveProtections = await RunProtectionScanOnPath(drive.Name, options, protectionProgress);
MergeDictionaries(protections, driveProtections);
}
return protections;
}
/// <summary>
/// Run protection scan on a given path
/// </summary>
@@ -83,18 +151,54 @@ namespace MPF.Frontend.Tools
#endif
{
var scanner = new Scanner(
options.ScanArchivesForProtection,
options.Processing.ProtectionScanning.ScanArchivesForProtection,
scanContents: true, // Hardcoded value to avoid issues
scanPaths: true, // Hardcoded value to avoid issues
scanSubdirectories: true, // Hardcoded value to avoid issues
options.IncludeDebugProtectionInformation,
options.Processing.ProtectionScanning.IncludeDebugProtectionInformation,
progress);
return scanner.GetProtections(path);
});
// If nothing was returned, return
if (found == null || found.Count == 0)
if (found is null || found.Count == 0)
return [];
// Return the filtered set of protections
return found;
}
/// <summary>
/// Run protection scan on a disc image
/// </summary>
/// <param name="image">Image path to scan for protection</param>
/// <param name="options">Options object that determines what to scan</param>
/// <param name="progress">Optional progress callback</param>
/// <returns>Set of all detected copy protections with an optional error string</returns>
public static async Task<Dictionary<string, List<string>>> RunProtectionScanOnImage(string image,
Options options,
IProgress<ProtectionProgress>? progress = null)
{
#if NET40
var found = await Task.Factory.StartNew(() =>
#else
var found = await Task.Run(() =>
#endif
{
var scanner = new Scanner(
scanArchives: false, // Disable extracting disc images for now
scanContents: false, // Disabled for image scanning
scanPaths: false, // Disabled for image scanning
scanSubdirectories: false, // Disabled for image scanning
options.Processing.ProtectionScanning.IncludeDebugProtectionInformation,
progress);
return scanner.GetProtections(image);
});
// If nothing was returned, return
if (found is null || found.Count == 0)
return [];
// Return the filtered set of protections
@@ -105,13 +209,16 @@ namespace MPF.Frontend.Tools
/// Format found protections to a deduplicated, ordered string
/// </summary>
/// <param name="protections">Dictionary of file to list of protection mappings</param>
/// <param name="drive">Drive object representing the current drive</param>
/// <returns>Detected protections, if any</returns>
public static string? FormatProtections(Dictionary<string, List<string>>? protections)
public static string? FormatProtections(Dictionary<string, List<string>>? protections, Drive? drive)
{
// If the filtered list is empty in some way, return
if (protections == null)
return "(CHECK WITH PROTECTIONID)";
else if (protections.Count == 0)
if (protections is null)
return "[EXTERNAL SCAN NEEDED]";
else if (protections.Count == 0 && drive?.Name is null)
return "Mounted disc path missing [EXTERNAL SCAN NEEDED]";
else if (protections.Count == 0 && drive?.Name is not null)
return "None found [OMIT FROM SUBMISSION]";
// Sanitize context-sensitive protections
@@ -124,7 +231,7 @@ namespace MPF.Frontend.Tools
{
if (value.Count == 0)
continue;
foreach (var prot in value)
{
if (!protectionValues.Contains(prot))
@@ -137,7 +244,7 @@ namespace MPF.Frontend.Tools
.Distinct()
.ToList();
#endif
// Sanitize and join protections for writing
string protectionString = SanitizeFoundProtections(protectionValues);
if (string.IsNullOrEmpty(protectionString))
@@ -201,7 +308,7 @@ namespace MPF.Frontend.Tools
string[] paths = [.. protections.Keys];
foreach (var path in paths)
{
if (!protections.TryGetValue(path, out var values) || values == null || values.Count == 0)
if (!protections.TryGetValue(path, out var values) || values is null || values.Count == 0)
continue;
// Always copy the values if they're valid
@@ -226,7 +333,7 @@ namespace MPF.Frontend.Tools
// Loop through the matching paths
foreach (var path in matchingPaths)
{
if (!filtered.TryGetValue(path, out var values) || values == null || values.Count == 0)
if (!filtered.TryGetValue(path, out var values) || values is null || values.Count == 0)
continue;
if (values.Exists(s => !s.Contains("GitHub") &&
@@ -263,6 +370,7 @@ namespace MPF.Frontend.Tools
foundProtections = foundProtections.FindAll(p => !p.StartsWith("[Exception opening file") && !p.StartsWith("[Access issue when opening file"));
foundProtections.Add("Exception occurred while scanning [RESCAN NEEDED]");
}
if (foundProtections.Exists(p => p.StartsWith("[Access issue when opening file")))
{
foundProtections = foundProtections.FindAll(p => !p.StartsWith("[Exception opening file") && !p.StartsWith("[Access issue when opening file"));
@@ -427,7 +535,7 @@ namespace MPF.Frontend.Tools
.FindAll(p => p != "SafeDisc 2+");
}
// Best case for SafeDisc 1.X: A full SafeDisc version is found that isn't part of a version range.
// Best case for SafeDisc 1.X: A full SafeDisc version is found that isn't part of a version range.
else if (foundProtections.Exists(p => Regex.IsMatch(p, @"SafeDisc 1\.[0-9]{2}\.[0-9]{3}$", RegexOptions.Compiled)
&& !Regex.IsMatch(p, @"SafeDisc 1\.[0-9]{2}\.[0-9]{3}-[0-9]\.[0-9]{2}\.[0-9]{3}", RegexOptions.Compiled)))
{
@@ -441,8 +549,8 @@ namespace MPF.Frontend.Tools
}
// Next best case for SafeDisc 1: A SafeDisc version range is found from "SECDRV.SYS".
else if (foundProtections.Exists(p => p.StartsWith("Macrovision Security Driver")
&& Regex.IsMatch(p, @"SafeDisc 1\.[0-9]{2}\.[0-9]{3}-[1-2]\.[0-9]{2}\.[0-9]{3}", RegexOptions.Compiled)
else if (foundProtections.Exists(p => (p.StartsWith("Macrovision Security Driver")
&& Regex.IsMatch(p, @"SafeDisc 1\.[0-9]{2}\.[0-9]{3}-[1-2]\.[0-9]{2}\.[0-9]{3}", RegexOptions.Compiled))
|| Regex.IsMatch(p, @"SafeDisc 1\.[0-9]{2}\.[0-9]{3}$")))
{
foundProtections = foundProtections.FindAll(p => !p.StartsWith("Macrovision Protection File"))
@@ -536,6 +644,12 @@ namespace MPF.Frontend.Tools
}
}
if (foundProtections.Exists(p => p.StartsWith("StarForce Keyless")))
{
foundProtections = foundProtections.FindAll(p => !p.StartsWith("StarForce Keyless"));
foundProtections.Add("StarForce Keyless");
}
// Sysiphus
if (foundProtections.Exists(p => p == "Sysiphus")
&& foundProtections.Exists(p => p.StartsWith("Sysiphus") && p.Length > "Sysiphus".Length))
@@ -557,5 +671,31 @@ namespace MPF.Frontend.Tools
foundProtections.Sort();
return string.Join(", ", [.. foundProtections]);
}
/// <summary>
/// Merge two dictionaries together based on keys
/// </summary>
/// <param name="original">Source dictionary to add to</param>
/// <param name="add">Second dictionary to add from</param>
/// TODO: Remove from here when IO is updated
private static void MergeDictionaries(Dictionary<string, List<string>> original, Dictionary<string, List<string>> add)
{
// Ignore if there are no values to append
if (add.Count == 0)
return;
// Loop through and add from the new dictionary
foreach (var kvp in add)
{
// Ignore empty values
if (kvp.Value.Count == 0)
continue;
if (!original.ContainsKey(kvp.Key))
original[kvp.Key] = [];
original[kvp.Key].AddRange(kvp.Value);
}
}
}
}

View File

@@ -10,6 +10,7 @@ using BinaryObjectScanner;
using MPF.Processors;
using SabreTools.RedumpLib;
using SabreTools.RedumpLib.Data;
using SabreTools.RedumpLib.Data.Sections;
using SabreTools.RedumpLib.Web;
namespace MPF.Frontend.Tools
@@ -55,54 +56,72 @@ namespace MPF.Frontend.Tools
var outputDirectory = Path.GetDirectoryName(outputPath);
string outputFilename = Path.GetFileName(outputPath);
// If a standard log zip was provided, replace the suffix with ".tmp" for easier processing
if (outputFilename.EndsWith("_logs.zip", StringComparison.OrdinalIgnoreCase))
{
int zipSuffixIndex = outputFilename.LastIndexOf("_logs.zip", StringComparison.OrdinalIgnoreCase);
#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER
outputFilename = outputFilename[..zipSuffixIndex] + ".tmp";
#else
outputFilename = outputFilename.Substring(0, zipSuffixIndex) + ".tmp";
#endif
}
// Check that all of the relevant files are there
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])}"));
resultProgress?.Report(ResultEventArgs.Failure($"This may indicate an issue with the hardware or media, including unsupported devices.\nPlease see dumping program documentation for more details."));
resultProgress?.Report(ResultEventArgs.Failure($"There were files missing from the output:\n{string.Join("\n", [.. missingFiles])}\nThis may indicate an issue with the hardware or media, including unsupported devices.\nPlease see dumping program documentation for more details."));
return null;
}
// Extract files from existing log archive, if it exists
#if NET462_OR_GREATER || NETCOREAPP
processor.ExtractFromLogs(mediaType, outputDirectory, outputFilename);
#endif
// Assemble a base path
string basePath = Path.GetFileNameWithoutExtension(outputFilename);
if (!string.IsNullOrEmpty(outputDirectory))
basePath = Path.Combine(outputDirectory, basePath);
// Create the default submission info
SubmissionInfo info = CreateDefaultSubmissionInfo(processor, system, mediaType, options.AddPlaceholders);
SubmissionInfo info = CreateDefaultSubmissionInfo(processor, system, mediaType, options.Processing.MediaInformation.AddPlaceholders);
// Get specific tool output handling
processor.GenerateSubmissionInfo(info, mediaType, basePath, options.EnableRedumpCompatibility);
if (options.IncludeArtifacts)
processor.GenerateSubmissionInfo(info, mediaType, basePath, options.Processing.MediaInformation.EnableRedumpCompatibility);
if (options.Processing.IncludeArtifacts)
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))
_ = await FillFromRedump(options, info, resultProgress);
if (!string.IsNullOrEmpty(info.TracksAndWriteOffsets.ClrMameProData))
{
bool filledInfo = await FillFromRedump(options, info, resultProgress);
// Add a placeholder for the logs link if not a verification
if (!filledInfo)
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.LogsLink] = "[Please provide a link to your logs here]";
}
// If we have both ClrMamePro and Size and Checksums data, remove the ClrMamePro
if (!string.IsNullOrEmpty(info.SizeAndChecksums?.CRC32))
if (!string.IsNullOrEmpty(info.SizeAndChecksums.CRC32))
info.TracksAndWriteOffsets.ClrMameProData = null;
// Add the volume label to comments, if possible or necessary
string? volLabels = FormatVolumeLabels(drive?.VolumeLabel, processor.VolumeLabels);
if (volLabels != null)
info.CommonDiscInfo!.CommentsSpecialFields![SiteCode.VolumeLabel] = volLabels;
if (volLabels is not null)
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.VolumeLabel] = volLabels;
// Extract info based generically on MediaType
ProcessMediaType(info, mediaType, options.AddPlaceholders);
ProcessMediaType(info, mediaType, options.Processing.MediaInformation.AddPlaceholders);
// Extract info based specifically on RedumpSystem
ProcessSystem(info, system, drive, options.AddPlaceholders, processor is DiscImageCreator, basePath);
ProcessSystem(info, system, drive, options.Processing.MediaInformation.AddPlaceholders, processor is DiscImageCreator, basePath);
// Run anti-modchip check, if necessary
if (drive != null && system.SupportsAntiModchipScans() && info.CopyProtection!.AntiModchip == YesNo.NULL)
if (drive is not null && system.SupportsAntiModchipScans() && info.CopyProtection.AntiModchip == YesNo.NULL)
{
resultProgress?.Report(ResultEventArgs.Success("Checking for anti-modchip strings... this might take a while!"));
resultProgress?.Report(ResultEventArgs.Neutral("Checking for anti-modchip strings... this might take a while!"));
info.CopyProtection.AntiModchip = await ProtectionTool.GetPlayStationAntiModchipDetected(drive?.Name) ? YesNo.Yes : YesNo.No;
resultProgress?.Report(ResultEventArgs.Success("Anti-modchip string scan complete!"));
}
@@ -110,17 +129,23 @@ namespace MPF.Frontend.Tools
// Run copy protection, if possible or necessary
if (system.SupportsCopyProtectionScans())
{
resultProgress?.Report(ResultEventArgs.Success("Running copy protection scan... this might take a while!"));
resultProgress?.Report(ResultEventArgs.Neutral("Running copy protection scan... this might take a while!"));
Dictionary<string, List<string>>? protections = null;
try
{
if (options.ScanForProtection && drive?.Name != null)
protections = await ProtectionTool.RunProtectionScanOnPath(drive.Name, options, protectionProgress);
Dictionary<string, List<string>>? protections = null;
if (options.Processing.ProtectionScanning.ScanForProtection)
{
// Explicitly note missing/invalid device paths
if (drive?.Name is null)
resultProgress?.Report(ResultEventArgs.Success("No mounted device path found, protection outputs may be incomplete!"));
var protectionString = ProtectionTool.FormatProtections(protections);
protections = await ProtectionTool.RunCombinedProtectionScans(basePath, drive, options, protectionProgress);
}
info.CopyProtection!.Protection += protectionString;
var protectionString = ProtectionTool.FormatProtections(protections, drive);
info.CopyProtection.Protection += protectionString;
info.CopyProtection.FullProtections = ReformatProtectionDictionary(protections);
resultProgress?.Report(ResultEventArgs.Success("Copy protection scan complete!"));
}
@@ -131,14 +156,14 @@ namespace MPF.Frontend.Tools
}
// Set fields that may have automatic filling otherwise
info.CommonDiscInfo!.Category ??= DiscCategory.Games;
info.VersionAndEditions!.Version ??= options.AddPlaceholders ? RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Category ??= DiscCategory.Games;
info.VersionAndEditions.Version ??= options.Processing.MediaInformation.AddPlaceholders ? RequiredIfExistsValue : string.Empty;
// Comments and contents have odd handling
if (string.IsNullOrEmpty(info.CommonDiscInfo.Comments))
info.CommonDiscInfo.Comments = options.AddPlaceholders ? OptionalValue : string.Empty;
info.CommonDiscInfo.Comments = options.Processing.MediaInformation.AddPlaceholders ? OptionalValue : string.Empty;
if (string.IsNullOrEmpty(info.CommonDiscInfo.Contents))
info.CommonDiscInfo.Contents = options.AddPlaceholders ? OptionalValue : string.Empty;
info.CommonDiscInfo.Contents = options.Processing.MediaInformation.AddPlaceholders ? OptionalValue : string.Empty;
// Normalize the disc type with all current information
Validator.NormalizeDiscType(info);
@@ -152,25 +177,24 @@ namespace MPF.Frontend.Tools
/// <param name="options">Options object representing user-defined options</param>
/// <param name="info">Existing SubmissionInfo object to fill</param>
/// <param name="resultProgress">Optional result progress callback</param>
public async static Task<bool> FillFromRedump(Options options,
public static async Task<bool> FillFromRedump(Options options,
SubmissionInfo info,
IProgress<ResultEventArgs>? resultProgress = null)
{
// If information should not be pulled at all
if (!options.RetrieveMatchInformation)
if (!options.Processing.Login.RetrieveMatchInformation)
return false;
// Set the current dumper based on username
info.DumpersAndStatus ??= new DumpersAndStatusSection();
info.DumpersAndStatus.Dumpers = [options.RedumpUsername ?? "Anonymous User"];
info.DumpersAndStatus.Dumpers = [options.Processing.Login.RedumpUsername ?? "Anonymous User"];
info.PartiallyMatchedIDs = [];
// Login to Redump, if possible
var wc = new RedumpClient();
if (!string.IsNullOrEmpty(options.RedumpUsername) && !string.IsNullOrEmpty(options.RedumpPassword))
if (!string.IsNullOrEmpty(options.Processing.Login.RedumpUsername) && !string.IsNullOrEmpty(options.Processing.Login.RedumpPassword))
{
bool? loggedIn = await wc.Login(options.RedumpUsername!, options.RedumpPassword!);
if (loggedIn == null)
bool? loggedIn = await wc.Login(options.Processing.Login.RedumpUsername!, options.Processing.Login.RedumpPassword!);
if (loggedIn is null)
{
resultProgress?.Report(ResultEventArgs.Failure("There was an unknown error connecting to Redump, skipping..."));
return false;
@@ -186,8 +210,8 @@ namespace MPF.Frontend.Tools
List<int[]> foundIdSets = [];
// Loop through all of the hashdata to find matching IDs
resultProgress?.Report(ResultEventArgs.Success("Finding disc matches on Redump..."));
var splitData = info.TracksAndWriteOffsets?.ClrMameProData?.TrimEnd('\n')?.Split('\n');
resultProgress?.Report(ResultEventArgs.Neutral("Finding disc matches on Redump..."));
var splitData = info.TracksAndWriteOffsets.ClrMameProData?.TrimEnd('\n')?.Split('\n');
int trackCount = splitData?.Length ?? 0;
foreach (string hashData in splitData ?? [])
{
@@ -195,7 +219,7 @@ namespace MPF.Frontend.Tools
if (string.IsNullOrEmpty(hashData))
{
trackCount--;
resultProgress?.Report(ResultEventArgs.Success("Blank line found, skipping!"));
resultProgress?.Report(ResultEventArgs.Neutral("Blank line found, skipping!"));
continue;
}
@@ -230,7 +254,7 @@ namespace MPF.Frontend.Tools
|| hashData.Contains("(Track AA.5).bin"))
{
trackCount--;
resultProgress?.Report(ResultEventArgs.Success("Extra track found, skipping!"));
resultProgress?.Report(ResultEventArgs.Neutral("Extra track found, skipping!"));
continue;
}
@@ -242,9 +266,9 @@ namespace MPF.Frontend.Tools
}
var foundIds = await Validator.ValidateSingleTrack(wc, info, sha1);
if (foundIds != null && foundIds.Count == 1)
if (foundIds is not null && foundIds.Count == 1)
resultProgress?.Report(ResultEventArgs.Success($"Single match found for {sha1}"));
else if (foundIds != null && foundIds.Count != 1)
else if (foundIds is not null && foundIds.Count != 1)
resultProgress?.Report(ResultEventArgs.Success($"Multiple matches found for {sha1}"));
else
resultProgress?.Report(ResultEventArgs.Failure($"No matches found for {sha1}"));
@@ -253,7 +277,7 @@ namespace MPF.Frontend.Tools
foundIdSets.Add(foundIds?.ToArray() ?? []);
// Ensure that all tracks are found
allFound &= (foundIds != null && foundIds.Count >= 1);
allFound &= foundIds is not null && foundIds.Count >= 1;
}
// If all tracks were found, check if there are any fully-matched IDs
@@ -264,7 +288,7 @@ namespace MPF.Frontend.Tools
foreach (var set in foundIdSets)
{
// First track is always all IDs
if (fullyMatchedIdsSet == null)
if (fullyMatchedIdsSet is null)
{
fullyMatchedIdsSet = [.. set];
continue;
@@ -282,25 +306,25 @@ namespace MPF.Frontend.Tools
{
string sha1 = info.CommonDiscInfo.CommentsSpecialFields[SiteCode.UniversalHash];
var foundIds = await Validator.ValidateUniversalHash(wc, info);
if (foundIds != null && foundIds.Count == 1)
if (foundIds is not null && foundIds.Count == 1)
resultProgress?.Report(ResultEventArgs.Success($"Single match found for universal hash {sha1}"));
else if (foundIds != null && foundIds.Count != 1)
else if (foundIds is not null && foundIds.Count != 1)
resultProgress?.Report(ResultEventArgs.Success($"Multiple matches found for universal hash {sha1}"));
else
resultProgress?.Report(ResultEventArgs.Failure($"No matches found for universal hash {sha1}"));
// Ensure that the hash is found
allFound = (foundIds != null && foundIds.Count == 1);
allFound = foundIds is not null && foundIds.Count == 1;
// If we found a match, then the disc is a match
if (foundIds != null && foundIds.Count == 1)
if (foundIds is not null && foundIds.Count == 1)
fullyMatchedIdsSet = [.. foundIds];
else
fullyMatchedIdsSet = [];
}
// Get a list version of the fully matched IDs
List<int> fullyMatchedIdsList = fullyMatchedIdsSet != null ? [.. fullyMatchedIdsSet] : [];
List<int> fullyMatchedIdsList = fullyMatchedIdsSet is not null ? [.. fullyMatchedIdsSet] : [];
// Make sure we only have unique IDs
var partiallyMatchedIds = new HashSet<int>();
@@ -308,12 +332,12 @@ namespace MPF.Frontend.Tools
info.PartiallyMatchedIDs = [.. partiallyMatchedIds];
info.PartiallyMatchedIDs.Sort();
resultProgress?.Report(ResultEventArgs.Success("Match finding complete! " + (fullyMatchedIdsList != null && fullyMatchedIdsList.Count > 0
resultProgress?.Report(ResultEventArgs.Success("Match finding complete! " + (fullyMatchedIdsList is not null && fullyMatchedIdsList.Count > 0
? "Fully Matched IDs: " + string.Join(",", [.. fullyMatchedIdsList.ConvertAll(i => i.ToString())])
: "No matches found")));
// Exit early if one failed or there are no matched IDs
if (!allFound || fullyMatchedIdsList == null || fullyMatchedIdsList.Count == 0)
if (!allFound || fullyMatchedIdsList is null || fullyMatchedIdsList.Count == 0)
return false;
// Find the first matched ID where the track count matches, we can grab a bunch of info from it
@@ -325,8 +349,8 @@ namespace MPF.Frontend.Tools
continue;
// Fill in the fields from the existing ID
resultProgress?.Report(ResultEventArgs.Success($"Filling fields from existing ID {fullyMatchedIdsList[i]}..."));
_ = await Builder.FillFromId(wc, info, fullyMatchedIdsList[i], options.PullAllInformation);
resultProgress?.Report(ResultEventArgs.Neutral($"Filling fields from existing ID {fullyMatchedIdsList[i]}..."));
_ = await Builder.FillFromId(wc, info, fullyMatchedIdsList[i], options.Processing.Login.PullAllInformation);
resultProgress?.Report(ResultEventArgs.Success("Information filling complete!"));
// Set the fully matched ID to the current
@@ -384,8 +408,6 @@ namespace MPF.Frontend.Tools
},
};
// Ensure that required sections exist
info = Builder.EnsureAllSections(info);
return info;
}
@@ -399,9 +421,10 @@ namespace MPF.Frontend.Tools
// Map to the internal program
InternalProgram? internalProgram = processor switch
{
Processors.Aaru => InternalProgram.Aaru,
Aaru => InternalProgram.Aaru,
CleanRip => InternalProgram.CleanRip,
DiscImageCreator => InternalProgram.DiscImageCreator,
// Dreamdump => InternalProgram.Dreamdump,
PS3CFW => InternalProgram.PS3CFW,
Redumper => InternalProgram.Redumper,
UmdImageCreator => InternalProgram.UmdImageCreator,
@@ -421,7 +444,7 @@ namespace MPF.Frontend.Tools
private static string? SimplifyVolumeLabel(string? label)
{
// Ignore empty labels
if (label == null || label.Length == 0)
if (label is null || label.Length == 0)
return null;
// Take only ASCII alphanumeric characters
@@ -438,7 +461,7 @@ namespace MPF.Frontend.Tools
// Ignore non-ASCII labels
string? simpleLabel = labelBuilder.ToString();
if (simpleLabel == null || simpleLabel.Length == 0)
if (simpleLabel is null || simpleLabel.Length == 0)
return null;
return simpleLabel;
@@ -452,23 +475,23 @@ namespace MPF.Frontend.Tools
private static string? FormatVolumeLabels(string? driveLabel, Dictionary<string, List<string>>? labels)
{
// Treat empty label as null
if (driveLabel != null && driveLabel.Length == 0)
if (driveLabel is not 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("\\")))
if (driveLabel is not null && (driveLabel.Contains("/") || driveLabel.Contains("\\")))
driveLabel = null;
// Must have at least one label to format
if (driveLabel == null && (labels == null || labels.Count == 0))
if (driveLabel is null && (labels is null || labels.Count == 0))
return null;
// If no labels given, use drive label
if (labels == null || labels.Count == 0)
if (labels is null || labels.Count == 0)
{
// Ignore common volume labels
if (FrontendTool.GetRedumpSystemFromVolumeLabel(driveLabel) != null)
if (FrontendTool.GetRedumpSystemFromVolumeLabel(driveLabel) is not null)
return null;
return driveLabel;
@@ -477,7 +500,7 @@ namespace MPF.Frontend.Tools
// Get the default label to compare against
// TODO: Full pairwise comparison of all labels, not just comparing against drive/UDF label.
string? defaultLabel = null;
if (driveLabel != null && driveLabel.Length != 0)
if (driveLabel is not null && driveLabel.Length != 0)
{
defaultLabel = SimplifyVolumeLabel(driveLabel);
}
@@ -492,7 +515,7 @@ namespace MPF.Frontend.Tools
#endif
// Remove duplicate/useless volume labels
if (defaultLabel != null && defaultLabel.Length != 0)
if (defaultLabel is not null && defaultLabel.Length != 0)
{
List<string> keys = [.. labels.Keys];
foreach (var label in keys)
@@ -506,7 +529,7 @@ namespace MPF.Frontend.Tools
// Get upper-case ASCII variant of the label
string? tempLabel = SimplifyVolumeLabel(label);
if (tempLabel == null)
if (tempLabel is null)
continue;
// Remove duplicate volume labels
@@ -516,10 +539,10 @@ namespace MPF.Frontend.Tools
}
// If no labels are left, use drive label
if (labels == null || labels.Count == 0)
if (labels is null || labels.Count == 0)
{
// Ignore common volume labels
if (FrontendTool.GetRedumpSystemFromVolumeLabel(driveLabel) != null)
if (FrontendTool.GetRedumpSystemFromVolumeLabel(driveLabel) is not null)
return null;
return driveLabel;
@@ -532,10 +555,10 @@ namespace MPF.Frontend.Tools
#else
string firstLabel = labels.First().Key;
#endif
if (labels.Count == 1 && (firstLabel == driveLabel || driveLabel == null))
if (labels.Count == 1 && (firstLabel == driveLabel || driveLabel is null))
{
// Ignore common volume labels
if (FrontendTool.GetRedumpSystemFromVolumeLabel(firstLabel) != null)
if (FrontendTool.GetRedumpSystemFromVolumeLabel(firstLabel) is not null)
return null;
return firstLabel;
@@ -545,14 +568,14 @@ namespace MPF.Frontend.Tools
List<string> volLabels = [];
// Begin formatted output with the label from Windows, if it is unique and not a common volume label
if (driveLabel != null && !labels.TryGetValue(driveLabel, out List<string>? value) && FrontendTool.GetRedumpSystemFromVolumeLabel(driveLabel) == null)
if (driveLabel is not null && !labels.TryGetValue(driveLabel, out List<string>? value) && FrontendTool.GetRedumpSystemFromVolumeLabel(driveLabel) is null)
volLabels.Add(driveLabel);
// Add remaining labels with their corresponding filesystems
foreach (var kvp in labels)
{
// Ignore common volume labels
if (FrontendTool.GetRedumpSystemFromVolumeLabel(kvp.Key) == null)
if (FrontendTool.GetRedumpSystemFromVolumeLabel(kvp.Key) is null)
volLabels.Add($"{kvp.Key} ({string.Join(", ", [.. kvp.Value])})");
}
@@ -571,11 +594,12 @@ namespace MPF.Frontend.Tools
/// </summary>
private static bool ProcessMediaType(SubmissionInfo info, MediaType? mediaType, bool addPlaceholders)
{
#pragma warning disable IDE0010
switch (mediaType)
{
case MediaType.CDROM:
case MediaType.GDROM:
info.CommonDiscInfo!.Layer0MasteringRing = addPlaceholders ? RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Layer0MasteringRing = addPlaceholders ? RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Layer0MasteringSID = addPlaceholders ? RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Layer0ToolstampMasteringCode = addPlaceholders ? RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Layer0MouldSID = addPlaceholders ? RequiredIfExistsValue : string.Empty;
@@ -588,9 +612,9 @@ namespace MPF.Frontend.Tools
case MediaType.BluRay:
// If we have a single-layer disc
if (info.SizeAndChecksums!.Layerbreak == default)
if (info.SizeAndChecksums.Layerbreak == default)
{
info.CommonDiscInfo!.Layer0MasteringRing = addPlaceholders ? RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Layer0MasteringRing = addPlaceholders ? RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Layer0MasteringSID = addPlaceholders ? RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Layer0ToolstampMasteringCode = addPlaceholders ? RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Layer0MouldSID = addPlaceholders ? RequiredIfExistsValue : string.Empty;
@@ -598,9 +622,9 @@ namespace MPF.Frontend.Tools
info.CommonDiscInfo.Layer0AdditionalMould = addPlaceholders ? RequiredIfExistsValue : string.Empty;
}
// If we have a dual-layer disc
else if (info.SizeAndChecksums!.Layerbreak2 == default)
else if (info.SizeAndChecksums.Layerbreak2 == default)
{
info.CommonDiscInfo!.Layer0MasteringRing = addPlaceholders ? RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Layer0MasteringRing = addPlaceholders ? RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Layer0MasteringSID = addPlaceholders ? RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Layer0ToolstampMasteringCode = addPlaceholders ? RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Layer0MouldSID = addPlaceholders ? RequiredIfExistsValue : string.Empty;
@@ -612,9 +636,9 @@ namespace MPF.Frontend.Tools
info.CommonDiscInfo.Layer1MouldSID = addPlaceholders ? RequiredIfExistsValue : string.Empty;
}
// If we have a triple-layer disc
else if (info.SizeAndChecksums!.Layerbreak3 == default)
else if (info.SizeAndChecksums.Layerbreak3 == default)
{
info.CommonDiscInfo!.Layer0MasteringRing = addPlaceholders ? RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Layer0MasteringRing = addPlaceholders ? RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Layer0MasteringSID = addPlaceholders ? RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Layer0ToolstampMasteringCode = addPlaceholders ? RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Layer0MouldSID = addPlaceholders ? RequiredIfExistsValue : string.Empty;
@@ -632,7 +656,7 @@ namespace MPF.Frontend.Tools
// If we have a quad-layer disc
else
{
info.CommonDiscInfo!.Layer0MasteringRing = addPlaceholders ? RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Layer0MasteringRing = addPlaceholders ? RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Layer0MasteringSID = addPlaceholders ? RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Layer0ToolstampMasteringCode = addPlaceholders ? RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Layer0MouldSID = addPlaceholders ? RequiredIfExistsValue : string.Empty;
@@ -655,22 +679,22 @@ namespace MPF.Frontend.Tools
break;
case MediaType.NintendoGameCubeGameDisc:
info.CommonDiscInfo!.Layer0MasteringRing = addPlaceholders ? RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Layer0MasteringRing = addPlaceholders ? RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Layer0MasteringSID = addPlaceholders ? RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Layer0ToolstampMasteringCode = addPlaceholders ? RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Layer0MouldSID = addPlaceholders ? RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Layer1MouldSID = addPlaceholders ? RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Layer0AdditionalMould = addPlaceholders ? RequiredIfExistsValue : string.Empty;
info.Extras!.BCA ??= addPlaceholders ? RequiredValue : string.Empty;
info.Extras.BCA ??= addPlaceholders ? RequiredValue : string.Empty;
break;
case MediaType.NintendoWiiOpticalDisc:
case MediaType.NintendoWiiUOpticalDisc:
// If we have a single-layer disc
if (info.SizeAndChecksums!.Layerbreak == default)
if (info.SizeAndChecksums.Layerbreak == default)
{
info.CommonDiscInfo!.Layer0MasteringRing = addPlaceholders ? RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Layer0MasteringRing = addPlaceholders ? RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Layer0MasteringSID = addPlaceholders ? RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Layer0ToolstampMasteringCode = addPlaceholders ? RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Layer0MouldSID = addPlaceholders ? RequiredIfExistsValue : string.Empty;
@@ -680,7 +704,7 @@ namespace MPF.Frontend.Tools
// If we have a dual-layer disc
else
{
info.CommonDiscInfo!.Layer0MasteringRing = addPlaceholders ? RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Layer0MasteringRing = addPlaceholders ? RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Layer0MasteringSID = addPlaceholders ? RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Layer0ToolstampMasteringCode = addPlaceholders ? RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Layer0MouldSID = addPlaceholders ? RequiredIfExistsValue : string.Empty;
@@ -692,14 +716,14 @@ namespace MPF.Frontend.Tools
info.CommonDiscInfo.Layer1MouldSID = addPlaceholders ? RequiredIfExistsValue : string.Empty;
}
info.Extras!.DiscKey = addPlaceholders ? RequiredValue : string.Empty;
info.Extras.DiscKey = addPlaceholders ? RequiredValue : string.Empty;
info.Extras.BCA ??= addPlaceholders ? RequiredValue : string.Empty;
break;
case MediaType.UMD:
// Both single- and dual-layer discs have two "layers" for the ring
info.CommonDiscInfo!.Layer0MasteringRing = addPlaceholders ? RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Layer0MasteringRing = addPlaceholders ? RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Layer0MasteringSID = addPlaceholders ? RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Layer0ToolstampMasteringCode = addPlaceholders ? RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Layer0MouldSID = addPlaceholders ? RequiredIfExistsValue : string.Empty;
@@ -708,12 +732,13 @@ namespace MPF.Frontend.Tools
info.CommonDiscInfo.Layer1MasteringSID = addPlaceholders ? RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Layer1ToolstampMasteringCode = addPlaceholders ? RequiredIfExistsValue : string.Empty;
info.SizeAndChecksums!.CRC32 ??= (addPlaceholders ? RequiredValue + " [Not automatically generated for UMD]" : string.Empty);
info.SizeAndChecksums.CRC32 ??= (addPlaceholders ? RequiredValue + " [Not automatically generated for UMD]" : string.Empty);
info.SizeAndChecksums.MD5 ??= (addPlaceholders ? RequiredValue + " [Not automatically generated for UMD]" : string.Empty);
info.SizeAndChecksums.SHA1 ??= (addPlaceholders ? RequiredValue + " [Not automatically generated for UMD]" : string.Empty);
info.TracksAndWriteOffsets!.ClrMameProData = null;
info.TracksAndWriteOffsets.ClrMameProData = null;
break;
}
#pragma warning restore IDE0010
return true;
}
@@ -723,89 +748,90 @@ namespace MPF.Frontend.Tools
/// </summary>
private static bool ProcessSystem(SubmissionInfo info, RedumpSystem? system, Drive? drive, bool addPlaceholders, bool isDiscImageCreator, string basePath)
{
#pragma warning disable IDE0010
// Extract info based specifically on RedumpSystem
switch (system)
{
case RedumpSystem.AcornArchimedes:
info.CommonDiscInfo!.Region ??= Region.UnitedKingdom;
info.CommonDiscInfo.Region ??= Region.UnitedKingdom;
break;
case RedumpSystem.AudioCD:
case RedumpSystem.DVDAudio:
case RedumpSystem.EnhancedCD:
case RedumpSystem.SuperAudioCD:
info.CommonDiscInfo!.Category ??= DiscCategory.Audio;
info.CommonDiscInfo.Category ??= DiscCategory.Audio;
break;
case RedumpSystem.BandaiPlaydiaQuickInteractiveSystem:
info.CommonDiscInfo!.EXEDateBuildDate ??= addPlaceholders ? RequiredValue : string.Empty;
info.CommonDiscInfo.EXEDateBuildDate ??= addPlaceholders ? RequiredValue : string.Empty;
info.CommonDiscInfo.Region ??= info.CommonDiscInfo.Region ?? Region.Japan;
break;
case RedumpSystem.BDVideo:
info.CommonDiscInfo!.Category ??= DiscCategory.Video;
info.CommonDiscInfo.Category ??= DiscCategory.Video;
bool bee = PhysicalTool.GetBusEncryptionEnabled(drive);
if (bee && string.IsNullOrEmpty(info.CopyProtection!.Protection))
if (bee && string.IsNullOrEmpty(info.CopyProtection.Protection))
info.CopyProtection.Protection = "Bus encryption enabled flag set";
else if (bee)
info.CopyProtection!.Protection += "\nBus encryption enabled flag set";
info.CopyProtection.Protection += "\nBus encryption enabled flag set";
else
info.CopyProtection!.Protection ??= addPlaceholders ? RequiredIfExistsValue : string.Empty;
info.CopyProtection.Protection ??= addPlaceholders ? RequiredIfExistsValue : string.Empty;
break;
case RedumpSystem.DVDVideo:
case RedumpSystem.HDDVDVideo:
info.CommonDiscInfo!.Category ??= DiscCategory.Video;
info.CopyProtection!.Protection ??= addPlaceholders ? RequiredIfExistsValue : string.Empty;
info.CommonDiscInfo.Category ??= DiscCategory.Video;
info.CopyProtection.Protection ??= addPlaceholders ? RequiredIfExistsValue : string.Empty;
break;
case RedumpSystem.CommodoreAmigaCD:
info.CommonDiscInfo!.EXEDateBuildDate ??= addPlaceholders ? RequiredValue : string.Empty;
info.CommonDiscInfo.EXEDateBuildDate ??= addPlaceholders ? RequiredValue : string.Empty;
break;
case RedumpSystem.CommodoreAmigaCD32:
info.CommonDiscInfo!.EXEDateBuildDate ??= addPlaceholders ? RequiredValue : string.Empty;
info.CommonDiscInfo.EXEDateBuildDate ??= addPlaceholders ? RequiredValue : string.Empty;
info.CommonDiscInfo.Region ??= Region.Europe;
break;
case RedumpSystem.CommodoreAmigaCDTV:
info.CommonDiscInfo!.EXEDateBuildDate ??= addPlaceholders ? RequiredValue : string.Empty;
info.CommonDiscInfo.EXEDateBuildDate ??= addPlaceholders ? RequiredValue : string.Empty;
info.CommonDiscInfo.Region ??= Region.Europe;
break;
case RedumpSystem.FujitsuFMTownsseries:
info.CommonDiscInfo!.EXEDateBuildDate ??= addPlaceholders ? RequiredValue : string.Empty;
info.CommonDiscInfo.EXEDateBuildDate ??= addPlaceholders ? RequiredValue : string.Empty;
info.CommonDiscInfo.Region ??= Region.Japan;
break;
case RedumpSystem.FujitsuFMTownsMarty:
info.CommonDiscInfo!.Region ??= Region.Japan;
info.CommonDiscInfo.Region ??= Region.Japan;
break;
case RedumpSystem.HasbroVideoNow:
case RedumpSystem.HasbroVideoNowColor:
case RedumpSystem.HasbroVideoNowJr:
case RedumpSystem.VideoCD:
info.CommonDiscInfo!.Category ??= DiscCategory.Video;
info.CommonDiscInfo.Category ??= DiscCategory.Video;
break;
case RedumpSystem.HasbroVideoNowXP:
case RedumpSystem.PhotoCD:
case RedumpSystem.SonyElectronicBook:
info.CommonDiscInfo!.Category ??= DiscCategory.Multimedia;
info.CommonDiscInfo.Category ??= DiscCategory.Multimedia;
break;
case RedumpSystem.IncredibleTechnologiesEagle:
info.CommonDiscInfo!.EXEDateBuildDate ??= addPlaceholders ? RequiredValue : string.Empty;
info.CommonDiscInfo.EXEDateBuildDate ??= addPlaceholders ? RequiredValue : string.Empty;
break;
case RedumpSystem.KonamieAmusement:
info.CommonDiscInfo!.EXEDateBuildDate ??= addPlaceholders ? RequiredValue : string.Empty;
info.CommonDiscInfo.EXEDateBuildDate ??= addPlaceholders ? RequiredValue : string.Empty;
break;
case RedumpSystem.KonamiFireBeat:
info.CommonDiscInfo!.EXEDateBuildDate ??= addPlaceholders ? RequiredValue : string.Empty;
info.CommonDiscInfo.EXEDateBuildDate ??= addPlaceholders ? RequiredValue : string.Empty;
break;
case RedumpSystem.KonamiPython2:
@@ -813,89 +839,91 @@ namespace MPF.Frontend.Tools
// TODO: Remove this hack when DIC supports build date output
if (isDiscImageCreator)
info.CommonDiscInfo!.EXEDateBuildDate = DiscImageCreator.GetPlayStationEXEDate($"{basePath}_volDesc.txt", kp2Exe);
info.CommonDiscInfo.EXEDateBuildDate = DiscImageCreator.GetPlayStationEXEDate($"{basePath}_volDesc.txt", kp2Exe);
SetCommentFieldIfNotExists(info, SiteCode.InternalSerialName, drive, PhysicalTool.GetPlayStationSerial);
info.CommonDiscInfo!.EXEDateBuildDate ??= PhysicalTool.GetFileDate(drive, kp2Exe, fixTwoDigitYear: true);
info.CommonDiscInfo.EXEDateBuildDate ??= PhysicalTool.GetFileDate(drive, kp2Exe, fixTwoDigitYear: true);
if (CommentFieldExists(info, SiteCode.InternalSerialName, out kp2Exe))
info.CommonDiscInfo!.Region = ProcessingTool.GetPlayStationRegion(kp2Exe);
info.CommonDiscInfo.Region = ProcessingTool.GetPlayStationRegion(kp2Exe);
SetVersionIfNotExists(info, drive, PhysicalTool.GetPlayStation2Version);
break;
case RedumpSystem.KonamiSystemGV:
info.CommonDiscInfo!.EXEDateBuildDate ??= addPlaceholders ? RequiredValue : string.Empty;
info.CommonDiscInfo.EXEDateBuildDate ??= addPlaceholders ? RequiredValue : string.Empty;
break;
case RedumpSystem.KonamiSystem573:
info.CommonDiscInfo!.EXEDateBuildDate ??= addPlaceholders ? RequiredValue : string.Empty;
info.CommonDiscInfo.EXEDateBuildDate ??= addPlaceholders ? RequiredValue : string.Empty;
break;
case RedumpSystem.KonamiTwinkle:
info.CommonDiscInfo!.EXEDateBuildDate ??= addPlaceholders ? RequiredValue : string.Empty;
info.CommonDiscInfo.EXEDateBuildDate ??= addPlaceholders ? RequiredValue : string.Empty;
break;
case RedumpSystem.MattelHyperScan:
info.CommonDiscInfo!.EXEDateBuildDate ??= addPlaceholders ? RequiredValue : string.Empty;
info.CommonDiscInfo.EXEDateBuildDate ??= addPlaceholders ? RequiredValue : string.Empty;
break;
case RedumpSystem.MicrosoftXboxOne:
info.CommonDiscInfo!.CommentsSpecialFields![SiteCode.Filename] = PhysicalTool.GetXboxFilenames(drive) ?? string.Empty;
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.Filename] = PhysicalTool.GetXboxFilenames(drive) ?? string.Empty;
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.TitleID] = PhysicalTool.GetXboxTitleID(drive) ?? string.Empty;
break;
case RedumpSystem.MicrosoftXboxSeriesXS:
info.CommonDiscInfo!.CommentsSpecialFields![SiteCode.Filename] = PhysicalTool.GetXboxFilenames(drive) ?? string.Empty;
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.Filename] = PhysicalTool.GetXboxFilenames(drive) ?? string.Empty;
info.CommonDiscInfo.CommentsSpecialFields[SiteCode.TitleID] = PhysicalTool.GetXboxTitleID(drive) ?? string.Empty;
break;
case RedumpSystem.NamcoSegaNintendoTriforce:
info.CommonDiscInfo!.EXEDateBuildDate ??= addPlaceholders ? RequiredValue : string.Empty;
info.CommonDiscInfo.EXEDateBuildDate ??= addPlaceholders ? RequiredValue : string.Empty;
break;
case RedumpSystem.NavisoftNaviken21:
info.CommonDiscInfo!.EXEDateBuildDate = addPlaceholders ? RequiredValue : string.Empty;
info.CommonDiscInfo.EXEDateBuildDate = addPlaceholders ? RequiredValue : string.Empty;
info.CommonDiscInfo.Region ??= Region.Japan;
break;
case RedumpSystem.NECPC88series:
info.CommonDiscInfo!.Region ??= Region.Japan;
info.CommonDiscInfo.Region ??= Region.Japan;
break;
case RedumpSystem.NECPC98series:
info.CommonDiscInfo!.EXEDateBuildDate = addPlaceholders ? RequiredValue : string.Empty;
info.CommonDiscInfo!.Region ??= Region.Japan;
info.CommonDiscInfo.EXEDateBuildDate = addPlaceholders ? RequiredValue : string.Empty;
info.CommonDiscInfo.Region ??= Region.Japan;
break;
case RedumpSystem.NECPCFXPCFXGA:
info.CommonDiscInfo!.Region ??= Region.Japan;
info.CommonDiscInfo.Region ??= Region.Japan;
break;
case RedumpSystem.SegaChihiro:
info.CommonDiscInfo!.EXEDateBuildDate ??= addPlaceholders ? RequiredValue : string.Empty;
info.CommonDiscInfo.EXEDateBuildDate ??= addPlaceholders ? RequiredValue : string.Empty;
break;
case RedumpSystem.SegaDreamcast:
info.CommonDiscInfo!.EXEDateBuildDate ??= addPlaceholders ? RequiredValue : string.Empty;
info.CommonDiscInfo.EXEDateBuildDate ??= addPlaceholders ? RequiredValue : string.Empty;
break;
case RedumpSystem.SegaNaomi:
info.CommonDiscInfo!.EXEDateBuildDate ??= addPlaceholders ? RequiredValue : string.Empty;
info.CommonDiscInfo.EXEDateBuildDate ??= addPlaceholders ? RequiredValue : string.Empty;
break;
case RedumpSystem.SegaNaomi2:
info.CommonDiscInfo!.EXEDateBuildDate ??= addPlaceholders ? RequiredValue : string.Empty;
info.CommonDiscInfo.EXEDateBuildDate ??= addPlaceholders ? RequiredValue : string.Empty;
break;
case RedumpSystem.SegaTitanVideo:
info.CommonDiscInfo!.EXEDateBuildDate ??= addPlaceholders ? RequiredValue : string.Empty;
info.CommonDiscInfo.EXEDateBuildDate ??= addPlaceholders ? RequiredValue : string.Empty;
break;
case RedumpSystem.SharpX68000:
info.CommonDiscInfo!.Region ??= Region.Japan;
info.CommonDiscInfo.Region ??= Region.Japan;
break;
case RedumpSystem.SNKNeoGeoCD:
info.CommonDiscInfo!.EXEDateBuildDate ??= addPlaceholders ? RequiredValue : string.Empty;
info.CommonDiscInfo.EXEDateBuildDate ??= addPlaceholders ? RequiredValue : string.Empty;
break;
case RedumpSystem.SonyPlayStation:
@@ -903,26 +931,26 @@ namespace MPF.Frontend.Tools
// TODO: Remove this hack when DIC supports build date output
if (isDiscImageCreator)
info.CommonDiscInfo!.EXEDateBuildDate = DiscImageCreator.GetPlayStationEXEDate($"{basePath}_volDesc.txt", ps1Exe, psx: true);
info.CommonDiscInfo.EXEDateBuildDate = DiscImageCreator.GetPlayStationEXEDate($"{basePath}_volDesc.txt", ps1Exe, psx: true);
SetCommentFieldIfNotExists(info, SiteCode.InternalSerialName, drive, PhysicalTool.GetPlayStationSerial);
info.CommonDiscInfo!.EXEDateBuildDate ??= PhysicalTool.GetFileDate(drive, ps1Exe, fixTwoDigitYear: true);
info.CommonDiscInfo.EXEDateBuildDate ??= PhysicalTool.GetFileDate(drive, ps1Exe, fixTwoDigitYear: true);
if (CommentFieldExists(info, SiteCode.InternalSerialName, out ps1Exe))
info.CommonDiscInfo!.Region = ProcessingTool.GetPlayStationRegion(ps1Exe);
info.CommonDiscInfo.Region = ProcessingTool.GetPlayStationRegion(ps1Exe);
break;
case RedumpSystem.SonyPlayStation2:
info.CommonDiscInfo!.LanguageSelection ??= [];
info.CommonDiscInfo.LanguageSelection ??= [];
string? ps2Exe = PhysicalTool.GetPlayStationExecutableName(drive);
// TODO: Remove this hack when DIC supports build date output
if (isDiscImageCreator)
info.CommonDiscInfo!.EXEDateBuildDate = DiscImageCreator.GetPlayStationEXEDate($"{basePath}_volDesc.txt", ps2Exe);
info.CommonDiscInfo.EXEDateBuildDate = DiscImageCreator.GetPlayStationEXEDate($"{basePath}_volDesc.txt", ps2Exe);
SetCommentFieldIfNotExists(info, SiteCode.InternalSerialName, drive, PhysicalTool.GetPlayStationSerial);
info.CommonDiscInfo!.EXEDateBuildDate ??= PhysicalTool.GetFileDate(drive, ps2Exe, fixTwoDigitYear: true);
info.CommonDiscInfo.EXEDateBuildDate ??= PhysicalTool.GetFileDate(drive, ps2Exe, fixTwoDigitYear: true);
if (CommentFieldExists(info, SiteCode.InternalSerialName, out ps2Exe))
info.CommonDiscInfo.Region = ProcessingTool.GetPlayStationRegion(ps2Exe);
@@ -931,7 +959,7 @@ namespace MPF.Frontend.Tools
break;
case RedumpSystem.SonyPlayStation3:
info.Extras!.DiscKey ??= addPlaceholders ? RequiredValue : string.Empty;
info.Extras.DiscKey ??= addPlaceholders ? RequiredValue : string.Empty;
info.Extras.DiscID ??= addPlaceholders ? RequiredValue : string.Empty;
SetCommentFieldIfNotExists(info, SiteCode.InternalSerialName, drive, PhysicalTool.GetPlayStation3Serial);
@@ -952,14 +980,15 @@ namespace MPF.Frontend.Tools
break;
case RedumpSystem.TomyKissSite:
info.CommonDiscInfo!.Category ??= DiscCategory.Video;
info.CommonDiscInfo!.Region ??= Region.Japan;
info.CommonDiscInfo.Category ??= DiscCategory.Video;
info.CommonDiscInfo.Region ??= Region.Japan;
break;
case RedumpSystem.ZAPiTGamesGameWaveFamilyEntertainmentSystem:
info.CopyProtection!.Protection ??= addPlaceholders ? RequiredIfExistsValue : string.Empty;
info.CopyProtection.Protection ??= addPlaceholders ? RequiredIfExistsValue : string.Empty;
break;
}
#pragma warning restore IDE0010
return true;
}
@@ -982,7 +1011,7 @@ namespace MPF.Frontend.Tools
private static bool CommentFieldExists(SubmissionInfo info, SiteCode key, out string? value)
{
// Ensure the comments fields exist
if (info.CommonDiscInfo!.CommentsSpecialFields == null)
if (info.CommonDiscInfo.CommentsSpecialFields is null)
info.CommonDiscInfo.CommentsSpecialFields = [];
// Check if the field exists
@@ -998,7 +1027,7 @@ namespace MPF.Frontend.Tools
/// <summary>
/// Set a comment field if it doesn't already have a value
/// </summary>
private static void SetCommentFieldIfNotExists(SubmissionInfo info, SiteCode key, Drive? drive, System.Func<Drive?, string?> valueFunc)
private static void SetCommentFieldIfNotExists(SubmissionInfo info, SiteCode key, Drive? drive, Func<Drive?, string?> valueFunc)
{
// If the field has a valid value, skip
if (CommentFieldExists(info, key, out _))
@@ -1006,8 +1035,8 @@ namespace MPF.Frontend.Tools
// Set the value
string? value = valueFunc(drive);
if (value != null)
info.CommonDiscInfo!.CommentsSpecialFields![key] = value;
if (value is not null)
info.CommonDiscInfo.CommentsSpecialFields[key] = value;
}
/// <summary>
@@ -1016,7 +1045,7 @@ namespace MPF.Frontend.Tools
private static bool ContentFieldExists(SubmissionInfo info, SiteCode key, out string? value)
{
// Ensure the contents fields exist
if (info.CommonDiscInfo!.ContentsSpecialFields == null)
if (info.CommonDiscInfo.ContentsSpecialFields is null)
info.CommonDiscInfo.ContentsSpecialFields = [];
// Check if the field exists
@@ -1040,8 +1069,8 @@ namespace MPF.Frontend.Tools
// Set the value
string? value = valueFunc(drive);
if (value != null)
info.CommonDiscInfo!.ContentsSpecialFields![key] = value;
if (value is not null)
info.CommonDiscInfo.ContentsSpecialFields![key] = value;
}
/// <summary>
@@ -1050,7 +1079,7 @@ namespace MPF.Frontend.Tools
private static void SetVersionIfNotExists(SubmissionInfo info, Drive? drive, Func<Drive?, string?> valueFunc)
{
// If the version already exists, skip
if (!string.IsNullOrEmpty(info.VersionAndEditions!.Version))
if (!string.IsNullOrEmpty(info.VersionAndEditions.Version))
return;
// Set the version
@@ -1065,7 +1094,7 @@ namespace MPF.Frontend.Tools
private static Dictionary<string, List<string>?> ReformatProtectionDictionary(Dictionary<string, List<string>>? oldDict)
{
// Null or empty protections return empty
if (oldDict == null || oldDict.Count == 0)
if (oldDict is null || oldDict.Count == 0)
return [];
// Reformat each set into a List

Some files were not shown because too many files have changed in this diff Show More