Compare commits

...

164 Commits
1.07 ... 1.15

Author SHA1 Message Date
Matt Nadareski
fbc9d04782 Advanced Support (#172)
* Who doesn't like drives?

* Add another TODO

* Use built in stuff, it's quicker

* More special handling for floppies, easier this time

* Fix broken test

* Set active drive priority, String -> string

* Track reason for no scanning

* Update DIC version and release notes
2019-11-17 01:06:41 -05:00
Matt Nadareski
24b08dd245 Update BurnOutSharp 2019-10-25 20:37:08 -07:00
Matt Nadareski
c7ebe69b05 Update BurnOutSharp 2019-10-24 13:25:28 -07:00
Matt Nadareski
22ffda4b5a Fix copy protection scan by preferring 32-bit 2019-10-19 02:42:01 -07:00
Matt Nadareski
b89c051d7d DICUI 1.14 Release 2019-10-01 11:57:15 -07:00
Matt Nadareski
8b41f03472 Update to new DIC version (#167)
* Remove `.` handling code since it should be in DIC now

* Add support for 3 new flags

* Fix dot tests

* Fix PS4 autodetect (Fixes #164)

* Fix PS4 version finding

* Update DIC archive path

* Add support for disk command (unused by default)
2019-10-01 11:53:44 -07:00
Matt Nadareski
700ff50eef Upgrades, people! (#166)
* First step: 4.6.2

* Make Check and Library .NET Core 3.0 compatible

* Enable 4.6.2 and 4.7.2 on DICUI

* DICUI .NET Core 3.0

* Solution items

* New Appeyor paths, environment

* Upgrade DICUI.Test for all frameworks too

* Fix .NET Core 3.0 difference in path handling
2019-10-01 11:36:01 -07:00
Matt Nadareski
95ac7236ff Fix PS4 version finding 2019-09-29 22:23:45 -07:00
Matt Nadareski
755f1b8e95 Root directories are weird (Fixes #163) 2019-09-29 21:28:20 -07:00
Matt Nadareski
d431a4c87f Fix PS4 autodetect (Fixes #164) 2019-09-29 21:18:02 -07:00
Matt Nadareski
04348d2d58 PSX.EXE is a valid filename to find 2019-09-17 20:59:10 -07:00
Matt Nadareski
6f5214c1a4 Even More Info (#161)
* Add (currently) hidden setting for disc info

* Show setting in Options menu

* Fix new window

* New place for combo box items

* Fixes to outputs

* Add category, fix a few things

* Actually use the custom converter

* Allow tabs in ringcode
2019-09-17 20:50:44 -07:00
Hennadiy Brych
1fe12be0b5 PSX date fixes (#157)
* Sony PlayStation date extraction fixed, 3 separate issues:
1. 190x year instead of 200x
2. Failure to get date for some titles where SYSTEM.CNF BOOT record doesn't have backslash after "cdrom:"
3. Date shift by one day due to Utc offset applied
Relaxed directory path requirements to allow dot and ampersand. DiscImageCreator had to be changed in order to support this, will be submitted separately.

* Reverted extra path characters modification.

* Reverted to UTC time
2019-08-28 00:02:13 -07:00
Matt Nadareski
9c9ca16366 Persist paths unless changing drive letters (fixes #154) 2019-08-12 14:08:55 -07:00
Matt Nadareski
1702db71d1 Add new Redump regions (GC; Uk,Au; U,Ca) 2019-08-05 11:07:51 -07:00
Matt Nadareski
0ba7ccdb9a HTML decode (fixes #150) 2019-07-30 00:19:02 -07:00
Matt Nadareski
3ccf65190e Migrate to archive.org 2019-07-18 11:26:17 -07:00
Matt Nadareski
6b9ee3d5ed Update AppVeyor config 2019-07-18 11:20:09 -07:00
Matt Nadareski
3ee0355034 Add speculative values for VideoNow dumping 2019-07-18 10:42:23 -07:00
Matt Nadareski
7074fa1e2c Update to newest DIC, create new release 2019-07-01 20:50:38 -07:00
Matt Nadareski
44b91a6611 Add initial type dectection, hopefully fixes #145 2019-06-17 14:36:54 -07:00
Matt Nadareski
b2185dbed9 Better ways of getting settings (defaults, existence, etc) 2019-05-26 22:30:06 -07:00
Matt Nadareski
ec4b69b6e6 Multiline outputs should lack prefix (force DAT multiline) 2019-05-26 00:57:06 -07:00
Matt Nadareski
b6db873a00 Settings and more (fixes #141) 2019-05-26 00:48:26 -07:00
Matt Nadareski
db9222b737 Accidential layerbreak infos 2019-05-24 14:26:11 -07:00
Matt Nadareski
b7bfa3ba28 Readonly Regex, Rather 2019-05-24 11:18:49 -07:00
Matt Nadareski
ab25687119 Better UMD support 2019-05-24 11:17:59 -07:00
Matt Nadareski
9bfa0a01ad I clearly remember how Remove works 2019-05-23 22:00:36 -07:00
Matt Nadareski
19c99fb7fe I'm having fun 2019-05-22 22:06:43 -07:00
Matt Nadareski
913244459e Oops, forgot a couple 2019-05-22 21:49:55 -07:00
Matt Nadareski
c66df99e22 Add a few more fun things that might get UI features later 2019-05-22 21:33:31 -07:00
Matt Nadareski
03f4a6e2e4 csproj cleanup 2019-05-22 16:13:47 -07:00
Matt Nadareski
31a243eeb4 Update changelist (been too long) 2019-05-22 16:07:15 -07:00
Matt Nadareski
043c0eff1c BluRay has a default layerbreak and known sizes 2019-05-22 15:49:15 -07:00
Matt Nadareski
ff44313e13 Buffs for potential future work 2019-05-21 00:22:16 -07:00
Matt Nadareski
e06ed31b21 Round 2, fight 2019-05-21 00:07:24 -07:00
Matt Nadareski
aeaec9e805 Add currently unused dump status 2019-05-20 23:39:37 -07:00
Matt Nadareski
6df0c76939 Stupid default namespace 2019-05-20 23:35:04 -07:00
Matt Nadareski
72efffcec4 Cleanup brigade 2019-05-20 22:14:53 -07:00
Matt Nadareski
930e4f7514 Only allow trailing spaces if there's no trailing directory marker 2019-05-20 15:08:41 -07:00
Matt Nadareski
85f71032b5 Fix trailing space handling for output directory 2019-05-20 15:00:41 -07:00
Matt Nadareski
ead530e2ec Code prettification 2019-05-20 00:12:06 -07:00
Matt Nadareski
dc14b1ea52 Both successes, not overwrite 2019-05-19 23:59:16 -07:00
Matt Nadareski
4628be2855 Simplify per-type and per-system code 2019-05-19 23:50:37 -07:00
Matt Nadareski
1f24c08770 Move some logic to SubmissionInfo, fix PS1/PS2/PS4 2019-05-19 22:13:57 -07:00
Matt Nadareski
4889b9d0bf Fix EXE parsing for PS1/PS2 discs 2019-05-14 21:05:05 -07:00
Matt Nadareski
b3d7422a66 Minor cleanup of fields and comments 2019-05-14 20:54:08 -07:00
Matt Nadareski
a0000528de Build date as string again 2019-05-14 20:50:17 -07:00
Matt Nadareski
2be46ec7a1 Trim fields that may have trailing whitespace 2019-05-14 01:56:39 -07:00
Matt Nadareski
f2510a08a4 Barcode, another low-hanging fruit 2019-05-14 01:51:48 -07:00
Matt Nadareski
2787377250 Add ability to get matching IDs from Redump 2019-05-14 01:46:10 -07:00
Matt Nadareski
e61ca31a3f Remove unused Forms version 2019-05-13 23:51:00 -07:00
Matt Nadareski
1b735b5d06 Migrate to SubmissionInfo object, add JSON output 2019-05-13 21:55:08 -07:00
Matt Nadareski
ad3d26cdea Better naming of blank-labeled discs 2019-05-12 21:18:07 -07:00
Matt Nadareski
f372ec4ccd Add new system, better submissioninfo, future 2019-05-11 22:32:22 -07:00
Matt Nadareski
44e75a50d7 Mass add of unused systems 2019-05-06 12:29:19 -07:00
Matt Nadareski
6f0ea2de3e Formats cleanup before adding more 2019-05-06 10:52:07 -07:00
Matt Nadareski
b4f0f7f4b3 Ensure all GD-ROM systems have LD optinos as well 2019-05-05 23:57:11 -07:00
Matt Nadareski
5027d67731 Add new VideoNow systems, cleanup 2019-04-27 17:11:39 -07:00
Matt Nadareski
6c8016345a Use full file path in Check (to correct relative paths) 2019-04-20 22:03:23 -07:00
Matt Nadareski
7ba04e63c7 Support JagCD (may need /ms still) 2019-04-11 21:12:36 -07:00
Matt Nadareski
77dc1d0029 Fix X360 DMI offset 2019-04-04 14:33:26 -07:00
Matt Nadareski
2b6538707f Add DMI extraction for XBOX/369 (fixes #139) 2019-04-04 01:09:51 -07:00
Matt Nadareski
902e4e5715 Make DICUI.Check better 2019-04-04 00:37:17 -07:00
Matt Nadareski
28f6d50e5a Better error checking; more DICUI.Check updates 2019-03-30 21:44:57 -07:00
Matt Nadareski
d8ed7d6ad7 Fix CD dumping with newest release; DICUI.Check minor update 2019-03-30 21:32:10 -07:00
Matt Nadareski
078d7d0ea3 Fix failing test 2019-03-27 17:37:03 -07:00
Matt Nadareski
5895a66c7a Update to DIC 20190326 2019-03-27 17:32:31 -07:00
Matt Nadareski
5ccff836e2 Add DVD for Panasonic M2 (fixes #138) 2019-02-26 11:57:12 -08:00
Matt Nadareski
b2c2e8c4d9 Reverse mould SID fields order (fixes #137) 2019-02-26 11:55:14 -08:00
Matt Nadareski
890959cfe0 Add DICUI.Check, standalone output parsing tool 2019-02-10 14:47:53 -08:00
Matt Nadareski
8729c7f20c Add new template to CD/GD as well 2019-01-28 21:15:07 -08:00
Matt Nadareski
74826909f4 Bump version to 1.12 2019-01-27 22:25:53 -08:00
Matt Nadareski
eb4904afb4 Add support for SCD/MCD headers (fixes #133) 2019-01-27 21:42:03 -08:00
Matt Nadareski
06975316b9 Add Panasonic M2 and Hasbro VideoNow to supported discs 2019-01-27 21:31:05 -08:00
Matt Nadareski
e0be24e54f Update links after organizational shift 2019-01-27 20:45:10 -08:00
Matt Nadareski
eb3cbc44a7 Add missing PVD text (fixes #128) 2019-01-27 16:30:15 -08:00
Matt Nadareski
d6f39bfd4c Ped-ant-ic (fixes #132) 2019-01-27 16:27:59 -08:00
Matt Nadareski
576fa07a2c Fix dumping status in Winforms 2018-11-07 20:27:35 -08:00
Matt Nadareski
ae2b26f84e Capitalization that's been bothering me 2018-11-05 20:30:39 -08:00
Matt Nadareski
1d9a2c9be7 Make sure that detected disc type is shown; cleanup 2018-11-05 20:27:01 -08:00
Matt Nadareski
538c0bba09 Fix output of the media type box in Winforms 2018-11-05 15:30:45 -08:00
Matt Nadareski
57c31cad48 Update AppVeyor build number 2018-11-05 14:51:14 -08:00
Matt Nadareski
093db36f44 Make Floppy Disk a supported format again 2018-11-05 14:51:00 -08:00
Matt Nadareski
fd4db3f8f0 Make SCM optional for Audio-CD (fixes #127) 2018-11-05 14:48:25 -08:00
Matt Nadareski
856a3161be Fix missing file extension 2018-10-22 11:09:28 -07:00
Matt Nadareski
dfafe9789a Update AppVeyor for new DIC version 2018-10-22 11:06:25 -07:00
Matt Nadareski
9f750d01c4 Correct submissionInfo output order (fixes #125) 2018-10-22 10:44:29 -07:00
Matt Nadareski
705ee82cbb Audio CDs don't have the _EdcEcc file right now 2018-10-22 10:41:10 -07:00
Matt Nadareski
d1f80efa41 Add DIC merge command and skip sector flag 2018-10-22 10:32:48 -07:00
Matt Nadareski
f88e6617e5 Fix some of the descriptions in submissionInfo (partial #115) 2018-10-15 17:22:42 -07:00
Matt Nadareski
1401422b08 Add DVD for PS3 (fixes #124) 2018-10-15 17:19:48 -07:00
Matt Nadareski
4539066af0 Update version numbers for 1.11 2018-10-08 12:53:59 -07:00
Matt Nadareski
ec23502275 Abstract out non-UI code to separate DLL (#122)
* Abstract out non-UI code to separate DLL

This change seems rather large, but it's mostly just moving anything that is not directly driving the UI to its own, separate library. This will make it easier at a later date for any UI improvements or changes as well as making the code much more discrete. One TODO has been added as a result of this change.

* Remove MessageBox from library

This change removes the last UI-driven elements from the library. This now makes the library (in theory) UI-agnostic and removes the TODO.

* Options is more UI-related

* Fix Nuget references in csproj

* Add Winforms UI

This is a clone of the current WPF UI but implemented in Windows Forms. WPF is not currently supported by Mono for Linux and macOS, so this can provide an alternative to those users who want to run on those systems instead. This also adds a second artifact for the Winforms build.
2018-10-08 11:06:22 -07:00
Matt Nadareski
331f875e7f Add better progress logging for dumps (fixes #121) 2018-09-24 12:17:57 -07:00
Matt Nadareski
e68f88062f Fix mundane test 2018-09-20 22:39:07 -07:00
Matt Nadareski
d1bb8184d1 Path correction 2018-09-20 22:18:07 -07:00
Matt Nadareski
b7b3f36402 Fix build 2018-09-20 21:30:13 -07:00
Matt Nadareski
859af8efea Format wars 2018-09-20 21:25:22 -07:00
Matt Nadareski
8594d7884c Update terminology (fixes #119) 2018-09-19 20:50:57 -07:00
Matt Nadareski
946dc929f1 Add profile for low-density part of GDROM
Currently, it's easier to just say "it's a CD" and call it a day
2018-09-19 20:49:33 -07:00
Matt Nadareski
1e5b1a205e Update DIC version for AppVeyor 2018-09-19 20:42:49 -07:00
Matt Nadareski
3271cd0ea3 Fix Saturn output info (fixes #118) 2018-09-10 18:27:13 -07:00
Matt Nadareski
647bab8cd3 Merge branch 'master' of https://github.com/reignstumble/DICUI 2018-09-10 16:44:49 -07:00
Matt Nadareski
89b2438dac Threefold fixes
1) Fix the issue where custom parameters that include the `/s 2` flag crash the program
2) Make editing custom parameters a little more intutive (still need to figure out either a way in-documentation or in-UI to explain the checkbox a little better). This part of the change needs to be more tested but there aren't many people using the current feature anyway.
3) Fix the random "Error count: -1" issue that some users were seeing (ended up being a result of more things being in the `_mainError.txt` file than originally anticipated)
2018-09-10 16:43:25 -07:00
Whovian9369
1dcd36d640 Change printable string misspellings relating to DIC (#117)
* Update DumpEnvironment.cs

Change Disk to Disc in printable strings of DumpEnvironment.cs

* Update OptionsWindow.xaml

Change Disk to Disc in printable strings of OptionsWindow.xaml
2018-09-03 13:16:03 -07:00
Matt Nadareski
2f63ebcd29 Fix unprotected DVD info; hopefully fix error count parsing 2018-09-03 00:38:52 -07:00
Matt Nadareski
316953f38c Add UmdImageCreator output parsing 2018-09-02 22:15:40 -07:00
Matt Nadareski
62813ac701 Fix tests 2018-09-01 18:03:48 -07:00
Matt Nadareski
22a936e60b XBOX CDs are not XISO formatted 2018-09-01 17:57:26 -07:00
Matt Nadareski
6412205fa3 Unknown sector ranges aren't recorded 2018-09-01 17:43:38 -07:00
Matt Nadareski
75c18ea3c4 Update for even more DIC changes 2018-09-01 17:02:09 -07:00
Matt Nadareski
6bdb93208e Add DVD-Video protection info 2018-08-29 14:40:35 -07:00
Matt Nadareski
588ed19692 Update README.md
The link for AppVeyor now goes directly to the artifacts page for easier downloading. Hopefully this reduces the issues that are seen with new users.
2018-08-28 21:44:07 -07:00
Matt Nadareski
d56ab5ab37 Update to new version of DIC in AppVeyor 2018-08-28 21:42:01 -07:00
Matt Nadareski
819d18112e My fault, this try/catch doesn't need to be here 2018-08-28 21:29:24 -07:00
Matt Nadareski
2e79cbb0db Fix XBOX/X360 outputs 2018-08-28 21:01:52 -07:00
Matt Nadareski
f024611de8 Take advantage of new XGD3 support in DIC (fixes #71) 2018-08-28 17:31:45 -07:00
Matt Nadareski
48e6283c37 Add PS4 PIC extraction (fixes #106) 2018-08-19 01:25:52 -07:00
Matt Nadareski
fec70f17bc ...wrong path 2018-08-19 00:50:58 -07:00
Matt Nadareski
257f7ab7df Last fix: subfoldering 2018-08-19 00:48:18 -07:00
Matt Nadareski
c1ed3aca02 Path is important 2018-08-19 00:43:32 -07:00
Matt Nadareski
ace6a78236 Attempt to fix AppVeyor 2018-08-19 00:41:34 -07:00
Matt Nadareski
f1e9f1d433 Add PS4 version finding, minor fixes (fixes #105) 2018-08-19 00:19:57 -07:00
Matt Nadareski
e83190c091 Writeback for updated path values (#111) 2018-08-17 20:22:08 -07:00
Matt Nadareski
82eabc12ca Try to fix output path checks (fixes #111) 2018-08-17 20:16:13 -07:00
Matt Nadareski
76b549d773 Add try/catch around dump (fixes #110) 2018-08-17 20:08:50 -07:00
Matt Nadareski
227688d7dc Fix PS2 VER spacing (fixes #112) 2018-08-17 19:24:55 -07:00
Matt Nadareski
4c9e2359af Update system info 2018-08-14 21:59:41 -07:00
Matt Nadareski
d179d7f464 Recognize new swap commands 2018-08-14 21:54:41 -07:00
Matt Nadareski
fff19e75fd Fix XBOX security sector format 2018-08-02 12:38:29 -07:00
Matt Nadareski
2175ccfb26 Update CHANGELIST 2018-07-29 12:44:46 -07:00
Matt Nadareski
621923bdba Add new Redump-recongized system 2018-07-24 19:27:45 -07:00
Matt Nadareski
3c216aa309 More accurate detection 2018-07-21 17:02:51 -07:00
Matt Nadareski
d85186e5cd Fix copy protection output again
This doesn't warrant a full PR
2018-07-19 23:40:17 -07:00
Matt Nadareski
1a94ad3d23 Don't try to get fancy 2018-07-19 15:34:16 -07:00
Matt Nadareski
91776d939c AppVeyor and Test (#103)
* Fixes to AppVeyor

* Fix tests
2018-07-19 15:31:25 -07:00
Matt Nadareski
3d058e633f Unblock and Update (#102)
* RAINBOW

* Add to FormatOutputData

* Update BurnOutSharp

* Fix parameter creation

* Minor improvements

* Update package versions
2018-07-19 14:11:58 -07:00
Matt Nadareski
94c0564fe8 Goodbye drive speed finders (#101)
* Goodbye drive speed finders

* More accurate scaling

* Ensure disposal
2018-07-17 16:42:38 -07:00
Matt Nadareski
87ecc7588e Update BurnOutSharp 2018-07-17 10:41:29 -07:00
Matt Nadareski
8a5c114a7e External and Fix (#100)
* Progress report updates log

* Logging additions

* Minor update

* Set halfway point only if nothing can be found

* Better population metrics

* QOL improvements

* More tiny logging updates

* Autoscroll

* Be consistent

* Update packages, use submodules

* Use NuGet

* Not 100% sure why I did it that way...

* Update README.md

* Make copy protect scan prompt an option

* Enhanced-CD might be Win/Mac

* Add unconfirmed formats

* Enhance!
2018-07-17 10:21:37 -07:00
ReignStumble
e307cb217f Fix DPI issue 2018-07-16 22:41:05 -04:00
Matt Nadareski
b8c56bea58 Whole Cleanup (#97)
* Cleanup TODOs

* Remove more TODOs

* Add case-insensitive dictionary for protection scans

* Namespace cleanups

* Space

* Minor fixes

* Oops

* Change layerbreak detect value
2018-07-15 22:26:22 -07:00
Matt Nadareski
564a6af9b8 Protection, Progress, and (Possibly) Empty Drives (#93)
* Include but mark inactive drives (fixes #87)

* Add more checks for the active flag

* Force users to choose on dump

* Fix quotes

* Update SolidShield 1

* Select first active by default

* Add TODO

* Add dumping progress indicator

* Clamp runtime

* Add first textfile scans; EA CdKey

* Slightly better executable detection

* Better file type detection

* Get as much into magic number checks as possible

* Nicer formatting

* Trailing slash

* Add back for benefit of the doubt

* Remove dead code

* Safer cabinet scanning

* Remove iXcomp; Add Unshield

* Fix build, add more comments

* Post-merge cleanup

* Add a new log line

* Make protection scan mechanics easier to see

* Add a space
2018-07-13 16:40:40 -07:00
Jacopo Santoni
5bcde889b3 Log Window enhancements (#95)
* Split type combobox into system combobox and disc type combobox

* corrected indentation for xaml file

* fixed merge with head

* fixed format

* fixed issues for PR, added KnownSystem.CUSTOM

* removed Updater.cs which ended by error in commit

* fixed GetOuptutName() for new drive/system combobox

* created LogWindow and first tests of output gathering

* integrated all the proof of concept related to stream fetching of DIC output into LogWindow

* working on LogWindow\ncreated more efficient output matching management, improved handling of process termination

* created Tasks file\nmoved some methods there, created DumpEnvironment to manage are arguments

* moved additional methods to Tasks to make it more modular

* changed StartDumping flow to avoid returning if extra tools are not found

* moved main dump workflow into Tasks class

* created specific DumpResult class for better error reporting/management

* fixes

* fixes Dispatcher thread issue with progress bar

* continued refactor
- split EnsureDiscInformation into an additional EnsureCorrectInformationForSystemAndMediaType
- proof of concept of using custom extensions to enum types to give better functionality (and encapsulation)
- changed cmb_MediaType to keep a List<MediaType?> and got rid of Tuple<string, MediaType?>

* restored GetDiscType functionality

* fixed btn_StartStop enabled on EnsureCorrect... error

* fixed whitespace

* fixed indentation

* merged conflicts

* moved log window

* working on LogWindow resize/location behavior

* working on message logging in LogWindow

* added working integration between MenuItem for LogWindow and its visibility status, fixes issues with positioning and visibility, correctly bound Verbose flag to property

* finished integrating LogWindow, added some verbose logs

* added logs

* fixed include order

* added option to show log window at startup, removed useless QuietMode property from MainWindow

* added precise calculation of MainWindow position when LogWindow is shown and fixed topmost cheat
2018-07-13 16:38:50 -07:00
Jacopo Santoni
b39c96cdd2 Log Window (#94)
* Split type combobox into system combobox and disc type combobox

* corrected indentation for xaml file

* fixed merge with head

* fixed format

* fixed issues for PR, added KnownSystem.CUSTOM

* removed Updater.cs which ended by error in commit

* fixed GetOuptutName() for new drive/system combobox

* created LogWindow and first tests of output gathering

* integrated all the proof of concept related to stream fetching of DIC output into LogWindow

* working on LogWindow\ncreated more efficient output matching management, improved handling of process termination

* created Tasks file\nmoved some methods there, created DumpEnvironment to manage are arguments

* moved additional methods to Tasks to make it more modular

* changed StartDumping flow to avoid returning if extra tools are not found

* moved main dump workflow into Tasks class

* created specific DumpResult class for better error reporting/management

* fixes

* fixes Dispatcher thread issue with progress bar

* continued refactor
- split EnsureDiscInformation into an additional EnsureCorrectInformationForSystemAndMediaType
- proof of concept of using custom extensions to enum types to give better functionality (and encapsulation)
- changed cmb_MediaType to keep a List<MediaType?> and got rid of Tuple<string, MediaType?>

* restored GetDiscType functionality

* fixed btn_StartStop enabled on EnsureCorrect... error

* fixed whitespace

* fixed indentation

* merged conflicts

* moved log window

* working on LogWindow resize/location behavior

* working on message logging in LogWindow

* added working integration between MenuItem for LogWindow and its visibility status, fixes issues with positioning and visibility, correctly bound Verbose flag to property

* finished integrating LogWindow, added some verbose logs

* added logs

* fixed include order

* added option to show log window at startup, removed useless QuietMode property from MainWindow
2018-07-13 15:48:35 -07:00
Matt Nadareski
2cc73a30f5 Protection Is Key (#92)
* Fix some protections, start adding IS scanning

* Fix IS CAB

* Update TODO
2018-07-10 10:23:52 -07:00
Matt Nadareski
be7d745d10 Create Parameters Class (#91)
* Update commented code

* Add Parameters class

This class is currently unused, but represents a set of parameters that can be passed to and from any given method. It has some copied/modified code from Validators.cs, for the time being due to the current overlap.

* Add better documentation

* Add and use DICFlag enumeration

* Port more things to Parameter-specific version

* Add commented code for later

* Added new options (#90)

* Split type combobox into system combobox and disc type combobox

* corrected indentation for xaml file

* fixed merge with head

* fixed format

* fixed issues for PR, added KnownSystem.CUSTOM

* removed Updater.cs which ended by error in commit

* fixed GetOuptutName() for new drive/system combobox

* added 4 new options: quiet mode, paranoid mode, disable media type detect and c2 reread amount

* added default C2 reread tries to config

* fixed issues for PR

* removed commented leftover

* Update commented code

* Add Parameters class

This class is currently unused, but represents a set of parameters that can be passed to and from any given method. It has some copied/modified code from Validators.cs, for the time being due to the current overlap.

* Add better documentation

* Add and use DICFlag enumeration

* Port more things to Parameter-specific version

* Add commented code for later

* Use Parameters object

* Fix dumping process

* Cleanup Validators
2018-07-09 21:42:02 -07:00
Jacopo Santoni
d51adccab4 Added new options (#90)
* Split type combobox into system combobox and disc type combobox

* corrected indentation for xaml file

* fixed merge with head

* fixed format

* fixed issues for PR, added KnownSystem.CUSTOM

* removed Updater.cs which ended by error in commit

* fixed GetOuptutName() for new drive/system combobox

* added 4 new options: quiet mode, paranoid mode, disable media type detect and c2 reread amount

* added default C2 reread tries to config

* fixed issues for PR

* removed commented leftover
2018-07-09 16:35:46 -07:00
Matt Nadareski
6141ce8539 Remove Disable Beep; Handle Error Case (#89)
* Disable beep not supported for these

* Remove testing code

This more or less ensures that the current run finishes properly

* Extra fixing for process issues

This, with the last 2 commits, make it so that geting disc speed works again. This was only found because in testing, many MANY instances of DiscImageCreator were made but never killed, polluting the process list. These issues should now be fixed.
2018-07-07 01:00:27 -07:00
Matt Nadareski
96d6e8bd2f Bits and Bobs (#88)
* Finally overhaul UI element naming

* Re-enable disk scan button

* Add cabfile scanning

* Fix csproj

* Fix TODO

* Add a couple more protections, disable one for now

* Fix SecuROM 7 detection

Thanks antimatter for helping test

* No beep for eject and speed check

* Fix Options after renames

* Ensure disc information in  couple places again
2018-07-07 00:08:22 -07:00
Matt Nadareski
c034df4266 More and more cleanup (#86)
* Namespace cleanups

* Make dump validation instanced

* Add note to Tasks

* Move stuff to DumpEnvironment

Most of the stuff in Tasks.cs acted on a single input parameter, namely a DumpEnvironment. Since that's the case, it was more logical to wrap those into DumpEnvironment and make them instance methods rather than keep them static. Due to this change, quite a few methods changed access, and some had to be marked internal due to wanting them to be tested separately.

* Gut Tasks

* One less thing in MainWindow

* Remove explicit cast

* Wrong check

* Create helper method

* Disable scan button on dump

* Remove unnecessary getters/setters

* Method name/description cleanup

* Address TODO

* Namespace cleanups

* Make dump validation instanced

* Add note to Tasks

* Move stuff to DumpEnvironment

Most of the stuff in Tasks.cs acted on a single input parameter, namely a DumpEnvironment. Since that's the case, it was more logical to wrap those into DumpEnvironment and make them instance methods rather than keep them static. Due to this change, quite a few methods changed access, and some had to be marked internal due to wanting them to be tested separately.

* Gut Tasks

* One less thing in MainWindow

* Remove explicit cast

* Wrong check

* Create helper method

* Disable scan button on dump

* Remove unnecessary getters/setters

* Method name/description cleanup

* Address TODO

* Clean up OnContentRendered

* Namespace cleanups

* Make dump validation instanced

* Add note to Tasks

* Move stuff to DumpEnvironment

Most of the stuff in Tasks.cs acted on a single input parameter, namely a DumpEnvironment. Since that's the case, it was more logical to wrap those into DumpEnvironment and make them instance methods rather than keep them static. Due to this change, quite a few methods changed access, and some had to be marked internal due to wanting them to be tested separately.

* Gut Tasks

* One less thing in MainWindow

* Remove explicit cast

* Wrong check

* Create helper method

* Disable scan button on dump

* Remove unnecessary getters/setters

* Method name/description cleanup

* Address TODO

* Clean up OnContentRendered

* Update event handlers
2018-07-05 21:34:04 -07:00
ReignStumble
fe04c6df73 Centered Window + No more resizable 2018-07-06 00:11:11 -04:00
ReignStumble
aff195eb71 Added Exit and About 2018-07-06 00:08:20 -04:00
ReignStumble
3aca999b63 New Menubar 2018-07-06 00:00:16 -04:00
ReignStumble
0e7ce76f01 Wait for UI to render before Populating 2018-07-05 23:43:01 -04:00
Matt Nadareski
6d72417512 Cleanups and mixups (#85)
Cleanups and Mixups
2018-07-05 16:52:34 -07:00
Matt Nadareski
ac89f06843 Separate out from Constants.cs 2018-07-05 13:33:08 -07:00
Matt Nadareski
39ce56d579 Post-merge cleanup 2018-07-05 13:18:01 -07:00
Matt Nadareski
9dbd30adba Merge DumpEnvironment/DumpInformation; Add Copy Protection Scan (#82)
* Merge DumpEnvironment and DumpInformation

* None of these need to be static

* Start adding protection checks

* Convert all BurnOut-related files from VB

* Placeholders for SafeDisc 3 and 4

* Fix some small things

* SubIntention not always output

* Make copy protect scan optional

* Try/catch on disc information to avoid crashes

* Add placeholders for Origin, Steam, UPlay

* Don't use copied method, for safety

* Protection cleanup

* More cleanup on SafeDisc v1/2

* Add area for cabfiles (for later); clean up more protections

* Comment out cabfile path, for now

* Underscores? Really?

* Namespace cleanup

* More Steam variations

* Add an actual UPlay installer name

* Skeleton for GFWL

* Add one for Origin

* More Steam, update note

* Add note kinda like GFWL

* Fix Origin installer name (IDK what I put there before...)

* Remove TODOs for ones with valid checks

* Add first GFWL installer name

* Move online services to last

Physical disc protections should ALWAYS come before an online service is mentioned. This makes sure that the physical media's information is not lost

* Add another TODO

* ...slightly longer comment

* Fix CDCops, start adding file lists

* More paths

* Even more paths

* Last paths for now

* Dictionary is smarter... so more work ahead

* Remind me why I'm doing this?

* Okay, recreated in dictionary now

* Reorganiation

* Alphabetization is fun

* Add unused call to new scan path

* Add TODO

* Remove TODO

* Remove TODO, comment out dummy files check

* Better state for no detected protection

* Make copy protect scan a Task so it can be used elsehwere later

* ScanEx -> Scan; cleanup

* Remove unused protection scan methods

These methods used to be a simple check for if a particular file existed. These are now captured in the "CreateProtectionMapping" dictionary

* Remove SuffixInStr

* Characters to literals, decimal to hex, start of consolidation

* Add remaining string-only mappings, cleanup

* Update summaries, remove unused flag

* Trim out unnecessary variables

These variables used to be used when a DLL or an EXE was found to have something in it but other files were needed to check against for better output. This also assumed a monolithic output in what protections were found. Now that we just list everything and all files are scanned, this should catch everything that comes through

* Remove unused path-based protections

* Accidentally wiped out Sysiphus

* CD Check is... special

* No more internal vars; static shock

* Add region tags

* Remove unused Dummy Files check

* Add scan for copy protection without dump

* Better checking of files

* Better message box

* Add TODO

* Clearer language for SafeDisc

* Fix SafeDisc scanning

Thanks to eientei95 for helping find this one

* Slight EVORE cleanup

* Fix SolidShield

Thanks to eientei95 for helping to fix this one

* Add sector scan note

* Add user-requested TODO

* Refactor of ComboBox underlying types (#84)

* Split type combobox into system combobox and disc type combobox

* corrected indentation for xaml file

* fixed merge with head

* fixed format

* fixed issues for PR, added KnownSystem.CUSTOM

* removed Updater.cs which ended by error in commit

* fixed GetOuptutName() for new drive/system combobox

* Refactored KnownSystem combobox management

- created KnownSystemComboBoxItem to manage both header and system items
- totally rewrote KnownSystem category (through KnownSystemCategory enum and markers)
- fixed null access in EnsureDiscInformation caused by null _drives
- rewrote cmb_SystemType management to use new classes

* - created Drive class to keep drive letters, volume label and is floppy flag altogether
- changed all the code to use the new Drive class in combobox and in DumpEnvironment

* fixed retrieval of value from cmb_KnownSystem combobox

* removed OrderedDictionary, not needed anymore

* Merge DumpEnvironment and DumpInformation

* None of these need to be static

* Start adding protection checks

* Convert all BurnOut-related files from VB

* Placeholders for SafeDisc 3 and 4

* Fix some small things

* SubIntention not always output

* Make copy protect scan optional

* Try/catch on disc information to avoid crashes

* Add placeholders for Origin, Steam, UPlay

* Don't use copied method, for safety

* Protection cleanup

* More cleanup on SafeDisc v1/2

* Add area for cabfiles (for later); clean up more protections

* Comment out cabfile path, for now

* Underscores? Really?

* Namespace cleanup

* More Steam variations

* Add an actual UPlay installer name

* Skeleton for GFWL

* Add one for Origin

* More Steam, update note

* Add note kinda like GFWL

* Fix Origin installer name (IDK what I put there before...)

* Remove TODOs for ones with valid checks

* Add first GFWL installer name

* Move online services to last

Physical disc protections should ALWAYS come before an online service is mentioned. This makes sure that the physical media's information is not lost

* Add another TODO

* ...slightly longer comment

* Fix CDCops, start adding file lists

* More paths

* Even more paths

* Last paths for now

* Dictionary is smarter... so more work ahead

* Remind me why I'm doing this?

* Okay, recreated in dictionary now

* Reorganiation

* Alphabetization is fun

* Add unused call to new scan path

* Add TODO

* Remove TODO

* Remove TODO, comment out dummy files check

* Better state for no detected protection

* Make copy protect scan a Task so it can be used elsehwere later

* ScanEx -> Scan; cleanup

* Remove unused protection scan methods

These methods used to be a simple check for if a particular file existed. These are now captured in the "CreateProtectionMapping" dictionary

* Remove SuffixInStr

* Characters to literals, decimal to hex, start of consolidation

* Add remaining string-only mappings, cleanup

* Update summaries, remove unused flag

* Trim out unnecessary variables

These variables used to be used when a DLL or an EXE was found to have something in it but other files were needed to check against for better output. This also assumed a monolithic output in what protections were found. Now that we just list everything and all files are scanned, this should catch everything that comes through

* Remove unused path-based protections

* Accidentally wiped out Sysiphus

* CD Check is... special

* No more internal vars; static shock

* Add region tags

* Remove unused Dummy Files check

* Add scan for copy protection without dump

* Better checking of files

* Better message box

* Add TODO

* Clearer language for SafeDisc

* Fix SafeDisc scanning

Thanks to eientei95 for helping find this one

* Slight EVORE cleanup

* Fix SolidShield

Thanks to eientei95 for helping to fix this one

* Add sector scan note

* Add user-requested TODO
2018-07-05 12:58:20 -07:00
Jacopo Santoni
48de63513e Refactor of ComboBox underlying types (#84)
* Split type combobox into system combobox and disc type combobox

* corrected indentation for xaml file

* fixed merge with head

* fixed format

* fixed issues for PR, added KnownSystem.CUSTOM

* removed Updater.cs which ended by error in commit

* fixed GetOuptutName() for new drive/system combobox

* Refactored KnownSystem combobox management

- created KnownSystemComboBoxItem to manage both header and system items
- totally rewrote KnownSystem category (through KnownSystemCategory enum and markers)
- fixed null access in EnsureDiscInformation caused by null _drives
- rewrote cmb_SystemType management to use new classes

* - created Drive class to keep drive letters, volume label and is floppy flag altogether
- changed all the code to use the new Drive class in combobox and in DumpEnvironment

* fixed retrieval of value from cmb_KnownSystem combobox

* removed OrderedDictionary, not needed anymore
2018-07-05 11:30:52 -07:00
Matt Nadareski
56eaf7c2c5 Add Test Project (#79)
* Add Test project; Migrate so there's not an external folder

* Add Test project; Migrate so that there's not an external folder

* Fix build; Add remaining test classes (skeletons)

* Fix more paths

* Make unit tests runnable, fix issue found by unit tests

* Add more tests, fix more things found by tests

* Add skeleton for ValidatorsTest, fix OrderedDictionary

* Add UIElementsTest

* Add new test classes, slightly update Result

* Implement DumpEnvirionment tests; fix minor things from testing

* Add Tasks testing skeletons; Reorder methods and change access modifiers for some

* Update notes for DumpInformation tests

* Implement a couple Validators tests; fix ValidateParameters

* Implement DetermineFlagsTest

* Make one test more readable

* More cleanup around ValidateParameters

* Split check

* WiiU is not supported by /raw command

* Add TODO question

* Update TODO with a plan
2018-06-28 19:41:18 -07:00
Matt Nadareski
c1bd30e008 Streamline Callbacks and Ensure MediaType (#78)
* Separate drive speeds; better ensuring of media type

This is the first attempt at separating out the drive speeds into separate categories. At the moment, it seems to be working just fine for CD and DVD.
This also includes some updated code to better ensure that the detected (or selected if the user has changed it) media type is kept between all of the regular changes

* Multiple medium

* Add more drive speed prototyping

* Strip out redundant calls

* Separate drive speeds; better ensuring of media type

This is the first attempt at separating out the drive speeds into separate categories. At the moment, it seems to be working just fine for CD and DVD.
This also includes some updated code to better ensure that the detected (or selected if the user has changed it) media type is kept between all of the regular changes

* Multiple medium

* Add more drive speed prototyping

* Strip out redundant calls

* Streamline merge

* Comment patrol; keep BluRay a first-class citizen

* HD-DVD is supported?!
2018-06-27 23:21:52 -07:00
Jacopo Santoni
4176f22d79 Added preferred dump speed option (#77)
* Split type combobox into system combobox and disc type combobox

* corrected indentation for xaml file

* fixed merge with head

* fixed format

* fixed issues for PR, added KnownSystem.CUSTOM

* removed Updater.cs which ended by error in commit

* fixed GetOuptutName() for new drive/system combobox

* added max dump speed option
- added slider element into OptionsWindow
- moved drive speeds to UIElements from MainWindow
- added setting to Options which is saved

still need to understand how to manage DVD/CD-ROM different speeds

* kept working on max dump speed settings

- rewrote max speed list management in Options
- added second slider in OptionsWindow
- added callback from OptionsWindow to MainWindow on updated options

* final tweaks before PR

* renamed maxDumpSpeed to preferredDumpSpeed

* restored SetCurrentDiscType functionality

* fixes for PR

* fixes for PR
2018-06-27 20:06:19 -07:00
68 changed files with 13841 additions and 4728 deletions

View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="dicPath" value="Programs\DiscImageCreator.exe"/>
<add key="subdumpPath" value="subdump.exe"/>
<add key="defaultOutputPath" value="ISO"/>
</appSettings>
</configuration>

View File

@@ -1,17 +0,0 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
namespace DICUI
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
}
}

View File

@@ -1,3 +1,73 @@
### 1.15 (2019-11-16)
- Updated to DIC version 20191116
- Support non-optical, non-floppy stuff better
- Update protection scanning and fix some things
### 1.14 (2019-10-01)
- Updated to DIC version 20191001
- Added builds for .NET 4.6.2, .NET 4.7.2, and .NET Core 3.0
- Updated and fixed a bunch of things related to Redump
- Fixed path persistence when changing system and media type
- Added more system autodetects
- Added new, optional, disc information filling window (WIP)
### 1.13 (2019-07-02)
- Added new DIC commands and flags
- Made DICUI Check more robust
- Added and updated systems along with format cleanup
- Created a new SubmissionInfo template (and internals)
- Added automatic grabbing of Redump information, if possible
- Better media format support (BD, UMD)
- Initial disc type detection
### 1.12.2 (2019-04-19)
- Added DICUI Check, a new standalone tool for parsing DIC output from platforms unsupported by DICUI
- Added a few machines/formats
- Updated to DIC version 20190326
- Added DMI data extraction for Xbox and X360
### 1.12.1 (2019-01-28)
- Fixed !submissionInfo.txt output for CD-ROM and GD-ROM
### 1.12 (2019-01-27)
- Added a few new systems and formats
- Added new DIC commands and flags
- Updated the `!submissionInfo.txt` file order
- Fixed Audio CD handling
- Added Sega CD / Mega CD header extraction
- Readded Floppy Disk as a supported format
- And more! See the full Git commit list for more details
### 1.11 (2018-09-20)
- Fix formatting of XBOX and XBOX 360 security sector output
- Add new XBOX swap commands and outputs
- Fixes for some PlayStation 2 and 4 outputs
- Added external programs to AppVeyor builds
- Fixed `.` in path issues with DIC; attempted to fix issues with `&`
- Combined XBOX 360 XGD 2/3 due to new DIC support with Kreon drives
- Fixed (semi-)longstanding bug with XBOX disc layer detection
- Added DVD-Video protection output
- Made custom parameters work a little more intuitively
- Added *EXPERIMENTAL* Winforms-based UI
- And more! See the full Git commit list for more details
### 1.10 (2018-07-29)
- Added many new options for user customization
- Added unit testing and an AppVeyor build
- Many code refactorings
- **LOG WINDOW**
- Separated out protection scan and Unshield ports to new projects
- Added "empty drive" support; should help with 3DO and HFS dumping
- And much more! See the full Git commit list for more details
### 1.07 (2018-06-27)
- Separated system and media type for easier navigation

6
DICUI.Check/App.config Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/>
</startup>
</configuration>

View File

@@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net462;net472;netcoreapp3.0</TargetFrameworks>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<OutputType>Exe</OutputType>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DICUI.Library\DICUI.Library.csproj">
<Project>{51ab0928-13f9-44bf-a407-b6957a43a056}</Project>
<Name>DICUI.Library</Name>
</ProjectReference>
</ItemGroup>
</Project>

180
DICUI.Check/Program.cs Normal file
View File

@@ -0,0 +1,180 @@
using System;
using System.IO;
using DICUI.Data;
using DICUI.Utilities;
namespace DICUI.Check
{
public class Program
{
public static void Main(string[] args)
{
// Help options
if (args.Length == 0
|| args[0] == "/h" || args[0] == "/?"
|| args[0] == "-h" || args[0] == "-?")
{
DisplayHelp();
return;
}
// List options
if (args[0] == "/lm" || args[0] == "/listmedia"
|| args[0] == "-lm" || args[0] == "--listmedia")
{
ListMediaTypes();
Console.ReadLine();
return;
}
else if (args[0] == "/ls" || args[0] == "/listsystems"
|| args[0] == "-ls" || args[0] == "--listsystems")
{
ListKnownSystems();
Console.ReadLine();
return;
}
// Normal operation check
if (args.Length < 3)
{
DisplayHelp("Invalid number of arguments");
return;
}
// Check the MediaType
var mediaType = Converters.StringToMediaType(args[0].Trim('"'));
if (mediaType == MediaType.NONE)
{
DisplayHelp($"{args[0]} is not a recognized media type");
return;
}
// Check the KnownSystem
var knownSystem = Converters.StringToKnownSystem(args[1].Trim('"'));
if (knownSystem == KnownSystem.NONE)
{
DisplayHelp($"{args[1]} is not a recognized system");
return;
}
// Check for Redump login credentials
string username = null, password = null;
int startIndex = 2;
if (args[2] == "-c" || args[2] == "--credentials")
{
username = args[3];
password = args[4];
startIndex = 5;
}
// Make a new Progress object
var progress = new Progress<Result>();
progress.ProgressChanged += ProgressUpdated;
// Loop through all the rest of the args
for (int i = startIndex; i < args.Length; i++)
{
// Check for a file
if (!File.Exists(args[i]))
{
DisplayHelp($"{args[i]} does not exist");
return;
}
// Get the full file path
string filepath = Path.GetFullPath(args[i]);
// Now populate an environment
var env = new DumpEnvironment
{
OutputDirectory = "",
OutputFilename = filepath,
System = knownSystem,
Type = mediaType,
ScanForProtection = false,
PromptForDiscInformation = false,
Username = username,
Password = password,
};
env.FixOutputPaths();
// Finally, attempt to do the output dance
var result = env.VerifyAndSaveDumpOutput(progress);
Console.WriteLine(result.Message);
}
}
/// <summary>
/// Display help for DICUI.Check
/// </summary>
/// <param name="error">Error string to prefix the help text with</param>
private static void DisplayHelp(string error = null)
{
if (error != null)
Console.WriteLine(error);
Console.WriteLine("Usage:");
Console.WriteLine("DICUI.Check.exe <mediatype> <system> [-c username password] </path/to/output.bin> ...");
Console.WriteLine();
Console.WriteLine(@"Common Media Types:\r\n
bd / bluray - BD-ROM
cd / cdrom - CD-ROM
dvd - DVD-ROM
fd / floppy - Floppy Disk
gd / gdrom - GD-ROM
umd - UMD");
Console.WriteLine("Run 'DICUI.Check.exe [-lm|--listmedia' for more options");
Console.WriteLine();
Console.WriteLine(@"Common Systems:\r\n
apple / mac - Apple Macintosh
cdi - Philips CD-i
ibm / ibmpc - IBM PC Compatible
psx / ps1 - Sony PlayStation
ps2 - Sony PlayStation 2
psp - Sony PlayStation Portable
saturn - Sega Saturn
xbox - Microsoft XBOX
x360 - Microsoft XBOX 360");
Console.WriteLine("Run 'DICUI.Check.exe [-ls|--listsystems' for more options");
}
/// <summary>
/// List all media types with their short usable names
/// </summary>
private static void ListMediaTypes()
{
Console.WriteLine("Supported Media Types:");
foreach (var val in Enum.GetValues(typeof(MediaType)))
{
if (((MediaType)val) == MediaType.NONE)
continue;
Console.WriteLine($"{((MediaType?)val).ShortName()} - {((MediaType?)val).LongName()}");
}
}
/// <summary>
/// List all known systems with their short usable names
/// </summary>
private static void ListKnownSystems()
{
Console.WriteLine("Supported Known Systems:");
foreach (var val in Enum.GetValues(typeof(KnownSystem)))
{
if (((KnownSystem)val) == KnownSystem.NONE)
continue;
Console.WriteLine($"{((KnownSystem?)val).ShortName()} - {((KnownSystem?)val).LongName()}");
}
}
/// <summary>
/// Simple process counter to write to console
/// </summary>
private static void ProgressUpdated(object sender, Result value)
{
Console.WriteLine(value.Message);
}
}
}

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("DICUI.Check")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("DICUI.Check")]
[assembly: AssemblyCopyright("Copyright © 2019")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("8cfde289-e171-4d49-a40d-5293265c1253")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,40 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net462;net472;netcoreapp3.0</TargetFrameworks>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<COMReference Include="IMAPI2">
<Guid>{2735412F-7F64-5B0F-8F00-5D77AFBE261E}</Guid>
<VersionMajor>1</VersionMajor>
<VersionMinor>0</VersionMinor>
<Lcid>0</Lcid>
<WrapperTool>tlbimp</WrapperTool>
<Isolated>False</Isolated>
<EmbedInteropTypes>True</EmbedInteropTypes>
</COMReference>
<COMReference Include="IMAPI2FS">
<Guid>{2C941FD0-975B-59BE-A960-9A2A262853A5}</Guid>
<VersionMajor>1</VersionMajor>
<VersionMinor>0</VersionMinor>
<Lcid>0</Lcid>
<WrapperTool>tlbimp</WrapperTool>
<Isolated>False</Isolated>
<EmbedInteropTypes>True</EmbedInteropTypes>
</COMReference>
</ItemGroup>
<ItemGroup>
<PackageReference Include="BurnOutSharp" Version="1.3.8.2" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
<PackageReference Include="System.Management" Version="4.6.0" />
</ItemGroup>
<ItemGroup>
<Reference Include="System.Management" />
</ItemGroup>
</Project>

View File

@@ -1,19 +1,9 @@
namespace DICUI.Data
{
/// <summary>
/// Text for UI elements
/// </summary>
public static class UIElements
{
public const string StartDumping = "Start Dumping";
public const string StopDumping = "Stop Dumping";
public const string FloppyDriveString = "<<FLOPPY>>";
}
/// <summary>
/// Top-level commands for DiscImageCreator
/// </summary>
public static class DICCommands
public static class DICCommandStrings
{
public const string Audio = "audio";
public const string BluRay = "bd";
@@ -21,29 +11,36 @@
public const string CompactDisc = "cd";
public const string Data = "data";
public const string DigitalVideoDisc = "dvd";
public const string Disk = "disk";
public const string DriveSpeed = "ls";
public const string Eject = "eject";
public const string Floppy = "fd";
public const string GDROM = "gd";
public const string MDS = "mds";
public const string Merge = "merge";
public const string Reset = "reset";
public const string SACD = "sacd";
public const string Start = "start";
public const string Stop = "stop";
public const string Sub = "sub";
public const string Swap = "swap";
public const string XBOX = "xbox";
public const string XBOXSwap = "xboxswap";
public const string XGD2Swap = "xgd2swap";
public const string XGD3Swap = "xgd3swap";
}
/// <summary>
/// Dumping flags for DiscImageCreator
/// </summary>
public static class DICFlags
public static class DICFlagStrings
{
public const string AddOffset = "/a";
public const string AMSF = "/p";
public const string AtariJaguar = "/aj";
public const string BEOpcode = "/be";
public const string C2Opcode = "/c2";
public const string CMI = "/c";
public const string CopyrightManagementInformation = "/c";
public const string D8Opcode = "/d8";
public const string DisableBeep = "/q";
public const string ForceUnitAccess = "/f";
@@ -52,15 +49,19 @@
public const string NoFixSubP = "/np";
public const string NoFixSubQ = "/nq";
public const string NoFixSubQLibCrypt = "/nl";
public const string NoFixSubQSecuROM = "/ns";
public const string NoFixSubRtoW = "/nr";
public const string NoFixSubQSecuROM = "/ns";
public const string NoSkipSS = "/nss";
public const string Raw = "/raw";
public const string Reverse = "/r";
public const string ScanAntiMod = "/am";
public const string ScanFileProtect = "/sf";
public const string ScanSectorProtect = "/ss";
public const string SeventyFour = "/74";
public const string SkipSector = "/sk";
public const string SubchannelReadLevel = "/s";
public const string VideoNow = "/vn";
public const string VideoNowColor = "/vnc";
}
/// <summary>
@@ -71,6 +72,7 @@
// Manual information
public const string TitleField = "Title";
public const string ForeignTitleField = "Foreign Title (Non-latin)";
public const string DiscNumberField = "Disc Number / Letter";
public const string DiscTitleField = "Disc Title";
public const string SystemField = "System";
@@ -78,45 +80,54 @@
public const string CategoryField = "Category";
public const string RegionField = "Region";
public const string LanguagesField = "Languages";
public const string PlaystationLanguageSelectionViaField = "Language Selection Via";
public const string DiscSerialField = "Disc Serial";
public const string BarcodeField = "Barcode";
public const string ISBNField = "ISBN";
public const string CommentsField = "Comments";
public const string ContentsField = "Contents";
public const string VersionField = "Version";
public const string EditionField = "Edition/Release";
public const string PlayStation3WiiDiscKeyField = "Disc Key";
public const string PlayStation3DiscIDField = "Disc ID";
public const string GameCubeWiiBCAField = "BCA";
public const string CopyProtectionField = "Copy Protection";
public const string MasteringRingField = "Mastering Ring";
public const string MasteringRingField = "Mastering Code (laser branded/etched)";
public const string MasteringSIDField = "Mastering SID Code";
public const string MouldSIDField = "Mould SID Code";
public const string AdditionalMouldField = "Additional Mould";
public const string ToolstampField = "Toolstamp or Mastering Code";
public const string ToolstampField = "Toolstamp or Mastering Code (engraved/stamped)";
// Automatic Information
public const string PVDField = "Primary Volume Descriptor (PVD)";
public const string DATField = "DAT";
public const string SizeField = "Size";
public const string CRC32Field = "CRC32";
public const string MD5Field = "MD5";
public const string SHA1Field = "SHA1";
public const string MatchingIDsField = "Matching IDs";
public const string ErrorCountField = "Error Count";
public const string CuesheetField = "Cuesheet";
public const string SubIntentionField = "SubIntention Data (SecuROM/LibCrypt)";
public const string WriteOffsetField = "Write Offset";
public const string LayerbreakField = "Layerbreak";
public const string PlaystationEXEDateField = "EXE Date";
public const string EXEDateBuildDate = "EXE/Build Date";
public const string HeaderField = "Header";
public const string PICField = "Permanent Information & Control (PIC)";
public const string PlayStationEDCField = "EDC";
public const string PlayStationAntiModchipField = "Anti-modchip";
public const string PlayStationLibCryptField = "LibCrypt";
public const string SaturnHeaderField = "Header";
public const string SaturnBuildDateField = "Build Date";
public const string XBOXDMIHash = "DMI.bin Hashes";
public const string XBOXPFIHash = "PFI.bin Hashes";
public const string XBOXSSHash = "SS.bin Hashes";
public const string XBOXSSRanges = "Security Sector Ranges";
public const string XBOXSSVersion = "Security Sector Version";
// Default values
public const string RequiredValue = "(REQUIRED)";
public const string RequiredIfExistsValue = "(REQUIRED, IF EXISTS)";
public const string OptionalValue = "(OPTIONAL)";
public const string YesNoValue = "Yes/No";
public const string DiscNotDetected = "Disc Not Detected";
}
}

View File

@@ -0,0 +1,601 @@
namespace DICUI.Data
{
/// <summary>
/// Category for Redump
/// </summary>
public enum Category
{
Games = 1,
Demos = 2,
Video = 3,
Audio = 4,
Multimedia = 5,
Applications = 6,
Coverdiscs = 7,
Educational = 8,
BonusDiscs = 9,
Preproduction = 10,
AddOns = 11,
}
/// <summary>
/// Supported DIC commands
/// </summary>
public enum DICCommand
{
NONE = 0,
Audio,
BluRay,
Close,
CompactDisc,
Data,
DigitalVideoDisc,
Disk,
DriveSpeed,
Eject,
Floppy,
GDROM,
MDS,
Merge,
Reset,
SACD,
Start,
Stop,
Sub,
Swap,
XBOX,
XBOXSwap,
XGD2Swap,
XGD3Swap,
}
/// <summary>
/// Supported DIC flags
/// </summary>
public enum DICFlag
{
NONE = 0,
AddOffset,
AMSF,
AtariJaguar,
BEOpcode,
C2Opcode,
CopyrightManagementInformation,
D8Opcode,
DisableBeep,
ForceUnitAccess,
MCN,
MultiSession,
NoFixSubP,
NoFixSubQ,
NoFixSubQLibCrypt,
NoFixSubRtoW,
NoFixSubQSecuROM,
NoSkipSS,
Raw,
Reverse,
ScanAntiMod,
ScanFileProtect,
ScanSectorProtect,
SeventyFour,
SkipSector,
SubchannelReadLevel,
VideoNow,
VideoNowColor,
}
/// <summary>
/// Drive type for dumping
/// </summary>
public enum InternalDriveType
{
Optical,
Floppy,
HardDisk,
Removable,
}
/// <summary>
/// Dump status for Redump
/// </summary>
public enum DumpStatus
{
BadDumpRed = 2,
PossibleBadDumpYellow = 3,
OriginalMediaBlue = 4,
TwoOrMoreDumpsGreen = 5,
}
/// <summary>
/// Known systems
/// </summary>
public enum KnownSystem
{
NONE = 0,
#region Disc-Based Consoles
AtariJaguarCD,
BandaiPlaydiaQuickInteractiveSystem,
BandaiApplePippin,
CommodoreAmigaCD32,
CommodoreAmigaCDTV,
EnvizionsEVOSmartConsole,
FujitsuFMTownsMarty,
HasbroVideoNow,
HasbroVideoNowColor,
HasbroVideoNowJr,
HasbroVideoNowXP,
MattelHyperscan,
MicrosoftXBOX,
MicrosoftXBOX360,
MicrosoftXBOXOne,
NECPCEngineTurboGrafxCD,
NECPCFX,
NintendoGameCube,
NintendoSonySuperNESCDROMSystem,
NintendoWii,
NintendoWiiU,
Panasonic3DOInteractiveMultiplayer, // The 3DO Company 3DO Interactive Multiplayer
PhilipsCDi,
PioneerLaserActive,
SegaCDMegaCD,
SegaDreamcast,
SegaSaturn,
SNKNeoGeoCD,
SonyPlayStation,
SonyPlayStation2,
SonyPlayStation3,
SonyPlayStation4,
SonyPlayStationPortable,
TandyMemorexVisualInformationSystem,
VMLabsNuon,
VTechVFlashVSmilePro,
ZAPiTGamesGameWaveFamilyEntertainmentSystem,
MarkerDiscBasedConsoleEnd,
#endregion
#region Cartridge-Based and Other Consoles
/*
AmstradGX4000,
APFMicrocomputerSystem,
Atari2600VCS,
Atari5200,
Atari7800,
AtariJaguar,
AtariXEVideoGameSystem,
Audiosonic1292AdvancedProgrammableVideoSystem,
BallyAstrocade,
BitCorporationDina,
CasioLoopy,
CasioPV1000,
Commodore64GamesSystem,
DaewooElectronicsZemmix,
EmersonArcadia2001,
EpochCassetteVision,
EpochSuperCassetteVision,
FairchildChannelF,
FuntechSuperACan,
GeneralConsumerElectricVectrex,
HeberBBCBridgeCompanion,
IntertonVC4000,
JungleTacVii,
LeapFrogClickStart,
LJNVideoArt,
MagnavoxOdyssey2,
MattelIntellivision,
NECPCEngineTurboGrafx16,
NichibutsuMyVision,
Nintendo64,
Nintendo64DD,
NintendoFamilyComputerNintendoEntertainmentSystem,
NintendoFamilyComputerDiskSystem,
NintendoSuperFamicomSuperNintendoEntertainmentSystem,
NintendoSwitch,
PhilipsVideopacPlusG7400,
RCAStudioII,
Sega32X,
SegaMarkIIIMasterSystem,
SegaMegaDriveGenesis,
SegaSG1000,
SNKNeoGeo,
SSDCOMPANYLIMITEDXaviXPORT,
ViewMasterInteractiveVision,
VTechCreatiVision,
VTechVSmile,
VTechSocrates,
WorldsOfWonderActionMax,
MarkerOtherConsoleEnd,
*/
#endregion
#region Computers
AcornArchimedes,
AppleMacintosh,
CommodoreAmiga,
FujitsuFMTowns,
IBMPCCompatible,
NECPC88,
NECPC98,
SharpX68000,
MarkerComputerEnd,
#endregion
#region Arcade
AmigaCUBOCD32,
AmericanLaserGames3DO,
Atari3DO,
Atronic,
AUSCOMSystem1,
BallyGameMagic,
CapcomCPSystemIII,
GlobalVRVarious,
GlobalVRVortek,
GlobalVRVortekV3,
ICEPCHardware,
IncredibleTechnologiesEagle,
IncredibleTechnologiesVarious,
KonamieAmusement,
KonamiFirebeat,
KonamiGVSystem,
KonamiM2,
KonamiPython,
KonamiPython2,
KonamiSystem573,
KonamiTwinkle,
KonamiVarious,
MeritIndustriesBoardwalk,
MeritIndustriesMegaTouchForce,
MeritIndustriesMegaTouchION,
MeritIndustriesMegaTouchMaxx,
MeritIndustriesMegaTouchXL,
NamcoCapcomSystem256,
NamcoCapcomTaitoSystem246,
NamcoSegaNintendoTriforce,
NamcoSystem12,
NamcoSystem357,
NewJatreCDi,
NichibutsuHighRateSystem,
NichibutsuSuperCD,
NichibutsuXRateSystem,
PanasonicM2,
PhotoPlayVarious,
RawThrillsVarious,
SegaChihiro,
SegaEuropaR,
SegaLindbergh,
SegaNaomi,
SegaNaomi2,
SegaNu,
SegaRingEdge,
SegaRingEdge2,
SegaRingWide,
SegaTitanVideo,
SegaSystem32,
SeibuCATSSystem,
TABAustriaQuizard,
TsunamiTsuMoMultiGameMotionSystem,
MarkerArcadeEnd,
#endregion
#region Other
AudioCD,
BDVideo,
DVDVideo,
EnhancedCD,
HDDVDVideo,
NavisoftNaviken21,
PalmOS,
PhilipsCDiDigitalVideo,
PhotoCD,
PlayStationGameSharkUpdates,
RainbowDisc,
SuperAudioCD,
TaoiKTV,
TomyKissSite,
VideoCD,
MarkerOtherEnd,
#endregion
}
/// <summary>
/// Known system category
/// </summary>
public enum KnownSystemCategory
{
DiscBasedConsole = 0,
OtherConsole,
Computer,
Arcade,
Other,
Custom
};
/// <summary>
/// List of all disc langauges
/// </summary>
public enum Language
{
Afrikaans,
Arabic,
Basque,
Bulgarian,
Catalan,
Chinese,
Croatian,
Czech,
Danish,
Dutch,
English,
Finnish,
French,
Gaelic,
German,
Greek,
Hebrew,
Hindi,
Hungarian,
Italian,
Japanese,
Korean,
Norwegian,
Polish,
Portuguese,
Punjabi,
Romanian,
Russian,
Slovak,
Slovenian,
Spanish,
Swedish,
Tamil,
Thai,
Turkish,
Ukrainian,
}
/// <summary>
/// All possible language selections
/// </summary>
public enum LanguageSelection
{
BiosSettings,
LanguageSelector,
OptionsMenu,
}
/// <summary>
/// Known media types
/// </summary>
public enum MediaType
{
NONE = 0,
#region Punched Media
ApertureCard,
JacquardLoomCard,
MagneticStripeCard,
OpticalPhonecard,
PunchedCard,
PunchedTape,
#endregion
#region Tape
Cassette,
DataCartridge,
OpenReel,
#endregion
#region Disc / Disc
BluRay,
CDROM,
DVD,
FloppyDisk,
Floptical,
GDROM,
HDDVD,
HardDisk,
IomegaBernoulliDisk,
IomegaJaz,
IomegaZip,
LaserDisc, // LD-ROM and LV-ROM variants
Nintendo64DD,
NintendoFamicomDiskSystem,
NintendoGameCubeGameDisc,
NintendoWiiOpticalDisc,
NintendoWiiUOpticalDisc,
UMD,
#endregion
// Unsorted Formats
Cartridge,
CED,
CompactFlash,
MMC,
SDCard,
FlashDrive,
}
/// <summary>
/// List of all known Redump systems
/// </summary>
public enum RedumpSystem
{
// Special BIOS sets
MicrosoftXboxBIOS,
NintendoGameCubeBIOS,
SonyPlayStationBIOS,
SonyPlayStation2BIOS,
// Regular systems
AcornArchimedes,
AppleMacintosh,
AudioCD,
BDVideo,
BandaiPippin,
BandaiPlaydiaQuickInteractiveSystem,
CommodoreAmigaCD,
CommodoreAmigaCD32,
CommodoreAmigaCDTV,
DVDVideo,
FujitsuFMTownsseries,
HasbroVideoNow,
HasbroVideoNowColor,
HasbroVideoNowJr,
HasbroVideoNowXP,
IBMPCcompatible,
IncredibleTechnologiesEagle,
KonamiFireBeat,
KonamiM2,
KonamiSystem573,
KonamiSystemGV,
KonamiTwinkle,
KonamieAmusement,
MattelHyperScan,
MemorexVisualInformationSystem,
MicrosoftXbox,
MicrosoftXbox360,
MicrosoftXboxOne,
NECPC88series,
NECPC98series,
NECPCEngineCDTurboGrafxCD,
NECPCFXPCFXGA,
NamcoSystem12,
NamcoSystem246,
NavisoftNaviken21,
NinendoGameCube,
NintendoWii,
NintendoWiiU,
PalmOS,
Panasonic3DOInteractiveMultiplayer,
PanasonicM2,
PhilipsCDi,
PhilipsCDiDigitalVideo,
PhotoCD,
PlayStationGameSharkUpdates,
SegaChihiro,
SegaDreamcast,
SegaLindbergh,
SegaMegaCDSegaCD,
SegaNaomi,
SegaNaomi2,
SegaRingEdge,
SegaRingEdge2,
SegaSaturn,
SegaTitanVideo,
SegaTriforce,
SharpX68000,
SNKNeoGeoCD,
SonyPlayStation,
SonyPlayStation2,
SonyPlayStation3,
SonyPlayStation4,
SonyPlayStationPortable,
TABAustriaQuizard,
TaoiKTV,
TomyKissSite,
VideoCD,
VMLabsNUON,
VTechVFlashVSmilePro,
ZAPiTGamesGameWaveFamilyEntertainmentSystem,
}
/// <summary>
/// List of all known Redump regions
/// </summary>
public enum Region
{
Argentina,
Asia,
AsiaEurope,
AsiaUSA,
Australia,
Austria,
AustriaSwitzerland,
Belgium,
BelgiumNetherlands,
Brazil,
Canada,
China,
Croatia,
Czech,
Denmark,
Europe,
EuropeAsia,
EuropeAustralia,
Finland,
France,
FranceSpain,
Germany,
GreaterChina,
Greece,
Hungary,
India,
Ireland,
Israel,
Italy,
Japan,
JapanAsia,
JapanEurope,
JapanKorea,
JapanUSA,
Korea,
LatinAmerica,
Netherlands,
Norway,
Poland,
Portugal,
Russia,
Scandinavia,
Singapore,
Slovakia,
SouthAfrica,
Spain,
Sweden,
Switzerland,
Taiwan,
Thailand,
Turkey,
UnitedArabEmirates,
UK,
UKAustralia,
Ukraine,
USA,
USAAsia,
USABrazil,
USACanada,
USAEurope,
USAJapan,
World,
}
/// <summary>
/// Generic yes/no values for Redump
/// </summary>
public enum YesNo
{
NULL = 0,
No = 1,
Yes = 2,
}
}

View File

@@ -0,0 +1,500 @@
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Net;
using DICUI.Utilities;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
namespace DICUI.Data
{
public class SubmissionInfo
{
/// <summary>
/// List of matched Redump IDs
/// </summary>
[JsonIgnore]
public List<int> MatchedIDs { get; set; }
/// <summary>
/// DateTime of when the disc was added
/// </summary>
[JsonIgnore]
public DateTime? Added { get; set; }
/// <summary>
/// DateTime of when the disc was last modified
/// </summary>
[JsonIgnore]
public DateTime? LastModified { get; set; }
[JsonProperty(PropertyName = "common_disc_info", DefaultValueHandling = DefaultValueHandling.Ignore)]
public CommonDiscInfoSection CommonDiscInfo { get; set; } = new CommonDiscInfoSection();
[JsonProperty(PropertyName = "versions_and_editions", DefaultValueHandling = DefaultValueHandling.Ignore)]
public VersionAndEditionsSection VersionAndEditions { get; set; } = new VersionAndEditionsSection();
[JsonProperty(PropertyName = "edc", DefaultValueHandling = DefaultValueHandling.Ignore)]
public EDCSection EDC { get; set; } = new EDCSection();
[JsonProperty(PropertyName = "parent_clone_relationship", DefaultValueHandling = DefaultValueHandling.Ignore)]
public ParentCloneRelationshipSection ParentCloneRelationship { get; set; } = new ParentCloneRelationshipSection();
[JsonProperty(PropertyName = "extras", DefaultValueHandling = DefaultValueHandling.Ignore)]
public ExtrasSection Extras { get; set; } = new ExtrasSection();
[JsonProperty(PropertyName = "copy_protection", DefaultValueHandling = DefaultValueHandling.Ignore)]
public CopyProtectionSection CopyProtection { get; set; } = new CopyProtectionSection();
[JsonProperty(PropertyName = "dumpers_and_status", DefaultValueHandling = DefaultValueHandling.Ignore)]
public DumpersAndStatusSection DumpersAndStatus { get; set; } = new DumpersAndStatusSection();
[JsonProperty(PropertyName = "tracks_and_write_offsets", DefaultValueHandling = DefaultValueHandling.Ignore)]
public TracksAndWriteOffsetsSection TracksAndWriteOffsets { get; set; } = new TracksAndWriteOffsetsSection();
[JsonProperty(PropertyName = "size_and_checksums", DefaultValueHandling = DefaultValueHandling.Ignore)]
public SizeAndChecksumsSection SizeAndChecksums { get; set; } = new SizeAndChecksumsSection();
#region Regexes
private readonly Regex addedRegex = new Regex(@"<tr><th>Added</th><td>(.*?)</td></tr>");
private readonly Regex barcodeRegex = new Regex(@"<tr><th>Barcode</th></tr><tr><td>(.*?)</td></tr>");
private readonly Regex bcaRegex = new Regex(@"<h3>BCA .*?/></h3></td><td .*?></td></tr>"
+ "<tr><th>Row</th><th>Contents</th><th>ASCII</th></tr>"
+ "<tr><td>(?<row1number>.*?)</td><td>(?<row1contents>.*?)</td><td>(?<row1ascii>.*?)</td></tr>"
+ "<tr><td>(?<row2number>.*?)</td><td>(?<row2contents>.*?)</td><td>(?<row2ascii>.*?)</td></tr>"
+ "<tr><td>(?<row3number>.*?)</td><td>(?<row3contents>.*?)</td><td>(?<row3ascii>.*?)</td></tr>"
+ "<tr><td>(?<row4number>.*?)</td><td>(?<row4contents>.*?)</td><td>(?<row4ascii>.*?)</td></tr>");
private readonly Regex categoryRegex = new Regex(@"<tr><th>Category</th><td>(.*?)</td></tr>");
private readonly Regex commentsRegex = new Regex(@"<tr><th>Comments</th></tr><tr><td>(.*?)</td></tr>");
private readonly Regex contentsRegex = new Regex(@"<tr><th>Contents</th></tr><tr .*?><td>(.*?)</td></tr>");
private readonly Regex discNumberLetterRegex = new Regex(@"\((.*?)\)");
private readonly Regex dumpersRegex = new Regex(@"<a href=""/discs/dumper/(.*?)/"">");
private readonly Regex editionRegex = new Regex(@"<tr><th>Edition</th><td>(.*?)</td></tr>");
private readonly Regex errorCountRegex = new Regex(@"<tr><th>Errors count</th><td>(.*?)</td></tr>");
private readonly Regex foreignTitleRegex = new Regex(@"<h2>(.*?)</h2>");
private readonly Regex fullMatchRegex = new Regex(@"<td class=""static"">full match ids: (.*?)</td>");
private readonly Regex languagesRegex = new Regex(@"<img src=""/images/languages/(.*?)\.png"" alt="".*?"" title="".*?"" />\s*");
private readonly Regex lastModifiedRegex = new Regex(@"<tr><th>Last modified</th><td>(.*?)</td></tr>");
private readonly Regex mediaRegex = new Regex(@"<tr><th>Media</th><td>(.*?)</td></tr>");
private readonly Regex partialMatchRegex = new Regex(@"<td class=""static"">partial match ids: (.*?)</td>");
private readonly Regex pvdRegex = new Regex(@"<h3>Primary Volume Descriptor (PVD) <img .*?/></h3></td><td .*?></td></tr>"
+ @"<tr><th>Record / Entry</th><th>Contents</th><th>Date</th><th>Time</th><th>GMT</th></tr>"
+ @"<tr><td>Creation</td><td>(?<creationbytes>.*?)</td><td>(?<creationdate>.*?)</td><td>(?<creationtime>.*?)</td><td>(?<creationtimezone>.*?)</td></tr>"
+ @"<tr><td>Modification</td><td>(?<modificationbytes>.*?)</td><td>(?<modificationdate>.*?)</td><td>(?<modificationtime>.*?)</td><td>(?<modificationtimezone>.*?)</td></tr>"
+ @"<tr><td>Expiration</td><td>(?<expirationbytes>.*?)</td><td>(?<expirationdate>.*?)</td><td>(?<expirationtime>.*?)</td><td>(?<expirationtimezone>.*?)</td></tr>"
+ @"<tr><td>Effective</td><td>(?<effectivebytes>.*?)</td><td>(?<effectivedate>.*?)</td><td>(?<effectivetime>.*?)</td><td>(?<effectivetimezone>.*?)</td></tr>");
private readonly Regex regionRegex = new Regex(@"<tr><th>Region</th><td><a href=""/discs/region/(.*?)/"">");
private readonly Regex ringCodeDoubleRegex = new Regex(@""); // Varies based on available fields, like Addtional Mould
private readonly Regex ringCodeSingleRegex = new Regex(@""); // Varies based on available fields, like Addtional Mould
private readonly Regex serialRegex = new Regex(@"<tr><th>Serial</th><td>(.*?)</td></tr>");
private readonly Regex systemRegex = new Regex(@"<tr><th>System</th><td><a href=""/discs/system/(.*?)/"">");
private readonly Regex titleRegex = new Regex(@"<h1>(.*?)</h1>");
private readonly Regex trackRegex = new Regex(@"<tr><td>(?<number>.*?)</td><td>(?<type>.*?)</td><td>(?<pregap>.*?)</td><td>(?<length>.*?)</td><td>(?<sectors>.*?)</td><td>(?<size>.*?)</td><td>(?<crc32>.*?)</td><td>(?<md5>.*?)</td><td>(?<sha1>.*?)</td></tr>");
private readonly Regex trackCountRegex = new Regex(@"<tr><th>Number of tracks</th><td>(.*?)</td></tr>");
private readonly Regex versionRegex = new Regex(@"<tr><th>Version</th><td>(.*?)</td></tr>");
private readonly Regex writeOffsetRegex = new Regex(@"<tr><th>Write offset</th><td>(.*?)</td></tr>");
#endregion
/// <summary>
/// Fill in information from a Redump disc page
/// </summary>
/// <param name="discData">String representation of the disc page</param>
public void FillFromDiscPage(string discData)
{
// Title, Disc Number/Letter, Disc Title
var match = titleRegex.Match(discData);
if (match.Success)
{
string title = WebUtility.HtmlDecode(match.Groups[1].Value);
// If we have parenthesis, title is everything before the first one
int firstParenLocation = title.IndexOf(" (");
if (firstParenLocation >= 0)
{
this.CommonDiscInfo.Title = title.Substring(0, firstParenLocation);
var subMatches = discNumberLetterRegex.Match(title);
for (int i = 1; i < subMatches.Groups.Count; i++)
{
string subMatch = subMatches.Groups[i].Value;
// Disc number or letter
if (subMatch.StartsWith("Disc"))
this.CommonDiscInfo.DiscNumberLetter = subMatch.Remove(0, "Disc ".Length);
// Disc title
else
this.CommonDiscInfo.DiscTitle = subMatch;
}
}
// Otherwise, leave the title as-is
else
{
this.CommonDiscInfo.Title = title;
}
}
// Foreign Title
match = foreignTitleRegex.Match(discData);
if (match.Success)
this.CommonDiscInfo.ForeignTitleNonLatin = WebUtility.HtmlDecode(match.Groups[1].Value);
else
this.CommonDiscInfo.ForeignTitleNonLatin = null;
// Category
match = categoryRegex.Match(discData);
if (match.Success)
this.CommonDiscInfo.Category = Converters.StringToCategory(match.Groups[1].Value);
else
this.CommonDiscInfo.Category = Data.Category.Games;
// Region
match = regionRegex.Match(discData);
if (match.Success)
this.CommonDiscInfo.Region = Converters.StringToRegion(match.Groups[1].Value);
// Languages
var matches = languagesRegex.Matches(discData);
if (matches.Count > 0)
{
List<Language?> tempLanguages = new List<Language?>();
foreach (Match submatch in matches)
tempLanguages.Add(Converters.StringToLanguage(submatch.Groups[1].Value));
this.CommonDiscInfo.Languages = tempLanguages.ToArray();
}
// Serial
match = serialRegex.Match(discData);
if (match.Success)
this.CommonDiscInfo.Serial = WebUtility.HtmlDecode(match.Groups[1].Value);
// Error count
match = errorCountRegex.Match(discData);
if (match.Success)
{
// If the error counts don't match, then use the one from the disc page
if (!string.IsNullOrEmpty(this.CommonDiscInfo.ErrorsCount) && match.Groups[1].Value != this.CommonDiscInfo.ErrorsCount)
this.CommonDiscInfo.ErrorsCount = match.Groups[1].Value;
}
// Version
match = versionRegex.Match(discData);
if (match.Success)
this.VersionAndEditions.Version = WebUtility.HtmlDecode(match.Groups[1].Value);
// Edition
match = editionRegex.Match(discData);
if (match.Success)
this.VersionAndEditions.OtherEditions = WebUtility.HtmlDecode(match.Groups[1].Value);
// Dumpers
matches = dumpersRegex.Matches(discData);
if (matches.Count > 0)
{
// Start with any currently listed dumpers
List<string> tempDumpers = new List<string>();
if (this.DumpersAndStatus.Dumpers.Length > 0)
{
foreach (string dumper in this.DumpersAndStatus.Dumpers)
tempDumpers.Add(dumper);
}
foreach (Match submatch in matches)
tempDumpers.Add(WebUtility.HtmlDecode(submatch.Groups[1].Value));
this.DumpersAndStatus.Dumpers = tempDumpers.ToArray();
}
// Barcode
match = barcodeRegex.Match(discData);
if (match.Success)
this.CommonDiscInfo.Barcode = WebUtility.HtmlDecode(match.Groups[1].Value);
// Comments
match = commentsRegex.Match(discData);
if (match.Success)
{
this.CommonDiscInfo.Comments = WebUtility.HtmlDecode(match.Groups[1].Value)
.Replace("<br />", "\n")
.Replace("<b>ISBN</b>", "[T:ISBN]") + "\n";
}
// Contents
match = contentsRegex.Match(discData);
if (match.Success)
{
this.CommonDiscInfo.Contents = WebUtility.HtmlDecode(match.Groups[1].Value)
.Replace("<br />", "\n")
.Replace("</div>", "");
this.CommonDiscInfo.Contents = Regex.Replace(this.CommonDiscInfo.Contents, @"<div .*?>", "");
}
// Added
match = addedRegex.Match(discData);
if (match.Success)
this.Added = DateTime.Parse(match.Groups[1].Value);
// Last Modified
match = lastModifiedRegex.Match(discData);
if (match.Success)
this.LastModified = DateTime.Parse(match.Groups[1].Value);
}
}
/// <summary>
/// Common disc info section of New Disc Form
/// </summary>
public class CommonDiscInfoSection
{
// TODO: Name not defined
[JsonProperty(PropertyName = "d_system", Required = Required.AllowNull)]
[JsonConverter(typeof(KnownSystemConverter))]
public KnownSystem? System { get; set; }
// TODO: Name not defined
// TODO: Have this convert to a new `RedumpMedia?` if possible, for submission
[JsonProperty(PropertyName = "d_media", Required = Required.AllowNull)]
[JsonConverter(typeof(MediaTypeConverter))]
public MediaType? Media { get; set; }
[JsonProperty(PropertyName = "d_title", Required = Required.AllowNull)]
public string Title { get; set; }
[JsonProperty(PropertyName = "d_title_foreign", DefaultValueHandling = DefaultValueHandling.Ignore)]
public string ForeignTitleNonLatin { get; set; }
[JsonProperty(PropertyName = "d_number", NullValueHandling = NullValueHandling.Ignore)]
public string DiscNumberLetter { get; set; }
[JsonProperty(PropertyName = "d_label", NullValueHandling = NullValueHandling.Ignore)]
public string DiscTitle { get; set; }
[JsonProperty(PropertyName = "d_category", Required = Required.AllowNull)]
public Category? Category { get; set; }
[JsonProperty(PropertyName = "d_region", Required = Required.AllowNull)]
[JsonConverter(typeof(RegionConverter))]
public Region? Region { get; set; }
[JsonProperty(PropertyName = "d_languages", Required = Required.AllowNull)]
[JsonConverter(typeof(LanguagesConverter))]
public Language?[] Languages { get; set; }
[JsonProperty(PropertyName = "d_languages_selection", NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)]
[JsonConverter(typeof(LanguageSelectionConverter))]
public LanguageSelection?[] LanguageSelection { get; set; }
[JsonProperty(PropertyName = "d_serial", NullValueHandling = NullValueHandling.Ignore)]
public string Serial { get; set; }
[JsonProperty(PropertyName = "d_ring", NullValueHandling = NullValueHandling.Ignore)]
public string Ring { get; }
[JsonProperty(PropertyName = "d_ring_0_id", NullValueHandling = NullValueHandling.Ignore)]
public string RingId { get; }
[JsonProperty(PropertyName = "d_ring_0_ma1", Required = Required.AllowNull)]
public string MasteringRingFirstLayerDataSide { get; set; }
[JsonProperty(PropertyName = "d_ring_0_ma1_sid", NullValueHandling = NullValueHandling.Ignore)]
public string MasteringSIDCodeFirstLayerDataSide { get; set; }
[JsonProperty(PropertyName = "d_ring_0_ts1", NullValueHandling = NullValueHandling.Ignore)]
public string ToolstampMasteringCodeFirstLayerDataSide { get; set; }
[JsonProperty(PropertyName = "d_ring_0_mo1_sid", NullValueHandling = NullValueHandling.Ignore)]
public string MouldSIDCodeFirstLayerDataSide { get; set; }
[JsonProperty(PropertyName = "dr_ring_0_mo1", NullValueHandling = NullValueHandling.Ignore)]
public string AdditionalMouldFirstLayerDataSide { get; set; }
[JsonProperty(PropertyName = "d_ring_0_ma2", NullValueHandling = NullValueHandling.Ignore)]
public string MasteringRingSecondLayerLabelSide { get; set; }
[JsonProperty(PropertyName = "d_ring_0_ma2_sid", NullValueHandling = NullValueHandling.Ignore)]
public string MasteringSIDCodeSecondLayerLabelSide { get; set; }
[JsonProperty(PropertyName = "d_ring_0_ts2", NullValueHandling = NullValueHandling.Ignore)]
public string ToolstampMasteringCodeSecondLayerLabelSide { get; set; }
[JsonProperty(PropertyName = "d_ring_0_mo2_sid", NullValueHandling = NullValueHandling.Ignore)]
public string MouldSIDCodeSecondLayerLabelSide { get; set; }
[JsonProperty(PropertyName = "dr_ring_0_mo2", NullValueHandling = NullValueHandling.Ignore)]
public string AdditionalMouldSecondLayerLabelSide { get; set; }
[JsonProperty(PropertyName = "d_ring_0_offsets", NullValueHandling = NullValueHandling.Ignore)]
public string RingOffsetsHidden { get { return "1"; } }
[JsonProperty(PropertyName = "d_ring_0_0_id", NullValueHandling = NullValueHandling.Ignore)]
public string RingZeroId { get; }
[JsonProperty(PropertyName = "d_ring_0_0_density", NullValueHandling = NullValueHandling.Ignore)]
public string RingZeroDensity { get; }
[JsonProperty(PropertyName = "d_ring_0_0_value", NullValueHandling = NullValueHandling.Ignore)]
public string RingWriteOffset { get; set; }
[JsonProperty(PropertyName = "d_ring_count", NullValueHandling = NullValueHandling.Ignore)]
public string RingCount { get { return "1"; } }
[JsonProperty(PropertyName = "d_barcode", NullValueHandling = NullValueHandling.Ignore)]
public string Barcode { get; set; }
[JsonProperty(PropertyName = "d_date", NullValueHandling = NullValueHandling.Ignore)]
public string EXEDateBuildDate { get; set; }
[JsonProperty(PropertyName = "d_errors", NullValueHandling = NullValueHandling.Ignore)]
public string ErrorsCount { get; set; }
[JsonProperty(PropertyName = "d_comments", NullValueHandling = NullValueHandling.Ignore)]
public string Comments { get; set; }
[JsonProperty(PropertyName = "d_contents", NullValueHandling = NullValueHandling.Ignore)]
public string Contents { get; set; }
}
/// <summary>
/// Version and editions section of New Disc form
/// </summary>
public class VersionAndEditionsSection
{
[JsonProperty(PropertyName = "d_version", NullValueHandling = NullValueHandling.Ignore)]
public string Version { get; set; }
[JsonProperty(PropertyName = "d_version_datfile", NullValueHandling = NullValueHandling.Ignore)]
public string VersionDatfile { get; set; }
[JsonProperty(PropertyName = "d_editions", NullValueHandling = NullValueHandling.Ignore)]
public string[] CommonEditions { get; set; }
[JsonProperty(PropertyName = "d_editions_text", NullValueHandling = NullValueHandling.Ignore)]
public string OtherEditions { get; set; }
}
/// <summary>
/// EDC section of New Disc form (PSX only)
/// </summary>
public class EDCSection
{
[JsonProperty(PropertyName = "d_edc", NullValueHandling = NullValueHandling.Ignore)]
public YesNo EDC { get; set; }
}
/// <summary>
/// Parent/Clone relationship section of New Disc form
/// </summary>
public class ParentCloneRelationshipSection
{
[JsonProperty(PropertyName = "d_parent_id", NullValueHandling = NullValueHandling.Ignore)]
public string ParentID { get; set; }
[JsonProperty(PropertyName = "d_is_regional_parent", NullValueHandling = NullValueHandling.Ignore)]
public bool RegionalParent { get; set; }
}
/// <summary>
/// Extras section of New Disc form
/// </summary>
public class ExtrasSection
{
[JsonProperty(PropertyName = "d_pvd", NullValueHandling = NullValueHandling.Ignore)]
public string PVD { get; set; }
[JsonProperty(PropertyName = "d_d1_key", NullValueHandling = NullValueHandling.Ignore)]
public string DiscKey { get; set; }
[JsonProperty(PropertyName = "d_d2_key", NullValueHandling = NullValueHandling.Ignore)]
public string DiscID { get; set; }
[JsonProperty(PropertyName = "d_pic_data", NullValueHandling = NullValueHandling.Ignore)]
public string PIC { get; set; }
[JsonProperty(PropertyName = "d_header", NullValueHandling = NullValueHandling.Ignore)]
public string Header { get; set; }
[JsonProperty(PropertyName = "d_bca", NullValueHandling = NullValueHandling.Ignore)]
public string BCA { get; set; }
[JsonProperty(PropertyName = "d_ssranges", NullValueHandling = NullValueHandling.Ignore)]
public string SecuritySectorRanges { get; set; }
}
/// <summary>
/// Copy protection section of New Disc form
/// </summary>
public class CopyProtectionSection
{
[JsonProperty(PropertyName = "d_protection_a", NullValueHandling = NullValueHandling.Ignore)]
public YesNo AntiModchip { get; set; }
[JsonProperty(PropertyName = "d_protection_1", NullValueHandling = NullValueHandling.Ignore)]
public YesNo LibCrypt { get; set; }
[JsonProperty(PropertyName = "d_libcrypt", NullValueHandling = NullValueHandling.Ignore)]
public string LibCryptData { get; set; }
[JsonProperty(PropertyName = "d_protection", NullValueHandling = NullValueHandling.Ignore)]
public string Protection { get; set; }
[JsonProperty(PropertyName = "d_securom", NullValueHandling = NullValueHandling.Ignore)]
public string SecuROMData { get; set; }
}
/// <summary>
/// Dumpers and status section of New Disc form (Moderator only)
/// </summary>
public class DumpersAndStatusSection
{
[JsonProperty(PropertyName = "d_status", NullValueHandling = NullValueHandling.Ignore)]
public DumpStatus Status { get; set; }
[JsonProperty(PropertyName = "d_dumpers", NullValueHandling = NullValueHandling.Ignore)]
public string[] Dumpers { get; set; }
[JsonProperty(PropertyName = "d_dumpers_text", NullValueHandling = NullValueHandling.Ignore)]
public string OtherDumpers { get; set; }
}
/// <summary>
/// Tracks and write offsets section of New Disc form (CD/GD-based)
/// </summary>
public class TracksAndWriteOffsetsSection
{
[JsonProperty(PropertyName = "d_tracks", NullValueHandling = NullValueHandling.Ignore)]
public string ClrMameProData { get; set; }
[JsonProperty(PropertyName = "d_cue", NullValueHandling = NullValueHandling.Ignore)]
public string Cuesheet { get; set; }
[JsonProperty(PropertyName = "d_offset", NullValueHandling = NullValueHandling.Ignore)]
public int[] CommonWriteOffsets { get; set; }
[JsonProperty(PropertyName = "d_offset_text", NullValueHandling = NullValueHandling.Ignore)]
public string OtherWriteOffsets { get; set; }
}
/// <summary>
/// Size & checksums section of New Disc form (DVD/BD/UMD-based)
/// </summary>
public class SizeAndChecksumsSection
{
[JsonProperty(PropertyName = "d_layerbreak", NullValueHandling = NullValueHandling.Ignore)]
public long Layerbreak { get; set; }
[JsonProperty(PropertyName = "d_size", NullValueHandling = NullValueHandling.Ignore)]
public long Size { get; set; }
[JsonProperty(PropertyName = "d_crc32", NullValueHandling = NullValueHandling.Ignore)]
public string CRC32 { get; set; }
[JsonProperty(PropertyName = "d_md5", NullValueHandling = NullValueHandling.Ignore)]
public string MD5 { get; set; }
[JsonProperty(PropertyName = "d_sha1", NullValueHandling = NullValueHandling.Ignore)]
public string SHA1 { get; set; }
}
}

View File

@@ -0,0 +1,37 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("DICUI.Library")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("DICUI.Library")]
[assembly: AssemblyCopyright("Copyright © 2019")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("51ab0928-13f9-44bf-a407-b6957a43a056")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.13")]
[assembly: AssemblyFileVersion("1.13.0.0")]
[assembly: InternalsVisibleTo("DICUI.Test")]

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,63 @@
using System.IO;
using DICUI.Data;
namespace DICUI.Utilities
{
/// <summary>
/// Represents information for a single drive
/// </summary>
public class Drive
{
/// <summary>
/// Represents drive type
/// </summary>
public InternalDriveType? InternalDriveType { get; set; }
/// <summary>
/// DriveInfo object representing the drive, if possible
/// </summary>
public DriveInfo DriveInfo { get; private set; }
/// <summary>
/// Windows drive letter
/// </summary>
public char Letter { get { return DriveInfo?.Name[0] ?? '\0'; } }
/// <summary>
/// Media label as read by Windows
/// </summary>
public string VolumeLabel
{
get
{
if (DriveInfo.IsReady)
{
if (string.IsNullOrWhiteSpace(DriveInfo.VolumeLabel))
return "track";
else
return DriveInfo.VolumeLabel;
}
else
{
return Template.DiscNotDetected;
}
}
}
/// <summary>
/// Drive partition format
/// </summary>
public string DriveFormat { get { return DriveInfo.DriveFormat; } }
/// <summary>
/// Represents if Windows has marked the drive as active
/// </summary>
public bool MarkedActive { get { return DriveInfo.IsReady; } }
public Drive(InternalDriveType? driveType, DriveInfo driveInfo)
{
this.InternalDriveType = driveType;
this.DriveInfo = driveInfo;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,252 @@
using DICUI.Data;
namespace DICUI.Utilities
{
public static class Extensions
{
#region Redump Information Lists
/// <summary>
/// List of systems that are not publically accessible
/// </summary>
public static readonly RedumpSystem[] BannedSystems = new RedumpSystem[]
{
RedumpSystem.AudioCD,
RedumpSystem.BDVideo,
RedumpSystem.DVDVideo,
RedumpSystem.HasbroVideoNow,
RedumpSystem.HasbroVideoNowColor,
RedumpSystem.HasbroVideoNowJr,
RedumpSystem.HasbroVideoNowXP,
RedumpSystem.KonamiM2,
RedumpSystem.MicrosoftXbox360,
RedumpSystem.MicrosoftXboxOne,
RedumpSystem.NavisoftNaviken21,
RedumpSystem.NintendoWii,
RedumpSystem.NintendoWiiU,
RedumpSystem.PanasonicM2,
RedumpSystem.PhilipsCDiDigitalVideo,
RedumpSystem.SegaRingEdge,
RedumpSystem.SegaRingEdge2,
RedumpSystem.SonyPlayStation3,
RedumpSystem.SonyPlayStation4,
RedumpSystem.VideoCD,
};
/// <summary>
/// List of systems that have a Cues pack
/// </summary>
public static readonly RedumpSystem[] HasCues = new RedumpSystem[]
{
RedumpSystem.AppleMacintosh,
RedumpSystem.AudioCD,
RedumpSystem.BandaiPippin,
RedumpSystem.BandaiPlaydiaQuickInteractiveSystem,
RedumpSystem.CommodoreAmigaCD,
RedumpSystem.CommodoreAmigaCD32,
RedumpSystem.CommodoreAmigaCDTV,
RedumpSystem.FujitsuFMTownsseries,
RedumpSystem.HasbroVideoNow,
RedumpSystem.HasbroVideoNowJr,
RedumpSystem.IBMPCcompatible,
RedumpSystem.IncredibleTechnologiesEagle,
RedumpSystem.KonamieAmusement,
RedumpSystem.KonamiFireBeat,
RedumpSystem.KonamiM2,
RedumpSystem.KonamiSystemGV,
RedumpSystem.MattelHyperScan,
RedumpSystem.MicrosoftXbox,
RedumpSystem.MicrosoftXbox360,
RedumpSystem.NamcoSystem246,
RedumpSystem.NavisoftNaviken21,
RedumpSystem.NECPC88series,
RedumpSystem.NECPC98series,
RedumpSystem.NECPCEngineCDTurboGrafxCD,
RedumpSystem.NECPCFXPCFXGA,
RedumpSystem.PalmOS,
RedumpSystem.Panasonic3DOInteractiveMultiplayer,
RedumpSystem.PanasonicM2,
RedumpSystem.PhilipsCDi,
RedumpSystem.PhilipsCDiDigitalVideo,
RedumpSystem.PhotoCD,
RedumpSystem.PlayStationGameSharkUpdates,
RedumpSystem.SegaChihiro,
RedumpSystem.SegaDreamcast,
RedumpSystem.SegaMegaCDSegaCD,
RedumpSystem.SegaNaomi,
RedumpSystem.SegaNaomi2,
RedumpSystem.SegaSaturn,
RedumpSystem.SegaTriforce,
RedumpSystem.SNKNeoGeoCD,
RedumpSystem.SonyPlayStation,
RedumpSystem.SonyPlayStation2,
RedumpSystem.SonyPlayStation3,
RedumpSystem.TABAustriaQuizard,
RedumpSystem.TomyKissSite,
RedumpSystem.VideoCD,
RedumpSystem.VTechVFlashVSmilePro,
};
/// <summary>
/// List of systems that has a Dat pack
/// </summary>
public static readonly RedumpSystem[] HasDat = new RedumpSystem[]
{
RedumpSystem.MicrosoftXboxBIOS,
RedumpSystem.NintendoGameCubeBIOS,
RedumpSystem.SonyPlayStationBIOS,
RedumpSystem.SonyPlayStation2BIOS,
RedumpSystem.AppleMacintosh,
RedumpSystem.AudioCD,
RedumpSystem.BDVideo,
RedumpSystem.BandaiPippin,
RedumpSystem.BandaiPlaydiaQuickInteractiveSystem,
RedumpSystem.CommodoreAmigaCD,
RedumpSystem.CommodoreAmigaCD32,
RedumpSystem.CommodoreAmigaCDTV,
RedumpSystem.DVDVideo,
RedumpSystem.FujitsuFMTownsseries,
RedumpSystem.HasbroVideoNow,
RedumpSystem.HasbroVideoNowJr,
RedumpSystem.IBMPCcompatible,
RedumpSystem.IncredibleTechnologiesEagle,
RedumpSystem.KonamiFireBeat,
RedumpSystem.KonamiM2,
RedumpSystem.KonamiSystemGV,
RedumpSystem.KonamieAmusement,
RedumpSystem.MattelHyperScan,
RedumpSystem.MicrosoftXbox,
RedumpSystem.MicrosoftXbox360,
RedumpSystem.MicrosoftXboxOne,
RedumpSystem.NamcoSystem246,
RedumpSystem.NavisoftNaviken21,
RedumpSystem.NECPC88series,
RedumpSystem.NECPC98series,
RedumpSystem.NECPCEngineCDTurboGrafxCD,
RedumpSystem.NECPCFXPCFXGA,
RedumpSystem.NinendoGameCube,
RedumpSystem.NintendoWii,
RedumpSystem.NintendoWiiU,
RedumpSystem.PalmOS,
RedumpSystem.Panasonic3DOInteractiveMultiplayer,
RedumpSystem.PanasonicM2,
RedumpSystem.PhilipsCDi,
RedumpSystem.PhilipsCDiDigitalVideo,
RedumpSystem.PhotoCD,
RedumpSystem.PlayStationGameSharkUpdates,
RedumpSystem.SegaChihiro,
RedumpSystem.SegaDreamcast,
RedumpSystem.SegaLindbergh,
RedumpSystem.SegaMegaCDSegaCD,
RedumpSystem.SegaNaomi,
RedumpSystem.SegaNaomi2,
RedumpSystem.SegaRingEdge,
RedumpSystem.SegaRingEdge2,
RedumpSystem.SegaSaturn,
RedumpSystem.SegaTriforce,
RedumpSystem.SNKNeoGeoCD,
RedumpSystem.SonyPlayStation,
RedumpSystem.SonyPlayStation2,
RedumpSystem.SonyPlayStation3,
RedumpSystem.SonyPlayStation4,
RedumpSystem.SonyPlayStationPortable,
RedumpSystem.TABAustriaQuizard,
RedumpSystem.TomyKissSite,
RedumpSystem.VideoCD,
RedumpSystem.VMLabsNUON,
RedumpSystem.VTechVFlashVSmilePro,
RedumpSystem.ZAPiTGamesGameWaveFamilyEntertainmentSystem,
};
/// <summary>
/// List of systems that has a Decrypted Keys pack
/// </summary>
public static readonly RedumpSystem[] HasDkeys = new RedumpSystem[]
{
RedumpSystem.SonyPlayStation3,
};
/// <summary>
/// List of systems that has a GDI pack
/// </summary>
public static readonly RedumpSystem[] HasGdi = new RedumpSystem[]
{
RedumpSystem.SegaChihiro,
RedumpSystem.SegaDreamcast,
RedumpSystem.SegaNaomi,
RedumpSystem.SegaNaomi2,
RedumpSystem.SegaTriforce,
};
/// <summary>
/// List of systems that has a Keys pack
/// </summary>
public static readonly RedumpSystem[] HasKeys = new RedumpSystem[]
{
RedumpSystem.NintendoWiiU,
RedumpSystem.SonyPlayStation3,
};
/// <summary>
/// List of systems that has an SBI pack
/// </summary>
public static readonly RedumpSystem[] HasSbi = new RedumpSystem[]
{
RedumpSystem.IBMPCcompatible,
RedumpSystem.SonyPlayStation,
};
#endregion
public static bool DoesSupportDriveSpeed(this MediaType? type)
{
switch (type)
{
case MediaType.CDROM:
case MediaType.DVD:
case MediaType.GDROM:
case MediaType.HDDVD:
case MediaType.BluRay:
case MediaType.NintendoGameCubeGameDisc:
case MediaType.NintendoWiiOpticalDisc:
return true;
default:
return false;
}
}
public static KnownSystemCategory Category(this KnownSystem? system)
{
if (system < KnownSystem.MarkerDiscBasedConsoleEnd)
return KnownSystemCategory.DiscBasedConsole;
/*
else if (system < KnownSystem.MarkerOtherConsoleEnd)
return KnownSystemCategory.OtherConsole;
*/
else if (system < KnownSystem.MarkerComputerEnd)
return KnownSystemCategory.Computer;
else if (system < KnownSystem.MarkerArcadeEnd)
return KnownSystemCategory.Arcade;
else if (system < KnownSystem.MarkerOtherEnd)
return KnownSystemCategory.Other;
else
return KnownSystemCategory.Custom;
}
public static bool IsMarker(this KnownSystem? system)
{
switch (system)
{
case KnownSystem.MarkerArcadeEnd:
case KnownSystem.MarkerComputerEnd:
case KnownSystem.MarkerDiscBasedConsoleEnd:
// case KnownSystem.MarkerOtherConsoleEnd:
case KnownSystem.MarkerOtherEnd:
return true;
default:
return false;
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,66 @@
namespace DICUI.Utilities
{
/// <summary>
/// Generic success/failure result object, with optional message
/// </summary>
public class Result
{
/// <summary>
/// Internal representation of success
/// </summary>
private readonly bool success;
/// <summary>
/// Optional message for the result
/// </summary>
public string Message { get; private set; }
private Result(bool success, string message)
{
this.success = success;
this.Message = message;
}
/// <summary>
/// Create a default success result with no message
/// </summary>
public static Result Success() => new Result(true, "");
/// <summary>
/// Create a success result with a custom message
/// </summary>
/// <param name="message">String to add as a message</param>
public static Result Success(string message) => new Result(true, message);
/// <summary>
/// Create a success result with a custom message with format parameters
/// </summary>
/// <param name="message">String to add as a message</param>
/// <param name="args">Formatting parameters for the string</param>
public static Result Success(string message, params object[] args) => new Result(true, string.Format(message, args));
/// <summary>
/// Create a default failure result with no message
/// </summary>
/// <returns></returns>
public static Result Failure() => new Result(false, "");
/// <summary>
/// Create a failure result with a custom message
/// </summary>
/// <param name="message">String to add as a message</param>
public static Result Failure(string message) => new Result(false, message);
/// <summary>
/// Create a failure result with a custom message with format parameters
/// </summary>
/// <param name="message">String to add as a message</param>
/// <param name="args">Formatting parameters for the string</param>
public static Result Failure(string message, params object[] args) => new Result(false, string.Format(message, args));
/// <summary>
/// Results can be compared to boolean values based on the success value
/// </summary>
public static implicit operator bool(Result result) => result.success;
}
}

View File

@@ -0,0 +1,956 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Management;
using System.Threading.Tasks;
using BurnOutSharp;
using IMAPI2;
using DICUI.Data;
namespace DICUI.Utilities
{
public static class Validators
{
/// <summary>
/// Get a list of valid MediaTypes for a given KnownSystem
/// </summary>
/// <param name="sys">KnownSystem value to check</param>
/// <returns>MediaTypes, if possible</returns>
public static List<MediaType?> GetValidMediaTypes(KnownSystem? sys)
{
var types = new List<MediaType?>();
switch (sys)
{
#region Consoles
// https://en.wikipedia.org/wiki/Atari_Jaguar_CD
case KnownSystem.AtariJaguarCD:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/Playdia
case KnownSystem.BandaiPlaydiaQuickInteractiveSystem:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/Apple_Bandai_Pippin
case KnownSystem.BandaiApplePippin:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/Amiga_CD32
case KnownSystem.CommodoreAmigaCD32:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/Commodore_CDTV
case KnownSystem.CommodoreAmigaCDTV:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/EVO_Smart_Console
case KnownSystem.EnvizionsEVOSmartConsole:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
break;
// https://en.wikipedia.org/wiki/FM_Towns_Marty
case KnownSystem.FujitsuFMTownsMarty:
types.Add(MediaType.CDROM);
types.Add(MediaType.FloppyDisk);
break;
// https://en.wikipedia.org/wiki/VideoNow
case KnownSystem.HasbroVideoNow:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/VideoNow
case KnownSystem.HasbroVideoNowColor:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/VideoNow
case KnownSystem.HasbroVideoNowJr:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/VideoNow
case KnownSystem.HasbroVideoNowXP:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/HyperScan
case KnownSystem.MattelHyperscan:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/Xbox_(console)
case KnownSystem.MicrosoftXBOX:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
break;
// https://en.wikipedia.org/wiki/Xbox_360
case KnownSystem.MicrosoftXBOX360:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
break;
// https://en.wikipedia.org/wiki/Xbox_One
case KnownSystem.MicrosoftXBOXOne:
types.Add(MediaType.BluRay);
break;
// https://en.wikipedia.org/wiki/TurboGrafx-16
case KnownSystem.NECPCEngineTurboGrafxCD:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/PC-FX
case KnownSystem.NECPCFX:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/GameCube
case KnownSystem.NintendoGameCube:
types.Add(MediaType.NintendoGameCubeGameDisc);
break;
// https://en.wikipedia.org/wiki/Super_NES_CD-ROM
case KnownSystem.NintendoSonySuperNESCDROMSystem:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/Wii
case KnownSystem.NintendoWii:
types.Add(MediaType.NintendoWiiOpticalDisc);
break;
// https://en.wikipedia.org/wiki/Wii_U
case KnownSystem.NintendoWiiU:
types.Add(MediaType.NintendoWiiUOpticalDisc);
break;
// https://en.wikipedia.org/wiki/3DO_Interactive_Multiplayer
case KnownSystem.Panasonic3DOInteractiveMultiplayer:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/Philips_CD-i
case KnownSystem.PhilipsCDi:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/LaserActive
case KnownSystem.PioneerLaserActive:
types.Add(MediaType.CDROM);
types.Add(MediaType.LaserDisc);
break;
// https://en.wikipedia.org/wiki/Sega_CD
case KnownSystem.SegaCDMegaCD:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/Dreamcast
case KnownSystem.SegaDreamcast:
types.Add(MediaType.CDROM); // Low density partition, MIL-CD
types.Add(MediaType.GDROM); // High density partition
break;
// https://en.wikipedia.org/wiki/Sega_Saturn
case KnownSystem.SegaSaturn:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/Neo_Geo_CD
case KnownSystem.SNKNeoGeoCD:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/PlayStation_(console)
case KnownSystem.SonyPlayStation:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/PlayStation_2
case KnownSystem.SonyPlayStation2:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
break;
// https://en.wikipedia.org/wiki/PlayStation_3
case KnownSystem.SonyPlayStation3:
types.Add(MediaType.BluRay);
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
break;
// https://en.wikipedia.org/wiki/PlayStation_4
case KnownSystem.SonyPlayStation4:
types.Add(MediaType.BluRay);
break;
// https://en.wikipedia.org/wiki/PlayStation_Portable
case KnownSystem.SonyPlayStationPortable:
types.Add(MediaType.UMD);
types.Add(MediaType.CDROM); // Development discs only
types.Add(MediaType.DVD); // Development discs only
break;
// https://en.wikipedia.org/wiki/Tandy_Video_Information_System
case KnownSystem.TandyMemorexVisualInformationSystem:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/Nuon_(DVD_technology)
case KnownSystem.VMLabsNuon:
types.Add(MediaType.DVD);
break;
// https://en.wikipedia.org/wiki/V.Flash
case KnownSystem.VTechVFlashVSmilePro:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/Game_Wave_Family_Entertainment_System
case KnownSystem.ZAPiTGamesGameWaveFamilyEntertainmentSystem:
types.Add(MediaType.DVD);
break;
#endregion
#region Computers
// https://en.wikipedia.org/wiki/Acorn_Archimedes
case KnownSystem.AcornArchimedes:
types.Add(MediaType.CDROM);
types.Add(MediaType.FloppyDisk);
break;
// https://en.wikipedia.org/wiki/Macintosh
case KnownSystem.AppleMacintosh:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
types.Add(MediaType.FloppyDisk);
types.Add(MediaType.HardDisk);
break;
// https://en.wikipedia.org/wiki/Amiga
case KnownSystem.CommodoreAmiga:
types.Add(MediaType.CDROM);
types.Add(MediaType.FloppyDisk);
break;
// https://en.wikipedia.org/wiki/FM_Towns
case KnownSystem.FujitsuFMTowns:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/IBM_PC_compatible
case KnownSystem.IBMPCCompatible:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
types.Add(MediaType.FloppyDisk);
types.Add(MediaType.HardDisk);
break;
// https://en.wikipedia.org/wiki/PC-8800_series
case KnownSystem.NECPC88:
types.Add(MediaType.CDROM);
types.Add(MediaType.FloppyDisk);
break;
// https://en.wikipedia.org/wiki/PC-9800_series
case KnownSystem.NECPC98:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
types.Add(MediaType.FloppyDisk);
break;
// https://en.wikipedia.org/wiki/X68000
case KnownSystem.SharpX68000:
types.Add(MediaType.CDROM);
types.Add(MediaType.FloppyDisk);
break;
#endregion
#region Arcade
// https://www.bigbookofamigahardware.com/bboah/product.aspx?id=36
case KnownSystem.AmigaCUBOCD32:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/Orbatak
case KnownSystem.AmericanLaserGames3DO:
types.Add(MediaType.CDROM);
break;
// http://system16.com/hardware.php?id=779
case KnownSystem.Atari3DO:
types.Add(MediaType.CDROM);
break;
// http://newlifegames.net/nlg/index.php?topic=22003.0
// http://newlifegames.net/nlg/index.php?topic=5486.msg119440
case KnownSystem.Atronic:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
break;
// https://www.arcade-museum.com/members/member_detail.php?member_id=406530
case KnownSystem.AUSCOMSystem1:
types.Add(MediaType.CDROM);
break;
// http://newlifegames.net/nlg/index.php?topic=285.0
case KnownSystem.BallyGameMagic:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/CP_System_III
case KnownSystem.CapcomCPSystemIII:
types.Add(MediaType.CDROM);
break;
// UNKNOWN
case KnownSystem.GlobalVRVarious:
types.Add(MediaType.CDROM);
break;
// https://service.globalvr.com/troubleshooting/vortek.html
case KnownSystem.GlobalVRVortek:
types.Add(MediaType.CDROM);
break;
// https://service.globalvr.com/downloads/v3/040-1001-01c-V3-System-Manual.pdf
case KnownSystem.GlobalVRVortekV3:
types.Add(MediaType.CDROM);
break;
// https://www.icegame.com/games
case KnownSystem.ICEPCHardware:
types.Add(MediaType.DVD);
break;
// https://github.com/mamedev/mame/blob/master/src/mame/drivers/iteagle.cpp
case KnownSystem.IncredibleTechnologiesEagle:
types.Add(MediaType.CDROM);
break;
// UNKNOWN
case KnownSystem.IncredibleTechnologiesVarious:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
break;
// https://en.wikipedia.org/wiki/E-Amusement
case KnownSystem.KonamieAmusement:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
break;
// http://system16.com/hardware.php?id=828
case KnownSystem.KonamiFirebeat:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
break;
// http://system16.com/hardware.php?id=577
case KnownSystem.KonamiGVSystem:
types.Add(MediaType.CDROM);
break;
// http://system16.com/hardware.php?id=575
case KnownSystem.KonamiM2:
types.Add(MediaType.CDROM);
break;
// http://system16.com/hardware.php?id=586
// http://system16.com/hardware.php?id=977
case KnownSystem.KonamiPython:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
break;
// http://system16.com/hardware.php?id=976
// http://system16.com/hardware.php?id=831
case KnownSystem.KonamiPython2:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
break;
// http://system16.com/hardware.php?id=582
// http://system16.com/hardware.php?id=822
// http://system16.com/hardware.php?id=823
case KnownSystem.KonamiSystem573:
types.Add(MediaType.CDROM);
break;
// http://system16.com/hardware.php?id=827
case KnownSystem.KonamiTwinkle:
types.Add(MediaType.CDROM);
break;
// UNKNOWN
case KnownSystem.KonamiVarious:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
break;
// http://www.meritgames.com/Support_Center/manuals/PM0591-01.pdf
case KnownSystem.MeritIndustriesBoardwalk:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
break;
// http://www.meritgames.com/Support_Center/Force%20Elite/PM0380-09.pdf
// http://www.meritgames.com/Support_Center/Force%20Upright/PM0382-07%20FORCE%20Upright%20manual.pdf
// http://www.meritgames.com/Support_Center/Force%20Upright/PM0383-07%20FORCE%20Upright%20manual.pdf
case KnownSystem.MeritIndustriesMegaTouchForce:
types.Add(MediaType.CDROM);
break;
// http://www.meritgames.com/Service%20Center/Ion%20Troubleshooting.pdf
case KnownSystem.MeritIndustriesMegaTouchION:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
break;
// http://www.meritgames.com/Support_Center/EZ%20Maxx/Manuals/MAXX%20Elite%20with%20coin.pdf
// http://www.meritgames.com/Support_Center/EZ%20Maxx/Manuals/MAXX%20Elite.pdf
// http://www.meritgames.com/Support_Center/manuals/90003010%20Maxx%20TSM_Rev%20C.pdf
case KnownSystem.MeritIndustriesMegaTouchMaxx:
types.Add(MediaType.CDROM);
break;
// http://www.meritgames.com/Support_Center/manuals/pm0076_OA_Megatouch%20XL%20Trouble%20Shooting%20Manual.pdf
// http://www.meritgames.com/Support_Center/MEGA%20XL/manuals/Megatouch_XL_pm0109-0D.pdf
// http://www.meritgames.com/Support_Center/MEGA%20XL/manuals/Megatouch_XL_Super_5000_manual.pdf
case KnownSystem.MeritIndustriesMegaTouchXL:
types.Add(MediaType.CDROM);
break;
// http://system16.com/hardware.php?id=546
// http://system16.com/hardware.php?id=872
case KnownSystem.NamcoCapcomSystem256:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
break;
// http://system16.com/hardware.php?id=543
case KnownSystem.NamcoCapcomTaitoSystem246:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
break;
// http://system16.com/hardware.php?id=545
case KnownSystem.NamcoSegaNintendoTriforce:
types.Add(MediaType.CDROM); // Low density partition
types.Add(MediaType.GDROM); // High density partition
break;
// http://system16.com/hardware.php?id=535
case KnownSystem.NamcoSystem12:
types.Add(MediaType.CDROM);
break;
// http://system16.com/hardware.php?id=900
case KnownSystem.NamcoSystem357:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
types.Add(MediaType.BluRay);
break;
// https://www.arcade-history.com/?n=the-yakyuuken-part-1&page=detail&id=33049
case KnownSystem.NewJatreCDi:
types.Add(MediaType.CDROM);
break;
// http://blog.system11.org/?p=2499
case KnownSystem.NichibutsuHighRateSystem:
types.Add(MediaType.DVD);
break;
// http://blog.system11.org/?p=2514
case KnownSystem.NichibutsuSuperCD:
types.Add(MediaType.CDROM);
break;
// http://collectedit.com/collectors/shou-time-213/arcade-pcbs-281/x-rate-dvd-series-17-newlywed-life-japan-by-nichibutsu-32245
case KnownSystem.NichibutsuXRateSystem:
types.Add(MediaType.DVD);
break;
// https://en.wikipedia.org/wiki/Panasonic_M2
case KnownSystem.PanasonicM2:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
break;
// https://github.com/mamedev/mame/blob/master/src/mame/drivers/photoply.cpp
case KnownSystem.PhotoPlayVarious:
types.Add(MediaType.CDROM);
break;
// UNKNOWN
case KnownSystem.RawThrillsVarious:
types.Add(MediaType.DVD);
break;
// http://system16.com/hardware.php?id=729
case KnownSystem.SegaChihiro:
types.Add(MediaType.CDROM); // Low density partition
types.Add(MediaType.GDROM); // High density partition
break;
// http://system16.com/hardware.php?id=907
case KnownSystem.SegaEuropaR:
types.Add(MediaType.DVD);
break;
// http://system16.com/hardware.php?id=985
// http://system16.com/hardware.php?id=731
// http://system16.com/hardware.php?id=984
// http://system16.com/hardware.php?id=986
case KnownSystem.SegaLindbergh:
types.Add(MediaType.DVD);
break;
// http://system16.com/hardware.php?id=721
// http://system16.com/hardware.php?id=723
// http://system16.com/hardware.php?id=906
// http://system16.com/hardware.php?id=722
case KnownSystem.SegaNaomi:
types.Add(MediaType.CDROM); // Low density partition
types.Add(MediaType.GDROM); // High density partition
break;
// http://system16.com/hardware.php?id=725
// http://system16.com/hardware.php?id=726
// http://system16.com/hardware.php?id=727
case KnownSystem.SegaNaomi2:
types.Add(MediaType.CDROM); // Low density partition
types.Add(MediaType.GDROM); // High density partition
break;
// http://system16.com/hardware.php?id=975
// https://en.wikipedia.org/wiki/List_of_Sega_arcade_system_boards#Sega_Nu
case KnownSystem.SegaNu:
types.Add(MediaType.BluRay);
break;
// http://system16.com/hardware.php?id=910
// https://en.wikipedia.org/wiki/List_of_Sega_arcade_system_boards#Sega_Ring_series
case KnownSystem.SegaRingEdge:
types.Add(MediaType.DVD);
break;
// http://system16.com/hardware.php?id=982
// https://en.wikipedia.org/wiki/List_of_Sega_arcade_system_boards#Sega_Ring_series
case KnownSystem.SegaRingEdge2:
types.Add(MediaType.DVD);
break;
// http://system16.com/hardware.php?id=911
// https://en.wikipedia.org/wiki/List_of_Sega_arcade_system_boards#Sega_Ring_series
case KnownSystem.SegaRingWide:
types.Add(MediaType.DVD);
break;
// http://system16.com/hardware.php?id=711
case KnownSystem.SegaTitanVideo:
types.Add(MediaType.CDROM);
break;
// http://system16.com/hardware.php?id=709
// http://system16.com/hardware.php?id=710
case KnownSystem.SegaSystem32:
types.Add(MediaType.CDROM);
break;
// https://github.com/mamedev/mame/blob/master/src/mame/drivers/seibucats.cpp
case KnownSystem.SeibuCATSSystem:
types.Add(MediaType.DVD);
break;
// https://www.tab.at/en/support/support/downloads
case KnownSystem.TABAustriaQuizard:
types.Add(MediaType.CDROM);
break;
// https://primetimeamusements.com/product/tsumo-multi-game-motion-system/
// https://www.highwaygames.com/arcade-machines/tsumo-tsunami-motion-8117/
case KnownSystem.TsunamiTsuMoMultiGameMotionSystem:
types.Add(MediaType.CDROM);
break;
#endregion
#region Others
// https://en.wikipedia.org/wiki/Audio_CD
case KnownSystem.AudioCD:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/Blu-ray#Player_profiles
case KnownSystem.BDVideo:
types.Add(MediaType.BluRay);
break;
// https://en.wikipedia.org/wiki/DVD-Video
case KnownSystem.DVDVideo:
types.Add(MediaType.DVD);
break;
// https://en.wikipedia.org/wiki/Blue_Book_(CD_standard)
case KnownSystem.EnhancedCD:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/HD_DVD
case KnownSystem.HDDVDVideo:
types.Add(MediaType.HDDVD);
break;
// UNKNOWN
case KnownSystem.NavisoftNaviken21:
types.Add(MediaType.CDROM);
break;
// UNKNOWN
case KnownSystem.PalmOS:
types.Add(MediaType.CDROM);
break;
// UNKNOWN
case KnownSystem.PhilipsCDiDigitalVideo:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/Photo_CD
case KnownSystem.PhotoCD:
types.Add(MediaType.CDROM);
break;
// UNKNOWN
case KnownSystem.PlayStationGameSharkUpdates:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/Doors_and_Windows_(EP)
case KnownSystem.RainbowDisc:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/Super_Audio_CD
case KnownSystem.SuperAudioCD:
types.Add(MediaType.CDROM);
break;
// https://www.cnet.com/products/tao-music-iktv-karaoke-station-karaoke-system-series/
case KnownSystem.TaoiKTV:
types.Add(MediaType.CDROM);
break;
// http://ultimateconsoledatabase.com/golden/kiss_site.htm
case KnownSystem.TomyKissSite:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/Video_CD
case KnownSystem.VideoCD:
types.Add(MediaType.CDROM);
break;
#endregion
case KnownSystem.NONE:
default:
types.Add(MediaType.NONE);
break;
}
return types;
}
/// <summary>
/// Create a list of systems
/// </summary>
/// <returns>KnownSystems, if possible</returns>
public static List<KnownSystem?> CreateListOfSystems()
{
return Enum.GetValues(typeof(KnownSystem))
.OfType<KnownSystem?>()
.Where(s => !s.IsMarker() && s != KnownSystem.NONE)
.ToList();
}
/// <summary>
/// Create a list of active drives matched to their volume labels
/// </summary>
/// <returns>Active drives, matched to labels, if possible</returns>
/// <remarks>
/// https://stackoverflow.com/questions/3060796/how-to-distinguish-between-usb-and-floppy-devices?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa
/// https://msdn.microsoft.com/en-us/library/aa394173(v=vs.85).aspx
/// </remarks>
public static List<Drive> CreateListOfDrives()
{
// Get all supported drive types
var drives = DriveInfo.GetDrives()
.Where(d => d.DriveType == DriveType.CDRom || d.DriveType == DriveType.Fixed || d.DriveType == DriveType.Removable)
.Select(d => new Drive(Converters.ToInternalDriveType(d.DriveType), d))
.ToList();
// Get the floppy drives and set the flag from removable
try
{
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\\CIMV2",
"SELECT * FROM Win32_LogicalDisk");
var collection = searcher.Get();
foreach (ManagementObject queryObj in collection)
{
uint? mediaType = (uint?)queryObj["MediaType"];
if (mediaType != null && ((mediaType > 0 && mediaType < 11) || (mediaType > 12 && mediaType < 22)))
{
char devId = queryObj["DeviceID"].ToString()[0];
drives.ForEach(d => { if (d.Letter == devId) { d.InternalDriveType = InternalDriveType.Floppy; } });
}
}
}
catch
{
// No-op
}
// Order the drives by drive letter
drives = drives.OrderBy(i => i.Letter).ToList();
return drives;
}
/// <summary>
/// Get the current media type from drive letter
/// </summary>
/// <param name="drive"></param>
/// <returns></returns>
/// <remarks>
/// https://stackoverflow.com/questions/11420365/detecting-if-disc-is-in-dvd-drive
/// </remarks>
public static MediaType? GetMediaType(Drive drive)
{
// Take care of the non-optical stuff first
// TODO: See if any of these can be more granular, like Optical is
if (drive.InternalDriveType == InternalDriveType.Floppy)
return MediaType.FloppyDisk;
else if (drive.InternalDriveType == InternalDriveType.HardDisk)
return MediaType.HardDisk;
else if (drive.InternalDriveType == InternalDriveType.Removable)
return MediaType.FlashDrive;
// Get the DeviceID from the current drive letter
string deviceId = null;
try
{
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\\CIMV2",
"SELECT * FROM Win32_CDROMDrive WHERE Id = '" + drive.Letter + ":\'");
var collection = searcher.Get();
foreach (ManagementObject queryObj in collection)
deviceId = (string)queryObj["DeviceID"];
}
catch
{
// We don't care what the error was
return null;
}
// If we got no valid device, we don't care and just return
if (deviceId == null)
return null;
// Get all relevant disc information
try
{
MsftDiscMaster2 discMaster = new MsftDiscMaster2();
deviceId = deviceId.ToLower().Replace('\\', '#');
string id = null;
foreach (var disc in discMaster)
{
if (disc.ToString().Contains(deviceId))
id = disc.ToString();
}
// If we couldn't find the drive, we don't care and return
if (id == null)
return null;
// Otherwise, we get the media type, if any
MsftDiscRecorder2 recorder = new MsftDiscRecorder2();
recorder.InitializeDiscRecorder(id);
MsftDiscFormat2Data dataWriter = new MsftDiscFormat2Data();
dataWriter.Recorder = recorder;
var media = dataWriter.CurrentPhysicalMediaType;
if (media != IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_UNKNOWN)
return Converters.ToMediaType(media);
}
catch
{
// We don't care what the error is
}
return null;
}
/// <summary>
/// Get the current system from drive
/// </summary>
/// <param name="drive"></param>
/// <returns></returns>
public static KnownSystem? GetKnownSystem(Drive drive)
{
// If drive or drive letter are provided, we can't do anything
if (drive?.Letter == null)
return null;
string drivePath = $"{drive.Letter}:\\";
// If we can't read the media in that drive, we can't do anything
if (!Directory.Exists(drivePath))
return null;
// We're going to assume for floppies, HDDs, and removable drives
// TODO: Try to be smarter about this
if (drive.InternalDriveType != InternalDriveType.Optical)
return KnownSystem.IBMPCCompatible;
// Sega Dreamcast
if (File.Exists(Path.Combine(drivePath, "IP.BIN")))
{
return KnownSystem.SegaDreamcast;
}
// Sega Mega-CD / Sega-CD
if (File.Exists(Path.Combine(drivePath, "_BOOT", "IP.BIN"))
|| File.Exists(Path.Combine(drivePath, "_BOOT", "SP.BIN"))
|| File.Exists(Path.Combine(drivePath, "_BOOT", "SP_AS.BIN"))
|| File.Exists(Path.Combine(drivePath, "FILESYSTEM.BIN")))
{
return KnownSystem.SegaCDMegaCD;
}
// Sony PlayStation and Sony PlayStation 2
if (File.Exists(Path.Combine(drivePath, "SYSTEM.CNF")))
{
// Check for either BOOT or BOOT2
using (StreamReader reader = File.OpenText(Path.Combine(drivePath, "SYSTEM.CNF")))
{
while (!reader.EndOfStream)
{
string line = reader.ReadLine();
if (line.Contains("BOOT2"))
return KnownSystem.SonyPlayStation2;
else if (line.Contains("BOOT"))
return KnownSystem.SonyPlayStation;
}
}
// If we have a weird disc, just assume PS1
return KnownSystem.SonyPlayStation;
}
// Sony PlayStation 4
if (drive.VolumeLabel.Equals("PS4VOLUME", StringComparison.OrdinalIgnoreCase))
{
return KnownSystem.SonyPlayStation4;
}
// V.Tech V.Flash / V.Smile Pro
if (File.Exists(Path.Combine(drivePath, "0SYSTEM")))
{
return KnownSystem.VTechVFlashVSmilePro;
}
// Default return
return KnownSystem.NONE;
}
/// <summary>
/// Verify that, given a system and a media type, they are correct
/// </summary>
public static Result GetSupportStatus(KnownSystem? system, MediaType? type)
{
// No system chosen, update status
if (system == KnownSystem.NONE)
return Result.Failure("Please select a valid system");
// If we're on an unsupported type, update the status accordingly
switch (type)
{
// Fully supported types
case MediaType.BluRay:
case MediaType.CDROM:
case MediaType.DVD:
case MediaType.FloppyDisk:
case MediaType.HardDisk:
case MediaType.CompactFlash:
case MediaType.SDCard:
case MediaType.FlashDrive:
case MediaType.HDDVD:
return Result.Success("{0} ready to dump", type.LongName());
// Partially supported types
case MediaType.GDROM:
case MediaType.NintendoGameCubeGameDisc:
case MediaType.NintendoWiiOpticalDisc:
return Result.Success("{0} partially supported for dumping", type.LongName());
// Special case for other supported tools
case MediaType.UMD:
return Result.Success("{0} supported for submission info parsing", type.LongName());
// Specifically unknown type
case MediaType.NONE:
return Result.Failure("Please select a valid media type");
// Undumpable but recognized types
default:
return Result.Failure("{0} media are not supported for dumping", type.LongName());
}
}
/// <summary>
/// Run protection scan on a given dump environment
/// </summary>
/// <param name="env">DumpEnvirionment containing all required information</param>
/// <returns>Copy protection detected in the envirionment, if any</returns>
public static async Task<string> RunProtectionScanOnPath(string path)
{
try
{
var found = await Task.Run(() =>
{
return ProtectionFind.Scan(path);
});
if (found == null || found.Count == 0)
return "None found";
return string.Join("\n", found.Select(kvp => kvp.Key + ": " + kvp.Value).ToArray());
}
catch (Exception ex)
{
return $"Path could not be scanned! {ex}";
}
}
}
}

View File

@@ -0,0 +1,36 @@
using System;
using System.Net;
namespace DICUI.Web
{
// https://stackoverflow.com/questions/1777221/using-cookiecontainer-with-webclient-class
public class CookieAwareWebClient : WebClient
{
private readonly CookieContainer m_container = new CookieContainer();
protected override WebRequest GetWebRequest(Uri address)
{
WebRequest request = base.GetWebRequest(address);
HttpWebRequest webRequest = request as HttpWebRequest;
if (webRequest != null)
{
webRequest.CookieContainer = m_container;
}
return request;
}
/// <summary>
/// Get the last downloaded filename, if possible
/// </summary>
/// <returns></returns>
public string GetLastFilename()
{
// Try to extract the filename from the Content-Disposition header
if (!string.IsNullOrEmpty(this.ResponseHeaders["Content-Disposition"]))
return this.ResponseHeaders["Content-Disposition"].Substring(this.ResponseHeaders["Content-Disposition"].IndexOf("filename=") + 9).Replace("\"", "");
return null;
}
}
}

View File

@@ -0,0 +1,385 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using DICUI.Data;
using DICUI.Utilities;
namespace DICUI.Web
{
public class RedumpAccess
{
#region Base URLs
private const string loginUrl = "http://forum.redump.org/login/";
#endregion
#region Disc URLs and Extensions
private const string discPageUrl = @"http://redump.org/disc/{0}/";
private const string wipDiscPageUrl = @"http://redump.org/newdisc/{0}/";
private const string changesExt = "/changes/";
private const string cueExt = "cue/";
private const string gdiExt = "gdi/";
private const string keyExt = "key/";
private const string md5Ext = "md5/";
private const string sbiExt = "sbi/";
private const string sfvExt = "sfv/";
private const string sha1Ext = "sha1/";
#endregion
#region List URLs
private const string lastModifiedUrl = @"http://redump.org/discs/sort/modified/dir/desc?page={0}";
private const string quickSearchUrl = @"http://redump.org/discs/quicksearch/{0}/?page={1}";
private const string userDumpsUrl = @"http://redump.org/discs/dumper/{0}/?page={1}";
private const string wipDumpsUrl = @"http://redump.org/discs-wip/";
#endregion
#region Pack URLs
private const string packCuesUrl = @"http://redump.org/cues/{0}/";
private const string packDatfileUrl = @"http://redump.org/datfile/{0}/";
private const string packDkeysUrl = @"http://redump.org/dkeys/{0}/";
private const string packGdiUrl = @"http://redump.org/gdi/{0}/";
private const string packKeysUrl = @"http://redump.org/keys/{0}/";
private const string packSbiUrl = @"http://redump.org/sbi/{0}/";
#endregion
#region Regexes
private readonly Regex discRegex = new Regex(@"<a href=""/disc/(\d+)/"">");
private readonly Regex newDiscRegex = new Regex(@"<a href=""/newdisc/(\d+)/"">");
private readonly Regex tokenRegex = new Regex(@"<input type=""hidden"" name=""csrf_token"" value=""(.*?)"" />");
#endregion
/// <summary>
/// Login to Redump, if possible
/// </summary>
/// <param name="wc">CookieAwareWebClient to hold the login state</param>
/// <param name="username">Redump username to log in for protected systems</param>
/// <param name="password">Redump password to log in for protected systems</param>
/// <returns>True login was successful, false otherwise</returns>
public bool RedumpLogin(CookieAwareWebClient wc, string username, string password)
{
if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password))
return false;
var loginPage = wc.DownloadString(loginUrl);
string token = this.tokenRegex.Match(loginPage).Groups[1].Value;
wc.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
wc.Encoding = Encoding.UTF8;
var response = wc.UploadString(loginUrl, $"form_sent=1&redirect_url=&csrf_token={token}&req_username={username}&req_password={password}&save_pass=0");
if (response.Contains("Incorrect username and/or password."))
return false;
else
return true;
}
#region Process IDs and Pages
/// <summary>
/// Get the list of the last modified IDs, in order of appearance
/// </summary>
/// <param name="wc">CookieAwareWebClient to hold the login state</param>
/// <param name="pageCount">Number of pages to grab until stopping; -1 means continue until end</param>
/// <returns>A list of IDs in order of last modified</returns>
private List<int> ProcessLastModified(CookieAwareWebClient wc, int pageCount = -1)
{
List<int> ids = new List<int>();
// If we have a -1 page count, set the maximum page limit
if (pageCount == -1)
pageCount = Int32.MaxValue;
// Keep getting last modified pages until there are none left
int pageNumber = 1;
while (pageNumber < pageCount)
{
List<int> pageIds = CheckSingleSitePage(wc, string.Format(lastModifiedUrl, pageNumber++));
ids.AddRange(pageIds);
if (pageIds.Count < 2)
break;
}
return ids;
}
/// <summary>
/// Retrieve premade packs from Redump
/// </summary>
/// <param name="wc">CookieAwareWebClient to hold the login state</param>
private void ProcessAllPacks(CookieAwareWebClient wc)
{
var cuesPacks = this.DownloadPacks(wc, packCuesUrl, Extensions.HasCues, "CUEs");
var datPacks = this.DownloadPacks(wc, packDatfileUrl, Extensions.HasDat, "DATs");
var dkeyPacks = this.DownloadPacks(wc, packDkeysUrl, Extensions.HasDkeys, "Decrypted KEYS");
var gdiPacks = this.DownloadPacks(wc, packGdiUrl, Extensions.HasGdi, "GDIs");
var keysPacks = this.DownloadPacks(wc, packKeysUrl, Extensions.HasKeys, "KEYS");
var sbiPacks = this.DownloadPacks(wc, packSbiUrl, Extensions.HasSbi, "SBIs");
}
/// <summary>
/// Retrieve premade packs from Redump
/// </summary>
/// <param name="wc">CookieAwareWebClient to hold the login state</param>
/// <param name="system">RedumpSystem to get all possible packs for</param>
private void ProcessPacksForSystem(CookieAwareWebClient wc, RedumpSystem system)
{
var packs = new Dictionary<string, byte[]>();
if (Extensions.HasCues.Contains(system))
packs.Add("cues", this.DownloadPack(wc, packCuesUrl, system, "CUEs"));
if (Extensions.HasDat.Contains(system))
packs.Add("dat", this.DownloadPack(wc, packDatfileUrl, system, "DATs"));
if (Extensions.HasDkeys.Contains(system))
packs.Add("dkeys", this.DownloadPack(wc, packDkeysUrl, system, "Decrypted KEYS"));
if (Extensions.HasGdi.Contains(system))
packs.Add("gdi", this.DownloadPack(wc, packGdiUrl, system, "GDIs"));
if (Extensions.HasKeys.Contains(system))
packs.Add("keys", this.DownloadPack(wc, packKeysUrl, system, "KEYS"));
if (Extensions.HasSbi.Contains(system))
packs.Add("sbi", this.DownloadPack(wc, packSbiUrl, system, "SBIs"));
}
/// <summary>
/// Get the list of IDs that associate with a given string
/// </summary>
/// <param name="wc">CookieAwareWebClient to hold the login state</param>
/// <param name="query">Value to search for in Redump</param>
/// <returns>A list of IDs associated with that value</returns>
public List<int> ProcessSearch(CookieAwareWebClient wc, string query)
{
List<int> ids = new List<int>();
// Keep getting quicksearch pages until there are none left
int pageNumber = 1;
while (true)
{
List<int> pageIds = CheckSingleSitePage(wc, string.Format(quickSearchUrl, query, pageNumber++));
ids.AddRange(pageIds);
if (pageIds.Count < 2)
break;
}
return ids;
}
/// <summary>
/// Get the list of IDs associated with the given user
/// </summary>
/// <param name="wc">CookieAwareWebClient to hold the login state</param>
/// <param name="username">Redump username to get the list of IDs for</param>
/// <returns>A list of IDs associated with that user</returns>
private List<int> ProcessUser(CookieAwareWebClient wc, string username)
{
List<int> ids = new List<int>();
// Keep getting user pages until there are none left
int pageNumber = 1;
while (true)
{
List<int> pageIds = CheckSingleSitePage(wc, string.Format(userDumpsUrl, username, pageNumber++));
ids.AddRange(pageIds);
if (pageIds.Count < 2)
break;
}
return ids;
}
#endregion
#region Single item processing
/// <summary>
/// Process a Redump site page as a list of possible IDs or disc page
/// </summary>
/// <param name="wc">CookieAwareWebClient to access the pages</param>
/// <param name="url">Page URL to check and parse</param>
/// <returns>List of matching IDs</returns>
private List<int> CheckSingleSitePage(CookieAwareWebClient wc, string url)
{
List<int> ids = new List<int>();
var dumpsPage = wc.DownloadString(url);
// If we have no dumps left
if (dumpsPage.Contains("No discs found."))
return ids;
// If we have a single disc page already
if (dumpsPage.Contains("<b>Download:</b>"))
{
var value = Regex.Match(dumpsPage, @"/disc/(\d+)/sfv/").Groups[1].Value;
if (Int32.TryParse(value, out int id))
ids.Add(id);
return ids;
}
// Otherwise, traverse each dump on the page
var matches = discRegex.Matches(dumpsPage);
foreach (Match match in matches)
{
try
{
if (Int32.TryParse(match.Groups[1].Value, out int value))
ids.Add(value);
}
catch (Exception ex)
{
Console.WriteLine($"An exception has occurred: {ex}");
continue;
}
}
return ids;
}
/// <summary>
/// Process a Redump WIP page as a list of possible IDs or disc page
/// </summary>
/// <param name="wc">CookieAwareWebClient to access the pages</param>
/// <param name="url">Page URL to check and parse</param>
/// <returns>List of matching IDs</returns>
private List<int> CheckSingleWIPPage(CookieAwareWebClient wc, string url)
{
List<int> ids = new List<int>();
var wipDumpsPage = wc.DownloadString(url);
// If we have no WIP dumps left
if (wipDumpsPage.Contains("No WIP discs found."))
return ids;
// Otherwise, traverse each dump on the page
var matches = newDiscRegex.Matches(wipDumpsPage);
foreach (Match match in matches)
{
try
{
if (Int32.TryParse(match.Groups[1].Value, out int value))
ids.Add(value);
}
catch (Exception ex)
{
Console.WriteLine($"An exception has occurred: {ex}");
continue;
}
}
return ids;
}
/// <summary>
/// Download an individual pack
/// </summary>
/// <param name="wc">CookieAwareWebClient to access the packs</param>
/// <param name="url">Base URL to download using</param>
/// <param name="system">System to download packs for</param>
/// <param name="title">Name of the pack that is downloading</param>
private byte[] DownloadPack(CookieAwareWebClient wc, string url, RedumpSystem system, string title)
{
Console.WriteLine($"Downloading {title}");
Console.Write($"\r{system.LongName()}{new string(' ', Console.BufferWidth - system.LongName().Length - 1)}");
var pack = wc.DownloadData(string.Format(url, system.ShortName()));
Console.Write($"\rComplete!{new string(' ', Console.BufferWidth - 10)}");
Console.WriteLine();
return pack;
}
/// <summary>
/// Download a set of packs
/// </summary>
/// <param name="wc">CookieAwareWebClient to access the packs</param>
/// <param name="url">Base URL to download using</param>
/// <param name="systems">List of systems to download packs for</param>
/// <param name="title">Name of the pack that is downloading</param>
private Dictionary<RedumpSystem, byte[]> DownloadPacks(CookieAwareWebClient wc, string url, RedumpSystem[] systems, string title)
{
var dict = new Dictionary<RedumpSystem, byte[]>();
Console.WriteLine($"Downloading {title}");
foreach (var system in systems)
{
Console.Write($"\r{system.LongName()}{new string(' ', Console.BufferWidth - system.LongName().Length - 1)}");
dict.Add(system, wc.DownloadData(string.Format(url, system.ShortName())));
}
Console.Write($"\rComplete!{new string(' ', Console.BufferWidth - 10)}");
Console.WriteLine();
return dict;
}
/// <summary>
/// Download an individual site ID page as a string, if possible
/// </summary>
/// <param name="wc">CookieAwareWebClient to access the pages</param>
/// <param name="id">Redump disc ID to retrieve</param>
/// <returns>Disc page as a string, null on error</returns>
public string DownloadSingleSiteID(CookieAwareWebClient wc, int id)
{
string paddedId = id.ToString().PadLeft(5, '0');
Console.WriteLine($"Processing ID: {paddedId}");
try
{
string discPage = wc.DownloadString(string.Format(discPageUrl, +id));
if (discPage.Contains($"Disc with ID \"{id}\" doesn't exist"))
return null;
else
return discPage;
}
catch (Exception ex)
{
Console.WriteLine($"An exception has occurred: {ex}");
return null;
}
}
/// <summary>
/// Download an individual WIP ID page as a string, if possible
/// </summary>
/// <param name="wc">CookieAwareWebClient to access the pages</param>
/// <param name="id">Redump disc ID to retrieve</param>
/// <returns>WIP disc page as a string, null on error</returns>
private string DownloadSingleWIPID(CookieAwareWebClient wc, int id)
{
string paddedId = id.ToString().PadLeft(5, '0');
Console.WriteLine($"Processing WIP ID: {paddedId}");
try
{
string discPage = wc.DownloadString(string.Format(wipDiscPageUrl, +id));
if (discPage.Contains($"WIP Disc with ID \"{id}\" doesn't exist"))
return null;
else
return discPage;
}
catch (Exception ex)
{
Console.WriteLine($"An exception has occurred: {ex}");
return null;
}
}
#endregion
}
}

View File

@@ -0,0 +1,33 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net462;net472;netcoreapp3.0</TargetFrameworks>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\DICUI.Library\DICUI.Library.csproj">
<Project>{51ab0928-13f9-44bf-a407-b6957a43a056}</Project>
<Name>DICUI.Library</Name>
</ProjectReference>
<ProjectReference Include="..\DICUI\DICUI.csproj">
<Project>{7b1b75eb-8940-466f-bd51-76471a57f9be}</Project>
<Name>DICUI</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeCoverage" Version="16.3.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.3.0" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.abstractions" Version="2.0.3" />
<PackageReference Include="xunit.analyzers" Version="0.10.0" />
<PackageReference Include="xunit.assert" Version="2.4.1" />
<PackageReference Include="xunit.core" Version="2.4.1" />
<PackageReference Include="xunit.extensibility.core" Version="2.4.1" />
<PackageReference Include="xunit.extensibility.execution" Version="2.4.1" />
<PackageReference Include="xunit.runner.console" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1" />
</ItemGroup>
</Project>

40
DICUI.Test/ResultTest.cs Normal file
View File

@@ -0,0 +1,40 @@
using DICUI.Utilities;
using Xunit;
namespace DICUI.Test
{
public class ResultTest
{
[Fact]
public void ResultSuccessTest()
{
Result actual = Result.Success();
Assert.Empty(actual.Message);
string message = "Success!";
actual = Result.Success(message);
Assert.Equal(message, actual.Message);
message = "Success! {0}";
string parameter = "Parameter";
actual = Result.Success(message, parameter);
Assert.Equal(string.Format(message, parameter), actual.Message);
}
[Fact]
public void ResultFailureTest()
{
Result actual = Result.Failure();
Assert.Empty(actual.Message);
string message = "Failure!";
actual = Result.Failure(message);
Assert.Equal(message, actual.Message);
message = "Failure! {0}";
string parameter = "Parameter";
actual = Result.Failure(message, parameter);
Assert.Equal(string.Format(message, parameter), actual.Message);
}
}
}

View File

@@ -0,0 +1,21 @@
using System.Linq;
using DICUI.Data;
using Xunit;
namespace DICUI.Test.Data
{
public class UIElementsTest
{
[Theory]
[InlineData(MediaType.CDROM, 72)]
[InlineData(MediaType.DVD, 24)]
[InlineData(MediaType.BluRay, 16)]
[InlineData(MediaType.LaserDisc, 72)] // TODO: Update when fully determined
[InlineData(null, 72)] // TODO: Update when fully determined
public void GetAllowedDriveSpeedForMediaTypeTest(MediaType? mediaType, int maxExpected)
{
var actual = Constants.GetSpeedsForMediaType(mediaType);
Assert.Equal(maxExpected, actual.Last());
}
}
}

View File

@@ -0,0 +1,129 @@
using System;
using DICUI.Data;
using DICUI.Utilities;
using Xunit;
namespace DICUI.Test.Utilities
{
public class ConvertersTest
{
[Theory]
[InlineData(DICCommand.Audio, MediaType.CDROM)]
[InlineData(DICCommand.BluRay, MediaType.BluRay)]
[InlineData(DICCommand.Close, null)]
[InlineData(DICCommand.CompactDisc, MediaType.CDROM)]
[InlineData(DICCommand.Data, MediaType.CDROM)]
[InlineData(DICCommand.DigitalVideoDisc, MediaType.DVD)]
[InlineData(DICCommand.Eject, null)]
[InlineData(DICCommand.Floppy, MediaType.FloppyDisk)]
[InlineData(DICCommand.GDROM, MediaType.GDROM)]
[InlineData(DICCommand.MDS, null)]
[InlineData(DICCommand.Reset, null)]
[InlineData(DICCommand.SACD, MediaType.CDROM)]
[InlineData(DICCommand.Start, null)]
[InlineData(DICCommand.Stop, null)]
[InlineData(DICCommand.Sub, null)]
[InlineData(DICCommand.Swap, MediaType.GDROM)]
[InlineData(DICCommand.XBOX, MediaType.DVD)]
public void BaseCommandToMediaTypeTest(DICCommand command, MediaType? expected)
{
MediaType? actual = command.ToMediaType();
Assert.Equal(expected, actual);
}
[Theory]
[InlineData(DICCommand.Audio, KnownSystem.AudioCD)]
[InlineData(DICCommand.BluRay, KnownSystem.SonyPlayStation3)]
[InlineData(DICCommand.Close, null)]
[InlineData(DICCommand.CompactDisc, KnownSystem.IBMPCCompatible)]
[InlineData(DICCommand.Data, KnownSystem.IBMPCCompatible)]
[InlineData(DICCommand.DigitalVideoDisc, KnownSystem.IBMPCCompatible)]
[InlineData(DICCommand.Eject, null)]
[InlineData(DICCommand.Floppy, KnownSystem.IBMPCCompatible)]
[InlineData(DICCommand.GDROM, KnownSystem.SegaDreamcast)]
[InlineData(DICCommand.MDS, null)]
[InlineData(DICCommand.Reset, null)]
[InlineData(DICCommand.SACD, KnownSystem.SuperAudioCD)]
[InlineData(DICCommand.Start, null)]
[InlineData(DICCommand.Stop, null)]
[InlineData(DICCommand.Sub, null)]
[InlineData(DICCommand.Swap, KnownSystem.SegaDreamcast)]
[InlineData(DICCommand.XBOX, KnownSystem.MicrosoftXBOX)]
public void BaseCommandToKnownSystemTest(DICCommand command, KnownSystem? expected)
{
KnownSystem? actual = Converters.ToKnownSystem(command);
Assert.Equal(expected, actual);
}
[Theory]
[InlineData(MediaType.CDROM, ".bin")]
[InlineData(MediaType.DVD, ".iso")]
[InlineData(MediaType.LaserDisc, ".raw")]
[InlineData(MediaType.NintendoWiiUOpticalDisc, ".wud")]
[InlineData(MediaType.FloppyDisk, ".img")]
[InlineData(MediaType.Cassette, ".wav")]
[InlineData(MediaType.NONE, null)]
public void MediaTypeToExtensionTest(MediaType? mediaType, string expected)
{
string actual = Converters.Extension(mediaType);
Assert.Equal(expected, actual);
}
[Theory]
[InlineData(MediaType.CDROM, "CD-ROM")]
[InlineData(MediaType.LaserDisc, "LD-ROM / LV-ROM")]
[InlineData(MediaType.NONE, "Unknown")]
public void MediaTypeToStringTest(MediaType? mediaType, string expected)
{
string actual = Converters.LongName(mediaType);
Assert.Equal(expected, actual);
}
[Theory]
[InlineData(KnownSystem.MicrosoftXBOX, "Microsoft XBOX")]
[InlineData(KnownSystem.NECPC88, "NEC PC-88")]
[InlineData(KnownSystem.KonamiPython, "Konami Python")]
[InlineData(KnownSystem.HDDVDVideo, "HD-DVD-Video")]
[InlineData(KnownSystem.NONE, "Unknown")]
public void KnownSystemToStringTest(KnownSystem? knownSystem, string expected)
{
string actual = Converters.LongName(knownSystem);
Assert.Equal(expected, actual);
}
[Fact]
public void KnownSystemHasValidCategory()
{
var values = Validators.CreateListOfSystems();
KnownSystem[] markers = { KnownSystem.MarkerArcadeEnd, KnownSystem.MarkerDiscBasedConsoleEnd, /* KnownSystem.MarkerOtherConsoleEnd, */ KnownSystem.MarkerComputerEnd, KnownSystem.MarkerOtherEnd };
values.ForEach(system => {
if (system == KnownSystem.NONE)
return;
// we check that the category is the first category value higher than the system
KnownSystemCategory category = ((KnownSystem?)system).Category();
KnownSystem marker = KnownSystem.NONE;
switch (category)
{
case KnownSystemCategory.Arcade: marker = KnownSystem.MarkerArcadeEnd; break;
case KnownSystemCategory.DiscBasedConsole: marker = KnownSystem.MarkerDiscBasedConsoleEnd; break;
/* case KnownSystemCategory.OtherConsole: marker = KnownSystem.MarkerOtherConsoleEnd; break; */
case KnownSystemCategory.Computer: marker = KnownSystem.MarkerComputerEnd; break;
case KnownSystemCategory.Other: marker = KnownSystem.MarkerOtherEnd; break;
}
Assert.NotEqual(KnownSystem.NONE, marker);
Assert.True(marker > system);
Array.ForEach(markers, mmarker =>
{
// a marker can be the same of the found one, or one of a category before or a category after but never in the middle between
// the system and the mapped category
Assert.True(mmarker == marker || mmarker < system || mmarker > marker);
});
});
}
}
}

View File

@@ -0,0 +1,96 @@
using System.IO;
using DICUI.Data;
using DICUI.Utilities;
using Xunit;
namespace DICUI.Test
{
public class DumpEnvironmentTest
{
[Theory]
[InlineData(null, 'D', false, MediaType.NONE, false)]
[InlineData("", 'D', false, MediaType.NONE, false)]
[InlineData("cd F test.bin 8 /c2 20", 'F', false, MediaType.CDROM, true)]
[InlineData("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)
{
var env = new DumpEnvironment
{
DICParameters = new Parameters(parameters),
Drive = isFloppy
? new Drive(InternalDriveType.Floppy, new DriveInfo(letter.ToString()))
: new Drive(InternalDriveType.Optical, new DriveInfo(letter.ToString())),
Type = mediaType,
};
bool actual = env.ParametersValid();
Assert.Equal(expected, actual);
}
[Theory]
[InlineData(null, null, null, null)]
[InlineData(" ", "", " ", "")]
[InlineData("super", "blah.bin", "super", "blah.bin")]
[InlineData("super\\hero", "blah.bin", "super\\hero", "blah.bin")]
[InlineData("super.hero", "blah.bin", "super.hero", "blah.bin")]
[InlineData("superhero", "blah.rev.bin", "superhero", "blah.rev.bin")]
[InlineData("super&hero", "blah.bin", "super_hero", "blah.bin")]
[InlineData("superhero", "blah&foo.bin", "superhero", "blah_foo.bin")]
public void FixOutputPathsTest(string outputDirectory, string outputFilename, string expectedOutputDirectory, string expectedOutputFilename)
{
var env = new DumpEnvironment
{
OutputDirectory = outputDirectory,
OutputFilename = outputFilename,
};
env.FixOutputPaths();
Assert.Equal(expectedOutputDirectory, env.OutputDirectory);
Assert.Equal(expectedOutputFilename, env.OutputFilename);
}
[Fact]
public void GetFirstTrackTest()
{
// TODO: Implement
Assert.True(true);
}
[Fact]
public void FormatOutputDataTest()
{
// TODO: Implement
Assert.True(true);
}
[Fact]
public void WriteOutputDataTest()
{
// TODO: Implement
Assert.True(true);
}
[Fact]
public void EjectDiscTest()
{
// TODO: Implement
Assert.True(true);
}
[Fact]
public void CancelDumpingTest()
{
// TODO: Implement
Assert.True(true);
}
[Fact]
public void StartDumpingTest()
{
// TODO: Implement
Assert.True(true);
}
}
}

View File

@@ -0,0 +1,37 @@
using System;
using DICUI.Data;
using DICUI.Utilities;
using Xunit;
namespace DICUI.Test.Utilities
{
public class KnownSystemExtensionsTest
{
[Fact]
public void IsMarkerTest()
{
var values = (KnownSystem[])Enum.GetValues(typeof(KnownSystem));
foreach(var system in values)
{
bool expected = system == KnownSystem.MarkerArcadeEnd || system == KnownSystem.MarkerComputerEnd ||
system == KnownSystem.MarkerOtherEnd || system == KnownSystem.MarkerDiscBasedConsoleEnd;
// || system == KnownSystem.MarkerOtherConsoleEnd;
bool actual = ((KnownSystem?)system).IsMarker();
Assert.Equal(expected, actual);
}
}
[Fact]
public void CategoryNameNotEmptyTest()
{
var values = (KnownSystemCategory[])Enum.GetValues(typeof(KnownSystemCategory));
foreach (var system in values)
{
string actual = ((KnownSystem?)system).LongName();
Assert.NotEqual("", actual);
}
}
}
}

View File

@@ -0,0 +1,46 @@
using DICUI.Data;
using DICUI.Utilities;
using Xunit;
namespace DICUI.Test.Utilities
{
public class MediaTypeExtensionsTest
{
[Theory]
[InlineData(MediaType.CDROM, "CD-ROM")]
[InlineData(MediaType.LaserDisc, "LD-ROM / LV-ROM")]
[InlineData(MediaType.NONE, "Unknown")]
public void NameTest(MediaType? mediaType, string expected)
{
string actual = mediaType.LongName();
Assert.NotNull(actual);
Assert.Equal(expected, actual);
}
[Theory]
[InlineData(MediaType.CDROM, ".bin")]
[InlineData(MediaType.DVD, ".iso")]
[InlineData(MediaType.LaserDisc, ".raw")]
[InlineData(MediaType.FloppyDisk, ".img")]
[InlineData(MediaType.NONE, null)]
public void ExtensionTest(MediaType? mediaType, string expected)
{
string actual = mediaType.Extension();
Assert.Equal(expected, actual);
}
[Theory]
[InlineData(MediaType.CDROM, true)]
[InlineData(MediaType.DVD, true)]
[InlineData(MediaType.FloppyDisk, false)]
[InlineData(MediaType.BluRay, true)]
[InlineData(MediaType.LaserDisc, false)]
public void DriveSpeedSupportedTest(MediaType? mediaType, bool expected)
{
bool actual = mediaType.DoesSupportDriveSpeed();
Assert.Equal(expected, actual);
}
}
}

View File

@@ -0,0 +1,85 @@
using System.Collections.Generic;
using System.Linq;
using DICUI.Data;
using DICUI.Utilities;
using Xunit;
namespace DICUI.Test.Utilities
{
public class ParametersTest
{
[Theory]
[InlineData(KnownSystem.MicrosoftXBOX, MediaType.CDROM, DICCommand.CompactDisc)]
[InlineData(KnownSystem.MicrosoftXBOX, MediaType.DVD, DICCommand.XBOX)]
[InlineData(KnownSystem.MicrosoftXBOX, MediaType.LaserDisc, DICCommand.NONE)]
[InlineData(KnownSystem.SegaNu, MediaType.BluRay, DICCommand.BluRay)]
[InlineData(KnownSystem.AppleMacintosh, MediaType.FloppyDisk, DICCommand.Floppy)]
[InlineData(KnownSystem.RawThrillsVarious, MediaType.GDROM, DICCommand.NONE)]
public void ParametersFromSystemAndTypeTest(KnownSystem? knownSystem, MediaType? mediaType, DICCommand expected)
{
Parameters actual = new Parameters(knownSystem, mediaType, 'D', "disc.bin", 16, true, -1);
Assert.Equal(expected, actual.Command);
}
[Theory]
[InlineData(KnownSystem.AppleMacintosh, MediaType.LaserDisc, true, 20, null, null)]
[InlineData(KnownSystem.NintendoGameCube, MediaType.NintendoGameCubeGameDisc, false, 20, null, new DICFlag[] { DICFlag.Raw })]
[InlineData(KnownSystem.IBMPCCompatible, MediaType.DVD, false, 20, null, new DICFlag[] { })]
/* paranoid mode tests */
[InlineData(KnownSystem.IBMPCCompatible, MediaType.CDROM, true, 1000, 2, new DICFlag[] { DICFlag.C2Opcode, DICFlag.NoFixSubQSecuROM, DICFlag.ScanFileProtect, DICFlag.ScanSectorProtect, DICFlag.SubchannelReadLevel })]
[InlineData(KnownSystem.AppleMacintosh, MediaType.CDROM, false, 20, null, new DICFlag[] { DICFlag.C2Opcode, DICFlag.NoFixSubQSecuROM, DICFlag.ScanFileProtect })]
[InlineData(KnownSystem.IBMPCCompatible, MediaType.DVD, true, 500, null, new DICFlag[] { DICFlag.CopyrightManagementInformation, DICFlag.ScanFileProtect })]
[InlineData(KnownSystem.HDDVDVideo, MediaType.HDDVD, true, 500, null, new DICFlag[] { DICFlag.CopyrightManagementInformation })]
[InlineData(KnownSystem.IBMPCCompatible, MediaType.DVD, false, 500, null, new DICFlag[] { })]
[InlineData(KnownSystem.HDDVDVideo, MediaType.HDDVD, false, 500, null, new DICFlag[] { })]
/* reread c2 */
[InlineData(KnownSystem.SegaDreamcast, MediaType.GDROM, false, 1000, null, new DICFlag[] { DICFlag.C2Opcode })]
[InlineData(KnownSystem.SegaDreamcast, MediaType.GDROM, false, -1, null, new DICFlag[] { DICFlag.C2Opcode })]
public void ParametersFromOptionsTest(KnownSystem? knownSystem, MediaType? mediaType, bool paranoid, int rereadC2, int? subchannelLevel, DICFlag[] expected)
{
Parameters actual = new Parameters(knownSystem, mediaType, 'D', "disc.bin", 16, paranoid, rereadC2);
HashSet<DICFlag> expectedSet = new HashSet<DICFlag>(expected ?? new DICFlag[0]);
HashSet<DICFlag> actualSet = new HashSet<DICFlag>(actual.Keys ?? new DICFlag[0]);
Assert.Equal(expectedSet, actualSet);
if (rereadC2 == -1 || !Validators.GetValidMediaTypes(knownSystem).Contains(mediaType))
Assert.Null(actual.C2OpcodeValue[0]);
else
Assert.Equal(rereadC2, actual.C2OpcodeValue[0]);
Assert.Equal(subchannelLevel, actual.SubchannelReadLevelValue);
}
[Theory]
[InlineData(null, null, null, null, null)]
[InlineData("", null, null, null, null)]
[InlineData("cd F test.bin 8 /c2 20", MediaType.CDROM, KnownSystem.IBMPCCompatible, "F", "test.bin")]
[InlineData("fd A blah\\test.img", MediaType.FloppyDisk, KnownSystem.IBMPCCompatible, "A", "blah\\test.img")]
[InlineData("dvd X super\\blah\\test.iso 8 /raw", MediaType.NintendoGameCubeGameDisc, KnownSystem.NintendoGameCube, "X", "super\\blah\\test.iso")]
[InlineData("stop D", null, null, "D", null)]
public void DetermineFlagsTest(string parameters, MediaType? expectedMediaType, KnownSystem? expectedKnownSystem, string expectedDriveLetter, string expectedPath)
{
Parameters actualParams = new Parameters(parameters);
bool actual = actualParams.DetermineFlags(out MediaType? actualMediaType, out KnownSystem? actualKnownSystem, out string actualDriveLetter, out string actualPath);
Assert.Equal(expectedMediaType, actualMediaType);
Assert.Equal(expectedKnownSystem, actualKnownSystem);
Assert.Equal(expectedDriveLetter, actualDriveLetter);
Assert.Equal(expectedPath, actualPath);
}
[Theory]
[InlineData(null, false)]
[InlineData("", false)]
[InlineData("cd F test.bin 8 /c2 20", true)]
[InlineData("fd A test.img", true)]
[InlineData("dvd X super\\test.iso 8 /raw", true)]
[InlineData("bd D longer\\path_test.iso 16", true)]
[InlineData("stop D", true)]
[InlineData("ls", false)]
public void ValidateParametersTest(string parameters, bool expected)
{
Parameters actual = new Parameters(parameters);
Assert.Equal(expected, actual.IsValid());
}
}
}

View File

@@ -0,0 +1,45 @@
using System;
using DICUI.Data;
using DICUI.Utilities;
using Xunit;
namespace DICUI.Test.Utilities
{
public class ValidatorsTest
{
[Theory]
[InlineData(KnownSystem.BandaiApplePippin, MediaType.CDROM)]
[InlineData(KnownSystem.MicrosoftXBOX, MediaType.DVD)]
[InlineData(KnownSystem.NintendoGameCube, MediaType.NintendoGameCubeGameDisc)]
[InlineData(KnownSystem.NintendoWii, MediaType.NintendoWiiOpticalDisc)]
[InlineData(KnownSystem.NintendoWiiU, MediaType.NintendoWiiUOpticalDisc)]
[InlineData(KnownSystem.SonyPlayStationPortable, MediaType.UMD)]
public void GetValidMediaTypesTest(KnownSystem? knownSystem, MediaType? expected)
{
var actual = Validators.GetValidMediaTypes(knownSystem);
Assert.Contains(expected, actual);
}
[Fact]
public void CreateListOfSystemsTest()
{
int expected = Enum.GetValues(typeof(KnownSystem)).Length - 5; // - 4 -1 for markers categories and KnownSystem.NONE
var actual = Validators.CreateListOfSystems();
Assert.Equal(expected, actual.Count);
}
[Fact]
public void CreateListOfDrivesTest()
{
// TODO: Implement
Assert.True(true);
}
[Fact]
public void GetDiscTypeTest()
{
// TODO: Implement
Assert.True(true);
}
}
}

View File

@@ -1,167 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{7B1B75EB-8940-466F-BD51-76471A57F9BE}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>DICUI</RootNamespace>
<AssemblyName>DICUI</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<WarningLevel>4</WarningLevel>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<IsWebBootstrapper>false</IsWebBootstrapper>
<PublishUrl>C:\Users\admin\Desktop\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>1</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<UseApplicationTrust>false</UseApplicationTrust>
<PublishWizardCompleted>true</PublishWizardCompleted>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>x86</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>Icon.ico</ApplicationIcon>
</PropertyGroup>
<PropertyGroup>
<ManifestCertificateThumbprint>654CEE5FEAF46C8C1C369D7ED34DA157828A8D2F</ManifestCertificateThumbprint>
</PropertyGroup>
<PropertyGroup>
<ManifestKeyFile>WpfApp1_TemporaryKey.pfx</ManifestKeyFile>
</PropertyGroup>
<PropertyGroup>
<GenerateManifests>true</GenerateManifests>
</PropertyGroup>
<PropertyGroup>
<SignManifests>false</SignManifests>
</PropertyGroup>
<PropertyGroup />
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Data" />
<Reference Include="System.Management" />
<Reference Include="System.Management.Instrumentation" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xaml">
<RequiredTargetFramework>4.0</RequiredTargetFramework>
</Reference>
<Reference Include="WindowsBase" />
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
</ItemGroup>
<ItemGroup>
<ApplicationDefinition Include="App.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Compile Include="Data\Constants.cs" />
<Compile Include="External\OrderedDictionary.cs" />
<Compile Include="External\IOrderedDictionary.cs" />
<Compile Include="Options.cs" />
<Compile Include="Tasks.cs" />
<Compile Include="Utilities\DumpInformation.cs" />
<Compile Include="Utilities\Validators.cs" />
<Compile Include="Utilities\Converters.cs" />
<Compile Include="OptionsWindow.xaml.cs">
<DependentUpon>OptionsWindow.xaml</DependentUpon>
</Compile>
<Page Include="MainWindow.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Compile Include="App.xaml.cs">
<DependentUpon>App.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="Data\Enumerations.cs" />
<Compile Include="MainWindow.xaml.cs">
<DependentUpon>MainWindow.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Page Include="OptionsWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs">
<SubType>Code</SubType>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include=".NETFramework,Version=v4.6.1">
<Visible>False</Visible>
<ProductName>Microsoft .NET Framework 4.6.1 %28x86 and x64%29</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>false</Install>
</BootstrapperPackage>
</ItemGroup>
<ItemGroup>
<Resource Include="Icon.ico" />
</ItemGroup>
<ItemGroup>
<COMReference Include="IMAPI2">
<Guid>{2735412F-7F64-5B0F-8F00-5D77AFBE261E}</Guid>
<VersionMajor>1</VersionMajor>
<VersionMinor>0</VersionMinor>
<Lcid>0</Lcid>
<WrapperTool>tlbimp</WrapperTool>
<Isolated>False</Isolated>
<EmbedInteropTypes>True</EmbedInteropTypes>
</COMReference>
<COMReference Include="IMAPI2FS">
<Guid>{2C941FD0-975B-59BE-A960-9A2A262853A5}</Guid>
<VersionMajor>1</VersionMajor>
<VersionMinor>0</VersionMinor>
<Lcid>0</Lcid>
<WrapperTool>tlbimp</WrapperTool>
<Isolated>False</Isolated>
<EmbedInteropTypes>True</EmbedInteropTypes>
</COMReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@@ -1,9 +1,22 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27130.2036
# Visual Studio Version 16
VisualStudioVersion = 16.0.28803.156
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DICUI", "DICUI.csproj", "{7B1B75EB-8940-466F-BD51-76471A57F9BE}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DICUI", "DICUI\DICUI.csproj", "{7B1B75EB-8940-466F-BD51-76471A57F9BE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DICUI.Test", "DICUI.Test\DICUI.Test.csproj", "{7CC064D2-38AB-4A05-8519-28660DE4562A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DICUI.Library", "DICUI.Library\DICUI.Library.csproj", "{51AB0928-13F9-44BF-A407-B6957A43A056}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DICUI.Check", "DICUI.Check\DICUI.Check.csproj", "{8CFDE289-E171-4D49-A40D-5293265C1253}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{4D1DCF5A-F0B0-4E81-A05B-F1A7D37C9D9D}"
ProjectSection(SolutionItems) = preProject
appveyor.yml = appveyor.yml
CHANGELIST.md = CHANGELIST.md
README.md = README.md
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -15,6 +28,18 @@ Global
{7B1B75EB-8940-466F-BD51-76471A57F9BE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7B1B75EB-8940-466F-BD51-76471A57F9BE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7B1B75EB-8940-466F-BD51-76471A57F9BE}.Release|Any CPU.Build.0 = Release|Any CPU
{7CC064D2-38AB-4A05-8519-28660DE4562A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7CC064D2-38AB-4A05-8519-28660DE4562A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7CC064D2-38AB-4A05-8519-28660DE4562A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7CC064D2-38AB-4A05-8519-28660DE4562A}.Release|Any CPU.Build.0 = Release|Any CPU
{51AB0928-13F9-44BF-A407-B6957A43A056}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{51AB0928-13F9-44BF-A407-B6957A43A056}.Debug|Any CPU.Build.0 = Debug|Any CPU
{51AB0928-13F9-44BF-A407-B6957A43A056}.Release|Any CPU.ActiveCfg = Release|Any CPU
{51AB0928-13F9-44BF-A407-B6957A43A056}.Release|Any CPU.Build.0 = Release|Any CPU
{8CFDE289-E171-4D49-A40D-5293265C1253}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8CFDE289-E171-4D49-A40D-5293265C1253}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8CFDE289-E171-4D49-A40D-5293265C1253}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8CFDE289-E171-4D49-A40D-5293265C1253}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

22
DICUI/App.config Normal file
View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="DICPath" value="Programs\DiscImageCreator.exe"/>
<add key="SubDumpPath" value="subdump.exe"/>
<add key="DefaultOutputPath" value="ISO"/>
<add key="PreferredDumpSpeedCD" value="72"/>
<add key="PreferredDumpSpeedDVD" value="24"/>
<add key="PreferredDumpSpeedBD" value="16"/>
<add key="QuietMode" value="false"/>
<add key="ParanoidMode" value="false"/>
<add key="ScanForProtection" value="true"/>
<add key="SkipMediaTypeDetection" value="false"/>
<add key="SkipSystemDetection" value="false"/>
<add key="RereadAmountForC2" value="20"/>
<add key="VerboseLogging" value="true"/>
<add key="OpenLogWindowAtStartup" value="true"/>
<add key="AddPlaceholders" value="true"/>
<add key="Username" value=""/>
<add key="Password" value=""/>
</appSettings>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/></startup></configuration>

View File

@@ -2,7 +2,7 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:DICUI"
StartupUri="MainWindow.xaml">
StartupUri="Windows\MainWindow.xaml">
<Application.Resources>
</Application.Resources>

11
DICUI/App.xaml.cs Normal file
View File

@@ -0,0 +1,11 @@
using System.Windows;
namespace DICUI
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
}
}

View File

@@ -0,0 +1,29 @@
using DICUI.Data;
using DICUI.Utilities;
namespace DICUI
{
/// <summary>
/// Represents a single item in the Category combo box
/// </summary>
public class CategoryComboBoxItem
{
private object data;
public CategoryComboBoxItem(Category? category) => data = category;
public static implicit operator Category? (CategoryComboBoxItem item) => item.data as Category?;
public string Name
{
get { return (data as Category?).LongName(); }
}
public bool IsChecked { get; set; }
public Category? Value
{
get { return data as Category?; }
}
}
}

View File

@@ -0,0 +1,35 @@
using System.Windows.Media;
using DICUI.Data;
using DICUI.Utilities;
namespace DICUI
{
/// <summary>
/// Represents a single item in the System combo box
/// </summary>
public class KnownSystemComboBoxItem
{
private object data;
public KnownSystemComboBoxItem(KnownSystem? system) => data = system;
public KnownSystemComboBoxItem(KnownSystemCategory? category) => data = category;
public Brush Foreground { get => IsHeader() ? Brushes.Gray : Brushes.Black; }
public bool IsHeader() => data is KnownSystemCategory?;
public bool IsSystem() => data is KnownSystem?;
public static implicit operator KnownSystem? (KnownSystemComboBoxItem item) => item.data as KnownSystem?;
public string Name
{
get
{
if (IsHeader())
return "---------- " + (data as KnownSystemCategory?).LongName() + " ----------";
else
return (data as KnownSystem?).LongName();
}
}
}
}

View File

@@ -0,0 +1,29 @@
using DICUI.Data;
using DICUI.Utilities;
namespace DICUI
{
/// <summary>
/// Represents a single item in the Language combo box
/// </summary>
public class LanguageComboBoxItem
{
private object data;
public LanguageComboBoxItem(Language? region) => data = region;
public static implicit operator Language? (LanguageComboBoxItem item) => item.data as Language?;
public string Name
{
get { return (data as Language?).LongName(); }
}
public bool IsChecked { get; set; }
public Language? Value
{
get { return data as Language?; }
}
}
}

View File

@@ -0,0 +1,20 @@
using DICUI.Data;
using DICUI.Utilities;
namespace DICUI
{
/// <summary>
/// Represents a single item in the MediaType combo box
/// </summary>
public class MediaTypeComboBoxItem
{
private MediaType? data;
public MediaTypeComboBoxItem(MediaType? mediaType) => data = mediaType;
public static implicit operator MediaType? (MediaTypeComboBoxItem item) => item.data;
public string Name { get { return data.LongName(); }
}
}
}

View File

@@ -0,0 +1,30 @@
using DICUI.Data;
using DICUI.Utilities;
namespace DICUI
{
/// <summary>
/// Represents a single item in the Region combo box
/// </summary>
public class RegionComboBoxItem
{
private object data;
public RegionComboBoxItem(Region? region) => data = region;
public static implicit operator Region? (RegionComboBoxItem item) => item.data as Region?;
public string Name
{
get
{
return (data as Region?).LongName();
}
}
public Region? Value
{
get { return data as Region?; }
}
}
}

56
DICUI/Constants.cs Normal file
View File

@@ -0,0 +1,56 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Media;
using DICUI.Data;
namespace DICUI
{
/// <summary>
/// Variables for UI elements
/// </summary>
public static class Constants
{
public const string StartDumping = "Start Dumping";
public const string StopDumping = "Stop Dumping";
public const int LogWindowMarginFromMainWindow = 10;
// Private lists of known drive speed ranges
private static IReadOnlyList<int> cd { get; } = new List<int> { 1, 2, 3, 4, 6, 8, 12, 16, 20, 24, 32, 40, 44, 48, 52, 56, 72 };
private static IReadOnlyList<int> dvd { get; } = cd.Where(s => s <= 24).ToList();
private static IReadOnlyList<int> bd { get; } = cd.Where(s => s <= 16).ToList();
private static IReadOnlyList<int> unknown { get; } = cd; // TODO: All or {1}? Maybe null?
/// <summary>
/// Get list of all drive speeds for a given MediaType
/// </summary>
/// <param name="type">MediaType? that represents the current item</param>
/// <returns>Read-only list of drive speeds</returns>
public static IReadOnlyList<int> GetSpeedsForMediaType(MediaType? type)
{
switch (type)
{
case MediaType.CDROM:
case MediaType.GDROM:
return cd;
case MediaType.DVD:
case MediaType.HDDVD:
case MediaType.NintendoGameCubeGameDisc:
case MediaType.NintendoWiiOpticalDisc:
return dvd;
case MediaType.BluRay:
return bd;
default:
return unknown;
}
}
// Create collections for UI based on known drive speeds
public static DoubleCollection SpeedsForCDAsCollection { get; } = GetDoubleCollectionFromIntList(cd);
public static DoubleCollection SpeedsForDVDAsCollection { get; } = GetDoubleCollectionFromIntList(dvd);
public static DoubleCollection SpeedsForBDAsCollection { get; } = GetDoubleCollectionFromIntList(bd);
private static DoubleCollection GetDoubleCollectionFromIntList(IReadOnlyList<int> list)
=> new DoubleCollection(list.Select(i => Convert.ToDouble(i)).ToList());
}
}

28
DICUI/DICUI.csproj Normal file
View File

@@ -0,0 +1,28 @@
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<TargetFrameworks>net462;net472;netcoreapp3.0</TargetFrameworks>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<OutputType>WinExe</OutputType>
<UseWindowsForms>true</UseWindowsForms>
<UseWPF>true</UseWPF>
<Prefer32Bit>true</Prefer32Bit>
<ApplicationIcon>Icon.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="System.Configuration.ConfigurationManager" Version="4.6.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DICUI.Library\DICUI.Library.csproj">
<Project>{51ab0928-13f9-44bf-a407-b6957a43a056}</Project>
<Name>DICUI.Library</Name>
</ProjectReference>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,33 @@
using System;
using System.Globalization;
using System.Windows.Data;
using DICUI.Data;
using DICUI.Utilities;
namespace DICUI
{
/// <summary>
/// Used to provide a converter to XAML files to render comboboxes with enum values
/// </summary>
public class EnumDescriptionConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is DICCommand)
return ((DICCommand)value).LongName();
else if (value is DICFlag)
return ((DICFlag)value).LongName();
else if (value is MediaType?)
return ((MediaType?)value).LongName();
else if (value is KnownSystem?)
return ((KnownSystem?)value).LongName();
else
return "";
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return string.Empty;
}
}
}

View File

Before

Width:  |  Height:  |  Size: 71 KiB

After

Width:  |  Height:  |  Size: 71 KiB

199
DICUI/Options.cs Normal file
View File

@@ -0,0 +1,199 @@
using System;
using System.Configuration;
using System.Linq;
using System.Reflection;
using DICUI.Data;
namespace DICUI
{
public class Options
{
public string DefaultOutputPath { get; private set; }
public string DICPath { get; private set; }
public string SubDumpPath { get; private set; }
public int PreferredDumpSpeedCD { get; set; }
public int PreferredDumpSpeedDVD { get; set; }
public int PreferredDumpSpeedBD { get; set; }
public bool QuietMode { get; set; }
public bool ParanoidMode { get; set; }
public bool ScanForProtection { get; set; }
public int RereadAmountForC2 { get; set; }
public bool AddPlaceholders { get; set; }
public bool PromptForDiscInformation { get; set; }
public bool SkipMediaTypeDetection { get; set; }
public bool SkipSystemDetection { get; set; }
public bool VerboseLogging { get; set; }
public bool OpenLogWindowAtStartup { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public void Save()
{
Configuration configFile = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
//TODO: reflection is used
//TODO: is remove needed, doesn't the value get directly overridden
Array.ForEach(
GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance),
p => {
configFile.AppSettings.Settings.Remove(p.Name);
configFile.AppSettings.Settings.Add(p.Name, Convert.ToString(p.GetValue(this)));
}
);
configFile.Save(ConfigurationSaveMode.Modified);
}
public void Load()
{
Configuration configFile = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
//TODO: hardcoded, we should find a better way
this.DICPath = GetStringSetting(configFile, "DICPath", "Programs\\DiscImageCreator.exe");
this.SubDumpPath = GetStringSetting(configFile, "SubDumpPath", "subdump.exe");
this.DefaultOutputPath = GetStringSetting(configFile, "DefaultOutputPath", "ISO");
this.PreferredDumpSpeedCD = GetInt32Setting(configFile, "PreferredDumpSpeedCD", 72);
this.PreferredDumpSpeedDVD = GetInt32Setting(configFile, "PreferredDumpSpeedDVD", 24);
this.PreferredDumpSpeedBD = GetInt32Setting(configFile, "PreferredDumpSpeedBD", 16);
this.QuietMode = GetBooleanSetting(configFile, "QuietMode", false);
this.ParanoidMode = GetBooleanSetting(configFile, "ParanoidMode", false);
this.ScanForProtection = GetBooleanSetting(configFile, "ScanForProtection", true);
this.SkipMediaTypeDetection = GetBooleanSetting(configFile, "SkipMediaTypeDetection", false);
this.SkipSystemDetection = GetBooleanSetting(configFile, "SkipSystemDetection", false);
this.RereadAmountForC2 = GetInt32Setting(configFile, "RereadAmountForC2", 20);
this.VerboseLogging = GetBooleanSetting(configFile, "VerboseLogging", true);
this.OpenLogWindowAtStartup = GetBooleanSetting(configFile, "OpenLogWindowAtStartup", true);
this.AddPlaceholders = GetBooleanSetting(configFile, "AddPlaceholders", true);
this.PromptForDiscInformation = GetBooleanSetting(configFile, "PromptForDiscInformation", true);
this.Username = GetStringSetting(configFile, "Username", "");
this.Password = GetStringSetting(configFile, "Password", "");
}
/// <summary>
/// Get a boolean setting from a configuration
/// </summary>
/// <param name="configFile">Current configuration file</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>
public bool GetBooleanSetting(Configuration configFile, string key, bool defaultValue)
{
var settings = configFile.AppSettings.Settings;
if (settings.AllKeys.Contains(key))
{
if (Boolean.TryParse(settings[key].Value, out bool value))
return value;
else
return defaultValue;
}
else
{
return defaultValue;
}
}
/// <summary>
/// Get a boolean setting from a configuration
/// </summary>
/// <param name="configFile">Current configuration file</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>
public int GetInt32Setting(Configuration configFile, string key, int defaultValue)
{
var settings = configFile.AppSettings.Settings;
if (settings.AllKeys.Contains(key))
{
if (Int32.TryParse(settings[key].Value, out int value))
return value;
else
return defaultValue;
}
else
{
return defaultValue;
}
}
/// <summary>
/// Get a boolean setting from a configuration
/// </summary>
/// <param name="configFile">Current configuration file</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>
public long GetInt64Setting(Configuration configFile, string key, long defaultValue)
{
var settings = configFile.AppSettings.Settings;
if (settings.AllKeys.Contains(key))
{
if (Int64.TryParse(settings[key].Value, out long value))
return value;
else
return defaultValue;
}
else
{
return defaultValue;
}
}
/// <summary>
/// Get a boolean setting from a configuration
/// </summary>
/// <param name="configFile">Current configuration file</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>
public string GetStringSetting(Configuration configFile, string key, string defaultValue)
{
var settings = configFile.AppSettings.Settings;
if (settings.AllKeys.Contains(key))
return settings[key].Value;
else
return defaultValue;
}
//TODO: probably should be generic for non-string options
//TODO: using reflection for Set and Get is orthodox but it works, should be changed to a key,value map probably
public void Set(string key, string value)
{
GetType().GetProperty(key, BindingFlags.Public | BindingFlags.Instance).SetValue(this, value);
}
public string Get(string key)
{
return GetType().GetProperty(key, BindingFlags.Public | BindingFlags.Instance).GetValue(this) as string;
}
public int GetPreferredDumpSpeedForMediaType(MediaType? type)
{
switch (type)
{
case MediaType.CDROM:
case MediaType.GDROM:
return PreferredDumpSpeedCD;
case MediaType.DVD:
case MediaType.HDDVD:
case MediaType.NintendoGameCubeGameDisc:
case MediaType.NintendoWiiOpticalDisc:
return PreferredDumpSpeedDVD;
case MediaType.BluRay:
return PreferredDumpSpeedBD;
default:
return 8;
}
}
}
}

View File

@@ -12,7 +12,7 @@ using System.Windows;
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("DICUI")]
[assembly: AssemblyCopyright("Copyright © 2018")]
[assembly: AssemblyCopyright("Copyright © 2019")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
@@ -51,5 +51,8 @@ using System.Windows;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyVersion("1.15")]
[assembly: AssemblyFileVersion("1.15.0.0")]
// Anything marked as internal can be used by the test methods
[assembly: InternalsVisibleTo("DICUI.Test")]

113
DICUI/ViewModels.cs Normal file
View File

@@ -0,0 +1,113 @@
using System;
using System.Windows.Media;
using DICUI.Windows;
namespace DICUI
{
public class OptionsViewModel
{
private Options _options;
public OptionsViewModel(Options options)
{
this._options = options;
}
public bool QuietMode
{
get { return _options.QuietMode; }
set { _options.QuietMode = value; }
}
public bool ParanoidMode
{
get { return _options.ParanoidMode; }
set { _options.ParanoidMode = value; }
}
public bool ScanForProtection
{
get { return _options.ScanForProtection; }
set { _options.ScanForProtection = value; }
}
public bool SkipMediaTypeDetection
{
get { return _options.SkipMediaTypeDetection; }
set { _options.SkipMediaTypeDetection = value; }
}
public bool SkipSystemDetection
{
get { return _options.SkipSystemDetection; }
set { _options.SkipSystemDetection = value; }
}
public string RereadAmountForC2
{
get { return Convert.ToString(_options.RereadAmountForC2); }
set
{
if (Int32.TryParse(value, out int result))
_options.RereadAmountForC2 = result;
}
}
public bool VerboseLogging
{
get { return _options.VerboseLogging; }
set
{
_options.VerboseLogging = value;
_options.Save();
}
}
public bool OpenLogWindowAtStartup
{
get { return _options.OpenLogWindowAtStartup; }
set
{
_options.OpenLogWindowAtStartup = value;
_options.Save();
}
}
}
public class LoggerViewModel
{
private LogWindow _logWindow;
public void SetWindow(LogWindow logWindow) => _logWindow = logWindow;
public bool WindowVisible
{
get => _logWindow != null ? _logWindow.IsVisible : false;
set
{
if (value)
{
_logWindow.AdjustPositionToMainWindow();
_logWindow.Show();
}
else
_logWindow.Hide();
}
}
public void VerboseLog(string text)
{
if (ViewModels.OptionsViewModel.VerboseLogging)
_logWindow.AppendToTextBox(text, Brushes.Yellow);
}
public void VerboseLog(string format, params object[] args) => VerboseLog(string.Format(format, args));
public void VerboseLogLn(string format, params object[] args) => VerboseLog(string.Format(format, args) + "\n");
}
public static class ViewModels
{
public static OptionsViewModel OptionsViewModel { get; set; }
public static LoggerViewModel LoggerViewModel { get; set; } = new LoggerViewModel();
}
}

View File

@@ -0,0 +1,156 @@
<Window x:Class="DICUI.Windows.DiscInformationWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:DICUI"
mc:Ignorable="d"
Title="Disc Information" Height="705" Width="515.132" ResizeMode="NoResize"
Closed="OnClosed">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="585"/>
<RowDefinition Height="80"/>
</Grid.RowDefinitions>
<GroupBox Grid.Row="0" Margin="5,5,5,5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Header="Common Disc Information">
<Grid Margin="10,15,10,10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Title" />
<TextBox x:Name="TitleTextBox" Grid.Row="0" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />
<Label Grid.Row="1" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Foreign Title (Non-Latin)" />
<TextBox x:Name="ForeignTitleTextBox" Grid.Row="1" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />
<Label Grid.Row="2" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Disc Number / Letter" />
<TextBox x:Name="DiscNumberLetterTextBox" Grid.Row="2" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />
<Label Grid.Row="3" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Disc Title" />
<TextBox x:Name="DiscTitleTextBox" Grid.Row="3" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />
<Label Grid.Row="4" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Category" />
<ComboBox x:Name="CategoryComboBox" Grid.Row="4" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" >
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Name}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<Label Grid.Row="5" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Region" />
<ComboBox x:Name="RegionComboBox" Grid.Row="5" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" >
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Name}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<Label Grid.Row="6" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Languages" />
<ListBox x:Name="LanguagesComboBox" Grid.Row="6" Grid.Column="1" Height="24" HorizontalAlignment="Stretch" SelectionMode="Multiple">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding IsChecked}" Content="{Binding Path=Name}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Label Grid.Row="7" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Serial" />
<TextBox x:Name="SerialTextBox" Grid.Row="7" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />
<!-- Layer 0 / Data Side -->
<Label Grid.Row="8" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Data/L0 Mastering Ring" />
<TextBox x:Name="L0MasteringRingTextBox" Grid.Row="8" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" AcceptsTab="True" />
<Label Grid.Row="9" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Data/L0 Mastering SID" />
<TextBox x:Name="L0MasteringSIDTextBox" Grid.Row="9" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />
<Label Grid.Row="10" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Data/L0 Toolstamp/Mastering Code" />
<TextBox x:Name="L0ToolstampTextBox" Grid.Row="10" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />
<Label Grid.Row="11" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Data/L0 Mould SID" />
<TextBox x:Name="L0MouldSIDTextBox" Grid.Row="11" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />
<Label Grid.Row="12" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Data/L0 Additional Mould" />
<TextBox x:Name="L0AdditionalMouldTextBox" Grid.Row="12" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />
<!-- Layer 1 / Label Side -->
<Label Grid.Row="13" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Label/L1 Mastering Ring" />
<TextBox x:Name="L1MasteringRingTextBox" Grid.Row="13" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" AcceptsTab="True" />
<Label Grid.Row="14" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Label/L1 Mastering SID" />
<TextBox x:Name="L1MasteringSIDTextBox" Grid.Row="14" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />
<Label Grid.Row="15" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Label/L1 Toolstamp/Mastering Code" />
<TextBox x:Name="L1ToolstampTextBox" Grid.Row="15" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />
<Label Grid.Row="16" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Label/L1 Mould SID" />
<TextBox x:Name="L1MouldSIDTextBox" Grid.Row="16" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />
<Label Grid.Row="17" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Label/L1 Additional Mould" />
<TextBox x:Name="L1AdditionalMouldTextBox" Grid.Row="17" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />
<Label Grid.Row="18" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Barcode" />
<TextBox x:Name="BarcodeTextBox" Grid.Row="18" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />
<!-- This needs to be a multiline textbox -->
<Label Grid.Row="19" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Comments" />
<TextBox x:Name="CommentsTextBox" Grid.Row="19" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" AcceptsReturn="True" AcceptsTab="True" />
<!-- This needs to be a multiline textbox -->
<Label Grid.Row="20" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Contents" />
<TextBox x:Name="ContentsTextBox" Grid.Row="20" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" AcceptsReturn="True" AcceptsTab="True"/>
</Grid>
</GroupBox>
<GroupBox Grid.Row="1" Margin="5,5,5,5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Header="Version and Editions">
<Grid Height="60">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="24"/>
<RowDefinition Height="24"/>
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Version" />
<TextBox x:Name="VersionTextBox" Grid.Row="0" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />
<Label Grid.Row="1" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Edition" />
<TextBox x:Name="EditionTextBox" Grid.Row="1" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />
</Grid>
</GroupBox>
</Grid>
</Window>

View File

@@ -0,0 +1,163 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using DICUI.Data;
namespace DICUI.Windows
{
/// <summary>
/// Interaction logic for DiscInformationWindow.xaml
/// </summary>
public partial class DiscInformationWindow : Window
{
private readonly MainWindow _mainWindow;
private readonly SubmissionInfo _submissionInfo;
private List<CategoryComboBoxItem> _categories;
private List<RegionComboBoxItem> _regions;
private List<LanguageComboBoxItem> _languages;
public DiscInformationWindow(MainWindow mainWindow, SubmissionInfo submissionInfo)
{
InitializeComponent();
_mainWindow = mainWindow;
_submissionInfo = submissionInfo;
PopulateCategories();
PopulateRegions();
PopulateLanguages();
}
public void Refresh()
{
TitleTextBox.Text = _submissionInfo.CommonDiscInfo.Title ?? "";
ForeignTitleTextBox.Text = _submissionInfo.CommonDiscInfo.ForeignTitleNonLatin ?? "";
DiscNumberLetterTextBox.Text = _submissionInfo.CommonDiscInfo.DiscNumberLetter ?? "";
DiscTitleTextBox.Text = _submissionInfo.CommonDiscInfo.DiscTitle ?? "";
CategoryComboBox.SelectedIndex = _categories.FindIndex(r => r == _submissionInfo.CommonDiscInfo.Category);
RegionComboBox.SelectedIndex = _regions.FindIndex(r => r == _submissionInfo.CommonDiscInfo.Region);
if (_submissionInfo.CommonDiscInfo.Languages != null)
{
foreach (var language in _submissionInfo.CommonDiscInfo.Languages)
_languages.Find(l => l == language).IsChecked = true;
}
SerialTextBox.Text = _submissionInfo.CommonDiscInfo.Serial ?? "";
L0MasteringRingTextBox.Text = _submissionInfo.CommonDiscInfo.MasteringRingFirstLayerDataSide ?? "";
L0MasteringSIDTextBox.Text = _submissionInfo.CommonDiscInfo.MasteringSIDCodeFirstLayerDataSide ?? "";
L0ToolstampTextBox.Text = _submissionInfo.CommonDiscInfo.ToolstampMasteringCodeFirstLayerDataSide ?? "";
L0MouldSIDTextBox.Text = _submissionInfo.CommonDiscInfo.MouldSIDCodeFirstLayerDataSide ?? "";
L0AdditionalMouldTextBox.Text = _submissionInfo.CommonDiscInfo.AdditionalMouldFirstLayerDataSide ?? "";
L1MasteringRingTextBox.Text = _submissionInfo.CommonDiscInfo.MasteringRingSecondLayerLabelSide ?? "";
L1MasteringSIDTextBox.Text = _submissionInfo.CommonDiscInfo.MasteringSIDCodeSecondLayerLabelSide ?? "";
L1ToolstampTextBox.Text = _submissionInfo.CommonDiscInfo.ToolstampMasteringCodeSecondLayerLabelSide ?? "";
L1MouldSIDTextBox.Text = _submissionInfo.CommonDiscInfo.MouldSIDCodeSecondLayerLabelSide ?? "";
L1AdditionalMouldTextBox.Text = _submissionInfo.CommonDiscInfo.AdditionalMouldSecondLayerLabelSide ?? "";
BarcodeTextBox.Text = _submissionInfo.CommonDiscInfo.Barcode ?? "";
CommentsTextBox.Text = _submissionInfo.CommonDiscInfo.Comments ?? "";
ContentsTextBox.Text = _submissionInfo.CommonDiscInfo.Contents ?? "";
VersionTextBox.Text = _submissionInfo.VersionAndEditions.Version ?? "";
EditionTextBox.Text = _submissionInfo.VersionAndEditions.OtherEditions ?? "";
}
/// <summary>
/// Get a complete list of categories and fill the combo box
/// </summary>
private void PopulateCategories()
{
var categories = Enum.GetValues(typeof(Category)).OfType<Category?>().ToList();
ViewModels.LoggerViewModel.VerboseLogLn("Populating categories, {0} categories found.", categories.Count);
_categories = new List<CategoryComboBoxItem>();
foreach (var category in categories)
{
_categories.Add(new CategoryComboBoxItem(category));
}
CategoryComboBox.ItemsSource = _categories;
CategoryComboBox.SelectedIndex = 0;
}
/// <summary>
/// Get a complete list of regions and fill the combo box
/// </summary>
private void PopulateRegions()
{
var regions = Enum.GetValues(typeof(Region)).OfType<Region?>().ToList();
ViewModels.LoggerViewModel.VerboseLogLn("Populating regions, {0} regions found.", regions.Count);
_regions = new List<RegionComboBoxItem>();
foreach (var region in regions)
{
_regions.Add(new RegionComboBoxItem(region));
}
RegionComboBox.ItemsSource = _regions;
RegionComboBox.SelectedIndex = 0;
}
/// <summary>
/// Get a complete list of languages and fill the combo box
/// </summary>
private void PopulateLanguages()
{
var languages = Enum.GetValues(typeof(Language)).OfType<Language?>().ToList();
ViewModels.LoggerViewModel.VerboseLogLn("Populating languages, {0} languages found.", languages.Count);
_languages = new List<LanguageComboBoxItem>();
foreach (var language in languages)
{
_languages.Add(new LanguageComboBoxItem(language));
}
LanguagesComboBox.ItemsSource = _languages;
LanguagesComboBox.SelectedIndex = 0;
}
#region Event Handlers
private void OnClosed(object sender, EventArgs e)
{
_submissionInfo.CommonDiscInfo.Title = TitleTextBox.Text ?? "";
_submissionInfo.CommonDiscInfo.ForeignTitleNonLatin = ForeignTitleTextBox.Text ?? "";
_submissionInfo.CommonDiscInfo.DiscNumberLetter = DiscNumberLetterTextBox.Text ?? "";
_submissionInfo.CommonDiscInfo.DiscTitle = DiscTitleTextBox.Text ?? "";
_submissionInfo.CommonDiscInfo.Category = (CategoryComboBox.SelectedItem as CategoryComboBoxItem)?.Value ?? Category.Games;
_submissionInfo.CommonDiscInfo.Region = (RegionComboBox.SelectedItem as RegionComboBoxItem)?.Value ?? Region.World;
var languages = new List<Language?>();
foreach (var language in _languages)
{
if (language.IsChecked)
languages.Add(language.Value);
}
if (languages.Count == 0)
languages.Add(null);
_submissionInfo.CommonDiscInfo.Languages = languages.ToArray();
_submissionInfo.CommonDiscInfo.Serial = SerialTextBox.Text ?? "";
_submissionInfo.CommonDiscInfo.MasteringRingFirstLayerDataSide = L0MasteringRingTextBox.Text ?? "";
_submissionInfo.CommonDiscInfo.MasteringSIDCodeFirstLayerDataSide = L0MasteringSIDTextBox.Text ?? "";
_submissionInfo.CommonDiscInfo.ToolstampMasteringCodeFirstLayerDataSide = L0ToolstampTextBox.Text ?? "";
_submissionInfo.CommonDiscInfo.MouldSIDCodeFirstLayerDataSide = L0MouldSIDTextBox.Text ?? "";
_submissionInfo.CommonDiscInfo.AdditionalMouldFirstLayerDataSide = L0AdditionalMouldTextBox.Text ?? "";
_submissionInfo.CommonDiscInfo.MasteringRingSecondLayerLabelSide = L1MasteringRingTextBox.Text ?? "";
_submissionInfo.CommonDiscInfo.MasteringSIDCodeSecondLayerLabelSide = L1MasteringSIDTextBox.Text ?? "";
_submissionInfo.CommonDiscInfo.ToolstampMasteringCodeSecondLayerLabelSide = L1ToolstampTextBox.Text ?? "";
_submissionInfo.CommonDiscInfo.MouldSIDCodeSecondLayerLabelSide = L1MouldSIDTextBox.Text ?? "";
_submissionInfo.CommonDiscInfo.AdditionalMouldSecondLayerLabelSide = L1AdditionalMouldTextBox.Text ?? "";
_submissionInfo.CommonDiscInfo.Barcode = BarcodeTextBox.Text ?? "";
_submissionInfo.CommonDiscInfo.Comments = CommentsTextBox.Text ?? "";
_submissionInfo.CommonDiscInfo.Contents = ContentsTextBox.Text ?? "";
_submissionInfo.VersionAndEditions.Version = VersionTextBox.Text ?? "";
_submissionInfo.VersionAndEditions.OtherEditions = EditionTextBox.Text ?? "";
Hide();
}
#endregion
}
}

View File

@@ -0,0 +1,54 @@
<Window x:Class="DICUI.Windows.LogWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:DICUI"
xmlns:diag="clr-namespace:System.Diagnostics;assembly=WindowsBase"
Title="Log Window" Height="350" Width="600" Closed="OnWindowClosed" Loaded="OnWindowLoaded"
>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="*" />
<RowDefinition Height="40" />
</Grid.RowDefinitions>
<Grid Grid.Row="0" Height="22" Margin="10 10 10 0">
<ProgressBar x:Name="progressBar" />
<TextBlock x:Name="progressLabel" Grid.Row="0" Height="22" HorizontalAlignment="Center" VerticalAlignment="Center" Padding="0 2 0 0" />
</Grid>
<Border Grid.Row="1" Background="White" BorderBrush="Gainsboro" BorderThickness="1" Margin="10">
<ScrollViewer Name="outputViewer" SizeChanged="ScrollViewer_SizeChanged">
<RichTextBox Name="output" FontFamily="Consolas" Background="#202020" IsReadOnly="true" TextChanged="OnTextChanged" />
</ScrollViewer>
</Border>
<Grid Grid.Row="2">
<Grid.RowDefinitions>
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition Width="4*"/>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<CheckBox Content="Verbose" Margin="10 0 0 10" Grid.Column="0" VerticalAlignment="Center"
ToolTip="Enable verbose logging of tasks"
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
IsChecked="{Binding Path=VerboseLogging}"
/>
<CheckBox Content="Open at startup" Margin="10 0 0 10" Grid.Column="1" Grid.ColumnSpan="2" VerticalAlignment="Center"
ToolTip="Open this window at startup"
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
IsChecked="{Binding Path=OpenLogWindowAtStartup}"
/>
<Button Margin="0 0 10 10" Grid.Column="3" Height="22" Width="60" Content="Clear" HorizontalAlignment="Right" Click="OnClearButton" />
<Button Margin="0 0 10 10" Grid.Column="4" Height="22" Width="60" Content="Hide" HorizontalAlignment="Right" Click="OnHideButton" />
<Button Visibility="Hidden" Name="AbortButton" Margin="0 0 10 10" Grid.Column="2" Height="22" Width="80" Content="Abort" HorizontalAlignment="Right" Click="OnAbortButton" />
</Grid>
</Grid>
</Window>

View File

@@ -0,0 +1,385 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Interop;
using System.Windows.Media;
namespace DICUI.Windows
{
public partial class LogWindow : Window
{
private const int GWL_STYLE = -16;
private const int WS_SYSMENU = 0x80000;
[DllImport("user32.dll", SetLastError = true)]
private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll")]
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
private MainWindow _mainWindow;
private FlowDocument _document;
private Paragraph _paragraph;
private List<Matcher> _matchers;
volatile Process _process;
public LogWindow(MainWindow mainWindow)
{
InitializeComponent();
this._mainWindow = mainWindow;
_document = new FlowDocument();
_paragraph = new Paragraph();
_document.Blocks.Add(_paragraph);
output.Document = _document;
_matchers = new List<Matcher>();
_matchers.Add(new Matcher(
"Descrambling data sector of img (LBA)",
@"\s*(\d+)\/\s*(\d+)$",
match => {
if (UInt32.TryParse(match.Groups[1].Value, out uint current) && UInt32.TryParse(match.Groups[2].Value, out uint total))
{
float percentProgress = (current / (float)total) * 100;
progressBar.Value = percentProgress;
progressLabel.Text = string.Format("Descrambling image.. ({0:##.##}%)", percentProgress);
}
}));
_matchers.Add(new Matcher(
@"Creating .scm (LBA)",
@"\s*(\d+)\/\s*(\d+)$",
match => {
if (UInt32.TryParse(match.Groups[1].Value, out uint current) && UInt32.TryParse(match.Groups[2].Value, out uint total))
{
float percentProgress = (current / (float)total) * 100;
progressBar.Value = percentProgress;
progressLabel.Text = string.Format("Creating scrambled image.. ({0:##.##}%)", percentProgress);
}
}));
_matchers.Add(new Matcher(
"Checking sectors (LBA)",
@"\s*(\d+)\/\s*(\d+)$",
match => {
if (UInt32.TryParse(match.Groups[1].Value, out uint current) && UInt32.TryParse(match.Groups[2].Value, out uint total))
{
float percentProgress = (current / (float)total) * 100;
progressBar.Value = percentProgress;
progressLabel.Text = string.Format("Checking for errors.. ({0:##.##}%)", percentProgress);
}
}));
_matchers.Add(new Matcher(
"Scanning sector (LBA)",
@"\s*(\d+)\/\s*(\d+)$",
match => {
if (UInt32.TryParse(match.Groups[1].Value, out uint current) && UInt32.TryParse(match.Groups[2].Value, out uint total))
{
float percentProgress = (current / (float)total) * 100;
progressBar.Value = percentProgress;
progressLabel.Text = string.Format("Scanning sectors for protection.. ({0:##.##}%)", percentProgress);
}
}));
}
public void StartDump(string args)
{
AppendToTextBox(string.Format("Launching DIC with args: {0}\r\n", args), Brushes.Orange);
Task.Run(() =>
{
_process = new Process()
{
StartInfo = new ProcessStartInfo()
{
FileName = @"Programs/DiscImageCreator.exe",
Arguments = args,
CreateNoWindow = true,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
},
};
StreamState stdoutState = new StreamState(false);
StreamState stderrState = new StreamState(true);
//_cmd.ErrorDataReceived += (process, text) => Dispatcher.Invoke(() => UpdateConsole(text.Data, Brushes.Red));
_process.Start();
var _1 = ConsumeOutput(_process.StandardOutput, s => Dispatcher.Invoke(() => UpdateConsole(s, stdoutState)));
var _2 = ConsumeOutput(_process.StandardError, s => Dispatcher.Invoke(() => UpdateConsole(s, stderrState)));
_process.EnableRaisingEvents = true;
_process.Exited += OnProcessExit;
});
}
public void AdjustPositionToMainWindow()
{
this.Left = _mainWindow.Left;
this.Top = _mainWindow.Top + _mainWindow.Height + Constants.LogWindowMarginFromMainWindow;
}
private void GracefullyTerminateProcess()
{
if (_process != null)
{
_process.Exited -= OnProcessExit;
bool isForced = !_process.HasExited;
if (isForced)
{
AppendToTextBox("\r\nForcefully Killing the process\r\n", Brushes.Red);
_process.Kill();
_process.WaitForExit();
}
AppendToTextBox(string.Format("\r\nExit Code: {0}\r\n", _process.ExitCode), _process.ExitCode == 0 ? Brushes.Green : Brushes.Red);
if (_process.ExitCode == 0)
{
Dispatcher.Invoke(() =>
{
progressLabel.Text = "Done!";
progressBar.Value = 100;
progressBar.Foreground = Brushes.Green;
});
}
else
{
Dispatcher.Invoke(() =>
{
progressLabel.Text = isForced ? "Aborted by user" : "Error, please check log!";
progressBar.Value = 100;
progressBar.Foreground = Brushes.Red;
});
}
_process.Close();
}
_process = null;
}
private void ScrollViewer_SizeChanged(object sender, SizeChangedEventArgs e)
{
outputViewer.ScrollToBottom();
}
async Task ConsumeOutput(TextReader reader, Action<string> callback)
{
char[] buffer = new char[256];
int cch;
while ((cch = await reader.ReadAsync(buffer, 0, buffer.Length)) > 0)
{
callback(new string(buffer, 0, cch));
}
}
// this is used to optimize the work since we need to process A LOT of text
struct Matcher
{
private readonly string prefix;
private readonly Regex regex;
private readonly int start;
private readonly Action<Match> lambda;
public Matcher(string prefix, string regex, Action<Match> lambda)
{
this.prefix = prefix;
this.regex = new Regex(regex);
this.start = prefix.Length;
this.lambda = lambda;
}
public bool Matches(ref string text) => text.StartsWith(prefix);
public void Apply(ref string text)
{
Match match = regex.Match(text, start);
lambda.Invoke(match);
}
}
private void ProcessStringForProgressBar(string text)
{
foreach (Matcher matcher in _matchers)
{
if (matcher.Matches(ref text))
{
matcher.Apply(ref text);
return;
}
}
}
class StreamState
{
public enum State
{
BEGIN,
READ_CARRIAGE,
};
public State state;
public readonly StringBuilder buffer;
public readonly bool isError;
public StreamState(bool isError)
{
this.state = State.BEGIN;
this.buffer = new StringBuilder();
this.isError = isError;
}
public bool HasData() => buffer.Length > 0;
public string Fetch() => buffer.ToString();
public void Clear() => buffer.Clear();
public void Append(char c) => buffer.Append(c);
public bool Is(State state) => this.state == state;
public void Set(State state) => this.state = state;
}
public void AppendToTextBox(string text, Brush color)
{
if (Application.Current.Dispatcher.CheckAccess())
{
Run run = new Run(text) { Foreground = color };
_paragraph.Inlines.Add(run);
}
else
Dispatcher.Invoke(() =>
{
Run run = new Run(text) { Foreground = color };
_paragraph.Inlines.Add(run);
});
}
private void UpdateConsole(string text, StreamState state)
{
/*if (c == '\r') { output.Inlines.Add(@"\r"); file.Write("\\r"); }
else if (c == '\n') { output.Inlines.Add(@"\n"); file.Write("\\n\n"); }
output.Inlines.Add(""+c);
file.Write(c);
file.Flush();
continue;*/
if (text != null)
{
foreach (char c in text)
{
switch (c)
{
case '\r' when (state.Is(StreamState.State.BEGIN)):
{
state.Set(StreamState.State.READ_CARRIAGE);
break;
}
case '\n' when (state.Is(StreamState.State.READ_CARRIAGE)):
{
if (state.buffer.Length > 0)
{
string buffer = state.Fetch();
AppendToTextBox(buffer, state.isError ? Brushes.Red : Brushes.White);
if (!state.isError)
ProcessStringForProgressBar(buffer);
}
_paragraph.Inlines.Add(new LineBreak());
state.Clear();
state.Set(StreamState.State.BEGIN);
break;
}
default:
if (state.Is(StreamState.State.READ_CARRIAGE) && state.HasData())
{
if (!(_paragraph.Inlines.LastInline is LineBreak))
_paragraph.Inlines.Remove(_paragraph.Inlines.LastInline);
string buffer = state.Fetch();
AppendToTextBox(buffer, state.isError ? Brushes.Red : Brushes.White);
if (!state.isError)
ProcessStringForProgressBar(buffer);
state.Clear();
}
state.Set(StreamState.State.BEGIN);
state.Append(c);
break;
}
}
}
}
#region EventHandlers
private void OnWindowClosed(object sender, EventArgs e)
{
GracefullyTerminateProcess();
}
private void OnWindowLoaded(object sender, EventArgs e)
{
var hwnd = new WindowInteropHelper(this).Handle;
SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_SYSMENU);
}
void OnProcessExit(object sender, EventArgs e)
{
Dispatcher.Invoke(() => AbortButton.IsEnabled = false);
GracefullyTerminateProcess();
}
private void OnHideButton(object sender, EventArgs e)
{
ViewModels.LoggerViewModel.WindowVisible = false;
//TODO: this should be bound directly to WindowVisible property in two way fashion
// we need to study how to properly do it in XAML
_mainWindow.ShowLogMenuItem.IsChecked = false;
}
private void OnClearButton(object sender, EventArgs e)
{
output.Document.Blocks.Clear();
}
private void OnAbortButton(object sender, EventArgs args)
{
GracefullyTerminateProcess();
}
private void OnStartButton(object sender, EventArgs args)
{
StartDump("cd e Gam.iso 16");
}
private void OnTextChanged(object sender, TextChangedEventArgs e)
{
outputViewer.ScrollToBottom();
}
#endregion
}
}

View File

@@ -0,0 +1,130 @@
<Window x:Class="DICUI.Windows.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:DICUI"
mc:Ignorable="d"
Title="Disc Image Creator GUI" Height="450" Width="600" WindowStartupLocation="CenterScreen" ResizeMode="CanMinimize"
LocationChanged="MainWindowLocationChanged" Activated="MainWindowActivated" Closing="MainWindowClosing">
<Window.Resources>
<local:EnumDescriptionConverter x:Key="enumConverter" />
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="4*"/>
<ColumnDefinition Width="13*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="4*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<StackPanel VerticalAlignment="Top" Grid.ColumnSpan="4">
<Menu Width="Auto" Height="20" >
<MenuItem Header="_File">
<MenuItem x:Name="AppExit" Header="E_xit" HorizontalAlignment="Left" Width="140" Click="AppExitClick" />
</MenuItem>
<MenuItem Header="_Tools">
<MenuItem x:Name="OptionsMenuItem" Header="_Options" HorizontalAlignment="Left" Width="140" Click="OptionsClick"/>
<MenuItem x:Name="ShowLogMenuItem" Header="Show _Log Window" IsCheckable="true" HorizontalAlignment="Left"
DataContext="{Binding Source={x:Static local:ViewModels.LoggerViewModel}}"
IsChecked="{Binding Path=WindowVisible}"
/>
</MenuItem>
<MenuItem Header="_Help">
<MenuItem x:Name="About" Header="_About" HorizontalAlignment="Left" Width="140" Click="AboutClick"/>
</MenuItem>
</Menu>
</StackPanel>
<GroupBox Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" Margin="5,5,5.2,5.4" HorizontalAlignment="Stretch" Header="Settings"/>
<GroupBox Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" Margin="5,4.6,5.2,4.8" HorizontalAlignment="Stretch" Header="Controls"/>
<GroupBox Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" Margin="5,5.2,5.2,4.8" HorizontalAlignment="Stretch" Header="Status"/>
<Grid Grid.Row="1" Grid.Column="0" Margin="15,25,15.2,10.4" Grid.ColumnSpan="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="2.5*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" Content="System/Media Type" />
<ComboBox x:Name="SystemTypeComboBox" Grid.Row="0" Grid.Column="1" Height="22" Width="250" HorizontalAlignment="Left" SelectionChanged="SystemTypeComboBoxSelectionChanged">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Name}" Foreground="{Binding Path=Foreground}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<ComboBox x:Name="MediaTypeComboBox" Grid.Row="0" Grid.Column="1" Height="22" Width="140" HorizontalAlignment="Right" SelectionChanged="MediaTypeComboBoxSelectionChanged">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Converter={StaticResource enumConverter}}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<Label Grid.Row="1" Grid.Column="0" VerticalAlignment="Center">Output Filename</Label>
<TextBox x:Name="OutputFilenameTextBox" Grid.Row="1" Grid.Column="1" Height="22" TextChanged="OutputFilenameTextBoxTextChanged" />
<Label Grid.Row="2" Grid.Column="0" VerticalAlignment="Center">Output Directory</Label>
<TextBox x:Name="OutputDirectoryTextBox" Grid.Row="2" Grid.Column="1" Height="22" Width="345" HorizontalAlignment="Left" TextChanged="OutputDirectoryTextBoxTextChanged" />
<Button x:Name="OutputDirectoryBrowseButton" Grid.Row="2" Grid.Column="1" Height="22" Width="50" HorizontalAlignment="Right" Content="Browse" Click="OutputDirectoryBrowseButtonClick"/>
<Label Grid.Row="3" Grid.Column="0" VerticalAlignment="Center">Drive Letter</Label>
<ComboBox x:Name="DriveLetterComboBox" Grid.Row="3" Grid.Column="1" Height="22" Width="60" HorizontalAlignment="Left" SelectionChanged="DriveLetterComboBoxSelectionChanged">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Letter}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<Label Grid.Row="4" Grid.Column="0" VerticalAlignment="Center">Drive Speed</Label>
<ComboBox x:Name="DriveSpeedComboBox" Grid.Row="4" Grid.Column="1" Height="22" Width="60" HorizontalAlignment="Left" SelectionChanged="DriveSpeedComboBoxSelectionChanged" />
<Label Grid.Row="5" Grid.Column="0" VerticalAlignment="Center">Parameters</Label>
<TextBox x:Name="ParametersTextBox" Grid.Row="5" Grid.Column="1" Height="22" Width="370" HorizontalAlignment="Left" IsEnabled="False" />
<CheckBox x:Name="EnableParametersCheckBox" Grid.Row="5" Grid.Column="1" Height="22" HorizontalAlignment="Right" IsChecked="False" Click="EnableParametersCheckBoxClick" />
</Grid>
<Grid Grid.Row="2" Grid.Column="0" Margin="15,19.6,15.2,9.8" Grid.ColumnSpan="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
</Grid.RowDefinitions>
<Button x:Name="StartStopButton" Grid.Row="0" Grid.Column="0" Height="22" Width="125" VerticalAlignment="Center" HorizontalAlignment="Center" Content="Start Dumping" Click="StartStopButtonClick" IsEnabled="False" />
<Button x:Name="DiskScanButton" Grid.Row="0" Grid.Column="1" Height="22" Width="125" VerticalAlignment="Center" HorizontalAlignment="Center" Content="Scan for disks" Click="DiskScanButtonClick" />
<Button x:Name="CopyProtectScanButton" Grid.Row="0" Grid.Column="2" Height="22" Width="125" VerticalAlignment="Center" HorizontalAlignment="Center" Content="Scan for protection" Click="CopyProtectScanButtonClick" />
<CheckBox x:Name="EjectWhenDoneCheckBox" Grid.Row="0" Grid.Column="3" VerticalAlignment="Center" HorizontalAlignment="Center" Content="Eject When Done" IsChecked="False" />
</Grid>
<Grid Grid.Row="3" Grid.Column="0" Margin="15,20.2,15.2,9.8" Grid.ColumnSpan="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
</Grid.RowDefinitions>
<Label x:Name="StatusLabel" Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Center" Content="Waiting for media..." />
</Grid>
</Grid>
</Window>

View File

@@ -0,0 +1,791 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using WinForms = System.Windows.Forms;
using DICUI.Data;
using DICUI.Utilities;
namespace DICUI.Windows
{
public partial class MainWindow : Window
{
// Private UI-related variables
private List<Drive> _drives;
private MediaType? _currentMediaType;
private List<KnownSystemComboBoxItem> _systems;
private List<MediaType?> _mediaTypes;
private bool _alreadyShown;
private DumpEnvironment _env;
// Option related
private Options _options;
private OptionsWindow _optionsWindow;
// User input related
private DiscInformationWindow _discInformationWindow;
private LogWindow _logWindow;
public MainWindow()
{
InitializeComponent();
// Initializes and load Options object
_options = new Options();
_options.Load();
ViewModels.OptionsViewModel = new OptionsViewModel(_options);
_logWindow = new LogWindow(this);
ViewModels.LoggerViewModel.SetWindow(_logWindow);
// Disable buttons until we load fully
StartStopButton.IsEnabled = false;
DiskScanButton.IsEnabled = false;
CopyProtectScanButton.IsEnabled = false;
if (_options.OpenLogWindowAtStartup)
{
this.WindowStartupLocation = WindowStartupLocation.Manual;
double combinedHeight = this.Height + _logWindow.Height + Constants.LogWindowMarginFromMainWindow;
Rectangle bounds = GetScaledCoordinates(WinForms.Screen.PrimaryScreen.WorkingArea);
this.Left = bounds.Left + (bounds.Width - this.Width) / 2;
this.Top = bounds.Top + (bounds.Height - combinedHeight) / 2;
}
}
#region Events
protected override void OnContentRendered(EventArgs e)
{
base.OnContentRendered(e);
if (_alreadyShown)
return;
_alreadyShown = true;
if (_options.OpenLogWindowAtStartup)
{
//TODO: this should be bound directly to WindowVisible property in two way fashion
// we need to study how to properly do it in XAML
ShowLogMenuItem.IsChecked = true;
ViewModels.LoggerViewModel.WindowVisible = true;
}
// Populate the list of systems
StatusLabel.Content = "Creating system list, please wait!";
PopulateSystems();
// Populate the list of drives
StatusLabel.Content = "Creating drive list, please wait!";
PopulateDrives();
}
private void StartStopButtonClick(object sender, RoutedEventArgs e)
{
// Dump or stop the dump
if ((string)StartStopButton.Content == Constants.StartDumping)
{
StartDumping();
}
else if ((string)StartStopButton.Content == Constants.StopDumping)
{
ViewModels.LoggerViewModel.VerboseLogLn("Canceling dumping process...");
_env.CancelDumping();
CopyProtectScanButton.IsEnabled = true;
if (EjectWhenDoneCheckBox.IsChecked == true)
{
ViewModels.LoggerViewModel.VerboseLogLn($"Ejecting disc in drive {_env.Drive.Letter}");
_env.EjectDisc();
}
}
}
private void OutputDirectoryBrowseButtonClick(object sender, RoutedEventArgs e)
{
BrowseFolder();
EnsureDiscInformation();
}
private void DiskScanButtonClick(object sender, RoutedEventArgs e)
{
PopulateDrives();
}
private void CopyProtectScanButtonClick(object sender, RoutedEventArgs e)
{
ScanAndShowProtection();
}
private void SystemTypeComboBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
{
// If we're on a separator, go to the next item and return
if ((SystemTypeComboBox.SelectedItem as KnownSystemComboBoxItem).IsHeader())
{
SystemTypeComboBox.SelectedIndex++;
return;
}
ViewModels.LoggerViewModel.VerboseLogLn("Changed system to: {0}", (SystemTypeComboBox.SelectedItem as KnownSystemComboBoxItem).Name);
PopulateMediaType();
GetOutputNames(false);
EnsureDiscInformation();
}
private void MediaTypeComboBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
{
// Only change the media type if the selection and not the list has changed
if (e.RemovedItems.Count == 1 && e.AddedItems.Count == 1)
{
_currentMediaType = MediaTypeComboBox.SelectedItem as MediaType?;
SetSupportedDriveSpeed();
}
GetOutputNames(false);
EnsureDiscInformation();
}
private void DriveLetterComboBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
{
CacheCurrentDiscType();
SetCurrentDiscType();
GetOutputNames(true);
SetSupportedDriveSpeed();
}
private void DriveSpeedComboBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
{
EnsureDiscInformation();
}
private void OutputFilenameTextBoxTextChanged(object sender, TextChangedEventArgs e)
{
EnsureDiscInformation();
}
private void OutputDirectoryTextBoxTextChanged(object sender, TextChangedEventArgs e)
{
EnsureDiscInformation();
}
private void ProgressUpdated(object sender, Result value)
{
StatusLabel.Content = value.Message;
ViewModels.LoggerViewModel.VerboseLogLn(value.Message);
}
private void MainWindowLocationChanged(object sender, EventArgs e)
{
if (_logWindow.IsVisible)
_logWindow.AdjustPositionToMainWindow();
}
private void MainWindowActivated(object sender, EventArgs e)
{
if (_logWindow.IsVisible && !this.Topmost)
{
_logWindow.Topmost = true;
_logWindow.Topmost = false;
}
}
private void MainWindowClosing(object sender, System.ComponentModel.CancelEventArgs e)
{
if (_logWindow.IsVisible)
_logWindow.Close();
}
private void EnableParametersCheckBoxClick(object sender, RoutedEventArgs e)
{
if (EnableParametersCheckBox.IsChecked == true)
ParametersTextBox.IsEnabled = true;
else
{
ParametersTextBox.IsEnabled = false;
ProcessCustomParameters();
}
}
// Toolbar Events
private void AppExitClick(object sender, RoutedEventArgs e)
{
Application.Current.Shutdown();
}
private void AboutClick(object sender, RoutedEventArgs e)
{
MessageBox.Show($"ReignStumble - Project Lead / UI Design{Environment.NewLine}" +
$"darksabre76 - Project Co-Lead / Backend Design{Environment.NewLine}" +
$"Jakz - Feature Contributor{Environment.NewLine}" +
$"NHellFire - Feature Contributor{Environment.NewLine}" +
$"Dizzzy - Concept/Ideas/Beta tester{Environment.NewLine}", "About", MessageBoxButton.OK, MessageBoxImage.Information);
}
private void OptionsClick(object sender, RoutedEventArgs e)
{
// lazy initialization
if (_optionsWindow == null)
{
_optionsWindow = new OptionsWindow(this, _options);
_optionsWindow.Closed += delegate
{
_optionsWindow = null;
};
}
_optionsWindow.Owner = this;
_optionsWindow.WindowStartupLocation = WindowStartupLocation.CenterOwner;
_optionsWindow.Refresh();
_optionsWindow.Show();
}
public void OnOptionsUpdated()
{
GetOutputNames(false);
SetSupportedDriveSpeed();
EnsureDiscInformation();
}
#endregion
#region Helpers
/// <summary>
/// Populate media type according to system type
/// </summary>
private void PopulateMediaType()
{
KnownSystem? currentSystem = SystemTypeComboBox.SelectedItem as KnownSystemComboBoxItem;
if (currentSystem != null)
{
_mediaTypes = Validators.GetValidMediaTypes(currentSystem);
MediaTypeComboBox.ItemsSource = _mediaTypes;
MediaTypeComboBox.IsEnabled = _mediaTypes.Count > 1;
MediaTypeComboBox.SelectedIndex = (_mediaTypes.IndexOf(_currentMediaType) >= 0 ? _mediaTypes.IndexOf(_currentMediaType) : 0);
}
else
{
MediaTypeComboBox.IsEnabled = false;
MediaTypeComboBox.ItemsSource = null;
MediaTypeComboBox.SelectedIndex = -1;
}
}
/// <summary>
/// Get a complete list of supported systems and fill the combo box
/// </summary>
private void PopulateSystems()
{
var knownSystems = Validators.CreateListOfSystems();
ViewModels.LoggerViewModel.VerboseLogLn("Populating systems, {0} systems found.", knownSystems.Count);
Dictionary<KnownSystemCategory, List<KnownSystem?>> mapping = knownSystems
.GroupBy(s => s.Category())
.ToDictionary(
k => k.Key,
v => v
.OrderBy(s => s.LongName())
.ToList()
);
_systems = new List<KnownSystemComboBoxItem>();
_systems.Add(new KnownSystemComboBoxItem(KnownSystem.NONE));
foreach (var group in mapping)
{
_systems.Add(new KnownSystemComboBoxItem(group.Key));
group.Value.ForEach(system => _systems.Add(new KnownSystemComboBoxItem(system)));
}
SystemTypeComboBox.ItemsSource = _systems;
SystemTypeComboBox.SelectedIndex = 0;
StartStopButton.IsEnabled = false;
}
/// <summary>
/// Get a complete list of active disc drives and fill the combo box
/// </summary>
/// <remarks>TODO: Find a way for this to periodically run, or have it hook to a "drive change" event</remarks>
private void PopulateDrives()
{
ViewModels.LoggerViewModel.VerboseLogLn("Scanning for drives..");
// Always enable the disk scan
DiskScanButton.IsEnabled = true;
// Populate the list of drives and add it to the combo box
_drives = Validators.CreateListOfDrives();
DriveLetterComboBox.ItemsSource = _drives;
if (DriveLetterComboBox.Items.Count > 0)
{
// Check for active optical drives first
int index = _drives.FindIndex(d => d.MarkedActive && d.InternalDriveType == InternalDriveType.Optical);
// Then we check for floppy drives
if (index == -1)
index = _drives.FindIndex(d => d.MarkedActive && d.InternalDriveType == InternalDriveType.Floppy);
// Then we try all other drive types
if (index == -1)
index = _drives.FindIndex(d => d.MarkedActive);
// Set the selected index
DriveLetterComboBox.SelectedIndex = (index != -1 ? index : 0);
StatusLabel.Content = "Valid drive found! Choose your Media Type";
CopyProtectScanButton.IsEnabled = true;
// Get the current media type
if (!_options.SkipSystemDetection && index != -1)
{
ViewModels.LoggerViewModel.VerboseLog("Trying to detect system for drive {0}.. ", _drives[index].Letter);
var currentSystem = Validators.GetKnownSystem(_drives[index]);
ViewModels.LoggerViewModel.VerboseLogLn(currentSystem == null || currentSystem == KnownSystem.NONE ? "unable to detect." : ("detected " + currentSystem.LongName() + "."));
if (currentSystem != null && currentSystem != KnownSystem.NONE)
{
int sysIndex = _systems.FindIndex(s => s == currentSystem);
SystemTypeComboBox.SelectedIndex = sysIndex;
}
}
// Only enable the start/stop if we don't have the default selected
StartStopButton.IsEnabled = (SystemTypeComboBox.SelectedItem as KnownSystemComboBoxItem) != KnownSystem.NONE;
ViewModels.LoggerViewModel.VerboseLogLn("Found {0} drives: {1}", _drives.Count, string.Join(", ", _drives.Select(d => d.Letter)));
}
else
{
DriveLetterComboBox.SelectedIndex = -1;
StatusLabel.Content = "No valid drive found!";
StartStopButton.IsEnabled = false;
CopyProtectScanButton.IsEnabled = false;
ViewModels.LoggerViewModel.VerboseLogLn("Found no drives");
}
}
/// <summary>
/// Browse for an output folder
/// </summary>
private void BrowseFolder()
{
WinForms.FolderBrowserDialog folderDialog = new WinForms.FolderBrowserDialog { ShowNewFolderButton = false, SelectedPath = System.AppDomain.CurrentDomain.BaseDirectory };
WinForms.DialogResult result = folderDialog.ShowDialog();
if (result == WinForms.DialogResult.OK)
{
OutputDirectoryTextBox.Text = folderDialog.SelectedPath;
}
}
/// <summary>
/// Create a DumpEnvironment with all current settings
/// </summary>
/// <returns>Filled DumpEnvironment instance</returns>
private DumpEnvironment DetermineEnvironment()
{
// Populate the new environment
var env = new DumpEnvironment()
{
// Paths to tools
SubdumpPath = _options.SubDumpPath,
DICPath = _options.DICPath,
OutputDirectory = OutputDirectoryTextBox.Text,
OutputFilename = OutputFilenameTextBox.Text,
// Get the currently selected options
Drive = DriveLetterComboBox.SelectedItem as Drive,
DICParameters = new Parameters(ParametersTextBox.Text),
QuietMode = _options.QuietMode,
ParanoidMode = _options.ParanoidMode,
ScanForProtection = _options.ScanForProtection,
RereadAmountC2 = _options.RereadAmountForC2,
AddPlaceholders = _options.AddPlaceholders,
PromptForDiscInformation = _options.PromptForDiscInformation,
Username = _options.Username,
Password = _options.Password,
System = SystemTypeComboBox.SelectedItem as KnownSystemComboBoxItem,
Type = MediaTypeComboBox.SelectedItem as MediaType?,
};
// Fix the output paths
env.FixOutputPaths();
// Disable automatic reprocessing of the textboxes until we're done
OutputDirectoryTextBox.TextChanged -= OutputDirectoryTextBoxTextChanged;
OutputFilenameTextBox.TextChanged -= OutputFilenameTextBoxTextChanged;
OutputDirectoryTextBox.Text = env.OutputDirectory;
OutputFilenameTextBox.Text = env.OutputFilename;
OutputDirectoryTextBox.TextChanged += OutputDirectoryTextBoxTextChanged;
OutputFilenameTextBox.TextChanged += OutputFilenameTextBoxTextChanged;
return env;
}
/// <summary>
/// Begin the dumping process using the given inputs
/// </summary>
private async void StartDumping()
{
if (_env == null)
_env = DetermineEnvironment();
// If still in custom parameter mode, check that users meant to continue or not
if (EnableParametersCheckBox.IsChecked == true)
{
MessageBoxResult result = MessageBox.Show("It looks like you have custom parameters that have not been saved. Would you like to apply those changes before starting to dump?", "Custom Changes", MessageBoxButton.YesNoCancel, MessageBoxImage.Question);
if (result == MessageBoxResult.Yes)
{
EnableParametersCheckBox.IsChecked = false;
ParametersTextBox.IsEnabled = false;
ProcessCustomParameters();
}
else if (result == MessageBoxResult.Cancel)
return;
// If "No", then we continue with the current known environment
}
try
{
// Check for the firmware first
// TODO: Remove this (and method) once DIC end-to-end logging becomes a thing
if (!await _env.DriveHasLatestFimrware())
{
MessageBox.Show($"DiscImageCreator has reported that drive {_env.Drive.Letter} is not updated to the most recent firmware. Please update the firmware for your drive and try again.", "Outdated Firmware", MessageBoxButton.OK, MessageBoxImage.Error);
return;
}
// Validate that the user explicitly wants an inactive drive to be considered for dumping
if (!_env.Drive.MarkedActive)
{
MessageBoxResult mbresult = MessageBox.Show("The currently selected drive does not appear to contain a disc! Are you sure you want to continue?", "Missing Disc", MessageBoxButton.YesNo, MessageBoxImage.Exclamation);
if (mbresult == MessageBoxResult.No || mbresult == MessageBoxResult.Cancel || mbresult == MessageBoxResult.None)
{
ViewModels.LoggerViewModel.VerboseLogLn("Dumping aborted!");
return;
}
}
// If a complete dump already exists
if (_env.FoundAllFiles())
{
MessageBoxResult mbresult = MessageBox.Show("A complete dump already exists! Are you sure you want to overwrite?", "Overwrite?", MessageBoxButton.YesNo, MessageBoxImage.Exclamation);
if (mbresult == MessageBoxResult.No || mbresult == MessageBoxResult.Cancel || mbresult == MessageBoxResult.None)
{
ViewModels.LoggerViewModel.VerboseLogLn("Dumping aborted!");
return;
}
}
StartStopButton.Content = Constants.StopDumping;
CopyProtectScanButton.IsEnabled = false;
StatusLabel.Content = "Beginning dumping process";
ViewModels.LoggerViewModel.VerboseLogLn("Starting dumping process..");
var progress = new Progress<Result>();
progress.ProgressChanged += ProgressUpdated;
Result result = await _env.StartDumping(progress);
if (result)
{
// Verify dump output and save it
result = _env.VerifyAndSaveDumpOutput(progress,
(si) =>
{
// lazy initialization
if (_discInformationWindow == null)
{
_discInformationWindow = new DiscInformationWindow(this, si);
_discInformationWindow.Closed += delegate
{
_discInformationWindow = null;
};
}
_discInformationWindow.Owner = this;
_discInformationWindow.WindowStartupLocation = WindowStartupLocation.CenterOwner;
_discInformationWindow.Refresh();
return _discInformationWindow.ShowDialog();
}
);
}
StatusLabel.Content = result ? "Dumping complete!" : result.Message;
ViewModels.LoggerViewModel.VerboseLogLn(result ? "Dumping complete!" : result.Message);
}
catch
{
// No-op, we don't care what it was
}
finally
{
StartStopButton.Content = Constants.StartDumping;
CopyProtectScanButton.IsEnabled = true;
}
if (EjectWhenDoneCheckBox.IsChecked == true)
{
ViewModels.LoggerViewModel.VerboseLogLn($"Ejecting disc in drive {_env.Drive.Letter}");
_env.EjectDisc();
}
}
/// <summary>
/// Ensure information is consistent with the currently selected disc type
/// </summary>
private void EnsureDiscInformation()
{
// Get the current environment information
_env = DetermineEnvironment();
// Take care of null cases
if (_env.System == null)
_env.System = KnownSystem.NONE;
if (_env.Type == null)
_env.Type = MediaType.NONE;
// Get the status to write out
Result result = Validators.GetSupportStatus(_env.System, _env.Type);
StatusLabel.Content = result.Message;
// Set the index for the current disc type
SetCurrentDiscType();
StartStopButton.IsEnabled = result && (_drives != null && _drives.Count > 0 ? true : false);
// If we're in a type that doesn't support drive speeds
DriveSpeedComboBox.IsEnabled = _env.Type.DoesSupportDriveSpeed();
// If input params are not enabled, generate the full parameters from the environment
if (!ParametersTextBox.IsEnabled)
{
string generated = _env.GetFullParameters((int?)DriveSpeedComboBox.SelectedItem);
if (generated != null)
ParametersTextBox.Text = generated;
}
}
/// <summary>
/// Get the default output directory name from the currently selected drive
/// </summary>
/// <param name="driveChanged">Force an updated name if the drive letter changes</param>
private void GetOutputNames(bool driveChanged)
{
Drive drive = DriveLetterComboBox.SelectedItem as Drive;
KnownSystem? systemType = SystemTypeComboBox.SelectedItem as KnownSystemComboBoxItem;
MediaType? mediaType = MediaTypeComboBox.SelectedItem as MediaType?;
// Set the output directory, if we changed drives or it's not already
if (driveChanged || string.IsNullOrEmpty(OutputDirectoryTextBox.Text))
OutputDirectoryTextBox.Text = Path.Combine(_options.DefaultOutputPath, drive?.VolumeLabel ?? string.Empty);
// Set the output filename, if we changed drives or it's not already
if (driveChanged || string.IsNullOrEmpty(OutputFilenameTextBox.Text))
OutputFilenameTextBox.Text = (drive?.VolumeLabel ?? systemType.LongName()) + (mediaType.Extension() ?? ".bin");
// If the extension for the file changed, update that automatically
else if (Path.GetExtension(OutputFilenameTextBox.Text) != mediaType.Extension())
OutputFilenameTextBox.Text = Path.GetFileNameWithoutExtension(OutputFilenameTextBox.Text) + (mediaType.Extension() ?? ".bin");
}
/// <summary>
/// Scan and show copy protection for the current disc
/// </summary>
private async void ScanAndShowProtection()
{
if (_env == null)
_env = DetermineEnvironment();
if (_env.Drive.Letter != default(char))
{
ViewModels.LoggerViewModel.VerboseLogLn("Scanning for copy protection in {0}", _env.Drive.Letter);
var tempContent = StatusLabel.Content;
StatusLabel.Content = "Scanning for copy protection... this might take a while!";
StartStopButton.IsEnabled = false;
DiskScanButton.IsEnabled = false;
CopyProtectScanButton.IsEnabled = false;
string protections = await Validators.RunProtectionScanOnPath(_env.Drive.Letter + ":\\");
if (!ViewModels.LoggerViewModel.WindowVisible)
MessageBox.Show(protections, "Detected Protection", MessageBoxButton.OK, MessageBoxImage.Information);
ViewModels.LoggerViewModel.VerboseLog("Detected the following protections in {0}:\r\n\r\n{1}", _env.Drive.Letter, protections);
StatusLabel.Content = tempContent;
StartStopButton.IsEnabled = true;
DiskScanButton.IsEnabled = true;
CopyProtectScanButton.IsEnabled = true;
}
}
/// <summary>
/// Set the drive speed based on reported maximum and user-defined option
/// </summary>
private void SetSupportedDriveSpeed()
{
// Set the drive speed list that's appropriate
var values = Constants.GetSpeedsForMediaType(_currentMediaType);
DriveSpeedComboBox.ItemsSource = values;
ViewModels.LoggerViewModel.VerboseLogLn("Supported media speeds: {0}", string.Join(",", values));
// Find the minimum set to compare against
int preferred = 100;
switch (_currentMediaType)
{
case MediaType.CDROM:
case MediaType.GDROM:
preferred = _options.PreferredDumpSpeedCD;
break;
case MediaType.DVD:
case MediaType.HDDVD:
case MediaType.NintendoGameCubeGameDisc:
case MediaType.NintendoWiiOpticalDisc:
preferred = _options.PreferredDumpSpeedDVD;
break;
case MediaType.BluRay:
preferred = _options.PreferredDumpSpeedBD;
break;
default:
preferred = _options.PreferredDumpSpeedCD;
break;
}
// Choose the lower of the two speeds between the allowed speeds and the user-defined one
// TODO: Inform more users about setting preferences in the settings so this comparison doesn't need to happen
int chosenSpeed = Math.Min(
values.Where(s => s <= values[values.Count / 2]).Last(),
preferred
);
// Set the selected speed
ViewModels.LoggerViewModel.VerboseLogLn("Setting drive speed to: {0}", chosenSpeed);
DriveSpeedComboBox.SelectedValue = chosenSpeed;
}
/// <summary>
/// Cache the current disc type to internal variable
/// </summary>
private void CacheCurrentDiscType()
{
// Get the drive letter from the selected item
Drive drive = DriveLetterComboBox.SelectedItem as Drive;
if (drive == null)
return;
// Get the current media type
if (!_options.SkipMediaTypeDetection)
{
ViewModels.LoggerViewModel.VerboseLog("Trying to detect media type for drive {0}.. ", drive.Letter);
_currentMediaType = Validators.GetMediaType(drive);
ViewModels.LoggerViewModel.VerboseLogLn(_currentMediaType == null ? "unable to detect." : ("detected " + _currentMediaType.LongName() + "."));
}
}
/// <summary>
/// Set the current disc type in the combo box
/// </summary>
private void SetCurrentDiscType()
{
// If we have an invalid current type, we don't care and return
if (_currentMediaType == null || _currentMediaType == MediaType.NONE)
return;
// Now set the selected item, if possible
int index = _mediaTypes.FindIndex(kvp => kvp.Value == _currentMediaType);
if (index != -1)
MediaTypeComboBox.SelectedIndex = index;
else
StatusLabel.Content = $"Disc of type '{Converters.LongName(_currentMediaType)}' found, but the current system does not support it!";
}
/// <summary>
/// Process the current custom parameters back into UI values
/// </summary>
private void ProcessCustomParameters()
{
_env.DICParameters = new Parameters(ParametersTextBox.Text);
int driveIndex = _drives.Select(d => d.Letter).ToList().IndexOf(_env.DICParameters.DriveLetter[0]);
if (driveIndex > -1)
DriveLetterComboBox.SelectedIndex = driveIndex;
int driveSpeed = _env.DICParameters.DriveSpeed ?? -1;
if (driveSpeed > 0)
DriveSpeedComboBox.SelectedValue = driveSpeed;
else
_env.DICParameters.DriveSpeed = (int?)DriveSpeedComboBox.SelectedValue;
string trimmedPath = _env.DICParameters.Filename?.Trim('"') ?? string.Empty;
string outputDirectory = Path.GetDirectoryName(trimmedPath);
string outputFilename = Path.GetFileName(trimmedPath);
if (!string.IsNullOrWhiteSpace(outputDirectory))
OutputDirectoryTextBox.Text = outputDirectory;
else
outputDirectory = OutputDirectoryTextBox.Text;
if (!string.IsNullOrWhiteSpace(outputFilename))
OutputFilenameTextBox.Text = outputFilename;
else
outputFilename = OutputFilenameTextBox.Text;
MediaType? mediaType = _env.DICParameters.Command.ToMediaType();
int mediaTypeIndex = _mediaTypes.IndexOf(mediaType);
if (mediaTypeIndex > -1)
MediaTypeComboBox.SelectedIndex = mediaTypeIndex;
}
#endregion
#region UI Helpers
/// <summary>
/// Get pixel coordinates based on DPI scaling
/// </summary>
/// <param name="bounds">Rectangle representing the bounds to transform</param>
/// <returns>Rectangle representing the scaled bounds</returns>
private Rectangle GetScaledCoordinates(Rectangle bounds)
{
using (Graphics g = Graphics.FromHwnd(IntPtr.Zero))
{
return new Rectangle(
TransformCoordinate(bounds.Left, g.DpiX),
TransformCoordinate(bounds.Top, g.DpiY),
TransformCoordinate(bounds.Width, g.DpiX),
TransformCoordinate(bounds.Height, g.DpiY));
}
}
/// <summary>
/// Transform an individual coordinate using DPI scaling
/// </summary>
/// <param name="coord">Current integer coordinate</param>
/// <param name="dpi">DPI scaling factor</param>
/// <returns>Scaled integer coordinate</returns>
private int TransformCoordinate(int coord, float dpi)
{
return (int)(coord / ((double)dpi / 96));
}
#endregion
}
}

View File

@@ -0,0 +1,177 @@
<Window x:Class="DICUI.Windows.OptionsWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:DICUI"
mc:Ignorable="d"
Title="Options" Height="580" Width="515.132">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="150"/>
<RowDefinition Height="100"/>
<RowDefinition Height="80"/>
<RowDefinition Height="40"/>
</Grid.RowDefinitions>
<GroupBox Grid.Column="0" Margin="5,5,5,5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Header="Paths" />
<Grid Margin="10,15,10,10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="2.0*" />
<ColumnDefinition Width="0.2*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="DiscImageCreator Path" />
<TextBox x:Name="DICPathTextBox" Grid.Row="0" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />
<Button x:Name="DICPathButton" Grid.Row="0" Grid.Column="2" Height="22" Width="22" Content="..." Click="BrowseForPathClick" />
<Label Grid.Row="1" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="subdump Path" />
<TextBox x:Name="SubDumpPathTextBox" Grid.Row="1" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />
<Button x:Name="SubDumpPathButton" Grid.Row="1" Grid.Column="2" Height="22" Width="22" Content="..." Click="BrowseForPathClick"/>
<Label Grid.Row="2" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Default Output Path" />
<TextBox x:Name="DefaultOutputPathTextBox" Grid.Row="2" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />
<Button x:Name="DefaultOutputPathButton" Grid.Row="2" Grid.Column="2" Height="22" Width="22" Content="..." Click="BrowseForPathClick" />
</Grid>
<GroupBox Grid.Row="1" Margin="5,5,5,5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Header="Preferred Dump Speed">
<Grid Height="100">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80"/>
<ColumnDefinition Width="2.0*"/>
<ColumnDefinition Width="40"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0" Content="CD-ROM" />
<Slider x:Name="DumpSpeedCDSlider" Grid.Row="0" Grid.Column="1" Minimum="1" Maximum="72" IsSnapToTickEnabled="True" TickPlacement="BottomRight" Ticks="{Binding Source={x:Static local:Constants.SpeedsForCDAsCollection}}" />
<TextBox x:Name="DumpSpeedCDTextBox" Grid.Row="0" Grid.Column="2" Width="22" Height="22" TextAlignment="Center" IsReadOnly="True" IsReadOnlyCaretVisible="False" VerticalAlignment="Center" Text="{Binding ElementName=DumpSpeedCDSlider, Path=Value, UpdateSourceTrigger=PropertyChanged}" Background="LightGray" Foreground="Gray"/>
<Label Grid.Row="1" Grid.Column="0" Content="DVD-ROM" />
<Slider x:Name="DumpSpeedDVDSlider" Grid.Row="1" Grid.Column="1" Minimum="1" Maximum="24" IsSnapToTickEnabled="True" TickPlacement="BottomRight" Ticks="{Binding Source={x:Static local:Constants.SpeedsForDVDAsCollection}}" />
<TextBox x:Name="DumpSpeedDVDTextBox" Grid.Row="1" Grid.Column="2" Width="22" Height="22" TextAlignment="Center" IsReadOnly="True" IsReadOnlyCaretVisible="False" VerticalAlignment="Center" Text="{Binding ElementName=DumpSpeedDVDSlider, Path=Value, UpdateSourceTrigger=PropertyChanged}" Background="LightGray" Foreground="Gray"/>
<Label Grid.Row="2" Grid.Column="0" Content="BD-ROM" />
<Slider x:Name="DumpSpeedBDSlider" Grid.Row="2" Grid.Column="1" Minimum="1" Maximum="16" IsSnapToTickEnabled="True" TickPlacement="BottomRight" Ticks="{Binding Source={x:Static local:Constants.SpeedsForBDAsCollection}}" />
<TextBox x:Name="DumpSpeedBDTextBox" Grid.Row="2" Grid.Column="2" Width="22" Height="22" TextAlignment="Center" IsReadOnly="True" IsReadOnlyCaretVisible="False" VerticalAlignment="Center" Text="{Binding ElementName=DumpSpeedBDSlider, Path=Value, UpdateSourceTrigger=PropertyChanged}" Background="LightGray" Foreground="Gray"/>
</Grid>
</GroupBox>
<GroupBox Grid.Row="2" Margin="5,5,5,5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Header="Options" Padding="10">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="24*" />
<RowDefinition Height="13*" />
<RowDefinition Height="11*"/>
</Grid.RowDefinitions>
<CheckBox Grid.Column="0" VerticalAlignment="Center" Content="Quiet Mode"
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
IsChecked="{Binding Path=QuietMode}"
ToolTip="Disable DiscImageCreator sounds" Margin="0,4"
/>
<CheckBox Grid.Column="1" VerticalAlignment="Center" Content="Paranoid Mode"
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
IsChecked="{Binding Path=ParanoidMode}"
ToolTip="Enable pedantic and super-safe flags" Margin="0,4"
/>
<Grid Grid.Column="2" Grid.ColumnSpan="2" Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Content="C2 Reread Tries:" />
<TextBox Grid.Column="1" VerticalAlignment="Center"
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
Text="{Binding Path=RereadAmountForC2}"
ToolTip="Specifies how many rereads are attempted on C2 error"
/>
</Grid>
<CheckBox Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="2" VerticalAlignment="Top" Content="Protection Scan"
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
IsChecked="{Binding Path=ScanForProtection}"
ToolTip="Enable automatic checking for copy protection on dumped media" Margin="0,4,0,0" Grid.RowSpan="2"
/>
<CheckBox Grid.Column="1" Grid.Row="1" VerticalAlignment="Center" Content="Skip Type Detect"
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
IsChecked="{Binding Path=SkipMediaTypeDetection}"
ToolTip="Disable trying to guess media type inserted (may improve performance at startup)" Margin="0,4" Grid.RowSpan="2"
/>
<CheckBox Grid.Column="2" Grid.Row="1" VerticalAlignment="Center" Content="Add Placeholders"
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
IsChecked="{Binding Path=AddPlaceholders}"
ToolTip="Enable adding placeholder text in the submissioninfo output for required and optional fields" Margin="0,4" Grid.RowSpan="2"
/>
<CheckBox Grid.Column="3" Grid.Row="1" VerticalAlignment="Center" Content="Show Disc Info"
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
IsChecked="{Binding Path=PromptForDiscInformation}"
ToolTip="Enable showing the disc information output after dumping" Margin="0,4" Grid.RowSpan="2"
/>
</Grid>
</GroupBox>
<GroupBox Grid.Row="3" Margin="5,5,5,5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Header="Redump Login" Padding="10">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Username" />
<TextBox x:Name="RedumpUsernameTextBox" Grid.Row="0" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />
<Label Grid.Row="0" Grid.Column="2" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Password" />
<TextBox x:Name="RedumpPasswordTextBox" Grid.Row="0" Grid.Column="3" Height="22" HorizontalAlignment="Stretch" />
</Grid>
</GroupBox>
<Grid Height="22" Grid.Row="4" Grid.Column="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Button x:Name="AcceptButton" Grid.Row="0" Grid.Column="1" Height="22" Width="80" Content="Accept" Click="OnAcceptClick" />
<Button x:Name="CancelButton" Grid.Row="0" Grid.Column="2" Height="22" Width="80" Content="Cancel" Click="OnCancelClick" />
</Grid>
</Grid>
</Window>

View File

@@ -5,26 +5,28 @@ using System.Windows.Forms;
using Button = System.Windows.Controls.Button;
using TextBox = System.Windows.Controls.TextBox;
namespace DICUI
namespace DICUI.Windows
{
/// <summary>
/// Interaction logic for OptionsWindow.xaml
/// </summary>
public partial class OptionsWindow : Window
{
private readonly MainWindow _mainWindow;
private readonly Options _options;
public OptionsWindow(Options options)
public OptionsWindow(MainWindow mainWindow, Options options)
{
InitializeComponent();
_options = options;
_mainWindow = mainWindow;
_options = options;
}
private OpenFileDialog CreateOpenFileDialog()
{
OpenFileDialog dialog = new OpenFileDialog();
dialog.InitialDirectory = System.AppDomain.CurrentDomain.BaseDirectory;
dialog.InitialDirectory = AppDomain.CurrentDomain.BaseDirectory;
dialog.Filter = "Executables (*.exe)|*.exe";
dialog.FilterIndex = 0;
dialog.RestoreDirectory = true;
@@ -40,23 +42,23 @@ namespace DICUI
private string[] PathSettings()
{
string[] pathSettings = { "defaultOutputPath", "dicPath", "subdumpPath" };
string[] pathSettings = { "DefaultOutputPath", "DICPath", "SubDumpPath" };
return pathSettings;
}
private TextBox TextBoxForPathSetting(string name)
{
return FindName("txt_" + name) as TextBox;
return FindName(name + "TextBox") as TextBox;
}
private void btn_BrowseForPath_Click(object sender, EventArgs e)
private void BrowseForPathClick(object sender, EventArgs e)
{
Button button = sender as Button;
// strips button prefix to obtain the setting name
string pathSettingName = button.Name.Substring("btn_".Length);
string pathSettingName = button.Name.Substring(0, button.Name.IndexOf("Button"));
// TODO: hack for now, then we'll see
bool shouldBrowseForPath = pathSettingName == "defaultOutputPath";
bool shouldBrowseForPath = pathSettingName == "DefaultOutputPath";
CommonDialog dialog = shouldBrowseForPath ? (CommonDialog)CreateFolderBrowserDialog() : CreateOpenFileDialog();
using (dialog)
@@ -94,22 +96,43 @@ namespace DICUI
}
}
private void btn_Accept_Click(object sender, EventArgs e)
public void Refresh()
{
Array.ForEach(PathSettings(), setting => _options.Set(setting, TextBoxForPathSetting(setting).Text));
_options.Save();
Hide();
Array.ForEach(PathSettings(), setting => TextBoxForPathSetting(setting).Text = _options.Get(setting));
DumpSpeedCDSlider.Value = _options.PreferredDumpSpeedCD;
DumpSpeedDVDSlider.Value = _options.PreferredDumpSpeedDVD;
DumpSpeedBDSlider.Value = _options.PreferredDumpSpeedBD;
RedumpUsernameTextBox.Text = _options.Username;
RedumpPasswordTextBox.Text = _options.Password;
}
private void btn_Cancel_Click(object sender, EventArgs e)
#region Event Handlers
private void OnAcceptClick(object sender, EventArgs e)
{
Array.ForEach(PathSettings(), setting => _options.Set(setting, TextBoxForPathSetting(setting).Text));
_options.PreferredDumpSpeedCD = Convert.ToInt32(DumpSpeedCDSlider.Value);
_options.PreferredDumpSpeedDVD = Convert.ToInt32(DumpSpeedDVDSlider.Value);
_options.PreferredDumpSpeedBD = Convert.ToInt32(DumpSpeedBDSlider.Value);
_options.Username = RedumpUsernameTextBox.Text;
_options.Password = RedumpPasswordTextBox.Text;
_options.Save();
Hide();
_mainWindow.OnOptionsUpdated();
}
private void OnCancelClick(object sender, EventArgs e)
{
// just hide the window and don't care
Hide();
}
public void Refresh()
{
Array.ForEach(PathSettings(), setting => TextBoxForPathSetting(setting).Text = _options.Get(setting));
}
#endregion
}
}

View File

@@ -1,161 +0,0 @@
namespace DICUI.Data
{
/// <summary>
/// Known systems
/// </summary>
/// <remarks>Ensure that Utilities methods are updated as well</remarks>
public enum KnownSystem
{
NONE = 0,
#region Consoles
BandaiPlaydiaQuickInteractiveSystem,
BandaiApplePippin,
CommodoreAmigaCD32,
CommodoreAmigaCDTV,
MattelHyperscan,
MicrosoftXBOX,
MicrosoftXBOX360XDG2,
MicrosoftXBOX360XDG3,
MicrosoftXBOXOne,
NECPCEngineTurboGrafxCD,
NECPCFX,
NintendoGameCube,
NintendoWii,
NintendoWiiU,
Panasonic3DOInteractiveMultiplayer,
PhilipsCDi,
SegaCDMegaCD,
SegaDreamcast,
SegaSaturn,
SNKNeoGeoCD,
SonyPlayStation,
SonyPlayStation2,
SonyPlayStation3,
SonyPlayStation4,
SonyPlayStationPortable,
VMLabsNuon,
VTechVFlashVSmilePro,
ZAPiTGamesGameWaveFamilyEntertainmentSystem,
#endregion
#region Computers
AcornArchimedes,
AppleMacintosh,
CommodoreAmigaCD,
FujitsuFMTowns,
IBMPCCompatible,
NECPC88,
NECPC98,
SharpX68000,
#endregion
#region Arcade
AmigaCUBOCD32,
AmericanLaserGames3DO,
Atari3DO,
Atronic,
AUSCOMSystem1,
BallyGameMagic,
CapcomCPSystemIII,
GlobalVRVarious,
GlobalVRVortek,
GlobalVRVortekV3,
ICEPCHardware,
IncredibleTechnologiesEagle,
IncredibleTechnologiesVarious,
KonamiFirebeat,
KonamiGVSystem,
KonamiM2,
KonamiPython,
KonamiPython2,
KonamiSystem573,
KonamiTwinkle,
KonamiVarious,
MeritIndustriesBoardwalk,
MeritIndustriesMegaTouchAurora,
MeritIndustriesMegaTouchForce,
MeritIndustriesMegaTouchION,
MeritIndustriesMegaTouchMaxx,
MeritIndustriesMegaTouchXL,
NamcoCapcomSystem256,
NamcoCapcomTaitoSystem246,
NamcoSegaNintendoTriforce,
NamcoSystem12,
NamcoSystem357,
NewJatreCDi,
NichibutsuHighRateSystem,
NichibutsuSuperCD,
NichibutsuXRateSystem,
PhotoPlayVarious,
RawThrillsVarious,
SegaChihiro,
SegaEuropaR,
SegaLindbergh,
SegaNaomi,
SegaNaomi2,
SegaNu,
SegaRingEdge,
SegaRingEdge2,
SegaRingWide,
SegaSTV,
SegaSystem32,
SeibuCATSSystem,
TABAustriaQuizard,
TandyMemorexVisualInformationSystem,
TsunamiTsuMoMultiGameMotionSystem,
#endregion
#region Other
AudioCD,
BDVideo,
DVDVideo,
EnhancedCD,
HDDVDVideo,
PalmOS,
PhilipsCDiDigitalVideo,
PhotoCD,
PlayStationGameSharkUpdates,
TaoiKTV,
TomyKissSite,
VideoCD,
#endregion
Custom = -1
}
/// <summary>
/// Known media types
/// </summary>
public enum MediaType
{
// Generic Optical Formats
NONE = 0,
CD,
DVD,
GDROM,
HDDVD,
BluRay,
LaserDisc,
// Special Optical Formats
GameCubeGameDisc,
WiiOpticalDisc,
WiiUOpticalDisc,
UMD,
// Non-Optical Formats
Floppy,
Cartridge,
Cassette,
CED,
}
}

View File

@@ -1,10 +0,0 @@
using System.Collections.Generic;
using System.Collections.Specialized;
namespace DICUI.External
{
// Adapted from https://www.codeproject.com/Articles/18615/OrderedDictionary-T-A-generic-implementation-of-IO
public interface IOrderedDictionary<TKey, TValue> : IOrderedDictionary, IDictionary<TKey, TValue>
{
}
}

View File

@@ -1,326 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
namespace DICUI.External
{
// Adapted from https://www.codeproject.com/Articles/18615/OrderedDictionary-T-A-generic-implementation-of-IO
public class OrderedDictionary<TKey, TValue> : IOrderedDictionary<TKey, TValue>
{
private List<KeyValuePair<TKey, TValue>> _list;
private Dictionary<TKey, TValue> _dictionary;
#region Interface properties
public int Count { get; }
int ICollection.Count => Count;
int ICollection<KeyValuePair<TKey, TValue>>.Count => Count;
ICollection IDictionary.Keys => _dictionary.Keys;
ICollection<TKey> IDictionary<TKey, TValue>.Keys => _dictionary.Keys;
ICollection IDictionary.Values => _dictionary.Values;
ICollection<TValue> IDictionary<TKey, TValue>.Values => _dictionary.Values;
bool IDictionary.IsReadOnly => false;
bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly => false;
bool IDictionary.IsFixedSize => false;
object ICollection.SyncRoot => new object();
bool ICollection.IsSynchronized => true;
public TValue this[int index]
{
get
{
return _list[index].Value;
}
set
{
if (index >= Count || index < 0)
throw new ArgumentOutOfRangeException("index",
"'index' must be non-negative and less than" +
" the size of the collection");
TKey key = _list[index].Key;
_list[index] = new KeyValuePair<TKey, TValue>(key, value);
_dictionary[key] = value;
}
}
object IOrderedDictionary.this[int index]
{
get
{
return _list[index].Value;
}
set
{
if (index >= Count || index < 0)
throw new ArgumentOutOfRangeException("index",
"'index' must be non-negative and less than" +
" the size of the collection");
var valueObj = (TValue)value;
if (valueObj == null)
throw new ArgumentException($"Value must be of type {typeof(TValue)}");
TKey key = _list[index].Key;
_list[index] = new KeyValuePair<TKey, TValue>(key, valueObj);
_dictionary[key] = valueObj;
}
}
object IDictionary.this[object key]
{
get
{
var keyObj = (TKey)key;
if (keyObj == null)
throw new ArgumentException($"Key must be of type {typeof(TKey)}");
return _dictionary[keyObj];
}
set
{
var keyObj = (TKey)key;
if (keyObj == null)
throw new ArgumentException($"Key must be of type {typeof(TKey)}");
var valueObj = (TValue)value;
if (valueObj == null)
throw new ArgumentException($"Value must be of type {typeof(TValue)}");
if (_dictionary.ContainsKey(keyObj))
{
_dictionary[keyObj] = valueObj;
_list[IndexOfKey(keyObj)] = new KeyValuePair<TKey, TValue>(keyObj, valueObj);
}
else
{
Add(keyObj, valueObj);
}
}
}
TValue IDictionary<TKey, TValue>.this[TKey key]
{
get
{
return _dictionary[key];
}
set
{
if (_dictionary.ContainsKey(key))
{
_dictionary[key] = value;
_list[IndexOfKey(key)] = new KeyValuePair<TKey, TValue>(key, value);
}
else
{
Add(key, value);
}
}
}
#endregion
public OrderedDictionary()
{
_list = new List<KeyValuePair<TKey, TValue>>();
_dictionary = new Dictionary<TKey, TValue>();
Count = 0;
}
public int Add(TKey key, TValue value)
{
_dictionary.Add(key, value);
_list.Add(new KeyValuePair<TKey, TValue>(key, value));
return Count - 1;
}
public void Insert(int index, TKey key, TValue value)
{
if (index > Count || index < 0)
throw new ArgumentOutOfRangeException("index");
_dictionary.Add(key, value);
_list.Insert(index, new KeyValuePair<TKey, TValue>(key, value));
}
void IOrderedDictionary.RemoveAt(int index)
{
if (index >= Count || index < 0)
throw new ArgumentOutOfRangeException("index",
"'index' must be non-negative and less than " +
"the size of the collection");
TKey key = _list[index].Key;
_list.RemoveAt(index);
_dictionary.Remove(key);
}
public bool Remove(TKey key)
{
if (null == key)
throw new ArgumentNullException("key");
int index = IndexOfKey(key);
if (index >= 0)
{
if (_dictionary.Remove(key))
{
_list.RemoveAt(index);
return true;
}
}
return false;
}
public bool ContainsKey(TKey key)
{
return _dictionary.ContainsKey(key);
}
private int IndexOfKey(TKey key)
{
return _list.FindIndex(kvp => kvp.Key.Equals(key));
}
#region Interface methods
IDictionaryEnumerator IOrderedDictionary.GetEnumerator()
{
return _dictionary.GetEnumerator();
}
void IOrderedDictionary.Insert(int index, object key, object value)
{
var keyObj = (TKey)key;
if (keyObj == null)
throw new ArgumentException($"Key must be of type {typeof(TKey)}");
var valueObj = (TValue)value;
if (valueObj == null)
throw new ArgumentException($"Value must be of type {typeof(TValue)}");
Insert(index, keyObj, valueObj);
}
bool IDictionary.Contains(object key)
{
var keyObj = (TKey)key;
if (keyObj == null)
throw new ArgumentException($"Key must be of type {typeof(TKey)}");
return _dictionary.ContainsKey(keyObj);
}
void IDictionary.Add(object key, object value)
{
var keyObj = (TKey)key;
if (keyObj == null)
throw new ArgumentException($"Key must be of type {typeof(TKey)}");
var valueObj = (TValue)value;
if (valueObj == null)
throw new ArgumentException($"Value must be of type {typeof(TValue)}");
Add(keyObj, valueObj);
}
void IDictionary.Clear()
{
_dictionary.Clear();
_list.Clear();
}
IDictionaryEnumerator IDictionary.GetEnumerator()
{
return _dictionary.GetEnumerator();
}
void IDictionary.Remove(object key)
{
var keyObj = (TKey)key;
if (keyObj == null)
throw new ArgumentException($"Key must be of type {typeof(TKey)}");
Remove(keyObj);
}
void ICollection.CopyTo(Array array, int index)
{
var arrayObj = array as KeyValuePair<TKey, TValue>[];
if (arrayObj == null)
throw new ArgumentException($"Key must be of type {typeof(KeyValuePair<TKey, TValue>[])}");
_list.CopyTo(arrayObj, index);
}
bool IDictionary<TKey, TValue>.ContainsKey(TKey key)
{
return ContainsKey(key);
}
void IDictionary<TKey, TValue>.Add(TKey key, TValue value)
{
Add(key, value);
}
bool IDictionary<TKey, TValue>.Remove(TKey key)
{
return Remove(key);
}
bool IDictionary<TKey, TValue>.TryGetValue(TKey key, out TValue value)
{
return _dictionary.TryGetValue(key, out value);
}
void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item)
{
Add(item.Key, item.Value);
}
void ICollection<KeyValuePair<TKey, TValue>>.Clear()
{
_dictionary.Clear();
_list.Clear();
}
bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> item)
{
return _list.Contains(item);
}
void ICollection<KeyValuePair<TKey, TValue>>.CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
{
_list.CopyTo(array, arrayIndex);
}
bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> item)
{
return Remove(item.Key);
}
IEnumerator<KeyValuePair<TKey, TValue>> IEnumerable<KeyValuePair<TKey, TValue>>.GetEnumerator()
{
return _list.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return _list.GetEnumerator();
}
#endregion
}
}

View File

@@ -1,103 +0,0 @@
<Window x:Class="DICUI.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:DICUI"
xmlns:utilities="clr-namespace:DICUI.Utilities"
mc:Ignorable="d"
Title="Disc Image Creator GUI" Height="450" Width="600">
<Window.Resources>
<utilities:EnumDescriptionConverter x:Key="enumConverter" />
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="4*"/>
<ColumnDefinition Width="13*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="4*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<ToolBarTray Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Height="30" HorizontalAlignment="Stretch" IsLocked="True">
<ToolBar>
<Button x:Name="tbr_Options" Content="Options" Click="tbr_Options_Click" />
</ToolBar>
</ToolBarTray>
<GroupBox Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" Margin="5,5,5.2,5.4" HorizontalAlignment="Stretch" Header="Settings"/>
<GroupBox Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" Margin="5,4.6,5.2,4.8" HorizontalAlignment="Stretch" Header="Controls"/>
<GroupBox Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" Margin="5,5.2,5.2,4.8" HorizontalAlignment="Stretch" Header="Status"/>
<Grid Grid.Row="1" Grid.Column="0" Margin="15,25,15.2,10.4" Grid.ColumnSpan="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="2.5*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" Content="System/Media Type" />
<ComboBox x:Name="cmb_SystemType" Grid.Row="0" Grid.Column="1" Height="22" Width="250" HorizontalAlignment="left" SelectionChanged="cmb_SystemType_SelectionChanged" />
<ComboBox x:Name="cmb_MediaType" Grid.Row="0" Grid.Column="1" Height="22" Width="140" HorizontalAlignment="right" SelectionChanged="cmb_MediaType_SelectionChanged">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Converter={StaticResource enumConverter}}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<Label Grid.Row="1" Grid.Column="0" VerticalAlignment="Center">Output Filename</Label>
<TextBox x:Name="txt_OutputFilename" Grid.Row="1" Grid.Column="1" Height="22" TextChanged="txt_OutputFilename_TextChanged" />
<Label Grid.Row="2" Grid.Column="0" VerticalAlignment="Center">Output Directory</Label>
<TextBox x:Name="txt_OutputDirectory" Grid.Row="2" Grid.Column="1" Height="22" Width="345" HorizontalAlignment="left" TextChanged="txt_OutputDirectory_TextChanged" />
<Button x:Name="btn_OutputDirectoryBrowse" Grid.Row="2" Grid.Column="1" Height="22" Width="50" HorizontalAlignment="Right" Content="Browse" Click="btn_OutputDirectoryBrowse_Click"/>
<Label Grid.Row="3" Grid.Column="0" VerticalAlignment="Center">Drive Letter</Label>
<ComboBox x:Name="cmb_DriveLetter" Grid.Row="3" Grid.Column="1" Height="22" Width="60" HorizontalAlignment="left" SelectionChanged="cmb_DriveLetter_SelectionChanged" />
<Label Grid.Row="4" Grid.Column="0" VerticalAlignment="Center">Drive Speed</Label>
<ComboBox x:Name="cmb_DriveSpeed" Grid.Row="4" Grid.Column="1" Height="22" Width="60" HorizontalAlignment="left" SelectionChanged="cmb_DriveSpeed_SelectionChanged" />
<Label Grid.Row="5" Grid.Column="0" VerticalAlignment="Center">Parameters</Label>
<TextBox x:Name="txt_Parameters" Grid.Row="5" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" IsEnabled="False" />
</Grid>
<Grid Grid.Row="2" Grid.Column="0" Margin="15,19.6,15.2,9.8" Grid.ColumnSpan="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
</Grid.RowDefinitions>
<Button x:Name="btn_StartStop" Grid.Row="0" Grid.Column="0" Height="22" Width="150" VerticalAlignment="Center" HorizontalAlignment="Center" Content="Start Dumping" Click="btn_StartStop_Click" IsEnabled="False" />
<Button x:Name="btn_Search" Grid.Row="0" Grid.Column="1" Height="22" Width="150" VerticalAlignment="Center" HorizontalAlignment="Center" Content="Scan for disks" Click="btn_Search_Click" />
<CheckBox x:Name="chk_EjectWhenDone" Grid.Row="0" Grid.Column="2" VerticalAlignment="Center" HorizontalAlignment="Center" Content="Eject When Done" IsChecked="False" />
</Grid>
<Grid Grid.Row="3" Grid.Column="0" Margin="15,20.2,15.2,9.8" Grid.ColumnSpan="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
</Grid.RowDefinitions>
<Label x:Name="lbl_Status" Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Center" Content="Waiting for CD or DVD..." />
</Grid>
</Grid>
</Window>

View File

@@ -1,529 +0,0 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Controls;
using WinForms = System.Windows.Forms;
using DICUI.Data;
using DICUI.Utilities;
namespace DICUI
{
public partial class MainWindow : Window
{
// Private UI-related variables
private List<KeyValuePair<char, string>> _drives { get; set; }
private MediaType? _currentMediaType { get; set; }
private List<int> _driveSpeeds { get { return new List<int> { 1, 2, 3, 4, 6, 8, 12, 16, 20, 24, 32, 40, 44, 48, 52, 56, 72 }; } }
private List<KeyValuePair<string, KnownSystem?>> _systems { get; set; }
private List<MediaType?> _mediaTypes { get; set; }
private DumpEnvironment _env;
// Option related
private Options _options;
private OptionsWindow _optionsWindow;
public MainWindow()
{
InitializeComponent();
// Initializes and load Options object
_options = new Options();
_options.Load();
// Populate the list of systems
PopulateSystems();
// Populate the list of drives
PopulateDrives();
// Populate the list of drive speeds
PopulateDriveSpeeds();
SetSupportedDriveSpeed();
}
#region Events
private void btn_StartStop_Click(object sender, RoutedEventArgs e)
{
// Dump or stop the dump
if ((string)btn_StartStop.Content == UIElements.StartDumping)
{
StartDumping();
}
else if ((string)btn_StartStop.Content == UIElements.StopDumping)
{
Tasks.CancelDumping(_env);
if (chk_EjectWhenDone.IsChecked == true)
{
Tasks.EjectDisc(_env);
}
}
}
private void btn_OutputDirectoryBrowse_Click(object sender, RoutedEventArgs e)
{
BrowseFolder();
EnsureDiscInformation();
}
private void btn_Search_Click(object sender, RoutedEventArgs e)
{
PopulateDrives();
SetCurrentDiscType();
SetSupportedDriveSpeed();
EnsureDiscInformation();
}
private void cmb_SystemType_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
PopulateMediaTypeAccordingToChosenSystem();
GetOutputNames();
EnsureDiscInformation();
}
private void cmb_MediaType_SelectionChanged(object sencder, SelectionChangedEventArgs e)
{
// TODO: This is giving people the benefit of the doubt that their change is valid
_currentMediaType = cmb_MediaType.SelectedItem as MediaType?;
GetOutputNames();
EnsureDiscInformation();
}
private void cmb_DriveLetter_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
SetCurrentDiscType();
SetSupportedDriveSpeed();
GetOutputNames();
EnsureDiscInformation();
}
private void cmb_DriveSpeed_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
EnsureDiscInformation();
}
private void tbr_Options_Click(object sender, RoutedEventArgs e)
{
// lazy initialization
if (_optionsWindow == null)
{
_optionsWindow = new OptionsWindow(_options);
_optionsWindow.Closed += delegate
{
_optionsWindow = null;
};
}
_optionsWindow.Owner = this;
_optionsWindow.WindowStartupLocation = WindowStartupLocation.CenterOwner;
_optionsWindow.Refresh();
_optionsWindow.Show();
}
private void txt_OutputFilename_TextChanged(object sender, TextChangedEventArgs e)
{
EnsureDiscInformation();
}
private void txt_OutputDirectory_TextChanged(object sender, TextChangedEventArgs e)
{
EnsureDiscInformation();
}
#endregion
#region Helpers
/// <summary>
/// Populate disc type according to system type
/// </summary>
private void PopulateMediaTypeAccordingToChosenSystem()
{
var currentSystem = cmb_SystemType.SelectedItem as KeyValuePair<string, KnownSystem?>?;
if (currentSystem != null)
{
_mediaTypes = Validators.GetValidMediaTypes(currentSystem?.Value).ToList();
cmb_MediaType.ItemsSource = _mediaTypes;
cmb_MediaType.IsEnabled = _mediaTypes.Count > 1;
cmb_MediaType.SelectedIndex = 0;
}
else
{
cmb_MediaType.IsEnabled = false;
cmb_MediaType.ItemsSource = null;
cmb_MediaType.SelectedIndex = -1;
}
}
/// <summary>
/// Get a complete list of supported systems and fill the combo box
/// </summary>
private void PopulateSystems()
{
_systems = Validators.CreateListOfSystems()
.Select(i => new KeyValuePair<string, KnownSystem?>(i.Key, i.Value))
.ToList();
cmb_SystemType.ItemsSource = _systems;
cmb_SystemType.DisplayMemberPath = "Key";
cmb_SystemType.SelectedIndex = 0;
btn_StartStop.IsEnabled = false;
}
/// <summary>
/// Get a complete list of active disc drives and fill the combo box
/// </summary>
/// <remarks>TODO: Find a way for this to periodically run, or have it hook to a "drive change" event</remarks>
private void PopulateDrives()
{
// Populate the list of drives and add it to the combo box
_drives = Validators.CreateListOfDrives()
.Select(i => new KeyValuePair<char, string>(i.Key, i.Value))
.ToList();
cmb_DriveLetter.ItemsSource = _drives;
cmb_DriveLetter.DisplayMemberPath = "Key";
if (cmb_DriveLetter.Items.Count > 0)
{
cmb_DriveLetter.SelectedIndex = 0;
lbl_Status.Content = "Valid optical disc found! Choose your Disc Type";
btn_StartStop.IsEnabled = true;
}
else
{
cmb_DriveLetter.SelectedIndex = -1;
lbl_Status.Content = "No valid optical disc found!";
btn_StartStop.IsEnabled = false;
}
}
/// <summary>
/// Get a complete list of (possible) disc drive speeds, and fill the combo box
/// </summary>
private void PopulateDriveSpeeds()
{
cmb_DriveSpeed.ItemsSource = _driveSpeeds;
cmb_DriveSpeed.SelectedItem = 8;
}
/// <summary>
/// Browse for an output folder
/// </summary>
private void BrowseFolder()
{
WinForms.FolderBrowserDialog folderDialog = new WinForms.FolderBrowserDialog { ShowNewFolderButton = false, SelectedPath = System.AppDomain.CurrentDomain.BaseDirectory };
WinForms.DialogResult result = folderDialog.ShowDialog();
if (result == WinForms.DialogResult.OK)
{
txt_OutputDirectory.Text = folderDialog.SelectedPath;
}
}
/// <summary>
/// Create a DumpEnvironment with all current settings
/// </summary>
/// <returns>Filled DumpEnvironment instance</returns>
private DumpEnvironment DetermineEnvironment()
{
// Populate all KVPs
var driveKvp = cmb_DriveLetter.SelectedItem as KeyValuePair<char, string>?;
var systemKvp = cmb_SystemType.SelectedValue as KeyValuePair<string, KnownSystem?>?;
return new DumpEnvironment()
{
// Paths to tools
SubdumpPath = _options.subdumpPath,
DICPath = _options.dicPath,
OutputDirectory = txt_OutputDirectory.Text,
OutputFilename = txt_OutputFilename.Text,
// Get the currently selected options
DriveLetter = (char)driveKvp?.Key,
IsFloppy = (driveKvp?.Value == UIElements.FloppyDriveString),
DICParameters = txt_Parameters.Text,
System = systemKvp?.Value,
Type = cmb_MediaType.SelectedItem as MediaType?
};
}
/// <summary>
/// Begin the dumping process using the given inputs
/// </summary>
private async void StartDumping()
{
_env = DetermineEnvironment();
btn_StartStop.Content = UIElements.StopDumping;
lbl_Status.Content = "Beginning dumping process";
var task = Tasks.StartDumping(_env);
Result result = await task;
lbl_Status.Content = result ? "Dumping complete!" : result.message;
btn_StartStop.Content = UIElements.StartDumping;
if (chk_EjectWhenDone.IsChecked == true)
Tasks.EjectDisc(_env);
}
/// <summary>
/// Ensure information is consistent with the currently selected disc type
/// </summary>
private void EnsureDiscInformation()
{
var systemKvp = cmb_SystemType.SelectedItem as KeyValuePair<string, KnownSystem?>?;
// If we're on a separator, go to the next item and return
if (systemKvp?.Value == null)
{
cmb_SystemType.SelectedIndex++;
return;
}
// Get the selected system info
var selectedSystem = systemKvp?.Value;
MediaType? selectedMediaType = cmb_MediaType.SelectedItem as MediaType? ?? MediaType.NONE;
Result result = GetSupportStatus(selectedSystem, selectedMediaType);
lbl_Status.Content = result.message;
btn_StartStop.IsEnabled = result && (_drives.Count > 0 ? true : false);
// If we're in a type that doesn't support drive speeds
cmb_DriveSpeed.IsEnabled = selectedMediaType.DoesSupportDriveSpeed() && selectedSystem.DoesSupportDriveSpeed();
// Special case for Custom input
if (selectedSystem == KnownSystem.Custom)
{
txt_Parameters.IsEnabled = true;
txt_OutputFilename.IsEnabled = false;
txt_OutputDirectory.IsEnabled = false;
btn_OutputDirectoryBrowse.IsEnabled = false;
cmb_DriveLetter.IsEnabled = false;
cmb_DriveSpeed.IsEnabled = false;
btn_StartStop.IsEnabled = (_drives.Count > 0 ? true : false);
lbl_Status.Content = "User input mode";
}
else
{
txt_Parameters.IsEnabled = false;
txt_OutputFilename.IsEnabled = true;
txt_OutputDirectory.IsEnabled = true;
btn_OutputDirectoryBrowse.IsEnabled = true;
cmb_DriveLetter.IsEnabled = true;
// Populate with the correct params for inputs (if we're not on the default option)
if (selectedSystem != KnownSystem.NONE && selectedMediaType != MediaType.NONE)
{
var driveletter = cmb_DriveLetter.SelectedValue as KeyValuePair<char, string>?;
// If drive letter is invalid, skip this
if (driveletter == null)
return;
string command = Converters.KnownSystemAndMediaTypeToBaseCommand(selectedSystem, selectedMediaType);
List<string> defaultParams = Converters.KnownSystemAndMediaTypeToParameters(selectedSystem, selectedMediaType);
txt_Parameters.Text = command
+ " " + driveletter?.Key
+ " \"" + Path.Combine(txt_OutputDirectory.Text, txt_OutputFilename.Text) + "\" "
+ (selectedMediaType != MediaType.Floppy
&& selectedMediaType != MediaType.BluRay
&& selectedSystem != KnownSystem.MicrosoftXBOX
&& selectedSystem != KnownSystem.MicrosoftXBOX360XDG2
&& selectedSystem != KnownSystem.MicrosoftXBOX360XDG3
? (int)cmb_DriveSpeed.SelectedItem + " " : "")
+ string.Join(" ", defaultParams);
}
}
}
/// <summary>
/// Verify that, given a system and a media type, they are correct
/// </summary>
private Result GetSupportStatus(KnownSystem? system, MediaType? type)
{
// No system chosen, update status
if (system == KnownSystem.NONE)
return Result.Failure("Please select a valid system");
// custom system chosen, then don't check anything
else if (system == KnownSystem.Custom)
return Result.Success("{0} ready to dump", type.Name());
// If we're on an unsupported type, update the status accordingly
switch (type)
{
case MediaType.NONE:
return Result.Failure("Please select a valid disc type");
case MediaType.GameCubeGameDisc:
case MediaType.GDROM:
return Result.Success("{0} discs are partially supported by DIC", type.Name());
case MediaType.HDDVD:
case MediaType.LaserDisc:
case MediaType.CED:
case MediaType.UMD:
case MediaType.WiiOpticalDisc:
case MediaType.WiiUOpticalDisc:
case MediaType.Cartridge:
case MediaType.Cassette:
return Result.Failure("{0} discs are not currently supported by DIC", type.Name());
default:
if (system == KnownSystem.MicrosoftXBOX360XDG3)
{
return Result.Failure("{0} discs are not currently supported by DIC", type.Name());
}
else
{
// TODO: this code should adjust things in a method which is meant to verify values so maybe we can find a better fit
// Take care of the selected item
if (_currentMediaType != null && _currentMediaType != MediaType.NONE)
{
int index = _mediaTypes.IndexOf(_currentMediaType);
if (index != -1)
{
if (cmb_MediaType.SelectedIndex != index)
{
cmb_MediaType.SelectedIndex = index;
}
}
else
{
return Result.Success("Disc of type {0} found, but the current system does not support it!", type.Name());
}
}
}
break;
}
return Result.Success("{0} ready to dump", type.Name());
}
/// <summary>
/// Get the default output directory name from the currently selected drive
/// </summary>
private void GetOutputNames()
{
var driveKvp = cmb_DriveLetter.SelectedItem as KeyValuePair<char, string>?;
var systemKvp = cmb_SystemType.SelectedItem as KeyValuePair<string, KnownSystem?>?;
MediaType? mediaType = cmb_MediaType.SelectedItem as MediaType?;
if (driveKvp != null
&& !String.IsNullOrWhiteSpace(driveKvp?.Value)
&& driveKvp?.Value != UIElements.FloppyDriveString
&& systemKvp != null
&& mediaType != null)
{
txt_OutputDirectory.Text = Path.Combine(_options.defaultOutputPath, driveKvp?.Value);
txt_OutputFilename.Text = driveKvp?.Value + mediaType.Extension();
}
else
{
txt_OutputDirectory.Text = _options.defaultOutputPath;
txt_OutputFilename.Text = "disc.bin";
}
}
/// <summary>
/// Get the highest supported drive speed as reported by DiscImageCreator
/// </summary>
private void SetSupportedDriveSpeed()
{
// Set generic drive speed just in case
cmb_DriveSpeed.SelectedItem = 8;
// Get the drive letter from the selected item
var selected = cmb_DriveLetter.SelectedItem as KeyValuePair<char, string>?;
if (selected == null || (selected?.Value == UIElements.FloppyDriveString))
{
return;
}
//Validators.GetDriveSpeed((char)selected?.Key);
//Validators.GetDriveSpeedEx((char)selected?.Key, MediaType.CD);
// Validate that the required program exists and it's not DICUI itself
if (!File.Exists(_options.dicPath) ||
Path.GetFullPath(_options.dicPath) == Path.GetFullPath(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName))
{
return;
}
char driveLetter = (char)selected?.Key;
Process childProcess = new Process()
{
StartInfo = new ProcessStartInfo()
{
FileName = _options.dicPath,
Arguments = DICCommands.DriveSpeed + " " + driveLetter,
CreateNoWindow = true,
UseShellExecute = false,
RedirectStandardOutput = true,
},
};
childProcess.Start();
childProcess.WaitForExit();
string output = childProcess.StandardOutput.ReadToEnd();
int index = output.IndexOf("ReadSpeedMaximum:");
string readspeed = Regex.Match(output.Substring(index), @"ReadSpeedMaximum: [0-9]+KB/sec \(([0-9]*)x\)").Groups[1].Value;
if (!Int32.TryParse(readspeed, out int speed) || speed <= 0)
{
return;
}
// If the value is in the list, we can set it immediately
if (_driveSpeeds.Contains(speed))
cmb_DriveSpeed.SelectedValue = speed;
// Otherwise, we need to set the next lowest value
else
cmb_DriveSpeed.SelectedValue = _driveSpeeds.Where(s => s < speed).Last();
}
/// <summary>
/// Set the current disc type in the combo box
/// </summary>
private void SetCurrentDiscType()
{
// Get the drive letter from the selected item
var selected = cmb_DriveLetter.SelectedItem as KeyValuePair<char, string>?;
if (selected == null || (selected?.Value == UIElements.FloppyDriveString))
{
return;
}
// Get the current optical disc type
_currentMediaType = Validators.GetDiscType(selected?.Key);
// If we have an invalid current type, we don't care and return
if (_currentMediaType == null || _currentMediaType == MediaType.NONE)
{
return;
}
// Now set the selected item, if possible
int index = _mediaTypes.FindIndex(kvp => kvp.Value == _currentMediaType);
if (index != -1)
{
cmb_MediaType.SelectedIndex = index;
}
else
{
lbl_Status.Content = $"Disc of type '{Converters.MediaTypeToString(_currentMediaType)}' found, but the current system does not support it!";
}
}
#endregion
}
}

View File

@@ -1,50 +0,0 @@
using System;
using System.Configuration;
using System.Reflection;
namespace DICUI
{
public class Options
{
public string defaultOutputPath { get; private set; }
public string dicPath { get; private set; }
public string subdumpPath { get; private set; }
public void Save()
{
Configuration configFile = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
//TODO: reflection is used
Array.ForEach(
GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance),
p => {
configFile.AppSettings.Settings.Remove(p.Name);
configFile.AppSettings.Settings.Add(p.Name, p.GetValue(this) as string);
}
);
configFile.Save(ConfigurationSaveMode.Modified);
}
public void Load()
{
//TODO: hardcoded, we should find a better way
dicPath = ConfigurationManager.AppSettings["dicPath"] ?? @"Programs\DiscImageCreator.exe";
subdumpPath = ConfigurationManager.AppSettings["subdumpPath"] ?? "subdump.exe";
defaultOutputPath = ConfigurationManager.AppSettings["defaultOutputPath"] ?? "ISO";
}
//TODO: probably should be generic for non-string options
//TODO: using reflection for Set and Get is orthodox but it works, should be changed to a key,value map probably
public void Set(string key, string value)
{
GetType().GetProperty(key, BindingFlags.Public | BindingFlags.Instance).SetValue(this, value);
}
public string Get(string key)
{
return GetType().GetProperty(key, BindingFlags.Public | BindingFlags.Instance).GetValue(this) as string;
}
}
}

View File

@@ -1,59 +0,0 @@
<Window x:Class="DICUI.OptionsWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:DICUI"
mc:Ignorable="d"
Title="Options" Height="260" Width="515.132">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="40"/>
</Grid.RowDefinitions>
<GroupBox Grid.Column="0" Margin="5,5,5,5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Header="Paths">
<Grid Margin="10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="2.0*" />
<ColumnDefinition Width="0.2*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="DicImageCreator Path:" FontWeight="Bold"/>
<TextBox x:Name="txt_dicPath" Grid.Row="0" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />
<Button x:Name="btn_dicPath" Grid.Row="0" Grid.Column="2" Height="22" Width="22" Content="..." Click="btn_BrowseForPath_Click" />
<Label Grid.Row="1" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="subdump Path:" FontWeight="Bold"/>
<TextBox x:Name="txt_subdumpPath" Grid.Row="1" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />
<Button x:Name="btn_subdumpPath" Grid.Row="1" Grid.Column="2" Height="22" Width="22" Content="..." Click="btn_BrowseForPath_Click"/>
<Label Grid.Row="2" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Default Output Path:" FontWeight="Bold"/>
<TextBox x:Name="txt_defaultOutputPath" Grid.Row="2" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />
<Button x:Name="btn_defaultOutputPath" Grid.Row="2" Grid.Column="2" Height="22" Width="22" Content="..." Click="btn_BrowseForPath_Click" />
</Grid>
</GroupBox>
<Grid Height="22" Grid.Row="1" Grid.Column="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Button x:Name="btn_Accept" Grid.Row="0" Grid.Column="1" Height="22" Width="80" Content="Accept" Click="btn_Accept_Click" />
<Button x:Name="btn_Cancel" Grid.Row="0" Grid.Column="2" Height="22" Width="80" Content="Cancel" Click="btn_Cancel_Click" />
</Grid>
</Grid>
</Window>

View File

@@ -2,16 +2,20 @@
DiscImageCreator UI in C#
[![Build status](https://ci.appveyor.com/api/projects/status/3ldav3v0c373jeqa?svg=true)](https://ci.appveyor.com/project/mnadareski/dicui/build/artifacts)
This is a community project, so if you have some time and knowledge to give, we'll be glad to add you to the contributor of this project :)
We are using DiscImageCreator (DIC), created by Sarami, and we would like to thanks him for his great software. The latest release of DIC can be found on [the GitHub page](https://github.com/saramibreak/DiscImageCreator)
This project relies on two open-source code ports to help perform copy protection scanning: [BurnOutSharp](https://github.com/mnadareski/BurnOutSharp) and [UnshieldSharp](https://github.com/mnadareski/UnshieldSharp)
## System Requirements
Even though this is written in C#, this program can only be used on Windows systems due to the base program, DiscImageCreator, being Windows-only.
Even though this is written in C#, this program can only be used on Windows systems due to the base program, DiscImageCreator, being Windows-only. There is some preliminary support for Linux underway, and we will try to integrate with that when the time comes.
- Windows 7 (newest version of Windows recommended)
- .NET Framework 4.6.1 Runtimes
- .NET Framework 4.6.2, .NET Framework 4.7.2, or .NET Core 3.0 Runtimes
- 128 MB of free RAM
- As much hard drive space as amount of discs you will be dumping (20+ GB recommended)
@@ -19,23 +23,29 @@ Ensure that your operating system is as up-to-date as possible, since some featu
## Releases
Download the latest release here:
[https://github.com/reignstumble/DICUI/releases](https://github.com/reignstumble/DICUI/releases)
For those who would rather the most recently stable build, ownload the latest release here:
[Releases Page](https://github.com/SabreTools/DICUI/releases)
For those who like to test the newest features, download the latest AppVeyor WIP build here: [AppVeyor](https://ci.appveyor.com/project/mnadareski/dicui/build/artifacts)
## Changelist
A list of all changes can now be found [here](https://github.com/reignstumble/DICUI/blob/master/CHANGELIST.md).
A list of all changes can now be found [here](https://github.com/SabreTools/DICUI/blob/master/CHANGELIST.md).
## Contributors
Here are the talented people who have contributed to the project so far:
**ReignStumble** - Project Lead / UI Design
- **darksabre76** - Project Lead / Backend Design
- **ReignStumble** - Former Project Lead / UI Design
- **Jakz** - Primary Feature Contributor
- **NHellFire** - Feature Contributor
**darksabre76** - Project Co-Lead / Backend Design
## Notable Testers
**Jakz** - Feature Contributor
These are the tireless individuals who have dedicated countless hours to help test the many features of DICUI and have worked with the development team closely:
**NHellFire** - Feature Contributor
**Dizzzy** - Concept/Ideas/Beta tester
- **Dizzzy/user7** - Concept, ideas, tester
- **Kludge** - Primary stress tester
- **ajshell1** - Tester
- **eientei95** - Tester

291
Tasks.cs
View File

@@ -1,291 +0,0 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using DICUI.Data;
using DICUI.Utilities;
namespace DICUI
{
/// <summary>
/// Generic success/failure result object, with optional message
/// </summary>
public class Result
{
private bool success;
public string message { get; private set; }
private Result(bool success, string message)
{
this.success = success;
this.message = message;
}
public static Result Success() => new Result(true, "");
public static Result Success(string message) => new Result(true, message);
public static Result Success(string message, params object[] args) => new Result(true, string.Format(message, args));
public static Result Failure(string message) => new Result(false, message);
public static Result Failure(string message, params object[] args) => new Result(false, string.Format(message, args));
public static implicit operator bool(Result result) => result.success;
}
/// <summary>
/// Represents the state of all settings to be used during dumping
/// </summary>
public class DumpEnvironment
{
// Tool paths
public string DICPath;
public string SubdumpPath;
// Output paths
public string OutputDirectory;
public string OutputFilename;
// UI information
public char DriveLetter;
public KnownSystem? System;
public MediaType? Type;
public bool IsFloppy;
public string DICParameters;
// External process information
public Process dicProcess;
/// <summary>
/// Checks if the configuration is valid
/// </summary>
/// <returns>True if the configuration is valid, false otherwise</returns>
public bool IsConfigurationValid()
{
return !((string.IsNullOrWhiteSpace(DICParameters)
|| !Validators.ValidateParameters(DICParameters)
|| (IsFloppy ^ Type == Data.MediaType.Floppy)));
}
/// <summary>
/// Adjust the current environment if we are given custom parameters
/// </summary>
public void AdjustForCustomConfiguration()
{
// If we have a custom configuration, we need to extract the best possible information from it
if (System == KnownSystem.Custom)
{
Validators.DetermineFlags(DICParameters, out Type, out System, out string letter, out string path);
DriveLetter = letter[0];
OutputDirectory = Path.GetDirectoryName(path);
OutputFilename = Path.GetFileName(path);
}
}
/// <summary>
/// Fix the output paths to remove characters that DiscImageCreator can't handle
/// </summary>
/// <remarks>
/// TODO: Investigate why the `&` replacement is needed
/// </remarks>
public void FixOutputPaths()
{
OutputDirectory = OutputDirectory.Replace('.', '_').Replace('&', '_');
OutputFilename = new StringBuilder(OutputFilename.Replace('&', '_')).Replace('.', '_', 0, OutputFilename.LastIndexOf('.')).ToString();
}
}
/// <summary>
/// Class containing dumping tasks
/// </summary>
public class Tasks
{
/// <summary>
/// Validate the current DumpEnvironment
/// </summary>
/// <param name="env">DumpEnvirionment containing all required information</param>
/// <returns>Result instance with the outcome</returns>
public static Result ValidateEnvironment(DumpEnvironment env)
{
// Validate that everything is good
if (!env.IsConfigurationValid())
return Result.Failure("Error! Current configuration is not supported!");
env.AdjustForCustomConfiguration();
env.FixOutputPaths();
// Validate that the required program exists
if (!File.Exists(env.DICPath))
return Result.Failure("Error! Could not find DiscImageCreator!");
// If a complete dump already exists
if (DumpInformation.FoundAllFiles(env.OutputDirectory, env.OutputFilename, env.Type))
{
MessageBoxResult result = MessageBox.Show("A complete dump already exists! Are you sure you want to overwrite?", "Overwrite?", MessageBoxButton.YesNo, MessageBoxImage.Exclamation);
if (result == MessageBoxResult.No || result == MessageBoxResult.Cancel || result == MessageBoxResult.None)
{
return Result.Failure("Dumping aborted!");
}
}
return Result.Success();
}
/// <summary>
/// Run DiscImageCreator with the given DumpEnvironment
/// </summary>
/// <param name="env">DumpEnvirionment containing all required information</param>
public static void ExecuteDiskImageCreator(DumpEnvironment env)
{
env.dicProcess = new Process()
{
StartInfo = new ProcessStartInfo()
{
FileName = env.DICPath,
Arguments = env.DICParameters,
},
};
env.dicProcess.Start();
env.dicProcess.WaitForExit();
}
/// <summary>
/// Execute subdump for a (potential) Sega Saturn dump
/// </summary>
/// <param name="env">DumpEnvirionment containing all required information</param>
public static async void ExecuteSubdump(DumpEnvironment env)
{
await Task.Run(() =>
{
Process childProcess = new Process()
{
StartInfo = new ProcessStartInfo()
{
FileName = env.SubdumpPath,
Arguments = "-i " + env.DriveLetter + ": -f " + Path.Combine(env.OutputDirectory, Path.GetFileNameWithoutExtension(env.OutputFilename) + "_subdump.sub") + "-mode 6 -rereadnum 25 -fix 2",
},
};
childProcess.Start();
childProcess.WaitForExit();
});
}
/// <summary>
/// Run any additional tools given a DumpEnvironment
/// </summary>
/// <param name="env">DumpEnvirionment containing all required information</param>
/// <returns>Result instance with the outcome</returns>
public static Result ExecuteAdditionalToolsAfterDIC(DumpEnvironment env)
{
// Special cases
switch (env.System)
{
case KnownSystem.SegaSaturn:
if (!File.Exists(env.SubdumpPath))
return Result.Failure("Error! Could not find subdump!");
ExecuteSubdump(env);
break;
}
return Result.Success();
}
/// <summary>
/// Verify that the current environment has a complete dump and create submission info is possible
/// </summary>
/// <param name="env">DumpEnvirionment containing all required information</param>
/// <returns>Result instance with the outcome</returns>
public static Result VerifyAndSaveDumpOutput(DumpEnvironment env)
{
// Check to make sure that the output had all the correct files
if (!DumpInformation.FoundAllFiles(env.OutputDirectory, env.OutputFilename, env.Type))
return Result.Failure("Error! Please check output directory as dump may be incomplete!");
Dictionary<string, string> templateValues = DumpInformation.ExtractOutputInformation(env.OutputDirectory, env.OutputFilename, env.System, env.Type, env.DriveLetter);
List<string> formattedValues = DumpInformation.FormatOutputData(templateValues, env.System, env.Type);
bool success = DumpInformation.WriteOutputData(env.OutputDirectory, env.OutputFilename, formattedValues);
return Result.Success();
}
/// <summary>
/// Eject the disc using DIC
/// </summary>
public static async void EjectDisc(DumpEnvironment env)
{
// Validate that the required program exists
if (!File.Exists(env.DICPath))
return;
CancelDumping(env);
if (env.IsFloppy)
return;
Process childProcess;
await Task.Run(() =>
{
childProcess = new Process()
{
StartInfo = new ProcessStartInfo()
{
FileName = env.DICPath,
Arguments = DICCommands.Eject + " " + env.DriveLetter,
CreateNoWindow = true,
UseShellExecute = false,
RedirectStandardOutput = true,
},
};
childProcess.Start();
childProcess.WaitForExit();
});
}
/// <summary>
/// Cancel an in-progress dumping process
/// </summary>
public static void CancelDumping(DumpEnvironment env)
{
try
{
if (env.dicProcess != null && !env.dicProcess.HasExited)
env.dicProcess.Kill();
}
catch
{ }
}
/// <summary>
/// This executes the complete dump workflow on a DumpEnvironment
/// </summary>
public static async Task<Result> StartDumping(DumpEnvironment env)
{
Result result = Tasks.ValidateEnvironment(env);
// is something is wrong in environment return
if (!result)
return result;
// execute DIC
await Task.Run(() => Tasks.ExecuteDiskImageCreator(env));
// execute additional tools
result = Tasks.ExecuteAdditionalToolsAfterDIC(env);
// is something is wrong with additional tools report and return
// TODO: don't return, just keep generating output from DIC
/*if (!result.Item1)
{
lbl_Status.Content = result.Item2;
btn_StartStop.Content = UIElements.StartDumping;
return;
}*/
// verify dump output and save it
result = Tasks.VerifyAndSaveDumpOutput(env);
return result;
}
}
}

View File

@@ -1,601 +0,0 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Windows.Data;
using IMAPI2;
using DICUI.Data;
namespace DICUI.Utilities
{
/// <summary>
/// Extensions for MediaType? for easier calling
/// </summary>
public static class MediaTypeExtensions
{
public static string Name(this MediaType? type)
{
return Converters.MediaTypeToString(type);
}
public static string Extension(this MediaType? type)
{
return Converters.MediaTypeToExtension(type);
}
public static bool DoesSupportDriveSpeed(this MediaType? type)
{
return type != MediaType.BluRay && type != MediaType.Floppy;
}
}
/// <summary>
/// Extensions for KnownSystem? for easier calling
/// </summary>
public static class KnownSystemExtensions
{
public static bool DoesSupportDriveSpeed(this KnownSystem? system)
{
return system != KnownSystem.MicrosoftXBOX
&& system != KnownSystem.MicrosoftXBOX360XDG2
&& system != KnownSystem.MicrosoftXBOX360XDG3;
}
}
/// <summary>
/// Used to provide a converter to XAML files to render comboboxes with enum values
/// </summary>
public class EnumDescriptionConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is MediaType?)
return ((MediaType?)value).Name();
else
return "";
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return string.Empty;
}
}
public static class Converters
{
/// <summary>
/// Get the MediaType associated with a given base command
/// </summary>
/// <param name="baseCommand">String value to check</param>
/// <returns>MediaType if possible, null on error</returns>
/// <remarks>This takes the "safe" route by assuming the larger of any given format</remarks>
public static MediaType? BaseCommmandToMediaType(string baseCommand)
{
switch (baseCommand)
{
case DICCommands.CompactDisc:
return MediaType.CD;
case DICCommands.GDROM:
case DICCommands.Swap:
return MediaType.GDROM;
case DICCommands.DigitalVideoDisc:
case DICCommands.XBOX:
return MediaType.DVD;
case DICCommands.BluRay:
return MediaType.BluRay;
// Non-optical
case DICCommands.Floppy:
return MediaType.Floppy;
default:
return null;
}
}
/// <summary>
/// Get the most common known system for a given MediaType
/// </summary>
/// <param name="baseCommand">String value to check</param>
/// <returns>KnownSystem if possible, null on error</returns>
public static KnownSystem? BaseCommandToKnownSystem(string baseCommand)
{
switch (baseCommand)
{
case DICCommands.CompactDisc:
case DICCommands.DigitalVideoDisc:
case DICCommands.Floppy:
return KnownSystem.IBMPCCompatible;
case DICCommands.GDROM:
case DICCommands.Swap:
return KnownSystem.SegaDreamcast;
case DICCommands.BluRay:
return KnownSystem.SonyPlayStation3;
case DICCommands.XBOX:
return KnownSystem.MicrosoftXBOX;
default:
return null;
}
}
/// <summary>
/// Convert IMAPI physical media type to a MediaType
/// </summary>
/// <param name="type">IMAPI_MEDIA_PHYSICAL_TYPE value to check</param>
/// <returns>MediaType if possible, null on error</returns>
public static MediaType? IMAPIDiskTypeToMediaType(IMAPI_MEDIA_PHYSICAL_TYPE type)
{
switch (type)
{
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_UNKNOWN:
return MediaType.NONE;
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_CDROM:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_CDR:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_CDRW:
return MediaType.CD;
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDROM:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDRAM:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDPLUSR:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDPLUSRW:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDPLUSR_DUALLAYER:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDDASHR:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDDASHRW:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDDASHR_DUALLAYER:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DISK:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDPLUSRW_DUALLAYER:
return MediaType.DVD;
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_HDDVDROM:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_HDDVDR:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_HDDVDRAM:
return MediaType.HDDVD;
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_BDROM:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_BDR:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_BDRE:
return MediaType.BluRay;
default:
return null;
}
}
/// <summary>
/// Get the default extension for a given disc type
/// </summary>
/// <param name="type">MediaType value to check</param>
/// <returns>Valid extension (with leading '.'), null on error</returns>
public static string MediaTypeToExtension(MediaType? type)
{
switch (type)
{
case MediaType.CD:
case MediaType.GDROM:
case MediaType.Cartridge:
return ".bin";
case MediaType.DVD:
case MediaType.HDDVD:
case MediaType.BluRay:
case MediaType.WiiOpticalDisc:
case MediaType.UMD:
return ".iso";
case MediaType.LaserDisc:
case MediaType.GameCubeGameDisc:
return ".raw";
case MediaType.WiiUOpticalDisc:
return ".wud";
case MediaType.Floppy:
return ".img";
case MediaType.Cassette:
return ".wav";
case MediaType.NONE:
case MediaType.CED:
default:
return null;
}
}
/// <summary>
/// Get the string representation of the MediaType enum values
/// </summary>
/// <param name="type">MediaType value to convert</param>
/// <returns>String representing the value, if possible</returns>
public static string MediaTypeToString(MediaType? type)
{
switch (type)
{
case MediaType.CD:
return "CD-ROM";
case MediaType.DVD:
return "DVD";
case MediaType.GDROM:
return "GD-ROM";
case MediaType.HDDVD:
return "HD-DVD";
case MediaType.BluRay:
return "BluRay";
case MediaType.LaserDisc:
return "LaserDisc";
case MediaType.CED:
return "CED";
case MediaType.GameCubeGameDisc:
return "GameCube Game";
case MediaType.WiiOpticalDisc:
return "Wii Optical";
case MediaType.WiiUOpticalDisc:
return "Wii U Optical";
case MediaType.UMD:
return "UMD";
case MediaType.Cartridge:
return "Cartridge";
case MediaType.Cassette:
return "Cassette Tape";
case MediaType.Floppy:
return "Floppy Disk";
case MediaType.NONE:
default:
return "Unknown";
}
}
/// <summary>
/// Get the DIC command to be used for a given MediaType
/// </summary>
/// <param name="type">MediaType value to check</param>
/// <returns>String containing the command, null on error</returns>
public static string KnownSystemAndMediaTypeToBaseCommand(KnownSystem? sys, MediaType? type)
{
switch (type)
{
case MediaType.CD:
if (sys == KnownSystem.MicrosoftXBOX)
{
return DICCommands.XBOX;
}
return DICCommands.CompactDisc;
case MediaType.DVD:
if (sys == KnownSystem.MicrosoftXBOX
|| sys == KnownSystem.MicrosoftXBOX360XDG2
|| sys == KnownSystem.MicrosoftXBOX360XDG3)
{
return DICCommands.XBOX;
}
return DICCommands.DigitalVideoDisc;
case MediaType.GDROM:
return DICCommands.GDROM;
case MediaType.HDDVD:
return null;
case MediaType.BluRay:
return DICCommands.BluRay;
// Special Formats
case MediaType.GameCubeGameDisc:
return DICCommands.DigitalVideoDisc;
case MediaType.WiiOpticalDisc:
return null;
case MediaType.WiiUOpticalDisc:
return null;
case MediaType.UMD:
return null;
// Non-optical
case MediaType.Floppy:
return DICCommands.Floppy;
default:
return null;
}
}
/// <summary>
/// Get list of default parameters for a given system and disc type
/// </summary>
/// <param name="sys">KnownSystem value to check</param>
/// <param name="type">MediaType value to check</param>
/// <returns>List of strings representing the parameters</returns>
public static List<string> KnownSystemAndMediaTypeToParameters(KnownSystem? sys, MediaType? type)
{
// First check to see if the combination of system and MediaType is valid
var validTypes = Validators.GetValidMediaTypes(sys);
if (!validTypes.Contains(type))
{
return null;
}
// Now sort based on disc type
List<string> parameters = new List<string>();
switch (type)
{
case MediaType.CD:
parameters.Add(DICFlags.C2Opcode); parameters.Add("20");
switch (sys)
{
case KnownSystem.AppleMacintosh:
case KnownSystem.IBMPCCompatible:
parameters.Add(DICFlags.NoFixSubQSecuROM);
parameters.Add(DICFlags.ScanFileProtect);
parameters.Add(DICFlags.ScanSectorProtect);
break;
case KnownSystem.NECPCEngineTurboGrafxCD:
parameters.Add(DICFlags.MCN);
break;
case KnownSystem.SonyPlayStation:
parameters.Add(DICFlags.ScanAntiMod);
parameters.Add(DICFlags.NoFixSubQLibCrypt);
break;
}
break;
case MediaType.DVD:
// Currently no defaults set
break;
case MediaType.GDROM:
parameters.Add(DICFlags.C2Opcode); parameters.Add("20");
break;
case MediaType.HDDVD:
break;
case MediaType.BluRay:
// Currently no defaults set
break;
// Special Formats
case MediaType.GameCubeGameDisc:
parameters.Add(DICFlags.Raw);
break;
case MediaType.WiiOpticalDisc:
// Currently no defaults set
break;
case MediaType.WiiUOpticalDisc:
// Currently no defaults set
break;
case MediaType.UMD:
break;
// Non-optical
case MediaType.Floppy:
// Currently no defaults set
break;
}
return parameters;
}
/// <summary>
/// Get the string representation of the KnownSystem enum values
/// </summary>
/// <param name="sys">KnownSystem value to convert</param>
/// <returns>String representing the value, if possible</returns>
public static string KnownSystemToString(KnownSystem? sys)
{
switch (sys)
{
#region Consoles
case KnownSystem.BandaiPlaydiaQuickInteractiveSystem:
return "Bandai Playdia Quick Interactive System";
case KnownSystem.BandaiApplePippin:
return "Bandai / Apple Pippin";
case KnownSystem.CommodoreAmigaCD32:
return "Commodore Amiga CD32";
case KnownSystem.CommodoreAmigaCDTV:
return "Commodore Amiga CDTV";
case KnownSystem.MattelHyperscan:
return "Mattel HyperScan";
case KnownSystem.MicrosoftXBOX:
return "Microsoft XBOX";
case KnownSystem.MicrosoftXBOX360XDG2:
return "Microsoft XBOX 360 (XDG2)";
case KnownSystem.MicrosoftXBOX360XDG3:
return "Microsoft XBOX 360 (XDG3)";
case KnownSystem.MicrosoftXBOXOne:
return "Microsoft XBOX One";
case KnownSystem.NECPCEngineTurboGrafxCD:
return "NEC PC-Engine / TurboGrafx CD";
case KnownSystem.NECPCFX:
return "NEC PC-FX / PC-FXGA";
case KnownSystem.NintendoGameCube:
return "Nintendo GameCube";
case KnownSystem.NintendoWii:
return "Nintendo Wii";
case KnownSystem.NintendoWiiU:
return "Nintendo Wii U";
case KnownSystem.Panasonic3DOInteractiveMultiplayer:
return "Panasonic 3DO Interactive Multiplayer";
case KnownSystem.PhilipsCDi:
return "Philips CD-i";
case KnownSystem.SegaCDMegaCD:
return "Sega CD / Mega CD";
case KnownSystem.SegaDreamcast:
return "Sega Dreamcast";
case KnownSystem.SegaSaturn:
return "Sega Saturn";
case KnownSystem.SNKNeoGeoCD:
return "SNK Neo Geo CD";
case KnownSystem.SonyPlayStation:
return "Sony PlayStation";
case KnownSystem.SonyPlayStation2:
return "Sony PlayStation 2";
case KnownSystem.SonyPlayStation3:
return "Sony PlayStation 3";
case KnownSystem.SonyPlayStation4:
return "Sony PlayStation 4";
case KnownSystem.SonyPlayStationPortable:
return "Sony PlayStation Portable";
case KnownSystem.VMLabsNuon:
return "VM Labs NUON";
case KnownSystem.VTechVFlashVSmilePro:
return "VTech V.Flash - V.Smile Pro";
case KnownSystem.ZAPiTGamesGameWaveFamilyEntertainmentSystem:
return "ZAPiT Games Game Wave Family Entertainment System";
#endregion
#region Computers
case KnownSystem.AcornArchimedes:
return "Acorn Archimedes";
case KnownSystem.AppleMacintosh:
return "Apple Macintosh";
case KnownSystem.CommodoreAmigaCD:
return "Commodore Amiga CD";
case KnownSystem.FujitsuFMTowns:
return "Fujitsu FM Towns series";
case KnownSystem.IBMPCCompatible:
return "IBM PC Compatible";
case KnownSystem.NECPC88:
return "NEC PC-88";
case KnownSystem.NECPC98:
return "NEC PC-98";
case KnownSystem.SharpX68000:
return "Sharp X68000";
#endregion
#region Arcade
case KnownSystem.AmigaCUBOCD32:
return "Amiga CUBO CD32";
case KnownSystem.AmericanLaserGames3DO:
return "American Laser Games 3DO";
case KnownSystem.Atari3DO:
return "Atari 3DO";
case KnownSystem.Atronic:
return "Atronic";
case KnownSystem.AUSCOMSystem1:
return "AUSCOM System 1";
case KnownSystem.BallyGameMagic:
return "Bally Game Magic";
case KnownSystem.CapcomCPSystemIII:
return "Capcom CP System III";
case KnownSystem.GlobalVRVarious:
return "Global VR PC-based Systems";
case KnownSystem.GlobalVRVortek:
return "Global VR Vortek";
case KnownSystem.GlobalVRVortekV3:
return "Global VR Vortek V3";
case KnownSystem.ICEPCHardware:
return "ICE PC-based Hardware";
case KnownSystem.IncredibleTechnologiesEagle:
return "Incredible Technologies Eagle";
case KnownSystem.IncredibleTechnologiesVarious:
return "Incredible Technologies PC-based Systems";
case KnownSystem.KonamiFirebeat:
return "Konami Firebeat";
case KnownSystem.KonamiGVSystem:
return "Konami GV System";
case KnownSystem.KonamiM2:
return "Konami M2";
case KnownSystem.KonamiPython:
return "Konami Python";
case KnownSystem.KonamiPython2:
return "Konami Python 2";
case KnownSystem.KonamiSystem573:
return "Konami System 573";
case KnownSystem.KonamiTwinkle:
return "Konami Twinkle";
case KnownSystem.KonamiVarious:
return "Konami PC-based Systems";
case KnownSystem.MeritIndustriesBoardwalk:
return "Merit Industries Boardwalk";
case KnownSystem.MeritIndustriesMegaTouchAurora:
return "Merit Industries MegaTouch Aurora";
case KnownSystem.MeritIndustriesMegaTouchForce:
return "Merit Industries MegaTouch Force";
case KnownSystem.MeritIndustriesMegaTouchION:
return "Merit Industries MegaTouch ION";
case KnownSystem.MeritIndustriesMegaTouchMaxx:
return "Merit Industries MegaTouch Maxx";
case KnownSystem.MeritIndustriesMegaTouchXL:
return "Merit Industries MegaTouch XL";
case KnownSystem.NamcoCapcomSystem256:
return "Namco / Capcom System 256/Super System 256";
case KnownSystem.NamcoCapcomTaitoSystem246:
return "Namco / Capcom / Taito System 246";
case KnownSystem.NamcoSegaNintendoTriforce:
return "Namco / Sega / Nintendo Triforce";
case KnownSystem.NamcoSystem12:
return "Namco System 12";
case KnownSystem.NamcoSystem357:
return "Namco System 357";
case KnownSystem.NewJatreCDi:
return "New Jatre CD-i";
case KnownSystem.NichibutsuHighRateSystem:
return "Nichibutsu High Rate System";
case KnownSystem.NichibutsuSuperCD:
return "Nichibutsu Super CD";
case KnownSystem.NichibutsuXRateSystem:
return "NichibutsuX-Rate System";
case KnownSystem.PhotoPlayVarious:
return "PhotoPlay PC-based Systems";
case KnownSystem.RawThrillsVarious:
return "Raw Thrills PC-based Systems";
case KnownSystem.SegaChihiro:
return "Sega Chihiro";
case KnownSystem.SegaEuropaR:
return "Sega Europa-R";
case KnownSystem.SegaLindbergh:
return "Sega Lindbergh";
case KnownSystem.SegaNaomi:
return "Sega Naomi";
case KnownSystem.SegaNaomi2:
return "Sega Naomi 2";
case KnownSystem.SegaNu:
return "Sega Nu";
case KnownSystem.SegaRingEdge:
return "Sega RingEdge";
case KnownSystem.SegaRingEdge2:
return "Sega RingEdge 2";
case KnownSystem.SegaRingWide:
return "Sega RingWide";
case KnownSystem.SegaSTV:
return "Sega STV";
case KnownSystem.SegaSystem32:
return "Sega System 32";
case KnownSystem.SeibuCATSSystem:
return "Seibu CATS System";
case KnownSystem.TABAustriaQuizard:
return "TAB-Austria Quizard";
case KnownSystem.TandyMemorexVisualInformationSystem:
return "Tandy / Memorex Visual Information System";
case KnownSystem.TsunamiTsuMoMultiGameMotionSystem:
return "Tsunami TsuMo Multi-Game Motion System";
#endregion
#region Others
case KnownSystem.AudioCD:
return "Audio CD";
case KnownSystem.BDVideo:
return "BD-Video";
case KnownSystem.DVDVideo:
return "DVD-Video";
case KnownSystem.EnhancedCD:
return "Enhanced CD";
case KnownSystem.HDDVDVideo:
return "HD-DVD-Video";
case KnownSystem.PalmOS:
return "PalmOS";
case KnownSystem.PhilipsCDiDigitalVideo:
return "Philips CD-i Digital Video";
case KnownSystem.PhotoCD:
return "Photo CD";
case KnownSystem.PlayStationGameSharkUpdates:
return "PlayStation GameShark Updates";
case KnownSystem.TaoiKTV:
return "Tao iKTV";
case KnownSystem.TomyKissSite:
return "Tomy Kiss-Site";
case KnownSystem.VideoCD:
return "Video CD";
#endregion
case KnownSystem.Custom:
return "Custom Input";
case KnownSystem.NONE:
default:
return "Unknown";
}
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,8 +1,12 @@
# version format
version: 1.06_{build}
version: 1.15-{build}
# pull request template
pull_requests:
do_not_increment_build_number: true
# vm template
image: Visual Studio 2017
image: Visual Studio 2019
# environment variables
environment:
@@ -10,7 +14,7 @@ environment:
# msbuild configuration
platform:
- AnyCPU
- Any CPU
configuration:
- Debug
@@ -28,9 +32,23 @@ build:
# post-build step
after_build:
- 7z a dicui_%APPVEYOR_BUILD_VERSION%.zip bin\Debug
- ps: appveyor DownloadFile https://github.com/saramibreak/DiscImageCreator/files/3854216/DiscImageCreator_20191116.zip
- ps: appveyor DownloadFile https://archive.org/download/subdump_fua_0x28/subdump_fua_0x28.zip
- 7z e DiscImageCreator_20191116.zip -oDICUI\bin\Debug\net462\Programs Release_ANSI\*
- 7z e DiscImageCreator_20191116.zip -oDICUI\bin\Debug\net472\Programs Release_ANSI\*
- 7z e DiscImageCreator_20191116.zip -oDICUI\bin\Debug\netcoreapp3.0\Programs Release_ANSI\*
- 7z e subdump_fua_0x28.zip -oDICUI\bin\Debug\net462 *
- mv DICUI\bin\Debug\net462\subdump_fua_0x28.exe DICUI\bin\Debug\net462\subdump.exe
- 7z e subdump_fua_0x28.zip -oDICUI\bin\Debug\net472 *
- mv DICUI\bin\Debug\net472\subdump_fua_0x28.exe DICUI\bin\Debug\net472\subdump.exe
- 7z e subdump_fua_0x28.zip -oDICUI\bin\Debug\netcoreapp3.0 *
- mv DICUI\bin\Debug\netcoreapp3.0\subdump_fua_0x28.exe DICUI\bin\Debug\netcoreapp3.0\subdump.exe
- 7z a DICUI.zip DICUI\bin\Debug\*
- 7z a DICUI-Check.zip DICUI.Check\bin\Debug\*
# artifact linking
artifacts:
- path: dicui_$(version).zip
name: DICUI
- path: DICUI.zip
name: DICUI
- path: DICUI-Check.zip
name: DICUI Check