Compare commits

...

19 Commits
1.13 ... 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
38 changed files with 1586 additions and 1018 deletions

View File

@@ -1,4 +1,20 @@
### 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
@@ -8,15 +24,18 @@
- 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

View File

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

View File

@@ -1,59 +1,21 @@
<?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')" />
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{8CFDE289-E171-4D49-A40D-5293265C1253}</ProjectGuid>
<TargetFrameworks>net462;net472;netcoreapp3.0</TargetFrameworks>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<OutputType>Exe</OutputType>
<RootNamespace>DICUI.Check</RootNamespace>
<AssemblyName>DICUI.Check</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</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>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<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>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@@ -92,6 +92,7 @@ namespace DICUI.Check
System = knownSystem,
Type = mediaType,
ScanForProtection = false,
PromptForDiscInformation = false,
Username = username,
Password = password,

View File

@@ -1,89 +1,11 @@
<?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')" />
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{51AB0928-13F9-44BF-A407-B6957A43A056}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>DICUI</RootNamespace>
<AssemblyName>DICUI.Library</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
<TargetFrameworks>net462;net472;netcoreapp3.0</TargetFrameworks>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="BurnOutSharp, Version=1.3.7.1, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\BurnOutSharp.1.3.7.1\lib\net461\BurnOutSharp.dll</HintPath>
</Reference>
<Reference Include="LessIO, Version=0.5.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\LessIO.0.5.0\lib\net40\LessIO.dll</HintPath>
</Reference>
<Reference Include="libmspackn, Version=0.8.0.0, Culture=neutral, processorArchitecture=x86">
<HintPath>..\packages\libmspack4n.0.8.0\lib\net40\libmspackn.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.12.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="PresentationFramework" />
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
<Reference Include="System.Management" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
<Reference Include="UnshieldSharp, Version=1.4.2.2, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\UnshieldSharp.1.4.2.2\lib\net461\UnshieldSharp.dll</HintPath>
</Reference>
<Reference Include="zlib.net, Version=1.0.3.0, Culture=neutral, PublicKeyToken=47d7877cb3620160">
<HintPath>..\packages\zlib.net.1.0.4.0\lib\zlib.net.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Data\Constants.cs" />
<Compile Include="Data\Enumerations.cs" />
<Compile Include="Data\SubmissionInfo.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Utilities\Converters.cs" />
<Compile Include="Utilities\Drive.cs" />
<Compile Include="Utilities\DumpEnvironment.cs" />
<Compile Include="Utilities\Extensions.cs" />
<Compile Include="Utilities\Parameters.cs" />
<Compile Include="Utilities\Result.cs" />
<Compile Include="Utilities\Validators.cs" />
<Compile Include="Web\CookieAwareWebClient.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="Web\RedumpAccess.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="mspack.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<COMReference Include="IMAPI2">
<Guid>{2735412F-7F64-5B0F-8F00-5D77AFBE261E}</Guid>
@@ -104,8 +26,15 @@
<EmbedInteropTypes>True</EmbedInteropTypes>
</COMReference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
<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>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
<ItemGroup>
<Reference Include="System.Management" />
</ItemGroup>
</Project>

View File

@@ -11,6 +11,7 @@
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";
@@ -36,6 +37,7 @@
{
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 CopyrightManagementInformation = "/c";
@@ -59,6 +61,7 @@
public const string SkipSector = "/sk";
public const string SubchannelReadLevel = "/s";
public const string VideoNow = "/vn";
public const string VideoNowColor = "/vnc";
}
/// <summary>

View File

@@ -30,6 +30,7 @@
CompactDisc,
Data,
DigitalVideoDisc,
Disk,
DriveSpeed,
Eject,
Floppy,
@@ -56,6 +57,7 @@
NONE = 0,
AddOffset,
AMSF,
AtariJaguar,
BEOpcode,
C2Opcode,
CopyrightManagementInformation,
@@ -79,6 +81,18 @@
SkipSector,
SubchannelReadLevel,
VideoNow,
VideoNowColor,
}
/// <summary>
/// Drive type for dumping
/// </summary>
public enum InternalDriveType
{
Optical,
Floppy,
HardDisk,
Removable,
}
/// <summary>
@@ -354,6 +368,16 @@
Ukrainian,
}
/// <summary>
/// All possible language selections
/// </summary>
public enum LanguageSelection
{
BiosSettings,
LanguageSelector,
OptionsMenu,
}
/// <summary>
/// Known media types
/// </summary>
@@ -406,6 +430,10 @@
// Unsorted Formats
Cartridge,
CED,
CompactFlash,
MMC,
SDCard,
FlashDrive,
}
/// <summary>
@@ -519,6 +547,7 @@
France,
FranceSpain,
Germany,
GreaterChina,
Greece,
Hungary,
India,
@@ -549,10 +578,12 @@
Turkey,
UnitedArabEmirates,
UK,
UKAustralia,
Ukraine,
USA,
USAAsia,
USABrazil,
USACanada,
USAEurope,
USAJapan,
World,

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Net;
using DICUI.Utilities;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
@@ -10,16 +11,253 @@ namespace DICUI.Data
{
public class SubmissionInfo
{
#region Common disc info
/// <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(StringEnumConverter))]
[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(StringEnumConverter))]
[JsonConverter(typeof(MediaTypeConverter))]
public MediaType? Media { get; set; }
[JsonProperty(PropertyName = "d_title", Required = Required.AllowNull)]
@@ -38,15 +276,16 @@ namespace DICUI.Data
public Category? Category { get; set; }
[JsonProperty(PropertyName = "d_region", Required = Required.AllowNull)]
[JsonConverter(typeof(StringEnumConverter))]
[JsonConverter(typeof(RegionConverter))]
public Region? Region { get; set; }
[JsonProperty(PropertyName = "d_languages", Required = Required.AllowNull)]
[JsonConverter(typeof(LanguagesConverter))]
public Language?[] Languages { get; set; }
// "Bios settings", "Language selector", "Options menu"
[JsonProperty(PropertyName = "d_languages_selection", NullValueHandling = NullValueHandling.Ignore)]
public string[] LanguageSelection { 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; }
@@ -116,11 +355,13 @@ namespace DICUI.Data
[JsonProperty(PropertyName = "d_contents", NullValueHandling = NullValueHandling.Ignore)]
public string Contents { get; set; }
}
#endregion
#region Version and Editions
/// <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; }
@@ -132,28 +373,34 @@ namespace DICUI.Data
[JsonProperty(PropertyName = "d_editions_text", NullValueHandling = NullValueHandling.Ignore)]
public string OtherEditions { get; set; }
}
#endregion
#region EDC (PSX-only)
/// <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; }
}
#endregion
#region Parent/Clone relationship
/// <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; }
}
#endregion
#region Extras
/// <summary>
/// Extras section of New Disc form
/// </summary>
public class ExtrasSection
{
[JsonProperty(PropertyName = "d_pvd", NullValueHandling = NullValueHandling.Ignore)]
public string PVD { get; set; }
@@ -174,11 +421,13 @@ namespace DICUI.Data
[JsonProperty(PropertyName = "d_ssranges", NullValueHandling = NullValueHandling.Ignore)]
public string SecuritySectorRanges { get; set; }
}
#endregion
#region Copy protection
/// <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; }
@@ -193,11 +442,13 @@ namespace DICUI.Data
[JsonProperty(PropertyName = "d_securom", NullValueHandling = NullValueHandling.Ignore)]
public string SecuROMData { get; set; }
}
#endregion
#region Dumpers and Status (Moderator only)
/// <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; }
@@ -206,11 +457,13 @@ namespace DICUI.Data
[JsonProperty(PropertyName = "d_dumpers_text", NullValueHandling = NullValueHandling.Ignore)]
public string OtherDumpers { get; set; }
}
#endregion
#region Tracks and write offsets (CD,GD-baed)
/// <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; }
@@ -222,11 +475,13 @@ namespace DICUI.Data
[JsonProperty(PropertyName = "d_offset_text", NullValueHandling = NullValueHandling.Ignore)]
public string OtherWriteOffsets { get; set; }
}
#endregion
#region Size & Checksum (DVD,BD,UMD-based)
/// <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; }
@@ -241,207 +496,5 @@ namespace DICUI.Data
[JsonProperty(PropertyName = "d_sha1", NullValueHandling = NullValueHandling.Ignore)]
public string SHA1 { get; set; }
#endregion
#region Nonstandard Information
[JsonIgnore]
public List<int> MatchedIDs { get; set; }
[JsonIgnore]
public DateTime? Added { get; set; }
[JsonIgnore]
public DateTime? LastModified { get; set; }
#endregion
#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 = match.Groups[1].Value;
// If we have parenthesis, title is everything before the first one
int firstParenLocation = title.IndexOf(" (");
if (firstParenLocation >= 0)
{
this.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.DiscNumberLetter = subMatch.Remove(0, "Disc ".Length);
// Disc title
else
this.DiscTitle = subMatch;
}
}
// Otherwise, leave the title as-is
else
{
this.Title = title;
}
}
// Foreign Title
match = foreignTitleRegex.Match(discData);
if (match.Success)
this.ForeignTitleNonLatin = match.Groups[1].Value;
else
this.ForeignTitleNonLatin = null;
// Category
match = categoryRegex.Match(discData);
if (match.Success)
this.Category = Converters.StringToCategory(match.Groups[1].Value);
else
this.Category = Data.Category.Games;
// Region
match = regionRegex.Match(discData);
if (match.Success)
this.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.Languages = tempLanguages.ToArray();
}
// Serial
match = serialRegex.Match(discData);
if (match.Success)
this.Serial = 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.ErrorsCount) && match.Groups[1].Value != this.ErrorsCount)
this.ErrorsCount = match.Groups[1].Value;
}
// Version
match = versionRegex.Match(discData);
if (match.Success)
this.Version = match.Groups[1].Value;
// Edition
match = editionRegex.Match(discData);
if (match.Success)
this.OtherEditions = 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.Dumpers.Length > 0)
{
foreach (string dumper in this.Dumpers)
tempDumpers.Add(dumper);
}
foreach (Match submatch in matches)
tempDumpers.Add(submatch.Groups[1].Value);
this.Dumpers = tempDumpers.ToArray();
}
// Barcode
match = barcodeRegex.Match(discData);
if (match.Success)
this.Barcode = match.Groups[1].Value;
// Comments
match = commentsRegex.Match(discData);
if (match.Success)
{
this.Comments = match.Groups[1].Value
.Replace("<br />", "\n")
.Replace("<b>ISBN</b>", "[T:ISBN]") + "\n";
}
// Contents
match = contentsRegex.Match(discData);
if (match.Success)
{
this.Contents = match.Groups[1].Value
.Replace("<br />", "\n")
.Replace("</div>", "");
this.Contents = Regex.Replace(this.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);
}
}
}

View File

@@ -1,5 +1,9 @@
using IMAPI2;
using System;
using System.IO;
using IMAPI2;
using DICUI.Data;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace DICUI.Utilities
{
@@ -7,6 +11,26 @@ namespace DICUI.Utilities
{
#region Cross-enumeration conversions
/// <summary>
/// Convert drive type to internal version, if possible
/// </summary>
/// <param name="driveType">DriveType value to check</param>
/// <returns>InternalDriveType, if possible, null on error</returns>
public static InternalDriveType? ToInternalDriveType(this DriveType driveType)
{
switch(driveType)
{
case DriveType.CDRom:
return InternalDriveType.Optical;
case DriveType.Fixed:
return InternalDriveType.HardDisk;
case DriveType.Removable:
return InternalDriveType.Removable;
default:
return null;
}
}
/// <summary>
/// Get the most common known system for a given MediaType
/// </summary>
@@ -21,6 +45,7 @@ namespace DICUI.Utilities
case DICCommand.CompactDisc:
case DICCommand.Data:
case DICCommand.DigitalVideoDisc:
case DICCommand.Disk:
case DICCommand.Floppy:
return KnownSystem.IBMPCCompatible;
case DICCommand.GDROM:
@@ -46,7 +71,7 @@ namespace DICUI.Utilities
/// </summary>
/// <param name="system">Redump system value to check</param>
/// <returns>KnownSystem if possible, null on error</returns>
public static KnownSystem? ToKnownSystem(this RedumpSystem system)
public static KnownSystem? ToKnownSystem(this RedumpSystem? system)
{
switch (system)
{
@@ -236,6 +261,8 @@ namespace DICUI.Utilities
// Non-optical
case DICCommand.Floppy:
return MediaType.FloppyDisk;
case DICCommand.Disk:
return MediaType.HardDisk;
default:
return null;
}
@@ -285,7 +312,7 @@ namespace DICUI.Utilities
/// </summary>
/// <param name="system">KnownSystem value to check</param>
/// <returns>RedumpSystem if possible, null on error</returns>
public static RedumpSystem? ToRedumpSystem(this KnownSystem system)
public static RedumpSystem? ToRedumpSystem(this KnownSystem? system)
{
switch (system)
{
@@ -446,6 +473,11 @@ namespace DICUI.Utilities
case MediaType.CDROM:
case MediaType.GDROM:
case MediaType.Cartridge:
case MediaType.HardDisk:
case MediaType.CompactFlash:
case MediaType.MMC:
case MediaType.SDCard:
case MediaType.FlashDrive:
return ".bin";
case MediaType.DVD:
case MediaType.HDDVD:
@@ -529,6 +561,8 @@ namespace DICUI.Utilities
return DICCommandStrings.Data;
case DICCommand.DigitalVideoDisc:
return DICCommandStrings.DigitalVideoDisc;
case DICCommand.Disk:
return DICCommandStrings.Disk;
case DICCommand.DriveSpeed:
return DICCommandStrings.DriveSpeed;
case DICCommand.Eject:
@@ -581,6 +615,8 @@ namespace DICUI.Utilities
return DICFlagStrings.AddOffset;
case DICFlag.AMSF:
return DICFlagStrings.AMSF;
case DICFlag.AtariJaguar:
return DICFlagStrings.AtariJaguar;
case DICFlag.BEOpcode:
return DICFlagStrings.BEOpcode;
case DICFlag.C2Opcode:
@@ -627,6 +663,8 @@ namespace DICUI.Utilities
return DICFlagStrings.SubchannelReadLevel;
case DICFlag.VideoNow:
return DICFlagStrings.VideoNow;
case DICFlag.VideoNowColor:
return DICFlagStrings.VideoNowColor;
case DICFlag.NONE:
default:
@@ -1007,6 +1045,26 @@ namespace DICUI.Utilities
}
}
/// <summary>
/// Get the string representation of the LanguageSelection enum values
/// </summary>
/// <param name="lang">LanguageSelection value to convert</param>
/// <returns>String representing the value, if possible</returns>
public static string LongName(this LanguageSelection? langSelect)
{
switch (langSelect)
{
case LanguageSelection.BiosSettings:
return "Bios settings";
case LanguageSelection.LanguageSelector:
return "Language selector";
case LanguageSelection.OptionsMenu:
return "Options menu";
default:
return string.Empty;
}
}
/// <summary>
/// Get the string representation of the MediaType enum values
/// </summary>
@@ -1315,6 +1373,8 @@ namespace DICUI.Utilities
return "France, Spain";
case Region.Germany:
return "Germany";
case Region.GreaterChina:
return "Greater China";
case Region.Greece:
return "Greece";
case Region.Hungary:
@@ -1375,6 +1435,8 @@ namespace DICUI.Utilities
return "United Arab Emirates";
case Region.UK:
return "UK";
case Region.UKAustralia:
return "UK, Australia";
case Region.Ukraine:
return "Ukraine";
case Region.USA:
@@ -1383,6 +1445,8 @@ namespace DICUI.Utilities
return "USA, Asia";
case Region.USABrazil:
return "USA, Brazil";
case Region.USACanada:
return "USA, Canada";
case Region.USAEurope:
return "USA, Europe";
case Region.USAJapan:
@@ -2072,6 +2136,8 @@ namespace DICUI.Utilities
return "F,S";
case Region.Germany:
return "G";
case Region.GreaterChina:
return "GC";
case Region.Greece:
return "Gr";
case Region.Hungary:
@@ -2132,6 +2198,8 @@ namespace DICUI.Utilities
return "Ae";
case Region.UK:
return "Uk";
case Region.UKAustralia:
return "Uk,Au";
case Region.Ukraine:
return "Ue";
case Region.USA:
@@ -2140,6 +2208,8 @@ namespace DICUI.Utilities
return "U,A";
case Region.USABrazil:
return "U,B";
case Region.USACanada:
return "U,Ca";
case Region.USAEurope:
return "U,E";
case Region.USAJapan:
@@ -3219,6 +3289,8 @@ namespace DICUI.Utilities
return Region.FranceSpain;
case "G":
return Region.Germany;
case "GC":
return Region.GreaterChina;
case "Gr":
return Region.Greece;
case "H":
@@ -3279,6 +3351,8 @@ namespace DICUI.Utilities
return Region.UnitedArabEmirates;
case "Uk":
return Region.UK;
case "Uk,Au":
return Region.UKAustralia;
case "Ue":
return Region.Ukraine;
case "U":
@@ -3287,6 +3361,8 @@ namespace DICUI.Utilities
return Region.USAAsia;
case "U,B":
return Region.USABrazil;
case "U,Ca":
return Region.USACanada;
case "U,E":
return Region.USAEurope;
case "U,J":
@@ -3300,4 +3376,111 @@ namespace DICUI.Utilities
#endregion
}
/// <summary>
/// Serialize KnownSystem enum values
/// </summary>
public class KnownSystemConverter : JsonConverter<KnownSystem?>
{
public override bool CanRead { get { return false; } }
public override KnownSystem? ReadJson(JsonReader reader, Type objectType, KnownSystem? existingValue, bool hasExistingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override void WriteJson(JsonWriter writer, KnownSystem? value, JsonSerializer serializer)
{
JToken t = JToken.FromObject(value.ToRedumpSystem()?.ShortName() ?? value.ShortName());
t.WriteTo(writer);
}
}
/// <summary>
/// Serialize Language enum values
/// </summary>
public class LanguagesConverter : JsonConverter<Language?[]>
{
public override bool CanRead { get { return false; } }
public override Language?[] ReadJson(JsonReader reader, Type objectType, Language?[] existingValue, bool hasExistingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override void WriteJson(JsonWriter writer, Language?[] value, JsonSerializer serializer)
{
JArray array = new JArray();
foreach (var val in value)
{
JToken t = JToken.FromObject(val.ShortName());
array.Add(t);
}
array.WriteTo(writer);
}
}
/// <summary>
/// Serialize Language enum values
/// </summary>
public class LanguageSelectionConverter : JsonConverter<LanguageSelection?[]>
{
public override bool CanRead { get { return false; } }
public override LanguageSelection?[] ReadJson(JsonReader reader, Type objectType, LanguageSelection?[] existingValue, bool hasExistingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override void WriteJson(JsonWriter writer, LanguageSelection?[] value, JsonSerializer serializer)
{
JArray array = new JArray();
foreach (var val in value)
{
JToken t = JToken.FromObject(val.LongName());
array.Add(t);
}
array.WriteTo(writer);
}
}
/// <summary>
/// Serialize MediaType enum values
/// </summary>
public class MediaTypeConverter : JsonConverter<MediaType?>
{
public override bool CanRead { get { return false; } }
public override MediaType? ReadJson(JsonReader reader, Type objectType, MediaType? existingValue, bool hasExistingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override void WriteJson(JsonWriter writer, MediaType? value, JsonSerializer serializer)
{
JToken t = JToken.FromObject(value.ShortName());
t.WriteTo(writer);
}
}
/// <summary>
/// Serialize Region enum values
/// </summary>
public class RegionConverter : JsonConverter<Region?>
{
public override bool CanRead { get { return false; } }
public override Region? ReadJson(JsonReader reader, Type objectType, Region? existingValue, bool hasExistingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override void WriteJson(JsonWriter writer, Region? value, JsonSerializer serializer)
{
JToken t = JToken.FromObject(value.ShortName());
t.WriteTo(writer);
}
}
}

View File

@@ -1,4 +1,7 @@
namespace DICUI.Utilities
using System.IO;
using DICUI.Data;
namespace DICUI.Utilities
{
/// <summary>
/// Represents information for a single drive
@@ -6,47 +9,55 @@
public class Drive
{
/// <summary>
/// Windows drive letter
/// Represents drive type
/// </summary>
public char Letter { get; private set; }
public InternalDriveType? InternalDriveType { get; set; }
/// <summary>
/// Represents if it is a floppy drive
/// DriveInfo object representing the drive, if possible
/// </summary>
public bool IsFloppy { get; private set; }
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; private set; }
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; private set; }
public bool MarkedActive { get { return DriveInfo.IsReady; } }
private Drive(char letter, string volumeLabel, bool isFloppy, bool markedActive)
public Drive(InternalDriveType? driveType, DriveInfo driveInfo)
{
this.Letter = letter;
this.IsFloppy = isFloppy;
this.VolumeLabel = volumeLabel;
this.MarkedActive = markedActive;
this.InternalDriveType = driveType;
this.DriveInfo = driveInfo;
}
/// <summary>
/// Create a new Floppy drive instance
/// </summary>
/// <param name="letter">Drive letter to use</param>
/// <returns>Drive object for a Floppy drive</returns>
public static Drive Floppy(char letter) => new Drive(letter, null, true, true);
/// <summary>
/// Create a new Optical drive instance
/// </summary>
/// <param name="letter">Drive letter to use</param>
/// <param name="volumeLabel">Media label, if it exists</param>
/// <param name="active">True if the drive is marked active, false otherwise</param>
/// <returns>Drive object for an Optical drive</returns>
public static Drive Optical(char letter, string volumeLabel, bool active) => new Drive(letter, volumeLabel, false, active);
}
}

View File

@@ -71,6 +71,11 @@ namespace DICUI.Utilities
/// Determines if placeholder values should be set for fields
/// </summary>
public bool AddPlaceholders { get; set; }
/// <summary>
/// Determines if the user should be prompted to input or fix submission data
/// </summary>
public bool PromptForDiscInformation { get; set; }
#endregion
@@ -199,8 +204,8 @@ namespace DICUI.Utilities
CancelDumping();
// Validate we're not trying to eject a floppy disk
if (Drive.IsFloppy)
// Validate we're not trying to eject a non-optical
if (Drive.InternalDriveType != InternalDriveType.Optical)
return;
Process childProcess;
@@ -240,20 +245,21 @@ namespace DICUI.Utilities
bool endedWithDirectorySeparator = OutputDirectory.EndsWith(Path.DirectorySeparatorChar.ToString());
bool endedWithSpace = OutputDirectory.EndsWith(" ");
// Normalize the path so the below filters work better
// Combine the path to make things separate easier
string combinedPath = Path.Combine(OutputDirectory, OutputFilename);
OutputDirectory = Path.GetDirectoryName(combinedPath);
OutputFilename = Path.GetFileName(combinedPath);
// If we have either a blank filename or path, just exit
if (String.IsNullOrWhiteSpace(OutputFilename) || String.IsNullOrWhiteSpace(OutputDirectory))
// If we have have a blank path, just return
if (string.IsNullOrWhiteSpace(combinedPath))
return;
// Now get the normalized paths
OutputDirectory = Path.GetDirectoryName(combinedPath);
OutputFilename = Path.GetFileName(combinedPath);
// Take care of extra path characters
OutputDirectory = new StringBuilder(OutputDirectory.Replace('.', '_').Replace('&', '_'))
OutputDirectory = new StringBuilder(OutputDirectory.Replace('&', '_'))
.Replace(':', '_', 0, OutputDirectory.LastIndexOf(':') == -1 ? 0 : OutputDirectory.LastIndexOf(':')).ToString();
OutputFilename = new StringBuilder(OutputFilename.Replace('&', '_'))
.Replace('.', '_', 0, OutputFilename.LastIndexOf('.') == -1 ? 0 : OutputFilename.LastIndexOf('.')).ToString();
OutputFilename = new StringBuilder(OutputFilename.Replace('&', '_')).ToString();
// Sanitize everything else
foreach (char c in Path.GetInvalidPathChars())
@@ -268,6 +274,16 @@ namespace DICUI.Utilities
// If we had a directory separator at the end before, add it again
if (endedWithDirectorySeparator)
OutputDirectory += Path.DirectorySeparatorChar;
// If we have a root directory, sanitize
if (Directory.Exists(OutputDirectory))
{
var possibleRootDir = new DirectoryInfo(OutputDirectory);
if (possibleRootDir.Parent == null)
{
OutputDirectory = OutputDirectory.Replace($"{Path.DirectorySeparatorChar}{Path.DirectorySeparatorChar}", $"{Path.DirectorySeparatorChar}");
}
}
}
catch
{
@@ -397,11 +413,6 @@ namespace DICUI.Utilities
progress?.Report(result);
}
// Verify dump output and save it
progress?.Report(Result.Success("Gathering submission information... please wait!"));
result = await Task.Run(() => VerifyAndSaveDumpOutput(progress));
progress?.Report(Result.Success("All submission information gathered!"));
return result;
}
@@ -409,8 +420,10 @@ namespace DICUI.Utilities
/// Verify that the current environment has a complete dump and create submission info is possible
/// </summary>
/// <returns>Result instance with the outcome</returns>
public Result VerifyAndSaveDumpOutput(IProgress<Result> progress)
public Result VerifyAndSaveDumpOutput(IProgress<Result> progress, Func<SubmissionInfo, bool?> ShowUserPrompt = null)
{
progress.Report(Result.Success("Gathering submission information... please wait!"));
// Check to make sure that the output had all the correct files
if (!FoundAllFiles())
return Result.Failure("Error! Please check output directory as dump may be incomplete!");
@@ -419,7 +432,12 @@ namespace DICUI.Utilities
SubmissionInfo submissionInfo = ExtractOutputInformation(progress);
progress?.Report(Result.Success("Extracting information complete!"));
// TODO: Add UI step here (possibly) to get user info on the disc
if (PromptForDiscInformation && ShowUserPrompt != null)
{
progress?.Report(Result.Success("Waiting for additional disc information..."));
bool? filledInfo = ShowUserPrompt(submissionInfo);
progress?.Report(Result.Success("Additional disc information added!"));
}
progress?.Report(Result.Success("Formatting extracted information..."));
List<string> formattedValues = FormatOutputData(submissionInfo);
@@ -434,6 +452,8 @@ namespace DICUI.Utilities
else
progress?.Report(Result.Failure("Writing could not complete!"));
progress.Report(Result.Success("All submission information gathered!"));
return Result.Success();
}
@@ -447,7 +467,10 @@ namespace DICUI.Utilities
/// <returns>True if the configuration is valid, false otherwise</returns>
internal bool ParametersValid()
{
return DICParameters.IsValid() && !(Drive.IsFloppy ^ Type == MediaType.FloppyDisk);
return DICParameters.IsValid()
&& !(Drive.InternalDriveType == InternalDriveType.Floppy ^ Type == MediaType.FloppyDisk)
&& !(Drive.InternalDriveType == InternalDriveType.HardDisk ^ Type == MediaType.HardDisk)
&& !(Drive.InternalDriveType == InternalDriveType.Removable ^ (Type == MediaType.CompactFlash || Type == MediaType.SDCard || Type == MediaType.FlashDrive));
}
#endregion
@@ -533,28 +556,37 @@ namespace DICUI.Utilities
string combinedBase = Path.Combine(OutputDirectory, outputFilename);
SubmissionInfo info = new SubmissionInfo()
{
System = this.System,
Media = this.Type,
Title = (this.AddPlaceholders ? Template.RequiredValue : ""),
ForeignTitleNonLatin = (AddPlaceholders ? Template.OptionalValue : ""),
DiscNumberLetter = (AddPlaceholders ? Template.OptionalValue : ""),
DiscTitle = (AddPlaceholders ? Template.OptionalValue : ""),
Category = Category.Games,
Region = null,
Languages = null,
Serial = (AddPlaceholders ? Template.RequiredIfExistsValue : ""),
Barcode = (AddPlaceholders ? Template.OptionalValue : ""),
Contents = (AddPlaceholders ? Template.OptionalValue : ""),
Version = (AddPlaceholders ? Template.RequiredIfExistsValue : ""),
OtherEditions = (AddPlaceholders ? "Original (VERIFY THIS)" : ""),
ClrMameProData = GetDatfile(combinedBase + ".dat"),
CommonDiscInfo = new CommonDiscInfoSection()
{
System = this.System,
Media = this.Type,
Title = (this.AddPlaceholders ? Template.RequiredValue : ""),
ForeignTitleNonLatin = (AddPlaceholders ? Template.OptionalValue : ""),
DiscNumberLetter = (AddPlaceholders ? Template.OptionalValue : ""),
DiscTitle = (AddPlaceholders ? Template.OptionalValue : ""),
Category = Category.Games,
Region = null,
Languages = null,
Serial = (AddPlaceholders ? Template.RequiredIfExistsValue : ""),
Barcode = (AddPlaceholders ? Template.OptionalValue : ""),
Contents = (AddPlaceholders ? Template.OptionalValue : ""),
},
VersionAndEditions = new VersionAndEditionsSection()
{
Version = (AddPlaceholders ? Template.RequiredIfExistsValue : ""),
OtherEditions = (AddPlaceholders ? "Original (VERIFY THIS)" : ""),
},
TracksAndWriteOffsets = new TracksAndWriteOffsetsSection()
{
ClrMameProData = GetDatfile(combinedBase + ".dat"),
},
};
// First and foremost, we want to get a list of matching IDs for each line in the DAT
if (!string.IsNullOrEmpty(info.ClrMameProData) && HasRedumpLogin)
if (!string.IsNullOrEmpty(info.TracksAndWriteOffsets.ClrMameProData) && HasRedumpLogin)
{
// Set the current dumper based on username
info.Dumpers = new string[] { this.Username };
info.DumpersAndStatus.Dumpers = new string[] { this.Username };
info.MatchedIDs = new List<int>();
using (CookieAwareWebClient wc = new CookieAwareWebClient())
@@ -565,7 +597,7 @@ namespace DICUI.Utilities
{
// Loop through all of the hashdata to find matching IDs
progress?.Report(Result.Success("Finding disc matches on Redump..."));
string[] splitData = info.ClrMameProData.Split('\n');
string[] splitData = info.TracksAndWriteOffsets.ClrMameProData.Split('\n');
foreach (string hashData in splitData)
{
if (GetISOHashValues(hashData, out long size, out string crc32, out string md5, out string sha1))
@@ -597,13 +629,13 @@ namespace DICUI.Utilities
{
case MediaType.CDROM:
case MediaType.GDROM: // TODO: Verify GD-ROM outputs this
info.MasteringRingFirstLayerDataSide = (AddPlaceholders ? Template.RequiredIfExistsValue : "");
info.MasteringSIDCodeFirstLayerDataSide = (AddPlaceholders ? Template.RequiredIfExistsValue : "");
info.ToolstampMasteringCodeFirstLayerDataSide = (AddPlaceholders ? Template.RequiredIfExistsValue : "");
info.MouldSIDCodeFirstLayerDataSide = (AddPlaceholders ? Template.RequiredIfExistsValue : "");
info.MouldSIDCodeSecondLayerLabelSide = (AddPlaceholders ? Template.RequiredIfExistsValue : "");
info.AdditionalMouldFirstLayerDataSide = (AddPlaceholders ? Template.RequiredIfExistsValue : "");
info.PVD = GetPVD(combinedBase + "_mainInfo.txt") ?? "Disc has no PVD"; ;
info.CommonDiscInfo.MasteringRingFirstLayerDataSide = (AddPlaceholders ? Template.RequiredIfExistsValue : "");
info.CommonDiscInfo.MasteringSIDCodeFirstLayerDataSide = (AddPlaceholders ? Template.RequiredIfExistsValue : "");
info.CommonDiscInfo.ToolstampMasteringCodeFirstLayerDataSide = (AddPlaceholders ? Template.RequiredIfExistsValue : "");
info.CommonDiscInfo.MouldSIDCodeFirstLayerDataSide = (AddPlaceholders ? Template.RequiredIfExistsValue : "");
info.CommonDiscInfo.MouldSIDCodeSecondLayerLabelSide = (AddPlaceholders ? Template.RequiredIfExistsValue : "");
info.CommonDiscInfo.AdditionalMouldFirstLayerDataSide = (AddPlaceholders ? Template.RequiredIfExistsValue : "");
info.Extras.PVD = GetPVD(combinedBase + "_mainInfo.txt") ?? "Disc has no PVD"; ;
long errorCount = -1;
if (File.Exists(combinedBase + ".img_EdcEcc.txt"))
@@ -611,16 +643,16 @@ namespace DICUI.Utilities
else if (File.Exists(combinedBase + ".img_EccEdc.txt"))
errorCount = GetErrorCount(combinedBase + ".img_EccEdc.txt");
info.ErrorsCount = (errorCount == -1 ? "Error retrieving error count" : errorCount.ToString());
info.Cuesheet = GetFullFile(combinedBase + ".cue") ?? ""; ;
info.CommonDiscInfo.ErrorsCount = (errorCount == -1 ? "Error retrieving error count" : errorCount.ToString());
info.TracksAndWriteOffsets.Cuesheet = GetFullFile(combinedBase + ".cue") ?? ""; ;
string cdWriteOffset = GetWriteOffset(combinedBase + "_disc.txt") ?? "";
info.RingWriteOffset = cdWriteOffset;
info.OtherWriteOffsets = cdWriteOffset;
info.CommonDiscInfo.RingWriteOffset = cdWriteOffset;
info.TracksAndWriteOffsets.OtherWriteOffsets = cdWriteOffset;
// GD-ROM-specfic options
if (Type == MediaType.GDROM)
info.Header = GetSegaHeader(combinedBase + "_mainInfo.txt") ?? "";
info.Extras.Header = GetSegaHeader(combinedBase + "_mainInfo.txt") ?? "";
break;
@@ -630,13 +662,13 @@ namespace DICUI.Utilities
bool isXbox = (System == KnownSystem.MicrosoftXBOX || System == KnownSystem.MicrosoftXBOX360);
// Get the individual hash data, as per internal
if (GetISOHashValues(info.ClrMameProData, out long size, out string crc32, out string md5, out string sha1))
if (GetISOHashValues(info.TracksAndWriteOffsets.ClrMameProData, out long size, out string crc32, out string md5, out string sha1))
{
info.Size = size;
info.CRC32 = crc32;
info.MD5 = md5;
info.SHA1 = sha1;
info.ClrMameProData = null;
info.SizeAndChecksums.Size = size;
info.SizeAndChecksums.CRC32 = crc32;
info.SizeAndChecksums.MD5 = md5;
info.SizeAndChecksums.SHA1 = sha1;
info.TracksAndWriteOffsets.ClrMameProData = null;
}
// Deal with the layerbreak
@@ -644,68 +676,68 @@ namespace DICUI.Utilities
if (Type == MediaType.DVD)
layerbreak = GetLayerbreak(combinedBase + "_disc.txt", isXbox) ?? "";
else if (Type == MediaType.BluRay)
layerbreak = (info.Size > 25025314816 ? "25025314816" : null);
layerbreak = (info.SizeAndChecksums.Size > 25025314816 ? "25025314816" : null);
// If we have a single-layer disc
if (String.IsNullOrWhiteSpace(layerbreak))
if (string.IsNullOrWhiteSpace(layerbreak))
{
info.MasteringRingFirstLayerDataSide = (AddPlaceholders ? Template.RequiredIfExistsValue : "");
info.MasteringSIDCodeFirstLayerDataSide = (AddPlaceholders ? Template.RequiredIfExistsValue : "");
info.ToolstampMasteringCodeFirstLayerDataSide = (AddPlaceholders ? Template.RequiredIfExistsValue : "");
info.MouldSIDCodeFirstLayerDataSide = (AddPlaceholders ? Template.RequiredIfExistsValue : "");
info.MouldSIDCodeSecondLayerLabelSide = (AddPlaceholders ? Template.RequiredIfExistsValue : "");
info.AdditionalMouldFirstLayerDataSide = (AddPlaceholders ? Template.RequiredIfExistsValue : "");
info.PVD = GetPVD(combinedBase + "_mainInfo.txt") ?? "";
info.CommonDiscInfo.MasteringRingFirstLayerDataSide = (AddPlaceholders ? Template.RequiredIfExistsValue : "");
info.CommonDiscInfo.MasteringSIDCodeFirstLayerDataSide = (AddPlaceholders ? Template.RequiredIfExistsValue : "");
info.CommonDiscInfo.ToolstampMasteringCodeFirstLayerDataSide = (AddPlaceholders ? Template.RequiredIfExistsValue : "");
info.CommonDiscInfo.MouldSIDCodeFirstLayerDataSide = (AddPlaceholders ? Template.RequiredIfExistsValue : "");
info.CommonDiscInfo.MouldSIDCodeSecondLayerLabelSide = (AddPlaceholders ? Template.RequiredIfExistsValue : "");
info.CommonDiscInfo.AdditionalMouldFirstLayerDataSide = (AddPlaceholders ? Template.RequiredIfExistsValue : "");
info.Extras.PVD = GetPVD(combinedBase + "_mainInfo.txt") ?? "";
}
// If we have a dual-layer disc
else
{
info.MasteringRingFirstLayerDataSide = (AddPlaceholders ? Template.RequiredIfExistsValue : "");
info.MasteringSIDCodeFirstLayerDataSide = (AddPlaceholders ? Template.RequiredIfExistsValue : "");
info.ToolstampMasteringCodeFirstLayerDataSide = (AddPlaceholders ? Template.RequiredIfExistsValue : "");
info.MouldSIDCodeFirstLayerDataSide = (AddPlaceholders ? Template.RequiredIfExistsValue : "");
info.AdditionalMouldFirstLayerDataSide = (AddPlaceholders ? Template.RequiredIfExistsValue : "");
info.CommonDiscInfo.MasteringRingFirstLayerDataSide = (AddPlaceholders ? Template.RequiredIfExistsValue : "");
info.CommonDiscInfo.MasteringSIDCodeFirstLayerDataSide = (AddPlaceholders ? Template.RequiredIfExistsValue : "");
info.CommonDiscInfo.ToolstampMasteringCodeFirstLayerDataSide = (AddPlaceholders ? Template.RequiredIfExistsValue : "");
info.CommonDiscInfo.MouldSIDCodeFirstLayerDataSide = (AddPlaceholders ? Template.RequiredIfExistsValue : "");
info.CommonDiscInfo.AdditionalMouldFirstLayerDataSide = (AddPlaceholders ? Template.RequiredIfExistsValue : "");
info.MasteringRingSecondLayerLabelSide = (AddPlaceholders ? Template.RequiredIfExistsValue : "");
info.MasteringSIDCodeSecondLayerLabelSide = (AddPlaceholders ? Template.RequiredIfExistsValue : "");
info.ToolstampMasteringCodeSecondLayerLabelSide = (AddPlaceholders ? Template.RequiredIfExistsValue : "");
info.MouldSIDCodeSecondLayerLabelSide = (AddPlaceholders ? Template.RequiredIfExistsValue : "");
info.CommonDiscInfo.MasteringRingSecondLayerLabelSide = (AddPlaceholders ? Template.RequiredIfExistsValue : "");
info.CommonDiscInfo.MasteringSIDCodeSecondLayerLabelSide = (AddPlaceholders ? Template.RequiredIfExistsValue : "");
info.CommonDiscInfo.ToolstampMasteringCodeSecondLayerLabelSide = (AddPlaceholders ? Template.RequiredIfExistsValue : "");
info.CommonDiscInfo.MouldSIDCodeSecondLayerLabelSide = (AddPlaceholders ? Template.RequiredIfExistsValue : "");
info.PVD = GetPVD(combinedBase + "_mainInfo.txt") ?? "";
info.Layerbreak = Int64.Parse(layerbreak);
info.Extras.PVD = GetPVD(combinedBase + "_mainInfo.txt") ?? "";
info.SizeAndChecksums.Layerbreak = Int64.Parse(layerbreak);
}
// Bluray-specific options
if (Type == MediaType.BluRay)
info.PIC = GetPIC(Path.Combine(OutputDirectory, "PIC.bin")) ?? "";
info.Extras.PIC = GetPIC(Path.Combine(OutputDirectory, "PIC.bin")) ?? "";
break;
case MediaType.NintendoGameCubeGameDisc:
info.BCA = (this.AddPlaceholders ? Template.RequiredValue : "");
info.Extras.BCA = (this.AddPlaceholders ? Template.RequiredValue : "");
break;
case MediaType.NintendoWiiOpticalDisc:
info.DiscKey = (this.AddPlaceholders ? Template.RequiredValue : "");
info.BCA = (this.AddPlaceholders ? Template.RequiredValue : "");
info.Extras.DiscKey = (this.AddPlaceholders ? Template.RequiredValue : "");
info.Extras.BCA = (this.AddPlaceholders ? Template.RequiredValue : "");
break;
case MediaType.UMD:
info.PVD = GetPVD(combinedBase + "_mainInfo.txt") ?? "";
info.CRC32 = (this.AddPlaceholders ? Template.RequiredValue + " [Not automatically generated for UMD]" : "");
info.MD5 = (this.AddPlaceholders ? Template.RequiredValue + " [Not automatically generated for UMD]" : "");
info.SHA1 = (this.AddPlaceholders ? Template.RequiredValue + " [Not automatically generated for UMD]" : "");
info.ClrMameProData = null;
info.Extras.PVD = GetPVD(combinedBase + "_mainInfo.txt") ?? "";
info.SizeAndChecksums.CRC32 = (this.AddPlaceholders ? Template.RequiredValue + " [Not automatically generated for UMD]" : "");
info.SizeAndChecksums.MD5 = (this.AddPlaceholders ? Template.RequiredValue + " [Not automatically generated for UMD]" : "");
info.SizeAndChecksums.SHA1 = (this.AddPlaceholders ? Template.RequiredValue + " [Not automatically generated for UMD]" : "");
info.TracksAndWriteOffsets.ClrMameProData = null;
if (GetUMDAuxInfo(combinedBase + "_disc.txt", out string title, out Category? umdcat, out string umdversion, out string umdlayer, out long umdsize))
{
info.Title = title ?? "";
info.Category = umdcat ?? Category.Games;
info.Version = umdversion ?? "";
info.Size = umdsize;
info.CommonDiscInfo.Title = title ?? "";
info.CommonDiscInfo.Category = umdcat ?? Category.Games;
info.VersionAndEditions.Version = umdversion ?? "";
info.SizeAndChecksums.Size = umdsize;
if (!String.IsNullOrWhiteSpace(umdlayer))
info.Layerbreak = Int64.Parse(umdlayer ?? "-1");
if (!string.IsNullOrWhiteSpace(umdlayer))
info.SizeAndChecksums.Layerbreak = Int64.Parse(umdlayer ?? "-1");
}
break;
@@ -718,93 +750,93 @@ namespace DICUI.Utilities
case KnownSystem.EnhancedCD:
case KnownSystem.IBMPCCompatible:
case KnownSystem.RainbowDisc:
if (string.IsNullOrWhiteSpace(info.Comments))
info.Comments += $"[T:ISBN] {(AddPlaceholders ? Template.OptionalValue : "")}";
if (string.IsNullOrWhiteSpace(info.CommonDiscInfo.Comments))
info.CommonDiscInfo.Comments += $"[T:ISBN] {(AddPlaceholders ? Template.OptionalValue : "")}";
progress?.Report(Result.Success("Running copy protection scan... this might take a while!"));
info.Protection = GetCopyProtection();
info.CopyProtection.Protection = GetCopyProtection();
progress?.Report(Result.Success("Copy protection scan complete!"));
if (File.Exists(combinedBase + "_subIntention.txt"))
{
FileInfo fi = new FileInfo(combinedBase + "_subIntention.txt");
if (fi.Length > 0)
info.SecuROMData = GetFullFile(combinedBase + "_subIntention.txt") ?? "";
info.CopyProtection.SecuROMData = GetFullFile(combinedBase + "_subIntention.txt") ?? "";
}
break;
case KnownSystem.BandaiPlaydiaQuickInteractiveSystem:
info.EXEDateBuildDate = (this.AddPlaceholders ? Template.RequiredValue : "");
info.CommonDiscInfo.EXEDateBuildDate = (this.AddPlaceholders ? Template.RequiredValue : "");
break;
case KnownSystem.BDVideo:
info.Protection = (AddPlaceholders ? Template.RequiredIfExistsValue : "");
info.CopyProtection.Protection = (AddPlaceholders ? Template.RequiredIfExistsValue : "");
break;
case KnownSystem.CommodoreAmiga:
info.EXEDateBuildDate = (this.AddPlaceholders ? Template.RequiredValue : "");
info.CommonDiscInfo.EXEDateBuildDate = (this.AddPlaceholders ? Template.RequiredValue : "");
break;
case KnownSystem.CommodoreAmigaCD32:
info.EXEDateBuildDate = (this.AddPlaceholders ? Template.RequiredValue : "");
info.CommonDiscInfo.EXEDateBuildDate = (this.AddPlaceholders ? Template.RequiredValue : "");
break;
case KnownSystem.CommodoreAmigaCDTV:
info.EXEDateBuildDate = (this.AddPlaceholders ? Template.RequiredValue : "");
info.CommonDiscInfo.EXEDateBuildDate = (this.AddPlaceholders ? Template.RequiredValue : "");
break;
case KnownSystem.DVDVideo:
info.Protection = GetDVDProtection(combinedBase + "_CSSKey.txt", combinedBase + "_disc.txt") ?? "";
info.CopyProtection.Protection = GetDVDProtection(combinedBase + "_CSSKey.txt", combinedBase + "_disc.txt") ?? "";
break;
case KnownSystem.FujitsuFMTowns:
info.EXEDateBuildDate = (this.AddPlaceholders ? Template.RequiredValue : "");
info.CommonDiscInfo.EXEDateBuildDate = (this.AddPlaceholders ? Template.RequiredValue : "");
break;
case KnownSystem.IncredibleTechnologiesEagle:
info.EXEDateBuildDate = (this.AddPlaceholders ? Template.RequiredValue : "");
info.CommonDiscInfo.EXEDateBuildDate = (this.AddPlaceholders ? Template.RequiredValue : "");
break;
case KnownSystem.KonamieAmusement:
info.EXEDateBuildDate = (this.AddPlaceholders ? Template.RequiredValue : "");
info.CommonDiscInfo.EXEDateBuildDate = (this.AddPlaceholders ? Template.RequiredValue : "");
break;
case KnownSystem.KonamiFirebeat:
info.EXEDateBuildDate = (this.AddPlaceholders ? Template.RequiredValue : "");
info.CommonDiscInfo.EXEDateBuildDate = (this.AddPlaceholders ? Template.RequiredValue : "");
break;
case KnownSystem.KonamiGVSystem:
info.EXEDateBuildDate = (this.AddPlaceholders ? Template.RequiredValue : "");
info.CommonDiscInfo.EXEDateBuildDate = (this.AddPlaceholders ? Template.RequiredValue : "");
break;
case KnownSystem.KonamiSystem573:
info.EXEDateBuildDate = (this.AddPlaceholders ? Template.RequiredValue : "");
info.CommonDiscInfo.EXEDateBuildDate = (this.AddPlaceholders ? Template.RequiredValue : "");
break;
case KnownSystem.KonamiTwinkle:
info.EXEDateBuildDate = (this.AddPlaceholders ? Template.RequiredValue : "");
info.CommonDiscInfo.EXEDateBuildDate = (this.AddPlaceholders ? Template.RequiredValue : "");
break;
case KnownSystem.MattelHyperscan:
info.EXEDateBuildDate = (this.AddPlaceholders ? Template.RequiredValue : "");
info.CommonDiscInfo.EXEDateBuildDate = (this.AddPlaceholders ? Template.RequiredValue : "");
break;
case KnownSystem.MicrosoftXBOX:
if (GetXBOXAuxInfo(combinedBase + "_disc.txt", out string dmihash, out string pfihash, out string sshash, out string ss, out string ssver))
{
info.Comments += $"{Template.XBOXDMIHash}: {dmihash ?? ""}\n" +
info.CommonDiscInfo.Comments += $"{Template.XBOXDMIHash}: {dmihash ?? ""}\n" +
$"{Template.XBOXPFIHash}: {pfihash ?? ""}\n" +
$"{Template.XBOXSSHash}: {sshash ?? ""}\n" +
$"{Template.XBOXSSVersion}: {ssver ?? ""}\n";
info.SecuritySectorRanges = ss ?? "";
info.Extras.SecuritySectorRanges = ss ?? "";
}
if (GetXBOXDMIInfo(Path.Combine(OutputDirectory, "DMI.bin"), out string serial, out string version, out Region? region))
{
info.Serial = serial ?? (this.AddPlaceholders ? Template.RequiredValue : "");
info.Version = version ?? (this.AddPlaceholders ? Template.RequiredValue : "");
info.Region = region;
info.CommonDiscInfo.Serial = serial ?? (this.AddPlaceholders ? Template.RequiredValue : "");
info.VersionAndEditions.Version = version ?? (this.AddPlaceholders ? Template.RequiredValue : "");
info.CommonDiscInfo.Region = region;
}
break;
@@ -812,128 +844,128 @@ namespace DICUI.Utilities
case KnownSystem.MicrosoftXBOX360:
if (GetXBOXAuxInfo(combinedBase + "_disc.txt", out string dmi360hash, out string pfi360hash, out string ss360hash, out string ss360, out string ssver360))
{
info.Comments += $"{Template.XBOXDMIHash}: {dmi360hash ?? ""}\n" +
info.CommonDiscInfo.Comments += $"{Template.XBOXDMIHash}: {dmi360hash ?? ""}\n" +
$"{Template.XBOXPFIHash}: {pfi360hash ?? ""}\n" +
$"{Template.XBOXSSHash}: {ss360hash ?? ""}\n" +
$"{Template.XBOXSSVersion}: {ssver360 ?? ""}\n";
info.SecuritySectorRanges = ss360 ?? "";
info.Extras.SecuritySectorRanges = ss360 ?? "";
}
if (GetXBOX360DMIInfo(Path.Combine(OutputDirectory, "DMI.bin"), out string serial360, out string version360, out Region? region360))
{
info.Serial = serial360 ?? (this.AddPlaceholders ? Template.RequiredValue : "");
info.Version = version360 ?? (this.AddPlaceholders ? Template.RequiredValue : "");
info.Region = region360;
info.CommonDiscInfo.Serial = serial360 ?? (this.AddPlaceholders ? Template.RequiredValue : "");
info.VersionAndEditions.Version = version360 ?? (this.AddPlaceholders ? Template.RequiredValue : "");
info.CommonDiscInfo.Region = region360;
}
break;
case KnownSystem.NamcoSegaNintendoTriforce:
info.EXEDateBuildDate = (this.AddPlaceholders ? Template.RequiredValue : "");
info.CommonDiscInfo.EXEDateBuildDate = (this.AddPlaceholders ? Template.RequiredValue : "");
break;
case KnownSystem.NavisoftNaviken21:
info.EXEDateBuildDate = (this.AddPlaceholders ? Template.RequiredValue : "");
info.CommonDiscInfo.EXEDateBuildDate = (this.AddPlaceholders ? Template.RequiredValue : "");
break;
case KnownSystem.NECPC98:
info.EXEDateBuildDate = (this.AddPlaceholders ? Template.RequiredValue : "");
info.CommonDiscInfo.EXEDateBuildDate = (this.AddPlaceholders ? Template.RequiredValue : "");
break;
case KnownSystem.SegaCDMegaCD:
info.Header = GetSegaHeader(combinedBase + "_mainInfo.txt") ?? "";
info.Extras.Header = GetSegaHeader(combinedBase + "_mainInfo.txt") ?? "";
// Take only the last 16 lines for Sega CD
if (!string.IsNullOrEmpty(info.Header))
info.Header = string.Join("\n", info.Header.Split('\n').Skip(16));
if (!string.IsNullOrEmpty(info.Extras.Header))
info.Extras.Header = string.Join("\n", info.Extras.Header.Split('\n').Skip(16));
if (GetSegaCDBuildInfo(info.Header, out string scdSerial, out string fixedDate))
if (GetSegaCDBuildInfo(info.Extras.Header, out string scdSerial, out string fixedDate))
{
info.Serial = scdSerial ?? "";
info.EXEDateBuildDate = fixedDate ?? "";
info.CommonDiscInfo.Serial = scdSerial ?? "";
info.CommonDiscInfo.EXEDateBuildDate = fixedDate ?? "";
}
break;
case KnownSystem.SegaChihiro:
info.EXEDateBuildDate = (this.AddPlaceholders ? Template.RequiredValue : "");
info.CommonDiscInfo.EXEDateBuildDate = (this.AddPlaceholders ? Template.RequiredValue : "");
break;
case KnownSystem.SegaDreamcast:
info.EXEDateBuildDate = (this.AddPlaceholders ? Template.RequiredValue : "");
info.CommonDiscInfo.EXEDateBuildDate = (this.AddPlaceholders ? Template.RequiredValue : "");
break;
case KnownSystem.SegaNaomi:
info.EXEDateBuildDate = (this.AddPlaceholders ? Template.RequiredValue : "");
info.CommonDiscInfo.EXEDateBuildDate = (this.AddPlaceholders ? Template.RequiredValue : "");
break;
case KnownSystem.SegaNaomi2:
info.EXEDateBuildDate = (this.AddPlaceholders ? Template.RequiredValue : "");
info.CommonDiscInfo.EXEDateBuildDate = (this.AddPlaceholders ? Template.RequiredValue : "");
break;
case KnownSystem.SegaSaturn:
info.Header = GetSegaHeader(combinedBase + "_mainInfo.txt") ?? "";
info.Extras.Header = GetSegaHeader(combinedBase + "_mainInfo.txt") ?? "";
// Take only the first 16 lines for Saturn
if (!string.IsNullOrEmpty(info.Header))
info.Header = string.Join("\n", info.Header.Split('\n').Take(16));
if (!string.IsNullOrEmpty(info.Extras.Header))
info.Extras.Header = string.Join("\n", info.Extras.Header.Split('\n').Take(16));
if (GetSaturnBuildInfo(info.Header, out string saturnSerial, out string saturnVersion, out string buildDate))
if (GetSaturnBuildInfo(info.Extras.Header, out string saturnSerial, out string saturnVersion, out string buildDate))
{
info.Serial = saturnSerial ?? "";
info.Version = saturnVersion ?? "";
info.EXEDateBuildDate = buildDate ?? "";
info.CommonDiscInfo.Serial = saturnSerial ?? "";
info.VersionAndEditions.Version = saturnVersion ?? "";
info.CommonDiscInfo.EXEDateBuildDate = buildDate ?? "";
}
break;
case KnownSystem.SegaTitanVideo:
info.EXEDateBuildDate = (this.AddPlaceholders ? Template.RequiredValue : "");
info.CommonDiscInfo.EXEDateBuildDate = (this.AddPlaceholders ? Template.RequiredValue : "");
break;
case KnownSystem.SNKNeoGeoCD:
info.EXEDateBuildDate = (this.AddPlaceholders ? Template.RequiredValue : "");
info.CommonDiscInfo.EXEDateBuildDate = (this.AddPlaceholders ? Template.RequiredValue : "");
break;
case KnownSystem.SonyPlayStation:
info.EXEDateBuildDate = GetPlayStationEXEDate(Drive?.Letter) ?? "";
info.EDC = GetMissingEDCCount(combinedBase + ".img_EdcEcc.txt") > 0 ? YesNo.No : YesNo.Yes;
info.AntiModchip = GetAntiModchipDetected(combinedBase + "_disc.txt") ? YesNo.Yes : YesNo.No;
info.LibCrypt = YesNo.No;
info.CommonDiscInfo.EXEDateBuildDate = GetPlayStationEXEDate(Drive?.Letter) ?? "";
info.EDC.EDC = GetMissingEDCCount(combinedBase + ".img_EdcEcc.txt") > 0 ? YesNo.No : YesNo.Yes;
info.CopyProtection.AntiModchip = GetAntiModchipDetected(combinedBase + "_disc.txt") ? YesNo.Yes : YesNo.No;
info.CopyProtection.LibCrypt = YesNo.No;
if (File.Exists(combinedBase + "_subIntention.txt"))
{
FileInfo fi = new FileInfo(combinedBase + "_subIntention.txt");
if (fi.Length > 0)
{
info.LibCrypt = YesNo.Yes;
info.LibCryptData = GetFullFile(combinedBase + "_subIntention.txt") ?? "";
info.CopyProtection.LibCrypt = YesNo.Yes;
info.CopyProtection.LibCryptData = GetFullFile(combinedBase + "_subIntention.txt") ?? "";
}
}
break;
case KnownSystem.SonyPlayStation2:
info.LanguageSelection = new string[] { "Bios settings", "Language selector", "Options menu" };
info.EXEDateBuildDate = GetPlayStationEXEDate(Drive?.Letter) ?? "";
info.Version = GetPlayStation2Version(Drive?.Letter) ?? "";
info.CommonDiscInfo.LanguageSelection = new LanguageSelection?[] { LanguageSelection.BiosSettings, LanguageSelection.LanguageSelector, LanguageSelection.OptionsMenu };
info.CommonDiscInfo.EXEDateBuildDate = GetPlayStationEXEDate(Drive?.Letter) ?? "";
info.VersionAndEditions.Version = GetPlayStation2Version(Drive?.Letter) ?? "";
break;
case KnownSystem.SonyPlayStation3:
info.DiscKey = (this.AddPlaceholders ? Template.RequiredValue : "");
info.DiscID = (this.AddPlaceholders ? Template.RequiredValue : "");
info.Extras.DiscKey = (this.AddPlaceholders ? Template.RequiredValue : "");
info.Extras.DiscID = (this.AddPlaceholders ? Template.RequiredValue : "");
break;
case KnownSystem.SonyPlayStation4:
info.Version = GetPlayStation4Version(Drive?.Letter) ?? "";
info.VersionAndEditions.Version = GetPlayStation4Version(Drive?.Letter) ?? "";
break;
case KnownSystem.ZAPiTGamesGameWaveFamilyEntertainmentSystem:
info.Protection = (AddPlaceholders ? Template.RequiredIfExistsValue : "");
info.CopyProtection.Protection = (AddPlaceholders ? Template.RequiredIfExistsValue : "");
break;
}
// Comments is one of the few fields with odd handling
if (string.IsNullOrEmpty(info.Comments))
info.Comments = (AddPlaceholders ? Template.OptionalValue : "");
if (string.IsNullOrEmpty(info.CommonDiscInfo.Comments))
info.CommonDiscInfo.Comments = (AddPlaceholders ? Template.OptionalValue : "");
return info;
}
@@ -953,62 +985,62 @@ namespace DICUI.Utilities
{
// Common Disc Info section
List<string> output = new List<string> { "Common Disc Info:" };
AddIfExists(output, Template.TitleField, info.Title, 1);
AddIfExists(output, Template.ForeignTitleField, info.ForeignTitleNonLatin, 1);
AddIfExists(output, Template.DiscNumberField, info.DiscNumberLetter, 1);
AddIfExists(output, Template.DiscTitleField, info.DiscTitle, 1);
AddIfExists(output, Template.SystemField, info.System.LongName(), 1);
AddIfExists(output, Template.MediaTypeField, GetFixedMediaType(info.Media, info.Layerbreak), 1);
AddIfExists(output, Template.CategoryField, info.Category.LongName(), 1);
AddIfExists(output, Template.TitleField, info.CommonDiscInfo.Title, 1);
AddIfExists(output, Template.ForeignTitleField, info.CommonDiscInfo.ForeignTitleNonLatin, 1);
AddIfExists(output, Template.DiscNumberField, info.CommonDiscInfo.DiscNumberLetter, 1);
AddIfExists(output, Template.DiscTitleField, info.CommonDiscInfo.DiscTitle, 1);
AddIfExists(output, Template.SystemField, info.CommonDiscInfo.System.LongName(), 1);
AddIfExists(output, Template.MediaTypeField, GetFixedMediaType(info.CommonDiscInfo.Media, info.SizeAndChecksums.Layerbreak), 1);
AddIfExists(output, Template.CategoryField, info.CommonDiscInfo.Category.LongName(), 1);
AddIfExists(output, Template.MatchingIDsField, info.MatchedIDs, 1);
AddIfExists(output, Template.RegionField, info.Region.LongName(), 1);
AddIfExists(output, Template.LanguagesField, (info.Languages ?? new Language?[] { null }).Select(l => l.LongName()).ToArray(), 1);
AddIfExists(output, Template.PlaystationLanguageSelectionViaField, info.LanguageSelection, 1);
AddIfExists(output, Template.DiscSerialField, info.Serial, 1);
AddIfExists(output, Template.RegionField, info.CommonDiscInfo.Region.LongName(), 1);
AddIfExists(output, Template.LanguagesField, (info.CommonDiscInfo.Languages ?? new Language?[] { null }).Select(l => l.LongName()).ToArray(), 1);
AddIfExists(output, Template.PlaystationLanguageSelectionViaField, (info.CommonDiscInfo.LanguageSelection ?? new LanguageSelection?[] { }).Select(l => l.ToString()).ToArray(), 1);
AddIfExists(output, Template.DiscSerialField, info.CommonDiscInfo.Serial, 1);
// All ringcode information goes in an indented area
output.Add(""); output.Add("\tRingcode Information:");
// If we have a dual-layer disc
if (info.Layerbreak != default(long))
if (info.SizeAndChecksums.Layerbreak != default(long))
{
AddIfExists(output, "Inner " + Template.MasteringRingField, info.MasteringRingFirstLayerDataSide, 2);
AddIfExists(output, "Inner " + Template.MasteringSIDField, info.MasteringSIDCodeFirstLayerDataSide, 2);
AddIfExists(output, "Inner " + Template.ToolstampField, info.ToolstampMasteringCodeFirstLayerDataSide, 2);
AddIfExists(output, "Outer " + Template.MasteringRingField, info.MasteringRingSecondLayerLabelSide, 2);
AddIfExists(output, "Outer " + Template.MasteringSIDField, info.MasteringSIDCodeSecondLayerLabelSide, 2);
AddIfExists(output, "Outer " + Template.ToolstampField, info.ToolstampMasteringCodeSecondLayerLabelSide, 2);
AddIfExists(output, "Data-Side " + Template.MouldSIDField, info.MouldSIDCodeFirstLayerDataSide, 2);
AddIfExists(output, "Label-Side " + Template.MouldSIDField, info.MouldSIDCodeSecondLayerLabelSide, 2);
AddIfExists(output, Template.AdditionalMouldField, info.AdditionalMouldFirstLayerDataSide, 2);
AddIfExists(output, "Inner " + Template.MasteringRingField, info.CommonDiscInfo.MasteringRingFirstLayerDataSide, 2);
AddIfExists(output, "Inner " + Template.MasteringSIDField, info.CommonDiscInfo.MasteringSIDCodeFirstLayerDataSide, 2);
AddIfExists(output, "Inner " + Template.ToolstampField, info.CommonDiscInfo.ToolstampMasteringCodeFirstLayerDataSide, 2);
AddIfExists(output, "Outer " + Template.MasteringRingField, info.CommonDiscInfo.MasteringRingSecondLayerLabelSide, 2);
AddIfExists(output, "Outer " + Template.MasteringSIDField, info.CommonDiscInfo.MasteringSIDCodeSecondLayerLabelSide, 2);
AddIfExists(output, "Outer " + Template.ToolstampField, info.CommonDiscInfo.ToolstampMasteringCodeSecondLayerLabelSide, 2);
AddIfExists(output, "Data-Side " + Template.MouldSIDField, info.CommonDiscInfo.MouldSIDCodeFirstLayerDataSide, 2);
AddIfExists(output, "Label-Side " + Template.MouldSIDField, info.CommonDiscInfo.MouldSIDCodeSecondLayerLabelSide, 2);
AddIfExists(output, Template.AdditionalMouldField, info.CommonDiscInfo.AdditionalMouldFirstLayerDataSide, 2);
}
// If we have a single-layer disc
else
{
AddIfExists(output, Template.MasteringRingField, info.MasteringRingFirstLayerDataSide, 2);
AddIfExists(output, Template.MasteringSIDField, info.MasteringSIDCodeFirstLayerDataSide, 2);
AddIfExists(output, "Data-Side " + Template.MouldSIDField, info.MouldSIDCodeFirstLayerDataSide, 2);
AddIfExists(output, "Label-Side " + Template.MouldSIDField, info.MouldSIDCodeSecondLayerLabelSide, 2);
AddIfExists(output, Template.AdditionalMouldField, info.AdditionalMouldFirstLayerDataSide, 2);
AddIfExists(output, Template.ToolstampField, info.ToolstampMasteringCodeFirstLayerDataSide, 2);
AddIfExists(output, Template.MasteringRingField, info.CommonDiscInfo.MasteringRingFirstLayerDataSide, 2);
AddIfExists(output, Template.MasteringSIDField, info.CommonDiscInfo.MasteringSIDCodeFirstLayerDataSide, 2);
AddIfExists(output, "Data-Side " + Template.MouldSIDField, info.CommonDiscInfo.MouldSIDCodeFirstLayerDataSide, 2);
AddIfExists(output, "Label-Side " + Template.MouldSIDField, info.CommonDiscInfo.MouldSIDCodeSecondLayerLabelSide, 2);
AddIfExists(output, Template.AdditionalMouldField, info.CommonDiscInfo.AdditionalMouldFirstLayerDataSide, 2);
AddIfExists(output, Template.ToolstampField, info.CommonDiscInfo.ToolstampMasteringCodeFirstLayerDataSide, 2);
}
AddIfExists(output, Template.BarcodeField, info.Barcode, 1);
AddIfExists(output, Template.EXEDateBuildDate, info.EXEDateBuildDate, 1);
AddIfExists(output, Template.ErrorCountField, info.ErrorsCount, 1);
AddIfExists(output, Template.CommentsField, info.Comments.Trim(), 1);
AddIfExists(output, Template.ContentsField, info.Contents.Trim(), 1);
AddIfExists(output, Template.BarcodeField, info.CommonDiscInfo.Barcode, 1);
AddIfExists(output, Template.EXEDateBuildDate, info.CommonDiscInfo.EXEDateBuildDate, 1);
AddIfExists(output, Template.ErrorCountField, info.CommonDiscInfo.ErrorsCount, 1);
AddIfExists(output, Template.CommentsField, info.CommonDiscInfo.Comments.Trim(), 1);
AddIfExists(output, Template.ContentsField, info.CommonDiscInfo.Contents.Trim(), 1);
// Version and Editions section
output.Add(""); output.Add("Version and Editions:");
AddIfExists(output, Template.VersionField, info.Version, 1);
AddIfExists(output, Template.EditionField, info.OtherEditions, 1);
AddIfExists(output, Template.VersionField, info.VersionAndEditions.Version, 1);
AddIfExists(output, Template.EditionField, info.VersionAndEditions.OtherEditions, 1);
// EDC section
if (info.EDC != YesNo.NULL)
if (info.EDC.EDC != YesNo.NULL)
{
output.Add("EDC:");
AddIfExists(output, Template.PlayStationEDCField, info.EDC.LongName(), 1);
AddIfExists(output, Template.PlayStationEDCField, info.EDC.EDC.LongName(), 1);
}
// Parent/Clone Relationship section
@@ -1017,31 +1049,31 @@ namespace DICUI.Utilities
// AddIfExists(output, Template.RegionalParentField, info.RegionalParent.ToString());
// Extras section
if (info.PVD != null || info.PIC != null || info.BCA != null)
if (info.Extras.PVD != null || info.Extras.PIC != null || info.Extras.BCA != null)
{
output.Add(""); output.Add("Extras:");
AddIfExists(output, Template.PVDField, info.PVD.Trim(), 1);
AddIfExists(output, Template.PlayStation3WiiDiscKeyField, info.DiscKey, 1);
AddIfExists(output, Template.PlayStation3DiscIDField, info.DiscID, 1);
AddIfExists(output, Template.PICField, info.PIC, 1);
AddIfExists(output, Template.HeaderField, info.Header, 1);
AddIfExists(output, Template.GameCubeWiiBCAField, info.BCA, 1);
AddIfExists(output, Template.XBOXSSRanges, info.SecuritySectorRanges, 1);
AddIfExists(output, Template.PVDField, info.Extras.PVD.Trim(), 1);
AddIfExists(output, Template.PlayStation3WiiDiscKeyField, info.Extras.DiscKey, 1);
AddIfExists(output, Template.PlayStation3DiscIDField, info.Extras.DiscID, 1);
AddIfExists(output, Template.PICField, info.Extras.PIC, 1);
AddIfExists(output, Template.HeaderField, info.Extras.Header, 1);
AddIfExists(output, Template.GameCubeWiiBCAField, info.Extras.BCA, 1);
AddIfExists(output, Template.XBOXSSRanges, info.Extras.SecuritySectorRanges, 1);
}
// Copy Protection section
if (info.Protection != null || info.EDC != YesNo.NULL)
if (info.CopyProtection.Protection != null || info.EDC.EDC != YesNo.NULL)
{
output.Add(""); output.Add("Copy Protection:");
if (info.EDC != YesNo.NULL)
if (info.EDC.EDC != YesNo.NULL)
{
AddIfExists(output, Template.PlayStationAntiModchipField, info.AntiModchip.LongName(), 1);
AddIfExists(output, Template.PlayStationLibCryptField, info.LibCrypt.LongName(), 1);
AddIfExists(output, Template.SubIntentionField, info.LibCryptData, 1);
AddIfExists(output, Template.PlayStationAntiModchipField, info.CopyProtection.AntiModchip.LongName(), 1);
AddIfExists(output, Template.PlayStationLibCryptField, info.CopyProtection.LibCrypt.LongName(), 1);
AddIfExists(output, Template.SubIntentionField, info.CopyProtection.LibCryptData, 1);
}
AddIfExists(output, Template.CopyProtectionField, info.Protection, 1);
AddIfExists(output, Template.SubIntentionField, info.SecuROMData, 1);
AddIfExists(output, Template.CopyProtectionField, info.CopyProtection.Protection, 1);
AddIfExists(output, Template.SubIntentionField, info.CopyProtection.SecuROMData, 1);
}
// Dumpers and Status section
@@ -1050,22 +1082,22 @@ namespace DICUI.Utilities
// AddIfExists(output, Template.OtherDumpersField, info.OtherDumpers);
// Tracks and Write Offsets section
if (!string.IsNullOrWhiteSpace(info.ClrMameProData))
if (!string.IsNullOrWhiteSpace(info.TracksAndWriteOffsets.ClrMameProData))
{
output.Add(""); output.Add("Tracks and Write Offsets:");
AddIfExists(output, Template.DATField, info.ClrMameProData + "\n", 1);
AddIfExists(output, Template.CuesheetField, info.Cuesheet, 1);
AddIfExists(output, Template.WriteOffsetField, info.OtherWriteOffsets, 1);
AddIfExists(output, Template.DATField, info.TracksAndWriteOffsets.ClrMameProData + "\n", 1);
AddIfExists(output, Template.CuesheetField, info.TracksAndWriteOffsets.Cuesheet, 1);
AddIfExists(output, Template.WriteOffsetField, info.TracksAndWriteOffsets.OtherWriteOffsets, 1);
}
// Size & Checksum section
else
{
output.Add(""); output.Add("Size & Checksum:");
AddIfExists(output, Template.LayerbreakField, (info.Layerbreak == default(long) ? null : info.Layerbreak.ToString()), 1);
AddIfExists(output, Template.SizeField, info.Size.ToString(), 1);
AddIfExists(output, Template.CRC32Field, info.CRC32, 1);
AddIfExists(output, Template.MD5Field, info.MD5, 1);
AddIfExists(output, Template.SHA1Field, info.SHA1, 1);
AddIfExists(output, Template.LayerbreakField, (info.SizeAndChecksums.Layerbreak == default(long) ? null : info.SizeAndChecksums.Layerbreak.ToString()), 1);
AddIfExists(output, Template.SizeField, info.SizeAndChecksums.Size.ToString(), 1);
AddIfExists(output, Template.CRC32Field, info.SizeAndChecksums.CRC32, 1);
AddIfExists(output, Template.MD5Field, info.SizeAndChecksums.MD5, 1);
AddIfExists(output, Template.SHA1Field, info.SizeAndChecksums.SHA1, 1);
}
// Make sure there aren't any instances of two blank lines in a row
@@ -1102,7 +1134,7 @@ namespace DICUI.Utilities
private void AddIfExists(List<string> output, string key, string value, int indent)
{
// If there's no valid value to write
if (string.IsNullOrWhiteSpace(value))
if (value == null)
return;
string prefix = "";
@@ -1208,6 +1240,8 @@ namespace DICUI.Utilities
if (!File.Exists(DICPath))
return Result.Failure("Error! Could not find DiscImageCreator!");
// TODO: Ensure output path not the same as input drive OR DIC/DICUI location
return Result.Success();
}
@@ -1430,17 +1464,17 @@ namespace DICUI.Utilities
// Now we format everything we can
string protection = "";
if (!String.IsNullOrEmpty(region))
if (!string.IsNullOrEmpty(region))
protection += $"Region: {region}\n";
if (!String.IsNullOrEmpty(rceProtection))
if (!string.IsNullOrEmpty(rceProtection))
protection += $"RCE Protection: {rceProtection}\n";
if (!String.IsNullOrEmpty(copyrightProtectionSystemType))
if (!string.IsNullOrEmpty(copyrightProtectionSystemType))
protection += $"Copyright Protection System Type: {copyrightProtectionSystemType}\n";
if (!String.IsNullOrEmpty(encryptedDiscKey))
if (!string.IsNullOrEmpty(encryptedDiscKey))
protection += $"Encrypted Disc Key: {encryptedDiscKey}\n";
if (!String.IsNullOrEmpty(playerKey))
if (!string.IsNullOrEmpty(playerKey))
protection += $"Player Key: {playerKey}\n";
if (!String.IsNullOrEmpty(decryptedDiscKey))
if (!string.IsNullOrEmpty(decryptedDiscKey))
protection += $"Decrypted Disc Key: {decryptedDiscKey}\n";
return protection;
@@ -1666,29 +1700,40 @@ namespace DICUI.Utilities
if (!Directory.Exists(drivePath))
return null;
// If we can't find SYSTEM.CNF, we don't have a PlayStation disc
// Get the two paths that we will need to check
string psxExePath = Path.Combine(drivePath, "PSX.EXE");
string systemCnfPath = Path.Combine(drivePath, "SYSTEM.CNF");
if (!File.Exists(systemCnfPath))
return null;
// Let's try reading SYSTEM.CNF to find the "BOOT" value
// Try both of the common paths that contain information
string exeName = null;
try
if (File.Exists(psxExePath))
{
using (StreamReader sr = File.OpenText(systemCnfPath))
exeName = "PSX.EXE";
}
else if (File.Exists(systemCnfPath))
{
// Let's try reading SYSTEM.CNF to find the "BOOT" value
try
{
// Not assuming proper ordering, just in case
string line = sr.ReadLine();
while (!line.StartsWith("BOOT"))
line = sr.ReadLine();
using (StreamReader sr = File.OpenText(systemCnfPath))
{
// Not assuming proper ordering, just in case
string line = sr.ReadLine();
while (!line.StartsWith("BOOT"))
line = sr.ReadLine();
// Once it finds the "BOOT" line, extract the name
exeName = Regex.Match(line, @"BOOT.*?=\s*cdrom.?:\\(.*?);.*").Groups[1].Value;
// Once it finds the "BOOT" line, extract the name
exeName = Regex.Match(line, @"BOOT.*?=\s*cdrom.?:\\?(.*?);.*").Groups[1].Value;
}
}
catch
{
// We don't care what the error was
return null;
}
}
catch
else
{
// We don't care what the error was
return null;
}
@@ -1697,8 +1742,11 @@ namespace DICUI.Utilities
if (!File.Exists(exePath))
return null;
// Fix the Y2K timestamp issue
FileInfo fi = new FileInfo(exePath);
return fi.LastWriteTimeUtc.ToString("yyyy-MM-dd");
DateTime dt = new DateTime(fi.LastWriteTimeUtc.Year >= 1900 && fi.LastWriteTimeUtc.Year < 1920 ? 2000 + fi.LastWriteTimeUtc.Year % 100 : fi.LastWriteTimeUtc.Year,
fi.LastWriteTimeUtc.Month, fi.LastWriteTimeUtc.Day);
return dt.ToString("yyyy-MM-dd");
}
/// <summary>
@@ -1796,7 +1844,7 @@ namespace DICUI.Utilities
{
using (BinaryReader br = new BinaryReader(File.OpenRead(paramSfoPath)))
{
br.BaseStream.Seek(0x9A4, SeekOrigin.Begin);
br.BaseStream.Seek(-0x08, SeekOrigin.End);
return new string(br.ReadChars(5));
}
}
@@ -1854,7 +1902,7 @@ namespace DICUI.Utilities
serial = null; date = null;
// If the input header is null, we can't do a thing
if (String.IsNullOrWhiteSpace(segaHeader))
if (string.IsNullOrWhiteSpace(segaHeader))
return false;
// Now read it in cutting it into lines for easier parsing
@@ -1937,7 +1985,7 @@ namespace DICUI.Utilities
serial = null; version = null; date = null;
// If the input header is null, we can't do a thing
if (String.IsNullOrWhiteSpace(segaHeader))
if (string.IsNullOrWhiteSpace(segaHeader))
return false;
// Now read it in cutting it into lines for easier parsing

View File

@@ -93,6 +93,11 @@ namespace DICUI.Utilities
/// </summary>
public int? ForceUnitAccessValue { get; set; }
/// <summary>
/// Set the no skip security sector flag value (default 100)
/// </summary>
public int? NoSkipSecuritySectorValue { get; set; }
/// <summary>
/// Set scan file timeout value (default 60)
/// </summary>
@@ -141,6 +146,7 @@ namespace DICUI.Utilities
BEOpcodeValue = null;
C2OpcodeValue = new int?[4];
ForceUnitAccessValue = null;
NoSkipSecuritySectorValue = null;
ScanFileProtectValue = null;
SubchannelReadLevelValue = null;
VideoNowValue = null;
@@ -246,6 +252,7 @@ namespace DICUI.Utilities
|| Command == DICCommand.CompactDisc
|| Command == DICCommand.Data
|| Command == DICCommand.DigitalVideoDisc
|| Command == DICCommand.Disk
|| Command == DICCommand.DriveSpeed
|| Command == DICCommand.Eject
|| Command == DICCommand.Floppy
@@ -272,6 +279,7 @@ namespace DICUI.Utilities
|| Command == DICCommand.CompactDisc
|| Command == DICCommand.Data
|| Command == DICCommand.DigitalVideoDisc
|| Command == DICCommand.Disk
|| Command == DICCommand.Floppy
|| Command == DICCommand.GDROM
|| Command == DICCommand.MDS
@@ -354,6 +362,13 @@ namespace DICUI.Utilities
parameters.Add(DICFlag.AMSF.LongName());
}
// Atari Jaguar CD
if (Command == DICCommand.CompactDisc)
{
if (this[DICFlag.AtariJaguar])
parameters.Add(DICFlag.AtariJaguar.LongName());
}
// BE Opcode
if (Command == DICCommand.Audio
|| Command == DICCommand.CompactDisc
@@ -444,8 +459,10 @@ namespace DICUI.Utilities
}
// Force Unit Access
if (Command == DICCommand.BluRay
if (Command == DICCommand.Audio
|| Command == DICCommand.BluRay
|| Command == DICCommand.CompactDisc
|| Command == DICCommand.Data
|| Command == DICCommand.DigitalVideoDisc
|| Command == DICCommand.Swap
|| Command == DICCommand.XBOX)
@@ -534,7 +551,11 @@ namespace DICUI.Utilities
|| Command == DICCommand.XGD3Swap)
{
if (this[DICFlag.NoSkipSS])
{
parameters.Add(DICFlag.NoSkipSS.LongName());
if (NoSkipSecuritySectorValue != null)
parameters.Add(NoSkipSecuritySectorValue.ToString());
}
}
// Raw read (2064 byte/sector)
@@ -546,7 +567,8 @@ namespace DICUI.Utilities
// Reverse read
if (Command == DICCommand.CompactDisc
|| Command == DICCommand.Data)
|| Command == DICCommand.Data
|| Command == DICCommand.DigitalVideoDisc)
{
if (this[DICFlag.Reverse])
parameters.Add(DICFlag.Reverse.LongName());
@@ -653,6 +675,13 @@ namespace DICUI.Utilities
}
}
// VideoNow Color
if (Command == DICCommand.CompactDisc)
{
if (this[DICFlag.VideoNowColor])
parameters.Add(DICFlag.VideoNowColor.LongName());
}
return string.Join(" ", parameters);
}
@@ -673,7 +702,7 @@ namespace DICUI.Utilities
private bool ValidateAndSetParameters(string parameters)
{
// The string has to be valid by itself first
if (String.IsNullOrWhiteSpace(parameters))
if (string.IsNullOrWhiteSpace(parameters))
return false;
// Now split the string into parts for easier validation
@@ -820,6 +849,23 @@ namespace DICUI.Utilities
index = 4;
break;
case DICCommandStrings.Disk:
if (!DoesExist(parts, 1) || !IsValidDriveLetter(parts[1]))
return false;
else
DriveLetter = parts[1];
if (!DoesExist(parts, 2) || IsFlag(parts[2]))
return false;
else
Filename = parts[2];
if (parts.Count > 3)
return false;
Command = DICCommand.Disk;
break;
case DICCommandStrings.DriveSpeed:
if (!DoesExist(parts, 1) || !IsValidDriveLetter(parts[1]))
return false;
@@ -1077,6 +1123,13 @@ namespace DICUI.Utilities
this[DICFlag.AMSF] = true;
break;
case DICFlagStrings.AtariJaguar:
if (parts[0] != DICCommandStrings.CompactDisc)
return false;
this[DICFlag.AtariJaguar] = true;
break;
case DICFlagStrings.BEOpcode:
if (parts[0] != DICCommandStrings.Audio
&& parts[0] != DICCommandStrings.CompactDisc
@@ -1158,12 +1211,12 @@ namespace DICUI.Utilities
case DICFlagStrings.ForceUnitAccess:
if (parts[0] != DICCommandStrings.Audio
&& parts[0] != DICCommandStrings.BluRay
&& parts[0] != DICCommandStrings.CompactDisc
&& parts[0] != DICCommandStrings.DigitalVideoDisc
&& parts[0] != DICCommandStrings.Data
&& parts[0] != DICCommandStrings.GDROM
&& parts[0] != DICCommandStrings.XBOX)
&& parts[0] != DICCommandStrings.BluRay
&& parts[0] != DICCommandStrings.CompactDisc
&& parts[0] != DICCommandStrings.DigitalVideoDisc
&& parts[0] != DICCommandStrings.Data
&& parts[0] != DICCommandStrings.GDROM
&& parts[0] != DICCommandStrings.XBOX)
return false;
else if (!DoesExist(parts, i + 1))
{
@@ -1250,8 +1303,22 @@ namespace DICUI.Utilities
&& parts[0] != DICCommandStrings.XGD2Swap
&& parts[0] != DICCommandStrings.XGD3Swap)
return false;
else if (!DoesExist(parts, i + 1))
{
this[DICFlag.NoSkipSS] = true;
break;
}
else if (IsFlag(parts[i + 1]))
{
this[DICFlag.NoSkipSS] = true;
break;
}
else if (!IsValidNumber(parts[i + 1], lowerBound: 0))
return false;
this[DICFlag.NoSkipSS] = true;
ForceUnitAccessValue = Int32.Parse(parts[i + 1]);
i++;
break;
case DICFlagStrings.Raw:
@@ -1263,7 +1330,8 @@ namespace DICUI.Utilities
case DICFlagStrings.Reverse:
if (parts[0] != DICCommandStrings.CompactDisc
&& parts[0] != DICCommandStrings.Data)
&& parts[0] != DICCommandStrings.Data
&& parts[0] != DICCommandStrings.DigitalVideoDisc)
return false;
this[DICFlag.Reverse] = true;
@@ -1375,6 +1443,13 @@ namespace DICUI.Utilities
i++;
break;
case DICFlagStrings.VideoNowColor:
if (parts[0] != DICCommandStrings.CompactDisc)
return false;
this[DICFlag.VideoNowColor] = true;
break;
default:
return false;
}
@@ -1492,6 +1567,9 @@ namespace DICUI.Utilities
case MediaType.FloppyDisk:
Command = DICCommand.Floppy;
return;
case MediaType.HardDisk:
Command = DICCommand.Disk;
return;
default:
Command = DICCommand.NONE;
@@ -1547,11 +1625,20 @@ namespace DICUI.Utilities
SubchannelReadLevelValue = 2;
}
break;
case KnownSystem.AtariJaguarCD:
this[DICFlag.AtariJaguar] = true;
break;
case KnownSystem.HasbroVideoNow:
case KnownSystem.HasbroVideoNowColor:
case KnownSystem.HasbroVideoNowJr:
this[DICFlag.VideoNow] = true;
this.VideoNowValue = 18032;
break;
case KnownSystem.HasbroVideoNowColor:
this[DICFlag.VideoNowColor] = true;
break;
case KnownSystem.HasbroVideoNowXP:
this[DICFlag.VideoNow] = true;
this.VideoNowValue = 20832;
break;
case KnownSystem.NECPCEngineTurboGrafxCD:
this[DICFlag.MCN] = true;

View File

@@ -236,6 +236,7 @@ namespace DICUI.Utilities
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
types.Add(MediaType.FloppyDisk);
types.Add(MediaType.HardDisk);
break;
// https://en.wikipedia.org/wiki/Amiga
@@ -254,6 +255,7 @@ namespace DICUI.Utilities
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
@@ -700,9 +702,13 @@ namespace DICUI.Utilities
/// </remarks>
public static List<Drive> CreateListOfDrives()
{
var drives = new List<Drive>();
// 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
// Get the floppy drives and set the flag from removable
try
{
ManagementObjectSearcher searcher =
@@ -716,7 +722,7 @@ namespace DICUI.Utilities
if (mediaType != null && ((mediaType > 0 && mediaType < 11) || (mediaType > 12 && mediaType < 22)))
{
char devId = queryObj["DeviceID"].ToString()[0];
drives.Add(Drive.Floppy(devId));
drives.ForEach(d => { if (d.Letter == devId) { d.InternalDriveType = InternalDriveType.Floppy; } });
}
}
}
@@ -725,14 +731,7 @@ namespace DICUI.Utilities
// No-op
}
// Get the optical disc drives
List<Drive> discDrives = DriveInfo.GetDrives()
.Where(d => d.DriveType == DriveType.CDRom)
.Select(d => Drive.Optical(d.Name[0], (d.IsReady ? (string.IsNullOrWhiteSpace(d.VolumeLabel) ? "disc" : d.VolumeLabel) : Template.DiscNotDetected), d.IsReady))
.ToList();
// Add the two lists together and order
drives.AddRange(discDrives);
// Order the drives by drive letter
drives = drives.OrderBy(i => i.Letter).ToList();
return drives;
@@ -741,20 +740,29 @@ namespace DICUI.Utilities
/// <summary>
/// Get the current media type from drive letter
/// </summary>
/// <param name="driveLetter"></param>
/// <param name="drive"></param>
/// <returns></returns>
/// <remarks>
/// https://stackoverflow.com/questions/11420365/detecting-if-disc-is-in-dvd-drive
/// </remarks>
public static MediaType? GetMediaType(char? driveLetter)
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 = '" + driveLetter + ":\'");
"SELECT * FROM Win32_CDROMDrive WHERE Id = '" + drive.Letter + ":\'");
var collection = searcher.Get();
foreach (ManagementObject queryObj in collection)
@@ -804,22 +812,27 @@ namespace DICUI.Utilities
}
/// <summary>
/// Get the current system from drive letter
/// Get the current system from drive
/// </summary>
/// <param name="driveLetter"></param>
/// <param name="drive"></param>
/// <returns></returns>
public static KnownSystem? GetKnownSystem(char? driveLetter)
public static KnownSystem? GetKnownSystem(Drive drive)
{
// If no letter is provided, then we can't do anything
if (driveLetter == null)
// If drive or drive letter are provided, we can't do anything
if (drive?.Letter == null)
return null;
string drivePath = $"{driveLetter}:\\";
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")))
{
@@ -856,7 +869,7 @@ namespace DICUI.Utilities
}
// Sony PlayStation 4
if (File.Exists(Path.Combine(drivePath, "PSLogo.ico")))
if (drive.VolumeLabel.Equals("PS4VOLUME", StringComparison.OrdinalIgnoreCase))
{
return KnownSystem.SonyPlayStation4;
}
@@ -888,6 +901,10 @@ namespace DICUI.Utilities
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());
@@ -930,9 +947,9 @@ namespace DICUI.Utilities
return string.Join("\n", found.Select(kvp => kvp.Key + ": " + kvp.Value).ToArray());
}
catch
catch (Exception ex)
{
return "Path could not be scanned!";
return $"Path could not be scanned! {ex}";
}
}
}

View File

@@ -27,7 +27,7 @@ namespace DICUI.Web
public string GetLastFilename()
{
// Try to extract the filename from the Content-Disposition header
if (!String.IsNullOrEmpty(this.ResponseHeaders["Content-Disposition"]))
if (!string.IsNullOrEmpty(this.ResponseHeaders["Content-Disposition"]))
return this.ResponseHeaders["Content-Disposition"].Substring(this.ResponseHeaders["Content-Disposition"].IndexOf("filename=") + 9).Replace("\"", "");
return null;

Binary file not shown.

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="BurnOutSharp" version="1.3.7.1" targetFramework="net461" />
<package id="LessIO" version="0.5.0" targetFramework="net461" />
<package id="libmspack4n" version="0.8.0" targetFramework="net461" />
<package id="Newtonsoft.Json" version="12.0.2" targetFramework="net461" />
<package id="UnshieldSharp" version="1.4.2.2" targetFramework="net461" />
<package id="zlib.net" version="1.0.4.0" targetFramework="net461" />
</packages>

View File

@@ -1,83 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\Microsoft.NET.Test.Sdk.15.8.0\build\net45\Microsoft.Net.Test.Sdk.props" Condition="Exists('..\packages\Microsoft.NET.Test.Sdk.15.8.0\build\net45\Microsoft.Net.Test.Sdk.props')" />
<Import Project="..\packages\Microsoft.CodeCoverage.15.8.0\build\netstandard1.0\Microsoft.CodeCoverage.props" Condition="Exists('..\packages\Microsoft.CodeCoverage.15.8.0\build\netstandard1.0\Microsoft.CodeCoverage.props')" />
<Import Project="..\packages\xunit.runner.visualstudio.2.3.1\build\net20\xunit.runner.visualstudio.props" Condition="Exists('..\packages\xunit.runner.visualstudio.2.3.1\build\net20\xunit.runner.visualstudio.props')" />
<Import Project="..\packages\xunit.runner.console.2.3.1\build\xunit.runner.console.props" Condition="Exists('..\packages\xunit.runner.console.2.3.1\build\xunit.runner.console.props')" />
<Import Project="..\packages\xunit.core.2.3.1\build\xunit.core.props" Condition="Exists('..\packages\xunit.core.2.3.1\build\xunit.core.props')" />
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{7CC064D2-38AB-4A05-8519-28660DE4562A}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>DICUI.Test</RootNamespace>
<AssemblyName>DICUI.Test</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">15.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
<ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages</ReferencePath>
<IsCodedUITest>False</IsCodedUITest>
<TestProjectType>UnitTest</TestProjectType>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
<TargetFrameworks>net462;net472;netcoreapp3.0</TargetFrameworks>
<IsPackable>false</IsPackable>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.VisualStudio.CodeCoverage.Shim, Version=15.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.CodeCoverage.15.8.0\lib\net45\Microsoft.VisualStudio.CodeCoverage.Shim.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="xunit.abstractions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
<HintPath>..\packages\xunit.abstractions.2.0.1\lib\net35\xunit.abstractions.dll</HintPath>
</Reference>
<Reference Include="xunit.assert, Version=2.3.1.3858, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
<HintPath>..\packages\xunit.assert.2.3.1\lib\netstandard1.1\xunit.assert.dll</HintPath>
</Reference>
<Reference Include="xunit.core, Version=2.3.1.3858, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
<HintPath>..\packages\xunit.extensibility.core.2.3.1\lib\netstandard1.1\xunit.core.dll</HintPath>
</Reference>
<Reference Include="xunit.execution.desktop, Version=2.3.1.3858, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
<HintPath>..\packages\xunit.extensibility.execution.2.3.1\lib\net452\xunit.execution.desktop.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="UI\AllowedSpeedsTest.cs" />
<Compile Include="Utilities\DumpEnvironmentTest.cs" />
<Compile Include="ResultTest.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Utilities\DriveTest.cs" />
<Compile Include="Utilities\ConvertersTest.cs" />
<Compile Include="Utilities\KnownSystemExtensionsTest.cs" />
<Compile Include="Utilities\MediaTypeExtensionsTest.cs" />
<Compile Include="Utilities\ParametersTest.cs" />
<Compile Include="Utilities\ValidatorsTest.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Analyzer Include="..\packages\xunit.analyzers.0.10.0\analyzers\dotnet\cs\xunit.analyzers.dll" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DICUI.Library\DICUI.Library.csproj">
<Project>{51ab0928-13f9-44bf-a407-b6957a43a056}</Project>
@@ -88,22 +15,19 @@
<Name>DICUI</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\xunit.core.2.3.1\build\xunit.core.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\xunit.core.2.3.1\build\xunit.core.props'))" />
<Error Condition="!Exists('..\packages\xunit.core.2.3.1\build\xunit.core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\xunit.core.2.3.1\build\xunit.core.targets'))" />
<Error Condition="!Exists('..\packages\xunit.runner.console.2.3.1\build\xunit.runner.console.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\xunit.runner.console.2.3.1\build\xunit.runner.console.props'))" />
<Error Condition="!Exists('..\packages\xunit.runner.visualstudio.2.3.1\build\net20\xunit.runner.visualstudio.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\xunit.runner.visualstudio.2.3.1\build\net20\xunit.runner.visualstudio.props'))" />
<Error Condition="!Exists('..\packages\Microsoft.CodeCoverage.15.8.0\build\netstandard1.0\Microsoft.CodeCoverage.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.CodeCoverage.15.8.0\build\netstandard1.0\Microsoft.CodeCoverage.props'))" />
<Error Condition="!Exists('..\packages\Microsoft.CodeCoverage.15.8.0\build\netstandard1.0\Microsoft.CodeCoverage.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.CodeCoverage.15.8.0\build\netstandard1.0\Microsoft.CodeCoverage.targets'))" />
<Error Condition="!Exists('..\packages\Microsoft.NET.Test.Sdk.15.8.0\build\net45\Microsoft.Net.Test.Sdk.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.NET.Test.Sdk.15.8.0\build\net45\Microsoft.Net.Test.Sdk.props'))" />
<Error Condition="!Exists('..\packages\Microsoft.NET.Test.Sdk.15.8.0\build\net45\Microsoft.Net.Test.Sdk.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.NET.Test.Sdk.15.8.0\build\net45\Microsoft.Net.Test.Sdk.targets'))" />
</Target>
<Import Project="..\packages\xunit.core.2.3.1\build\xunit.core.targets" Condition="Exists('..\packages\xunit.core.2.3.1\build\xunit.core.targets')" />
<Import Project="..\packages\Microsoft.CodeCoverage.15.8.0\build\netstandard1.0\Microsoft.CodeCoverage.targets" Condition="Exists('..\packages\Microsoft.CodeCoverage.15.8.0\build\netstandard1.0\Microsoft.CodeCoverage.targets')" />
<Import Project="..\packages\Microsoft.NET.Test.Sdk.15.8.0\build\net45\Microsoft.Net.Test.Sdk.targets" Condition="Exists('..\packages\Microsoft.NET.Test.Sdk.15.8.0\build\net45\Microsoft.Net.Test.Sdk.targets')" />
</Project>
<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>

View File

@@ -1,20 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
[assembly: AssemblyTitle("DICUI.Test")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("DICUI.Test")]
[assembly: AssemblyCopyright("Copyright © 2018")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
[assembly: Guid("7cc064d2-38ab-4a05-8519-28660de4562a")]
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -1,15 +0,0 @@
using DICUI.Utilities;
using Xunit;
namespace DICUI.Test.Utilities
{
public class DriveTest
{
[Fact]
public void DriveConstructorsTest()
{
Assert.True(Drive.Floppy('a').IsFloppy);
Assert.False(Drive.Optical('d', "test", true).IsFloppy);
}
}
}

View File

@@ -1,4 +1,5 @@
using DICUI.Data;
using System.IO;
using DICUI.Data;
using DICUI.Utilities;
using Xunit;
@@ -18,7 +19,9 @@ namespace DICUI.Test
var env = new DumpEnvironment
{
DICParameters = new Parameters(parameters),
Drive = isFloppy ? Drive.Floppy(letter) : Drive.Optical(letter, "", true),
Drive = isFloppy
? new Drive(InternalDriveType.Floppy, new DriveInfo(letter.ToString()))
: new Drive(InternalDriveType.Optical, new DriveInfo(letter.ToString())),
Type = mediaType,
};
@@ -31,8 +34,8 @@ namespace DICUI.Test
[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.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)

View File

@@ -1,14 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.CodeCoverage" version="15.8.0" targetFramework="net461" />
<package id="Microsoft.NET.Test.Sdk" version="15.8.0" targetFramework="net461" />
<package id="xunit" version="2.3.1" targetFramework="net461" />
<package id="xunit.abstractions" version="2.0.1" targetFramework="net461" />
<package id="xunit.analyzers" version="0.10.0" targetFramework="net461" />
<package id="xunit.assert" version="2.3.1" targetFramework="net461" />
<package id="xunit.core" version="2.3.1" targetFramework="net461" />
<package id="xunit.extensibility.core" version="2.3.1" targetFramework="net461" />
<package id="xunit.extensibility.execution" version="2.3.1" targetFramework="net461" />
<package id="xunit.runner.console" version="2.3.1" targetFramework="net461" developmentDependency="true" />
<package id="xunit.runner.visualstudio" version="2.3.1" targetFramework="net461" developmentDependency="true" />
</packages>

View File

@@ -11,6 +11,13 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DICUI.Library", "DICUI.Libr
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
Debug|Any CPU = Debug|Any CPU

View File

@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="DICPath" value="Programs\DiscImageCreator.exe"/>
@@ -19,4 +19,4 @@
<add key="Username" value=""/>
<add key="Password" value=""/>
</appSettings>
</configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/></startup></configuration>

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,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,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?; }
}
}
}

View File

@@ -1,153 +1,28 @@
<?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')" />
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{7B1B75EB-8940-466F-BD51-76471A57F9BE}</ProjectGuid>
<TargetFrameworks>net462;net472;netcoreapp3.0</TargetFrameworks>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<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>
<UseWindowsForms>true</UseWindowsForms>
<UseWPF>true</UseWPF>
<Prefer32Bit>true</Prefer32Bit>
<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.Drawing" />
<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.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="Constants.cs" />
<Compile Include="EnumDescriptionConverter.cs" />
<Compile Include="MediaTypeComboBoxItem.cs" />
<Compile Include="Options.cs" />
<Compile Include="Windows\LogWindow.xaml.cs">
<DependentUpon>LogWindow.xaml</DependentUpon>
</Compile>
<Compile Include="Windows\OptionsWindow.xaml.cs">
<DependentUpon>OptionsWindow.xaml</DependentUpon>
</Compile>
<Compile Include="KnownSystemComboBoxItem.cs" />
<Compile Include="ViewModels.cs" />
<Page Include="Windows\LogWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Windows\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="Windows\MainWindow.xaml.cs">
<DependentUpon>MainWindow.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Page Include="Windows\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" />
<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>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@@ -21,6 +21,7 @@ namespace DICUI
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; }
@@ -70,6 +71,7 @@ namespace DICUI
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", "");

View File

@@ -51,8 +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.13")]
[assembly: AssemblyFileVersion("1.13.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")]

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

@@ -192,12 +192,12 @@ namespace DICUI.Windows
// this is used to optimize the work since we need to process A LOT of text
struct Matcher
{
private readonly String prefix;
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)
public Matcher(string prefix, string regex, Action<Match> lambda)
{
this.prefix = prefix;
this.regex = new Regex(regex);

View File

@@ -3,6 +3,7 @@ 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;
@@ -26,6 +27,9 @@ namespace DICUI.Windows
private Options _options;
private OptionsWindow _optionsWindow;
// User input related
private DiscInformationWindow _discInformationWindow;
private LogWindow _logWindow;
public MainWindow()
@@ -132,6 +136,7 @@ namespace DICUI.Windows
ViewModels.LoggerViewModel.VerboseLogLn("Changed system to: {0}", (SystemTypeComboBox.SelectedItem as KnownSystemComboBoxItem).Name);
PopulateMediaType();
GetOutputNames(false);
EnsureDiscInformation();
}
@@ -144,7 +149,7 @@ namespace DICUI.Windows
SetSupportedDriveSpeed();
}
GetOutputNames();
GetOutputNames(false);
EnsureDiscInformation();
}
@@ -152,7 +157,7 @@ namespace DICUI.Windows
{
CacheCurrentDiscType();
SetCurrentDiscType();
GetOutputNames();
GetOutputNames(true);
SetSupportedDriveSpeed();
}
@@ -245,7 +250,7 @@ namespace DICUI.Windows
public void OnOptionsUpdated()
{
GetOutputNames();
GetOutputNames(false);
SetSupportedDriveSpeed();
EnsureDiscInformation();
}
@@ -327,16 +332,27 @@ namespace DICUI.Windows
if (DriveLetterComboBox.Items.Count > 0)
{
int index = _drives.FindIndex(d => d.MarkedActive);
// 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 optical disc type
// 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].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)
@@ -349,7 +365,7 @@ namespace DICUI.Windows
// 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)));
ViewModels.LoggerViewModel.VerboseLogLn("Found {0} drives: {1}", _drives.Count, string.Join(", ", _drives.Select(d => d.Letter)));
}
else
{
@@ -402,6 +418,7 @@ namespace DICUI.Windows
ScanForProtection = _options.ScanForProtection,
RereadAmountC2 = _options.RereadAmountForC2,
AddPlaceholders = _options.AddPlaceholders,
PromptForDiscInformation = _options.PromptForDiscInformation,
Username = _options.Username,
Password = _options.Password,
@@ -490,6 +507,30 @@ namespace DICUI.Windows
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);
}
@@ -548,14 +589,24 @@ namespace DICUI.Windows
/// <summary>
/// Get the default output directory name from the currently selected drive
/// </summary>
private void GetOutputNames()
/// <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?;
OutputDirectoryTextBox.Text = Path.Combine(_options.DefaultOutputPath, drive?.VolumeLabel ?? string.Empty);
OutputFilenameTextBox.Text = (drive?.VolumeLabel ?? "disc") + (mediaType.Extension() ?? ".bin");
// 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>
@@ -639,14 +690,14 @@ namespace DICUI.Windows
{
// Get the drive letter from the selected item
Drive drive = DriveLetterComboBox.SelectedItem as Drive;
if (drive == null || drive.IsFloppy)
if (drive == null)
return;
// Get the current optical disc type
// 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.Letter);
_currentMediaType = Validators.GetMediaType(drive);
ViewModels.LoggerViewModel.VerboseLogLn(_currentMediaType == null ? "unable to detect." : ("detected " + _currentMediaType.LongName() + "."));
}
}
@@ -688,11 +739,11 @@ namespace DICUI.Windows
string trimmedPath = _env.DICParameters.Filename?.Trim('"') ?? string.Empty;
string outputDirectory = Path.GetDirectoryName(trimmedPath);
string outputFilename = Path.GetFileName(trimmedPath);
if (!String.IsNullOrWhiteSpace(outputDirectory))
if (!string.IsNullOrWhiteSpace(outputDirectory))
OutputDirectoryTextBox.Text = outputDirectory;
else
outputDirectory = OutputDirectoryTextBox.Text;
if (!String.IsNullOrWhiteSpace(outputFilename))
if (!string.IsNullOrWhiteSpace(outputFilename))
OutputFilenameTextBox.Text = outputFilename;
else
outputFilename = OutputFilenameTextBox.Text;

View File

@@ -84,20 +84,21 @@
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<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"
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"
ToolTip="Enable pedantic and super-safe flags" Margin="0,4"
/>
<Grid Grid.Column="2" Grid.ColumnSpan="2" Grid.Row="0">
<Grid.ColumnDefinitions>
@@ -116,19 +117,25 @@
<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"
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" Grid.ColumnSpan="2" VerticalAlignment="Center" Content="Skip Media Type Detection"
<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)"
ToolTip="Disable trying to guess media type inserted (may improve performance at startup)" Margin="0,4" Grid.RowSpan="2"
/>
<CheckBox Grid.Column="3" Grid.Row="1" VerticalAlignment="Center" Content="Add Placeholders"
<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"
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>
@@ -149,12 +156,12 @@
<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*"/>

View File

@@ -15,7 +15,7 @@ This project relies on two open-source code ports to help perform copy protectio
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)

View File

@@ -1,12 +1,12 @@
# version format
version: 1.12-{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:
@@ -32,11 +32,17 @@ build:
# post-build step
after_build:
- ps: appveyor DownloadFile https://github.com/saramibreak/DiscImageCreator/files/3341769/DiscImageCreator_20190627.zip
- ps: appveyor DownloadFile http://www.rawdump.net/tools/subdump_fua_0x28.zip
- 7z e DiscImageCreator_20190627.zip -oDICUI\bin\Debug\Programs Release_ANSI\*
- 7z e subdump_fua_0x28.zip -oDICUI\bin\Debug *
- mv DICUI\bin\Debug\subdump_fua_0x28.exe DICUI\bin\Debug\subdump.exe
- 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\*