Compare commits

..

35 Commits
1.6.8 ... 1.9.0

Author SHA1 Message Date
Matt Nadareski
67ee824e1b Bump version 2025-11-13 08:15:21 -05:00
Matt Nadareski
d256187a0a Add support for .NET 10 2025-11-13 08:09:47 -05:00
Matt Nadareski
6589fec1bc Update rolling tag 2025-10-26 20:28:50 -04:00
Matt Nadareski
c6832a5c2d Bump version 2025-10-22 08:58:57 -04:00
Matt Nadareski
77d922a9bc Minor collection cleanup in tests 2025-10-22 08:50:18 -04:00
Matt Nadareski
7b590e9bba Separate out sections to new files for maintainability 2025-10-22 08:41:57 -04:00
Matt Nadareski
0968bfe786 Ensure adding IDs only after 2025-10-21 18:41:53 -04:00
Matt Nadareski
5acb6ee128 Minor fixes 2025-10-21 18:36:15 -04:00
Matt Nadareski
5dc9ef27ef Update gitignore 2025-10-21 18:32:30 -04:00
Matt Nadareski
d5ccc0c65c Simplify downloader creation 2025-10-21 18:29:04 -04:00
Matt Nadareski
0ef9c6f87a Add console writes on failure cases 2025-10-21 18:11:20 -04:00
Matt Nadareski
638630ccab Disallow some fields from being null 2025-10-21 17:44:15 -04:00
Matt Nadareski
6c3afd25d4 Formatting pass 2025-10-21 17:33:12 -04:00
Matt Nadareski
02572c75fc Make timeout configurable by implementer 2025-10-21 17:30:31 -04:00
Matt Nadareski
cb5b42166d Reduce tab-to-space size to 2 2025-10-16 08:02:09 -04:00
Matt Nadareski
97ea30228e Bump version 2025-10-12 09:00:39 -04:00
Deterous
675af1a619 Add XboxOne/SX TitleID (#12) 2025-10-12 08:56:09 -04:00
Matt Nadareski
28c3f54cc5 Update test packages 2025-10-07 16:21:47 -04:00
Matt Nadareski
51486950fa Bump version 2025-09-24 13:35:03 -04:00
Matt Nadareski
1b1ba94247 Remove reliance on Models library 2025-09-24 13:33:42 -04:00
Matt Nadareski
c4345d0c34 Bump version 2025-09-22 18:00:58 -04:00
Matt Nadareski
b88b877672 Update Nuget packages 2025-09-22 17:58:12 -04:00
Matt Nadareski
f0c5375ac5 There 2025-09-10 21:53:06 -04:00
Matt Nadareski
1f4cca7fa0 Bump version 2025-09-05 10:14:28 -04:00
Matt Nadareski
5161913d96 Update Nuget packages 2025-09-05 09:45:00 -04:00
Deterous
c10b21a485 Add Polymega system (#11)
* Add Polymega system

* Polymega detected by windows
2025-08-31 01:22:51 -04:00
Matt Nadareski
99adad582c Forgot this test update 2025-08-23 09:52:31 -04:00
Matt Nadareski
6956617386 Bump version 2025-08-23 09:48:43 -04:00
Matt Nadareski
b5522c5bb0 Add High Siera volume descriptor pseudo-tag 2025-08-23 09:48:07 -04:00
Matt Nadareski
889cedb87a Bump version 2025-07-24 09:01:21 -04:00
Matt Nadareski
eba722b23a Be consistent about end-of-file newlines 2025-07-24 08:59:57 -04:00
Matt Nadareski
5d77af7e97 Add .NET Standard 2.0 and 2.1 2025-07-24 08:55:29 -04:00
Matt Nadareski
d9cb9394e0 Update nuget packages 2025-07-24 08:48:37 -04:00
Matt Nadareski
dfb5ac762a Bump version 2025-07-21 12:08:21 -04:00
Matt Nadareski
2459165990 Add Interplay ID pseudo-tag 2025-07-20 20:40:59 -04:00
55 changed files with 1294 additions and 1032 deletions

View File

@@ -9,17 +9,17 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
with:
submodules: recursive
fetch-depth: 0
- name: Setup .NET
uses: actions/setup-dotnet@v4
uses: actions/setup-dotnet@v5
with:
dotnet-version: |
6.0.x
8.0.x
9.0.x
10.0.x
- name: Run tests
run: dotnet test
@@ -27,8 +27,16 @@ jobs:
- name: Run publish script
run: ./publish-nix.sh -d
- name: Update rolling tag
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git tag -f rolling
git push origin :refs/tags/rolling || true
git push origin rolling --force
- name: Upload to rolling
uses: ncipollo/release-action@v1.14.0
uses: ncipollo/release-action@v1.20.0
with:
allowUpdates: True
artifacts: "*.nupkg,*.snupkg"

View File

@@ -6,15 +6,15 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- name: Setup .NET
uses: actions/setup-dotnet@v4
uses: actions/setup-dotnet@v5
with:
dotnet-version: |
6.0.x
8.0.x
9.0.x
10.0.x
- name: Build
run: dotnet build

296
.gitignore vendored
View File

@@ -1,15 +1,7 @@
*.swp
*.*~
project.lock.json
.DS_Store
*.pyc
nupkg/
# Visual Studio Code
.vscode
# Rider
.idea
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.suo
@@ -17,6 +9,9 @@ nupkg/
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
@@ -24,15 +19,280 @@ nupkg/
[Rr]eleases/
x64/
x86/
build/
bld/
[Bb]in/
[Oo]bj/
[Oo]ut/
msbuild.log
msbuild.err
msbuild.wrn
[Ll]og/
# Visual Studio 2015
# Visual Studio 2015 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
**/Properties/launchSettings.json
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Typescript v1 declaration files
typings/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# JetBrains Rider
.idea/
*.sln.iml
# CodeRush
.cr/
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs

22
.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,22 @@
{
// Use IntelliSense to find out which attributes exist for C# debugging
// Use hover for the description of the existing attributes
// For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
"version": "0.2.0",
"configurations": [
{
"name": ".NET Core Launch",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/RedumpTool/bin/Debug/net10.0/RedumpTool.dll",
"args": [],
"cwd": "${workspaceFolder}/RedumpTool",
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
"console": "internalConsole",
"stopAtEntry": false,
"justMyCode": false
}
]
}

24
.vscode/tasks.json vendored Normal file
View File

@@ -0,0 +1,24 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "build",
"command": "dotnet",
"type": "shell",
"args": [
"build",
// Ask dotnet build to generate full paths for file names.
"/property:GenerateFullPaths=true",
// Do not generate summary otherwise it leads to duplicate errors in Problems panel
"/consoleloggerparameters:NoSummary"
],
"group": "build",
"presentation": {
"reveal": "silent"
},
"problemMatcher": "$msCompile"
}
]
}

7
LICENSE Normal file
View File

@@ -0,0 +1,7 @@
Copyright (c) 2018-2025 Matt Nadareski
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -12,6 +12,7 @@ namespace RedumpTool
// Show help if nothing is input
if (args == null || args.Length == 0)
{
Console.WriteLine("At least one argument is required");
ShowHelp();
return;
}
@@ -20,6 +21,7 @@ namespace RedumpTool
Feature feature = DeriveFeature(args[0]);
if (feature == Feature.NONE)
{
Console.WriteLine("The feature could not be derived");
ShowHelp();
return;
}
@@ -28,6 +30,7 @@ namespace RedumpTool
var downloader = CreateDownloader(feature, args);
if (downloader == null)
{
Console.WriteLine("A downloader could not be created from the inputs");
ShowHelp();
return;
}
@@ -45,6 +48,7 @@ namespace RedumpTool
}
else if (downloaderResult.Count == 0 && downloader.Feature != Feature.Packs)
{
Console.WriteLine("No results were found");
ShowHelp();
}
}
@@ -76,20 +80,8 @@ namespace RedumpTool
/// <returns>Initialized Downloader on success, null otherwise</returns>
private static Downloader? CreateDownloader(Feature feature, string[] args)
{
// Set temporary internal variables
string? outDir = null;
string? username = null;
string? password = null;
int minimumId = -1;
int maximumId = -1;
string? queryString = null;
bool useSubfolders = false;
bool onlyNew = false;
bool onlyList = false;
bool noSlash = false;
bool force = false;
// Now loop through all of the arguments
// Loop through all of the arguments
var downloader = new Downloader() { Feature = feature };
try
{
for (int i = 1; i < args.Length; i++)
@@ -99,69 +91,73 @@ namespace RedumpTool
// Output directory
case "-o":
case "--output":
outDir = args[++i].Trim('"');
downloader.OutDir = args[++i].Trim('"');
break;
// Username
case "-u":
case "--username":
username = args[++i];
downloader.Username = args[++i];
break;
// Password
case "-p":
case "--password":
password = args[++i];
downloader.Password = args[++i];
break;
// Minimum Redump ID
case "-min":
case "--minimum":
if (!int.TryParse(args[++i], out minimumId))
if (!int.TryParse(args[++i], out int minimumId))
minimumId = -1;
downloader.MinimumId = minimumId;
break;
// Maximum Redump ID
case "-max":
case "--maximum":
if (!int.TryParse(args[++i], out maximumId))
if (!int.TryParse(args[++i], out int maximumId))
maximumId = -1;
downloader.MaximumId = maximumId;
break;
// Quicksearch text
case "-q":
case "--query":
queryString = args[++i];
downloader.QueryString = args[++i];
break;
// Packs subfolders
case "-s":
case "--subfolders":
useSubfolders = true;
downloader.UseSubfolders = true;
break;
// Use last modified
case "-n":
case "--onlynew":
onlyNew = true;
downloader.OnlyNew = true;
break;
// List instead of download
case "-l":
case "--list":
onlyList = true;
downloader.OnlyList = true;
break;
// Don't filter forward slashes from queries
case "-ns":
case "--noslash":
noSlash = true;
downloader.NoSlash = true;
break;
// Force continuation
case "-f":
case "--force":
force = true;
downloader.Force = true;
break;
// Everything else
@@ -178,18 +174,18 @@ namespace RedumpTool
}
// Output directory validation
if (!onlyList && string.IsNullOrEmpty(outDir))
if (!downloader.OnlyList && string.IsNullOrEmpty(downloader.OutDir))
{
Console.WriteLine("No output directory set!");
return null;
}
else if (!onlyList && !string.IsNullOrEmpty(outDir))
else if (!downloader.OnlyList && !string.IsNullOrEmpty(downloader.OutDir))
{
// Create the output directory, if it doesn't exist
try
{
if (!Directory.Exists(outDir))
Directory.CreateDirectory(outDir);
if (!Directory.Exists(downloader.OutDir))
Directory.CreateDirectory(downloader.OutDir!);
}
catch (Exception ex)
{
@@ -199,40 +195,25 @@ namespace RedumpTool
}
// Range verification
if (feature == Feature.Site && !onlyNew && (minimumId < 0 || maximumId < 0))
if (feature == Feature.Site && !downloader.OnlyNew && (downloader.MinimumId < 0 || downloader.MaximumId < 0))
{
Console.WriteLine("Please enter a valid range of Redump IDs");
return null;
}
else if (feature == Feature.WIP && !onlyNew && (minimumId < 0 || maximumId < 0))
else if (feature == Feature.WIP && !downloader.OnlyNew && (downloader.MinimumId < 0 || downloader.MaximumId < 0))
{
Console.WriteLine("Please enter a valid range of WIP IDs");
return null;
}
// Query verification (and cleanup)
if (feature == Feature.Quicksearch && string.IsNullOrEmpty(queryString))
if (feature == Feature.Quicksearch && string.IsNullOrEmpty(downloader.QueryString))
{
Console.WriteLine("Please enter a query for searching");
return null;
}
// Create and return the downloader
var downloader = new Downloader()
{
Feature = feature,
MinimumId = minimumId,
MaximumId = maximumId,
QueryString = queryString,
OutDir = outDir,
UseSubfolders = useSubfolders,
OnlyNew = onlyNew,
OnlyList = onlyList,
Force = force,
NoSlash = noSlash,
Username = username,
Password = password,
};
// Return the downloader
return downloader;
}

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net20;net35;net40;net452;net462;net472;net48;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0;net9.0</TargetFrameworks>
<TargetFrameworks>net20;net35;net40;net452;net462;net472;net48;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0;net9.0;net10.0</TargetFrameworks>
<OutputType>Exe</OutputType>
<CheckEolTargetFramework>false</CheckEolTargetFramework>
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
@@ -9,7 +9,7 @@
<Nullable>enable</Nullable>
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<Version>1.6.8</Version>
<Version>1.9.0</Version>
</PropertyGroup>
<!-- Support All Frameworks -->
@@ -23,11 +23,11 @@
<RuntimeIdentifiers>win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64;osx-arm64</RuntimeIdentifiers>
</PropertyGroup>
<PropertyGroup Condition="$(RuntimeIdentifier.StartsWith(`osx-arm`))">
<TargetFrameworks>net6.0;net7.0;net8.0;net9.0</TargetFrameworks>
<TargetFrameworks>net6.0;net7.0;net8.0;net9.0;net10.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\SabreTools.RedumpLib\SabreTools.RedumpLib.csproj" />
</ItemGroup>
</Project>
</Project>

View File

@@ -26,102 +26,6 @@ namespace SabreTools.RedumpLib.Test
Assert.Equal(expectNull, si == null);
}
[Fact]
public void EnsureAllSections_Null_Filled()
{
SubmissionInfo? si = null;
var actual = Builder.EnsureAllSections(si);
Assert.NotNull(actual);
Assert.NotNull(actual.CommonDiscInfo);
Assert.NotNull(actual.CommonDiscInfo.CommentsSpecialFields);
Assert.NotNull(actual.CommonDiscInfo.ContentsSpecialFields);
Assert.NotNull(actual.VersionAndEditions);
Assert.NotNull(actual.EDC);
Assert.NotNull(actual.ParentCloneRelationship);
Assert.NotNull(actual.Extras);
Assert.NotNull(actual.CopyProtection);
Assert.NotNull(actual.DumpersAndStatus);
Assert.NotNull(actual.TracksAndWriteOffsets);
Assert.NotNull(actual.SizeAndChecksums);
Assert.NotNull(actual.DumpingInfo);
Assert.NotNull(actual.Artifacts);
}
[Fact]
public void EnsureAllSections_Empty_Filled()
{
SubmissionInfo? si = new SubmissionInfo
{
CommonDiscInfo = null,
VersionAndEditions = null,
EDC = null,
ParentCloneRelationship = null,
Extras = null,
CopyProtection = null,
DumpersAndStatus = null,
TracksAndWriteOffsets = null,
SizeAndChecksums = null,
DumpingInfo = null,
Artifacts = null,
};
var actual = Builder.EnsureAllSections(si);
Assert.NotNull(actual);
Assert.NotNull(actual.CommonDiscInfo);
Assert.NotNull(actual.CommonDiscInfo.CommentsSpecialFields);
Assert.NotNull(actual.CommonDiscInfo.ContentsSpecialFields);
Assert.NotNull(actual.VersionAndEditions);
Assert.NotNull(actual.EDC);
Assert.NotNull(actual.ParentCloneRelationship);
Assert.NotNull(actual.Extras);
Assert.NotNull(actual.CopyProtection);
Assert.NotNull(actual.DumpersAndStatus);
Assert.NotNull(actual.TracksAndWriteOffsets);
Assert.NotNull(actual.SizeAndChecksums);
Assert.NotNull(actual.DumpingInfo);
Assert.NotNull(actual.Artifacts);
}
[Fact]
public void EnsureAllSections_Filled_Filled()
{
SubmissionInfo? si = new SubmissionInfo
{
CommonDiscInfo = new CommonDiscInfoSection
{
CommentsSpecialFields = [],
ContentsSpecialFields = [],
},
VersionAndEditions = new VersionAndEditionsSection(),
EDC = new EDCSection(),
ParentCloneRelationship = new ParentCloneRelationshipSection(),
Extras = new ExtrasSection(),
CopyProtection = new CopyProtectionSection(),
DumpersAndStatus = new DumpersAndStatusSection(),
TracksAndWriteOffsets = new TracksAndWriteOffsetsSection(),
SizeAndChecksums = new SizeAndChecksumsSection(),
DumpingInfo = new DumpingInfoSection(),
Artifacts = [],
};
var actual = Builder.EnsureAllSections(si);
Assert.NotNull(actual);
Assert.NotNull(actual.CommonDiscInfo);
Assert.NotNull(actual.CommonDiscInfo.CommentsSpecialFields);
Assert.NotNull(actual.CommonDiscInfo.ContentsSpecialFields);
Assert.NotNull(actual.VersionAndEditions);
Assert.NotNull(actual.EDC);
Assert.NotNull(actual.ParentCloneRelationship);
Assert.NotNull(actual.Extras);
Assert.NotNull(actual.CopyProtection);
Assert.NotNull(actual.DumpersAndStatus);
Assert.NotNull(actual.TracksAndWriteOffsets);
Assert.NotNull(actual.SizeAndChecksums);
Assert.NotNull(actual.DumpingInfo);
Assert.NotNull(actual.Artifacts);
}
[Fact]
public void InjectSubmissionInformation_BothNull_Null()
{
@@ -135,7 +39,7 @@ namespace SabreTools.RedumpLib.Test
[Fact]
public void InjectSubmissionInformation_ValidInputNullSeed_Valid()
{
SubmissionInfo? si = new SubmissionInfo();
SubmissionInfo? si = new();
SubmissionInfo? seed = null;
var actual = Builder.InjectSubmissionInformation(si, seed);
@@ -145,8 +49,8 @@ namespace SabreTools.RedumpLib.Test
[Fact]
public void InjectSubmissionInformation_BothValid_Valid()
{
SubmissionInfo? si = new SubmissionInfo();
SubmissionInfo? seed = new SubmissionInfo();
SubmissionInfo? si = new();
SubmissionInfo? seed = new();
var actual = Builder.InjectSubmissionInformation(si, seed);
Assert.NotNull(actual);
@@ -188,4 +92,4 @@ namespace SabreTools.RedumpLib.Test
Assert.Equal(expected, actual);
}
}
}
}

View File

@@ -97,7 +97,7 @@ namespace SabreTools.RedumpLib.Test.Data
public static List<object?[]> GenerateDiscTypeMappingTestData()
{
var testData = new List<object?[]>() { new object?[] { null, true } };
foreach (DiscType? discType in Enum.GetValues(typeof(DiscType)))
foreach (DiscType? discType in Enum.GetValues<DiscType>().Cast<DiscType?>())
{
if (_mappableDiscTypes.Contains(discType))
testData.Add([discType, false]);
@@ -115,7 +115,7 @@ namespace SabreTools.RedumpLib.Test.Data
public static List<object?[]> GenerateRedumpSystemMappingTestData()
{
var testData = new List<object?[]>() { new object?[] { null } };
foreach (RedumpSystem? redumpSystem in Enum.GetValues(typeof(RedumpSystem)))
foreach (RedumpSystem? redumpSystem in Enum.GetValues<RedumpSystem>().Cast<RedumpSystem?>())
{
testData.Add([redumpSystem]);
}
@@ -131,7 +131,7 @@ namespace SabreTools.RedumpLib.Test.Data
{
var testData = new List<object?[]>() { new object?[] { null, true } };
foreach (MediaType? mediaType in Enum.GetValues(typeof(MediaType)))
foreach (MediaType? mediaType in Enum.GetValues<MediaType>().Cast<MediaType?>())
{
if (_mappableMediaTypes.Contains(mediaType))
testData.Add([mediaType, false]);
@@ -197,7 +197,7 @@ namespace SabreTools.RedumpLib.Test.Data
public static List<object?[]> GenerateDiscCategoryTestData()
{
var testData = new List<object?[]>() { new object?[] { null, true } };
foreach (DiscCategory? discCategory in Enum.GetValues(typeof(DiscCategory)))
foreach (DiscCategory? discCategory in Enum.GetValues<DiscCategory>().Cast<DiscCategory?>())
{
testData.Add([discCategory, false]);
}
@@ -262,7 +262,7 @@ namespace SabreTools.RedumpLib.Test.Data
public static List<object?[]> GenerateDiscTypeTestData()
{
var testData = new List<object?[]>() { new object?[] { null, true } };
foreach (DiscType? discType in Enum.GetValues(typeof(DiscType)))
foreach (DiscType? discType in Enum.GetValues<DiscType>().Cast<DiscType?>())
{
if (discType == DiscType.NONE)
testData.Add([discType, true]);
@@ -352,7 +352,7 @@ namespace SabreTools.RedumpLib.Test.Data
[Fact]
public void Language_ThreeLetterCode_NoDuplicates()
{
var fullLanguages = Enum.GetValues(typeof(Language)).Cast<Language?>().ToList();
var fullLanguages = Enum.GetValues<Language>().Cast<Language?>().ToList();
var filteredLanguages = new Dictionary<string, Language?>();
int totalCount = 0;
@@ -379,7 +379,7 @@ namespace SabreTools.RedumpLib.Test.Data
[Fact]
public void Language_ThreeLetterCodeAlt_NoDuplicates()
{
var fullLanguages = Enum.GetValues(typeof(Language)).Cast<Language?>().ToList();
var fullLanguages = Enum.GetValues<Language>().Cast<Language?>().ToList();
var filteredLanguages = new Dictionary<string, Language?>();
int totalCount = 0;
@@ -406,7 +406,7 @@ namespace SabreTools.RedumpLib.Test.Data
[Fact]
public void Language_TwoLetterCode_NoDuplicates()
{
var fullLanguages = Enum.GetValues(typeof(Language)).Cast<Language?>().ToList();
var fullLanguages = Enum.GetValues<Language>().Cast<Language?>().ToList();
var filteredLanguages = new Dictionary<string, Language?>();
int totalCount = 0;
@@ -434,7 +434,7 @@ namespace SabreTools.RedumpLib.Test.Data
public static List<object?[]> GenerateLanguageTestData()
{
var testData = new List<object?[]>() { new object?[] { null, true } };
foreach (Language? language in Enum.GetValues(typeof(Language)))
foreach (Language? language in Enum.GetValues<Language>().Cast<Language?>())
{
testData.Add([language, false]);
}
@@ -497,7 +497,7 @@ namespace SabreTools.RedumpLib.Test.Data
public static List<object?[]> GenerateLanguageSelectionTestData()
{
var testData = new List<object?[]>() { new object?[] { null, true } };
foreach (LanguageSelection? languageSelection in Enum.GetValues(typeof(LanguageSelection)))
foreach (LanguageSelection? languageSelection in Enum.GetValues<LanguageSelection>().Cast<LanguageSelection?>())
{
testData.Add([languageSelection, false]);
}
@@ -557,7 +557,7 @@ namespace SabreTools.RedumpLib.Test.Data
public static List<object?[]> GenerateMediaTypeTestData()
{
var testData = new List<object?[]>() { new object?[] { null, true } };
foreach (MediaType? mediaType in Enum.GetValues(typeof(MediaType)))
foreach (MediaType? mediaType in Enum.GetValues<MediaType>().Cast<MediaType?>())
{
testData.Add([mediaType, false]);
}
@@ -609,7 +609,7 @@ namespace SabreTools.RedumpLib.Test.Data
[Fact]
public void Region_ShortName_NoDuplicates()
{
var fullRegions = Enum.GetValues(typeof(Region)).Cast<Region?>().ToList();
var fullRegions = Enum.GetValues<Region>().Cast<Region?>().ToList();
var filteredRegions = new Dictionary<string, Region?>();
int totalCount = 0;
@@ -664,7 +664,7 @@ namespace SabreTools.RedumpLib.Test.Data
public static List<object?[]> GenerateRegionTestData()
{
var testData = new List<object?[]>() { new object?[] { null, true } };
foreach (Region? region in Enum.GetValues(typeof(Region)))
foreach (Region? region in Enum.GetValues<Region>().Cast<Region?>())
{
testData.Add([region, false]);
}
@@ -703,6 +703,7 @@ namespace SabreTools.RedumpLib.Test.Data
SiteCode.EditionNonLatin,
SiteCode.Filename,
SiteCode.Genre,
SiteCode.HighSierraVolumeDescriptor,
SiteCode.InternalName,
SiteCode.InternalSerialName,
SiteCode.ISBN,
@@ -719,6 +720,7 @@ namespace SabreTools.RedumpLib.Test.Data
SiteCode.Series,
SiteCode.SSHash,
SiteCode.SSVersion,
SiteCode.TitleID,
SiteCode.UniversalHash,
SiteCode.VCD,
SiteCode.VFCCode,
@@ -736,6 +738,7 @@ namespace SabreTools.RedumpLib.Test.Data
SiteCode.ElectronicArtsID,
SiteCode.FoxInteractiveID,
SiteCode.GTInteractiveID,
SiteCode.InterplayID,
SiteCode.JASRACID,
SiteCode.KingRecordsID,
SiteCode.KoeiID,
@@ -782,6 +785,7 @@ namespace SabreTools.RedumpLib.Test.Data
SiteCode.Filename,
SiteCode.Games,
SiteCode.GameFootage,
SiteCode.HighSierraVolumeDescriptor,
SiteCode.Multisession,
SiteCode.NetYarozeGames,
SiteCode.Patches,
@@ -892,7 +896,7 @@ namespace SabreTools.RedumpLib.Test.Data
public static List<object?[]> GenerateSiteCodeTestData()
{
var testData = new List<object?[]>() { new object?[] { null, true } };
foreach (SiteCode? siteCode in Enum.GetValues(typeof(SiteCode)))
foreach (SiteCode? siteCode in Enum.GetValues<SiteCode>().Cast<SiteCode?>())
{
testData.Add([siteCode, false]);
}
@@ -907,7 +911,7 @@ namespace SabreTools.RedumpLib.Test.Data
public static List<object?[]> GenerateBooleanSiteCodesTestData()
{
var testData = new List<object?[]>() { new object?[] { null, false } };
foreach (SiteCode siteCode in Enum.GetValues(typeof(SiteCode)))
foreach (SiteCode siteCode in Enum.GetValues<SiteCode>())
{
if (_booleanSiteCodes.Contains(siteCode))
testData.Add([siteCode, true]);
@@ -925,7 +929,7 @@ namespace SabreTools.RedumpLib.Test.Data
public static List<object?[]> GenerateCommentSiteCodesTestData()
{
var testData = new List<object?[]>() { new object?[] { null, false } };
foreach (SiteCode siteCode in Enum.GetValues(typeof(SiteCode)))
foreach (SiteCode siteCode in Enum.GetValues<SiteCode>())
{
if (_commentSiteCodes.Contains(siteCode))
testData.Add([siteCode, true]);
@@ -943,7 +947,7 @@ namespace SabreTools.RedumpLib.Test.Data
public static List<object?[]> GenerateContentSiteCodesTestData()
{
var testData = new List<object?[]>() { new object?[] { null, false } };
foreach (SiteCode siteCode in Enum.GetValues(typeof(SiteCode)))
foreach (SiteCode siteCode in Enum.GetValues<SiteCode>())
{
if (_contentSiteCodes.Contains(siteCode))
testData.Add([siteCode, true]);
@@ -961,7 +965,7 @@ namespace SabreTools.RedumpLib.Test.Data
public static List<object?[]> GenerateMultilineSiteCodesTestData()
{
var testData = new List<object?[]>() { new object?[] { null, false } };
foreach (SiteCode siteCode in Enum.GetValues(typeof(SiteCode)))
foreach (SiteCode siteCode in Enum.GetValues<SiteCode>())
{
if (_multilineSiteCodes.Contains(siteCode))
testData.Add([siteCode, true]);
@@ -1184,6 +1188,7 @@ namespace SabreTools.RedumpLib.Test.Data
[RedumpSystem.NintendoWiiU] = SystemCategory.DiscBasedConsole,
[RedumpSystem.Panasonic3DOInteractiveMultiplayer] = SystemCategory.DiscBasedConsole,
[RedumpSystem.PhilipsCDi] = SystemCategory.DiscBasedConsole,
[RedumpSystem.PlaymajiPolymega] = SystemCategory.DiscBasedConsole,
[RedumpSystem.PioneerLaserActive] = SystemCategory.DiscBasedConsole,
[RedumpSystem.SegaDreamcast] = SystemCategory.DiscBasedConsole,
[RedumpSystem.SegaMegaCDSegaCD] = SystemCategory.DiscBasedConsole,
@@ -1534,6 +1539,7 @@ namespace SabreTools.RedumpLib.Test.Data
RedumpSystem.NECPCEngineCDTurboGrafxCD,
RedumpSystem.NECPCFXPCFXGA,
RedumpSystem.NintendoSonySuperNESCDROMSystem,
RedumpSystem.PlaymajiPolymega,
RedumpSystem.SegaDreamcast,
RedumpSystem.SegaMegaCDSegaCD,
RedumpSystem.SegaSaturn,
@@ -1912,7 +1918,7 @@ namespace SabreTools.RedumpLib.Test.Data
public static List<object?[]> GenerateRedumpSystemTestData()
{
var testData = new List<object?[]>() { new object?[] { null, true } };
foreach (RedumpSystem? redumpSystem in Enum.GetValues(typeof(RedumpSystem)))
foreach (RedumpSystem? redumpSystem in Enum.GetValues<RedumpSystem>().Cast<RedumpSystem?>())
{
// We want to skip all markers for this
if (redumpSystem.IsMarker())
@@ -1931,7 +1937,7 @@ namespace SabreTools.RedumpLib.Test.Data
public static List<object?[]> GenerateAudioSystemsTestData()
{
var testData = new List<object?[]>() { new object?[] { null, false } };
foreach (RedumpSystem redumpSystem in Enum.GetValues(typeof(RedumpSystem)))
foreach (RedumpSystem redumpSystem in Enum.GetValues<RedumpSystem>())
{
if (_audioSystems.Contains(redumpSystem))
testData.Add([redumpSystem, true]);
@@ -1949,7 +1955,7 @@ namespace SabreTools.RedumpLib.Test.Data
public static List<object?[]> GenerateAvailableSystemsTestData()
{
var testData = new List<object?[]>() { new object?[] { null, false } };
foreach (RedumpSystem redumpSystem in Enum.GetValues(typeof(RedumpSystem)))
foreach (RedumpSystem redumpSystem in Enum.GetValues<RedumpSystem>())
{
if (_availableSystems.Contains(redumpSystem))
testData.Add([redumpSystem, true]);
@@ -1967,7 +1973,7 @@ namespace SabreTools.RedumpLib.Test.Data
public static List<object?[]> GenerateBannedSystemsTestData()
{
var testData = new List<object?[]>() { new object?[] { null, false } };
foreach (RedumpSystem redumpSystem in Enum.GetValues(typeof(RedumpSystem)))
foreach (RedumpSystem redumpSystem in Enum.GetValues<RedumpSystem>())
{
if (_bannedSystems.Contains(redumpSystem))
testData.Add([redumpSystem, true]);
@@ -1985,7 +1991,7 @@ namespace SabreTools.RedumpLib.Test.Data
public static List<object?[]> GenerateCategoriesSystemTestData()
{
var testData = new List<object?[]>() { new object?[] { null, SystemCategory.NONE } };
foreach (RedumpSystem redumpSystem in Enum.GetValues(typeof(RedumpSystem)))
foreach (RedumpSystem redumpSystem in Enum.GetValues<RedumpSystem>())
{
testData.Add([redumpSystem, _systemCategoryMap[redumpSystem]]);
}
@@ -2000,7 +2006,7 @@ namespace SabreTools.RedumpLib.Test.Data
public static List<object?[]> GenerateCuesheetSystemsTestData()
{
var testData = new List<object?[]>() { new object?[] { null, false } };
foreach (RedumpSystem redumpSystem in Enum.GetValues(typeof(RedumpSystem)))
foreach (RedumpSystem redumpSystem in Enum.GetValues<RedumpSystem>())
{
if (_systemsWithCues.Contains(redumpSystem))
testData.Add([redumpSystem, true]);
@@ -2018,7 +2024,7 @@ namespace SabreTools.RedumpLib.Test.Data
public static List<object?[]> GenerateDatSystemsTestData()
{
var testData = new List<object?[]>() { new object?[] { null, false } };
foreach (RedumpSystem redumpSystem in Enum.GetValues(typeof(RedumpSystem)))
foreach (RedumpSystem redumpSystem in Enum.GetValues<RedumpSystem>())
{
if (_systemsWithDats.Contains(redumpSystem))
testData.Add([redumpSystem, true]);
@@ -2036,7 +2042,7 @@ namespace SabreTools.RedumpLib.Test.Data
public static List<object?[]> GenerateDKeySystemsTestData()
{
var testData = new List<object?[]>() { new object?[] { null, false } };
foreach (RedumpSystem redumpSystem in Enum.GetValues(typeof(RedumpSystem)))
foreach (RedumpSystem redumpSystem in Enum.GetValues<RedumpSystem>())
{
if (_systemsWithDKeys.Contains(redumpSystem))
testData.Add([redumpSystem, true]);
@@ -2054,7 +2060,7 @@ namespace SabreTools.RedumpLib.Test.Data
public static List<object?[]> GenerateGdiSystemsTestData()
{
var testData = new List<object?[]>() { new object?[] { null, false } };
foreach (RedumpSystem redumpSystem in Enum.GetValues(typeof(RedumpSystem)))
foreach (RedumpSystem redumpSystem in Enum.GetValues<RedumpSystem>())
{
if (_systemsWithGdis.Contains(redumpSystem))
testData.Add([redumpSystem, true]);
@@ -2072,7 +2078,7 @@ namespace SabreTools.RedumpLib.Test.Data
public static List<object?[]> GenerateKeySystemsTestData()
{
var testData = new List<object?[]>() { new object?[] { null, false } };
foreach (RedumpSystem redumpSystem in Enum.GetValues(typeof(RedumpSystem)))
foreach (RedumpSystem redumpSystem in Enum.GetValues<RedumpSystem>())
{
if (_systemsWithKeys.Contains(redumpSystem))
testData.Add([redumpSystem, true]);
@@ -2090,7 +2096,7 @@ namespace SabreTools.RedumpLib.Test.Data
public static List<object?[]> GenerateLsdSystemsTestData()
{
var testData = new List<object?[]>() { new object?[] { null, false } };
foreach (RedumpSystem redumpSystem in Enum.GetValues(typeof(RedumpSystem)))
foreach (RedumpSystem redumpSystem in Enum.GetValues<RedumpSystem>())
{
if (_systemsWithLsds.Contains(redumpSystem))
testData.Add([redumpSystem, true]);
@@ -2108,7 +2114,7 @@ namespace SabreTools.RedumpLib.Test.Data
public static List<object?[]> GenerateMarkerSystemsTestData()
{
var testData = new List<object?[]>() { new object?[] { null, false } };
foreach (RedumpSystem redumpSystem in Enum.GetValues(typeof(RedumpSystem)))
foreach (RedumpSystem redumpSystem in Enum.GetValues<RedumpSystem>())
{
if (_markerSystems.Contains(redumpSystem))
testData.Add([redumpSystem, true]);
@@ -2126,7 +2132,7 @@ namespace SabreTools.RedumpLib.Test.Data
public static List<object?[]> GenerateReversedRingcodeSystemsTestData()
{
var testData = new List<object?[]>() { new object?[] { null, false } };
foreach (RedumpSystem redumpSystem in Enum.GetValues(typeof(RedumpSystem)))
foreach (RedumpSystem redumpSystem in Enum.GetValues<RedumpSystem>())
{
if (_reverseRingcodeSystems.Contains(redumpSystem))
testData.Add([redumpSystem, true]);
@@ -2144,7 +2150,7 @@ namespace SabreTools.RedumpLib.Test.Data
public static List<object?[]> GenerateSbiSystemsTestData()
{
var testData = new List<object?[]>() { new object?[] { null, false } };
foreach (RedumpSystem redumpSystem in Enum.GetValues(typeof(RedumpSystem)))
foreach (RedumpSystem redumpSystem in Enum.GetValues<RedumpSystem>())
{
if (_systemsWithSbis.Contains(redumpSystem))
testData.Add([redumpSystem, true]);
@@ -2162,7 +2168,7 @@ namespace SabreTools.RedumpLib.Test.Data
public static List<object?[]> GenerateWindowsDetectedSystemsTestData()
{
var testData = new List<object?[]>() { new object?[] { null, false } };
foreach (RedumpSystem redumpSystem in Enum.GetValues(typeof(RedumpSystem)))
foreach (RedumpSystem redumpSystem in Enum.GetValues<RedumpSystem>())
{
if (_windowsDetectedSystems.Contains(redumpSystem))
testData.Add([redumpSystem, true]);
@@ -2180,7 +2186,7 @@ namespace SabreTools.RedumpLib.Test.Data
public static List<object?[]> GenerateXGDSystemsTestData()
{
var testData = new List<object?[]>() { new object?[] { null, false } };
foreach (RedumpSystem redumpSystem in Enum.GetValues(typeof(RedumpSystem)))
foreach (RedumpSystem redumpSystem in Enum.GetValues<RedumpSystem>())
{
if (_xgdSystems.Contains(redumpSystem))
testData.Add([redumpSystem, true]);
@@ -2219,7 +2225,7 @@ namespace SabreTools.RedumpLib.Test.Data
public static List<object?[]> GenerateSystemCategoryTestData()
{
var testData = new List<object?[]>() { new object?[] { null, true } };
foreach (SystemCategory? systemCategory in Enum.GetValues(typeof(SystemCategory)))
foreach (SystemCategory? systemCategory in Enum.GetValues<SystemCategory>().Cast<SystemCategory?>())
{
if (systemCategory == SystemCategory.NONE)
testData.Add([systemCategory, true]);
@@ -2285,7 +2291,7 @@ namespace SabreTools.RedumpLib.Test.Data
public static List<object?[]> GenerateYesNoTestData()
{
var testData = new List<object?[]>() { new object?[] { null, false } };
foreach (YesNo? yesNo in Enum.GetValues(typeof(YesNo)))
foreach (YesNo? yesNo in Enum.GetValues<YesNo>().Cast<YesNo?>())
{
testData.Add([yesNo, false]);
}

View File

@@ -5,4 +5,4 @@ namespace SabreTools.RedumpLib.Test
// Tests here will require installing and using the Moq library
// to mock the RedumpClient type.
}
}
}

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using SabreTools.RedumpLib.Data;
using SabreTools.RedumpLib.Data.Sections;
using Xunit;
namespace SabreTools.RedumpLib.Test
@@ -66,7 +67,7 @@ namespace SabreTools.RedumpLib.Test
string expected = "Version and Editions:\n\tVersion: XXXXXX\n\tEdition/Release: XXXXXX\n";
var builder = new StringBuilder();
VersionAndEditionsSection? section = new VersionAndEditionsSection
VersionAndEditionsSection? section = new()
{
Version = "XXXXXX",
OtherEditions = "XXXXXX",
@@ -118,7 +119,7 @@ namespace SabreTools.RedumpLib.Test
string expected = "EDC:\n\tEDC: Yes\n";
var builder = new StringBuilder();
EDCSection? section = new EDCSection { EDC = YesNo.Yes };
EDCSection? section = new() { EDC = YesNo.Yes };
RedumpSystem? system = RedumpSystem.SonyPlayStation;
Formatter.FormatOutputData(builder, section, system);
@@ -151,7 +152,7 @@ namespace SabreTools.RedumpLib.Test
string expected = string.Empty;
var builder = new StringBuilder();
ExtrasSection? section = new ExtrasSection
ExtrasSection? section = new()
{
PVD = null,
PIC = null,
@@ -171,7 +172,7 @@ namespace SabreTools.RedumpLib.Test
string expected = "Extras:\n\tPrimary Volume Descriptor (PVD): XXXXXX\n\tDisc Key: XXXXXX\n\tDisc ID: XXXXXX\n\tPermanent Information & Control (PIC): XXXXXX\n\tHeader: XXXXXX\n\tBCA: XXXXXX\n\tSecurity Sector Ranges: XXXXXX\n";
var builder = new StringBuilder();
ExtrasSection? section = new ExtrasSection
ExtrasSection? section = new()
{
PVD = "XXXXXX",
DiscKey = "XXXXXX",
@@ -213,7 +214,7 @@ namespace SabreTools.RedumpLib.Test
string expected = string.Empty;
var builder = new StringBuilder();
CopyProtectionSection? section = new CopyProtectionSection
CopyProtectionSection? section = new()
{
Protection = null,
AntiModchip = null,
@@ -235,7 +236,7 @@ namespace SabreTools.RedumpLib.Test
string expected = "Copy Protection:\n\tCopy Protection: XXXXXX\n\tSubIntention Data (SecuROM/LibCrypt): XXXXXX\n";
var builder = new StringBuilder();
CopyProtectionSection? section = new CopyProtectionSection
CopyProtectionSection? section = new()
{
AntiModchip = YesNo.Yes,
LibCrypt = YesNo.Yes,
@@ -257,7 +258,7 @@ namespace SabreTools.RedumpLib.Test
string expected = "Copy Protection:\n\tAnti-modchip: Yes\n\tLibCrypt: Yes\n\tSubIntention Data (SecuROM/LibCrypt): XXXXXX\n\tCopy Protection: XXXXXX\n\tSubIntention Data (SecuROM/LibCrypt): XXXXXX\n";
var builder = new StringBuilder();
CopyProtectionSection? section = new CopyProtectionSection
CopyProtectionSection? section = new()
{
AntiModchip = YesNo.Yes,
LibCrypt = YesNo.Yes,
@@ -283,7 +284,7 @@ namespace SabreTools.RedumpLib.Test
string expected = "Tracks and Write Offsets:\n\tDAT:\n\n\n\n\n";
var builder = new StringBuilder();
TracksAndWriteOffsetsSection? section = new TracksAndWriteOffsetsSection();
TracksAndWriteOffsetsSection? section = new();
Formatter.FormatOutputData(builder, section);
@@ -297,7 +298,7 @@ namespace SabreTools.RedumpLib.Test
string expected = "Tracks and Write Offsets:\n\tDAT:\n\nXXXXXX\n\n\n\tCuesheet: XXXXXX\n\tWrite Offset: XXXXXX\n";
var builder = new StringBuilder();
TracksAndWriteOffsetsSection? section = new TracksAndWriteOffsetsSection
TracksAndWriteOffsetsSection? section = new()
{
ClrMameProData = "XXXXXX",
Cuesheet = "XXXXXX",
@@ -340,7 +341,7 @@ namespace SabreTools.RedumpLib.Test
string expected = "Dumping Info:\n\tFrontend Version: XXXXXX\n\tDumping Program: XXXXXX\n\tDate: XXXXXX\n\tParameters: XXXXXX\n\tManufacturer: XXXXXX\n\tModel: XXXXXX\n\tFirmware: XXXXXX\n\tReported Disc Type: XXXXXX\n\tC2 Error Count: XXXXXX\n";
var builder = new StringBuilder();
DumpingInfoSection? section = new DumpingInfoSection
DumpingInfoSection? section = new()
{
FrontendVersion = "XXXXXX",
DumpingProgram = "XXXXXX",
@@ -556,7 +557,7 @@ namespace SabreTools.RedumpLib.Test
string? expected = "BD-ROM-66";
MediaType? mediaType = MediaType.BluRay;
string? picIdentifier = Models.PIC.Constants.DiscTypeIdentifierROMUltra;
string? picIdentifier = "BDU";
long? size = null;
long? layerbreak = 12345;
long? layerbreak2 = null;
@@ -622,7 +623,7 @@ namespace SabreTools.RedumpLib.Test
string? expected = "BD-ROM-33";
MediaType? mediaType = MediaType.BluRay;
string? picIdentifier = Models.PIC.Constants.DiscTypeIdentifierROMUltra;
string? picIdentifier = "BDU";
long? size = null;
long? layerbreak = null;
long? layerbreak2 = null;
@@ -874,4 +875,4 @@ namespace SabreTools.RedumpLib.Test
#endregion
}
}
}

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net6.0;net8.0;net9.0</TargetFrameworks>
<TargetFrameworks>net8.0;net9.0;net10.0</TargetFrameworks>
<CheckEolTargetFramework>false</CheckEolTargetFramework>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
@@ -24,11 +24,11 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeCoverage" Version="17.13.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.13.0" />
<PackageReference Include="Microsoft.CodeCoverage" Version="18.0.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.0.1" />
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.abstractions" Version="2.0.3" />
<PackageReference Include="xunit.analyzers" Version="1.21.0" />
<PackageReference Include="xunit.analyzers" Version="1.25.0" />
<PackageReference Include="xunit.assert" Version="2.9.3" />
<PackageReference Include="xunit.core" Version="2.9.3" />
<PackageReference Include="xunit.extensibility.core" Version="2.9.3" />
@@ -37,7 +37,7 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="xunit.runner.visualstudio" Version="3.0.2">
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.5">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>

View File

@@ -2,6 +2,7 @@
using System.Collections.Generic;
using Newtonsoft.Json;
using SabreTools.RedumpLib.Data;
using SabreTools.RedumpLib.Data.Sections;
using Xunit;
namespace SabreTools.RedumpLib.Test
@@ -43,7 +44,7 @@ namespace SabreTools.RedumpLib.Test
{
SchemaVersion = 1,
FullyMatchedID = 3,
PartiallyMatchedIDs = new List<int> { 0, 1, 2, 3 },
PartiallyMatchedIDs = [0, 1, 2, 3],
Added = DateTime.UtcNow,
LastModified = DateTime.UtcNow,
@@ -57,8 +58,8 @@ namespace SabreTools.RedumpLib.Test
DiscTitle = "Install Disc",
Category = DiscCategory.Games,
Region = Region.World,
Languages = new Language?[] { Language.English, Language.Spanish, Language.French },
LanguageSelection = new LanguageSelection?[] { LanguageSelection.BiosSettings },
Languages = [Language.English, Language.Spanish, Language.French],
LanguageSelection = [LanguageSelection.BiosSettings],
Serial = "Disc Serial",
Layer0MasteringRing = "L0 Mastering Ring",
Layer0MasteringSID = "L0 Mastering SID",
@@ -96,7 +97,7 @@ namespace SabreTools.RedumpLib.Test
{
Version = "Original",
VersionDatfile = "Alt",
CommonEditions = new string[] { "Taikenban" },
CommonEditions = ["Taikenban"],
OtherEditions = "Rerelease",
},
@@ -134,7 +135,7 @@ namespace SabreTools.RedumpLib.Test
DumpersAndStatus = new DumpersAndStatusSection()
{
Status = DumpStatus.TwoOrMoreGreen,
Dumpers = new string[] { "Dumper1", "Dumper2" },
Dumpers = ["Dumper1", "Dumper2"],
OtherDumpers = "Dumper3",
},
@@ -142,7 +143,7 @@ namespace SabreTools.RedumpLib.Test
{
ClrMameProData = "Datfile",
Cuesheet = "Cuesheet",
CommonWriteOffsets = new int[] { 0, 12, -12 },
CommonWriteOffsets = [0, 12, -12],
OtherWriteOffsets = "-2",
},

View File

@@ -1,4 +1,5 @@
using SabreTools.RedumpLib.Data;
using SabreTools.RedumpLib.Data.Sections;
using Xunit;
namespace SabreTools.RedumpLib.Test
@@ -11,7 +12,7 @@ namespace SabreTools.RedumpLib.Test
[Fact]
public void NormalizeDiscType_InvalidMedia_Untouched()
{
SubmissionInfo si = new SubmissionInfo
var si = new SubmissionInfo
{
CommonDiscInfo = new CommonDiscInfoSection { Media = null }
};
@@ -25,10 +26,10 @@ namespace SabreTools.RedumpLib.Test
public void NormalizeDiscType_InvalidSizeChecksums_Untouched()
{
DiscType expected = DiscType.CD;
SubmissionInfo si = new SubmissionInfo
var si = new SubmissionInfo
{
CommonDiscInfo = new CommonDiscInfoSection { Media = DiscType.CD },
SizeAndChecksums = null,
SizeAndChecksums = new(),
};
Validator.NormalizeDiscType(si);
@@ -40,7 +41,7 @@ namespace SabreTools.RedumpLib.Test
public void NormalizeDiscType_UnformattedType_Fixed()
{
DiscType expected = DiscType.CD;
SubmissionInfo si = new SubmissionInfo
var si = new SubmissionInfo
{
CommonDiscInfo = new CommonDiscInfoSection { Media = DiscType.CD },
SizeAndChecksums = new SizeAndChecksumsSection(),
@@ -57,7 +58,7 @@ namespace SabreTools.RedumpLib.Test
public void NormalizeDiscType_DVD9_Fixed(DiscType type)
{
DiscType expected = DiscType.DVD9;
SubmissionInfo si = new SubmissionInfo
var si = new SubmissionInfo
{
CommonDiscInfo = new CommonDiscInfoSection { Media = type },
SizeAndChecksums = new SizeAndChecksumsSection { Layerbreak = 12345 },
@@ -74,7 +75,7 @@ namespace SabreTools.RedumpLib.Test
public void NormalizeDiscType_DVD5_Fixed(DiscType type)
{
DiscType expected = DiscType.DVD5;
SubmissionInfo si = new SubmissionInfo
var si = new SubmissionInfo
{
CommonDiscInfo = new CommonDiscInfoSection { Media = type },
SizeAndChecksums = new SizeAndChecksumsSection(),
@@ -95,7 +96,7 @@ namespace SabreTools.RedumpLib.Test
public void NormalizeDiscType_BD128_Fixed(DiscType type)
{
DiscType expected = DiscType.BD128;
SubmissionInfo si = new SubmissionInfo
var si = new SubmissionInfo
{
CommonDiscInfo = new CommonDiscInfoSection { Media = type },
SizeAndChecksums = new SizeAndChecksumsSection { Layerbreak3 = 12345 },
@@ -116,7 +117,7 @@ namespace SabreTools.RedumpLib.Test
public void NormalizeDiscType_BD100_Fixed(DiscType type)
{
DiscType expected = DiscType.BD100;
SubmissionInfo si = new SubmissionInfo
var si = new SubmissionInfo
{
CommonDiscInfo = new CommonDiscInfoSection { Media = type },
SizeAndChecksums = new SizeAndChecksumsSection { Layerbreak2 = 12345 },
@@ -137,13 +138,13 @@ namespace SabreTools.RedumpLib.Test
public void NormalizeDiscType_BD66PIC_Fixed(DiscType type)
{
DiscType expected = DiscType.BD66;
SubmissionInfo si = new SubmissionInfo
var si = new SubmissionInfo
{
CommonDiscInfo = new CommonDiscInfoSection { Media = type },
SizeAndChecksums = new SizeAndChecksumsSection
{
Layerbreak = 12345,
PICIdentifier = Models.PIC.Constants.DiscTypeIdentifierROMUltra,
PICIdentifier = "BDU",
},
};
@@ -162,7 +163,7 @@ namespace SabreTools.RedumpLib.Test
public void NormalizeDiscType_BD66Size_Fixed(DiscType type)
{
DiscType expected = DiscType.BD66;
SubmissionInfo si = new SubmissionInfo
var si = new SubmissionInfo
{
CommonDiscInfo = new CommonDiscInfoSection { Media = type },
SizeAndChecksums = new SizeAndChecksumsSection
@@ -187,7 +188,7 @@ namespace SabreTools.RedumpLib.Test
public void NormalizeDiscType_BD50_Fixed(DiscType type)
{
DiscType expected = DiscType.BD50;
SubmissionInfo si = new SubmissionInfo
var si = new SubmissionInfo
{
CommonDiscInfo = new CommonDiscInfoSection { Media = type },
SizeAndChecksums = new SizeAndChecksumsSection { Layerbreak = 12345 },
@@ -208,12 +209,12 @@ namespace SabreTools.RedumpLib.Test
public void NormalizeDiscType_BD33PIC_Fixed(DiscType type)
{
DiscType expected = DiscType.BD33;
SubmissionInfo si = new SubmissionInfo
var si = new SubmissionInfo
{
CommonDiscInfo = new CommonDiscInfoSection { Media = type },
SizeAndChecksums = new SizeAndChecksumsSection
{
PICIdentifier = Models.PIC.Constants.DiscTypeIdentifierROMUltra,
PICIdentifier = "BDU",
},
};
@@ -232,7 +233,7 @@ namespace SabreTools.RedumpLib.Test
public void NormalizeDiscType_BD33Size_Fixed(DiscType type)
{
DiscType expected = DiscType.BD33;
SubmissionInfo si = new SubmissionInfo
var si = new SubmissionInfo
{
CommonDiscInfo = new CommonDiscInfoSection { Media = type },
SizeAndChecksums = new SizeAndChecksumsSection
@@ -256,7 +257,7 @@ namespace SabreTools.RedumpLib.Test
public void NormalizeDiscType_BD25_Fixed(DiscType type)
{
DiscType expected = DiscType.BD25;
SubmissionInfo si = new SubmissionInfo
var si = new SubmissionInfo
{
CommonDiscInfo = new CommonDiscInfoSection { Media = type },
SizeAndChecksums = new SizeAndChecksumsSection(),
@@ -273,7 +274,7 @@ namespace SabreTools.RedumpLib.Test
public void NormalizeDiscType_UMDDL_Fixed(DiscType type)
{
DiscType expected = DiscType.UMDDL;
SubmissionInfo si = new SubmissionInfo
var si = new SubmissionInfo
{
CommonDiscInfo = new CommonDiscInfoSection { Media = type },
SizeAndChecksums = new SizeAndChecksumsSection { Layerbreak = 12345 },
@@ -290,7 +291,7 @@ namespace SabreTools.RedumpLib.Test
public void NormalizeDiscType_UMDSL_Fixed(DiscType type)
{
DiscType expected = DiscType.UMDSL;
SubmissionInfo si = new SubmissionInfo
var si = new SubmissionInfo
{
CommonDiscInfo = new CommonDiscInfoSection { Media = type },
SizeAndChecksums = new SizeAndChecksumsSection(),
@@ -301,4 +302,4 @@ namespace SabreTools.RedumpLib.Test
Assert.Equal(expected, si.CommonDiscInfo.Media);
}
}
}
}

View File

@@ -44,4 +44,4 @@ namespace SabreTools.RedumpLib.Attributes
return attributes[0] as HumanReadableAttribute;
}
}
}
}

View File

@@ -22,4 +22,4 @@ namespace SabreTools.RedumpLib.Attributes
/// </summary>
public string? ShortName { get; set; }
}
}
}

View File

@@ -23,4 +23,4 @@ namespace SabreTools.RedumpLib.Attributes
/// </summary>
public string? ThreeLetterCodeAlt { get; set; }
}
}
}

View File

@@ -52,4 +52,4 @@ namespace SabreTools.RedumpLib.Attributes
/// </summary>
public bool HasSbi { get; set; } = false;
}
}
}

View File

@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
#if NET40_OR_GREATER || NETCOREAPP
#if NET40_OR_GREATER || NETCOREAPP || NETSTANDARD2_0_OR_GREATER
using System.Net;
#endif
using System.Text;
@@ -10,6 +10,7 @@ using System.Threading.Tasks;
using System.Xml;
using Newtonsoft.Json;
using SabreTools.RedumpLib.Data;
using SabreTools.RedumpLib.Data.Sections;
using SabreTools.RedumpLib.Web;
namespace SabreTools.RedumpLib
@@ -253,8 +254,6 @@ namespace SabreTools.RedumpLib
/// <param name="includeAllData">True to include all pullable information, false to do bare minimum</param>
public async static Task<bool> FillFromId(RedumpClient rc, SubmissionInfo info, int id, bool includeAllData)
{
// Ensure that required sections exist
info = EnsureAllSections(info);
var discData = await rc.DownloadSingleSiteID(id);
if (string.IsNullOrEmpty(discData))
return false;
@@ -269,7 +268,11 @@ namespace SabreTools.RedumpLib
int firstParenLocation = title?.IndexOf(" (") ?? -1;
if (title != null && firstParenLocation >= 0)
{
#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER
info.CommonDiscInfo!.Title = title[..firstParenLocation];
#else
info.CommonDiscInfo!.Title = title.Substring(0, firstParenLocation);
#endif
var submatches = Constants.DiscNumberLetterRegex.Matches(title);
foreach (Match? submatch in submatches)
{
@@ -280,7 +283,11 @@ namespace SabreTools.RedumpLib
// Disc number or letter
if (submatchValue.StartsWith("Disc"))
#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER
info.CommonDiscInfo.DiscNumberLetter = submatchValue["Disc ".Length..];
#else
info.CommonDiscInfo.DiscNumberLetter = submatchValue.Remove(0, "Disc ".Length);
#endif
// Issue number
else if (ulong.TryParse(submatchValue, out _))
@@ -605,35 +612,6 @@ namespace SabreTools.RedumpLib
return true;
}
/// <summary>
/// Ensure all required sections in a submission info exist
/// </summary>
/// <param name="info">SubmissionInfo object to verify</param>
public static SubmissionInfo EnsureAllSections(SubmissionInfo? info)
{
// If there's no info, create one
info ??= new SubmissionInfo();
// Ensure all sections
info.CommonDiscInfo ??= new CommonDiscInfoSection();
info.VersionAndEditions ??= new VersionAndEditionsSection();
info.EDC ??= new EDCSection();
info.ParentCloneRelationship ??= new ParentCloneRelationshipSection();
info.Extras ??= new ExtrasSection();
info.CopyProtection ??= new CopyProtectionSection();
info.DumpersAndStatus ??= new DumpersAndStatusSection();
info.TracksAndWriteOffsets ??= new TracksAndWriteOffsetsSection();
info.SizeAndChecksums ??= new SizeAndChecksumsSection();
info.DumpingInfo ??= new DumpingInfoSection();
info.Artifacts ??= [];
// Ensure special dictionaries
info.CommonDiscInfo.CommentsSpecialFields ??= [];
info.CommonDiscInfo.ContentsSpecialFields ??= [];
return info;
}
/// <summary>
/// Inject information from a seed SubmissionInfo into the existing one
/// </summary>
@@ -645,62 +623,52 @@ namespace SabreTools.RedumpLib
if (seed == null)
return info;
// Ensure that required sections exist
info = EnsureAllSections(info);
// Otherwise, inject information as necessary
if (info.CommonDiscInfo != null && seed.CommonDiscInfo != null)
{
// Info that only overwrites if supplied
if (!string.IsNullOrEmpty(seed.CommonDiscInfo.Title)) info.CommonDiscInfo.Title = seed.CommonDiscInfo.Title;
if (!string.IsNullOrEmpty(seed.CommonDiscInfo.ForeignTitleNonLatin)) info.CommonDiscInfo.ForeignTitleNonLatin = seed.CommonDiscInfo.ForeignTitleNonLatin;
if (!string.IsNullOrEmpty(seed.CommonDiscInfo.DiscNumberLetter)) info.CommonDiscInfo.DiscNumberLetter = seed.CommonDiscInfo.DiscNumberLetter;
if (!string.IsNullOrEmpty(seed.CommonDiscInfo.DiscTitle)) info.CommonDiscInfo.DiscTitle = seed.CommonDiscInfo.DiscTitle;
if (seed.CommonDiscInfo.Category != null) info.CommonDiscInfo.Category = seed.CommonDiscInfo.Category;
if (seed.CommonDiscInfo.Region != null) info.CommonDiscInfo.Region = seed.CommonDiscInfo.Region;
if (seed.CommonDiscInfo.Languages != null) info.CommonDiscInfo.Languages = seed.CommonDiscInfo.Languages;
if (seed.CommonDiscInfo.LanguageSelection != null) info.CommonDiscInfo.LanguageSelection = seed.CommonDiscInfo.LanguageSelection;
if (!string.IsNullOrEmpty(seed.CommonDiscInfo.Serial)) info.CommonDiscInfo.Serial = seed.CommonDiscInfo.Serial;
if (!string.IsNullOrEmpty(seed.CommonDiscInfo.Barcode)) info.CommonDiscInfo.Barcode = seed.CommonDiscInfo.Barcode;
if (!string.IsNullOrEmpty(seed.CommonDiscInfo.Comments)) info.CommonDiscInfo.Comments = seed.CommonDiscInfo.Comments;
if (seed.CommonDiscInfo.CommentsSpecialFields != null) info.CommonDiscInfo.CommentsSpecialFields = seed.CommonDiscInfo.CommentsSpecialFields;
if (!string.IsNullOrEmpty(seed.CommonDiscInfo.Contents)) info.CommonDiscInfo.Contents = seed.CommonDiscInfo.Contents;
if (seed.CommonDiscInfo.ContentsSpecialFields != null) info.CommonDiscInfo.ContentsSpecialFields = seed.CommonDiscInfo.ContentsSpecialFields;
info ??= new SubmissionInfo();
// Info that always overwrites
info.CommonDiscInfo.Layer0MasteringRing = seed.CommonDiscInfo.Layer0MasteringRing;
info.CommonDiscInfo.Layer0MasteringSID = seed.CommonDiscInfo.Layer0MasteringSID;
info.CommonDiscInfo.Layer0ToolstampMasteringCode = seed.CommonDiscInfo.Layer0ToolstampMasteringCode;
info.CommonDiscInfo.Layer0MouldSID = seed.CommonDiscInfo.Layer0MouldSID;
info.CommonDiscInfo.Layer0AdditionalMould = seed.CommonDiscInfo.Layer0AdditionalMould;
// Info that only overwrites if supplied
if (!string.IsNullOrEmpty(seed.CommonDiscInfo.Title)) info.CommonDiscInfo.Title = seed.CommonDiscInfo.Title;
if (!string.IsNullOrEmpty(seed.CommonDiscInfo.ForeignTitleNonLatin)) info.CommonDiscInfo.ForeignTitleNonLatin = seed.CommonDiscInfo.ForeignTitleNonLatin;
if (!string.IsNullOrEmpty(seed.CommonDiscInfo.DiscNumberLetter)) info.CommonDiscInfo.DiscNumberLetter = seed.CommonDiscInfo.DiscNumberLetter;
if (!string.IsNullOrEmpty(seed.CommonDiscInfo.DiscTitle)) info.CommonDiscInfo.DiscTitle = seed.CommonDiscInfo.DiscTitle;
if (seed.CommonDiscInfo.Category != null) info.CommonDiscInfo.Category = seed.CommonDiscInfo.Category;
if (seed.CommonDiscInfo.Region != null) info.CommonDiscInfo.Region = seed.CommonDiscInfo.Region;
if (seed.CommonDiscInfo.Languages != null) info.CommonDiscInfo.Languages = seed.CommonDiscInfo.Languages;
if (seed.CommonDiscInfo.LanguageSelection != null) info.CommonDiscInfo.LanguageSelection = seed.CommonDiscInfo.LanguageSelection;
if (!string.IsNullOrEmpty(seed.CommonDiscInfo.Serial)) info.CommonDiscInfo.Serial = seed.CommonDiscInfo.Serial;
if (!string.IsNullOrEmpty(seed.CommonDiscInfo.Barcode)) info.CommonDiscInfo.Barcode = seed.CommonDiscInfo.Barcode;
if (!string.IsNullOrEmpty(seed.CommonDiscInfo.Comments)) info.CommonDiscInfo.Comments = seed.CommonDiscInfo.Comments;
if (seed.CommonDiscInfo.CommentsSpecialFields != null) info.CommonDiscInfo.CommentsSpecialFields = seed.CommonDiscInfo.CommentsSpecialFields;
if (!string.IsNullOrEmpty(seed.CommonDiscInfo.Contents)) info.CommonDiscInfo.Contents = seed.CommonDiscInfo.Contents;
if (seed.CommonDiscInfo.ContentsSpecialFields != null) info.CommonDiscInfo.ContentsSpecialFields = seed.CommonDiscInfo.ContentsSpecialFields;
info.CommonDiscInfo.Layer1MasteringRing = seed.CommonDiscInfo.Layer1MasteringRing;
info.CommonDiscInfo.Layer1MasteringSID = seed.CommonDiscInfo.Layer1MasteringSID;
info.CommonDiscInfo.Layer1ToolstampMasteringCode = seed.CommonDiscInfo.Layer1ToolstampMasteringCode;
info.CommonDiscInfo.Layer1MouldSID = seed.CommonDiscInfo.Layer1MouldSID;
info.CommonDiscInfo.Layer1AdditionalMould = seed.CommonDiscInfo.Layer1AdditionalMould;
// Info that always overwrites
info.CommonDiscInfo.Layer0MasteringRing = seed.CommonDiscInfo.Layer0MasteringRing;
info.CommonDiscInfo.Layer0MasteringSID = seed.CommonDiscInfo.Layer0MasteringSID;
info.CommonDiscInfo.Layer0ToolstampMasteringCode = seed.CommonDiscInfo.Layer0ToolstampMasteringCode;
info.CommonDiscInfo.Layer0MouldSID = seed.CommonDiscInfo.Layer0MouldSID;
info.CommonDiscInfo.Layer0AdditionalMould = seed.CommonDiscInfo.Layer0AdditionalMould;
info.CommonDiscInfo.Layer2MasteringRing = seed.CommonDiscInfo.Layer2MasteringRing;
info.CommonDiscInfo.Layer2MasteringSID = seed.CommonDiscInfo.Layer2MasteringSID;
info.CommonDiscInfo.Layer2ToolstampMasteringCode = seed.CommonDiscInfo.Layer2ToolstampMasteringCode;
info.CommonDiscInfo.Layer1MasteringRing = seed.CommonDiscInfo.Layer1MasteringRing;
info.CommonDiscInfo.Layer1MasteringSID = seed.CommonDiscInfo.Layer1MasteringSID;
info.CommonDiscInfo.Layer1ToolstampMasteringCode = seed.CommonDiscInfo.Layer1ToolstampMasteringCode;
info.CommonDiscInfo.Layer1MouldSID = seed.CommonDiscInfo.Layer1MouldSID;
info.CommonDiscInfo.Layer1AdditionalMould = seed.CommonDiscInfo.Layer1AdditionalMould;
info.CommonDiscInfo.Layer3MasteringRing = seed.CommonDiscInfo.Layer3MasteringRing;
info.CommonDiscInfo.Layer3MasteringSID = seed.CommonDiscInfo.Layer3MasteringSID;
info.CommonDiscInfo.Layer3ToolstampMasteringCode = seed.CommonDiscInfo.Layer3ToolstampMasteringCode;
}
info.CommonDiscInfo.Layer2MasteringRing = seed.CommonDiscInfo.Layer2MasteringRing;
info.CommonDiscInfo.Layer2MasteringSID = seed.CommonDiscInfo.Layer2MasteringSID;
info.CommonDiscInfo.Layer2ToolstampMasteringCode = seed.CommonDiscInfo.Layer2ToolstampMasteringCode;
if (info.VersionAndEditions != null && seed.VersionAndEditions != null)
{
// Info that only overwrites if supplied
if (!string.IsNullOrEmpty(seed.VersionAndEditions.Version)) info.VersionAndEditions.Version = seed.VersionAndEditions.Version;
if (!string.IsNullOrEmpty(seed.VersionAndEditions.OtherEditions)) info.VersionAndEditions.OtherEditions = seed.VersionAndEditions.OtherEditions;
}
info.CommonDiscInfo.Layer3MasteringRing = seed.CommonDiscInfo.Layer3MasteringRing;
info.CommonDiscInfo.Layer3MasteringSID = seed.CommonDiscInfo.Layer3MasteringSID;
info.CommonDiscInfo.Layer3ToolstampMasteringCode = seed.CommonDiscInfo.Layer3ToolstampMasteringCode;
if (info.CopyProtection != null && seed.CopyProtection != null)
{
// Info that only overwrites if supplied
if (!string.IsNullOrEmpty(seed.CopyProtection.Protection)) info.CopyProtection.Protection = seed.CopyProtection.Protection;
}
// Info that only overwrites if supplied
if (!string.IsNullOrEmpty(seed.VersionAndEditions.Version)) info.VersionAndEditions.Version = seed.VersionAndEditions.Version;
if (!string.IsNullOrEmpty(seed.VersionAndEditions.OtherEditions)) info.VersionAndEditions.OtherEditions = seed.VersionAndEditions.OtherEditions;
// Info that only overwrites if supplied
if (!string.IsNullOrEmpty(seed.CopyProtection.Protection)) info.CopyProtection.Protection = seed.CopyProtection.Protection;
return info;
}
@@ -713,7 +681,8 @@ namespace SabreTools.RedumpLib
return siteCode switch
{
// Multiple
SiteCode.InternalSerialName
SiteCode.HighSierraVolumeDescriptor
or SiteCode.InternalSerialName
or SiteCode.Multisession
or SiteCode.VolumeLabel => true,
@@ -732,6 +701,7 @@ namespace SabreTools.RedumpLib
// Microsoft Xbox One and Series X/S
SiteCode.Filename => true,
SiteCode.TitleID => true,
// Nintendo Gamecube
SiteCode.InternalName => true,

View File

@@ -19,8 +19,7 @@ namespace SabreTools.RedumpLib.Converters
return existingValue;
// Read the value
string? value = reader.Value as string;
if (value == null)
if (reader.Value is not string value)
return null;
// Try to parse the value
@@ -33,4 +32,4 @@ namespace SabreTools.RedumpLib.Converters
t.WriteTo(writer);
}
}
}
}

View File

@@ -19,8 +19,7 @@ namespace SabreTools.RedumpLib.Converters
return existingValue;
// Read the value
string? value = reader.Value as string;
if (value == null)
if (reader.Value is not string value)
return null;
// Try to parse the value
@@ -33,4 +32,4 @@ namespace SabreTools.RedumpLib.Converters
t.WriteTo(writer);
}
}
}
}

View File

@@ -18,7 +18,7 @@ namespace SabreTools.RedumpLib.Converters
// If we have a value already, don't overwrite it
if (hasExistingValue)
return existingValue ?? [];
// Get the current depth for checking
int currentDepth = reader.Depth;
@@ -26,8 +26,7 @@ namespace SabreTools.RedumpLib.Converters
List<Language> languages = [];
while (reader.Read() && reader.Depth > currentDepth)
{
string? value = reader.Value as string;
if (value == null)
if (reader.Value is not string value)
continue;
Language? lang = Data.Extensions.ToLanguage(value);
@@ -43,7 +42,7 @@ namespace SabreTools.RedumpLib.Converters
if (value == null)
return;
JArray array = new JArray();
JArray array = [];
foreach (var val in value)
{
JToken t = JToken.FromObject(val.ShortName() ?? string.Empty);
@@ -53,4 +52,4 @@ namespace SabreTools.RedumpLib.Converters
array.WriteTo(writer);
}
}
}
}

View File

@@ -18,7 +18,7 @@ namespace SabreTools.RedumpLib.Converters
// If we have a value already, don't overwrite it
if (hasExistingValue)
return existingValue ?? [];
// Get the current depth for checking
int currentDepth = reader.Depth;
@@ -26,8 +26,7 @@ namespace SabreTools.RedumpLib.Converters
List<LanguageSelection> selections = [];
while (reader.Read() && reader.Depth > currentDepth)
{
string? value = reader.Value as string;
if (value == null)
if (reader.Value is not string value)
continue;
LanguageSelection? sel = Data.Extensions.ToLanguageSelection(value);
@@ -43,7 +42,7 @@ namespace SabreTools.RedumpLib.Converters
if (value == null)
return;
JArray array = new JArray();
JArray array = [];
foreach (var val in value)
{
JToken t = JToken.FromObject(val.LongName() ?? string.Empty);
@@ -53,4 +52,4 @@ namespace SabreTools.RedumpLib.Converters
array.WriteTo(writer);
}
}
}
}

View File

@@ -19,8 +19,7 @@ namespace SabreTools.RedumpLib.Converters
return existingValue;
// Read the value
string? value = reader.Value as string;
if (value == null)
if (reader.Value is not string value)
return null;
// Try to parse the value
@@ -33,4 +32,4 @@ namespace SabreTools.RedumpLib.Converters
t.WriteTo(writer);
}
}
}
}

View File

@@ -19,8 +19,7 @@ namespace SabreTools.RedumpLib.Converters
return existingValue;
// Read the value
string? value = reader.Value as string;
if (value == null)
if (reader.Value is not string value)
return null;
// Try to parse the value
@@ -33,4 +32,4 @@ namespace SabreTools.RedumpLib.Converters
t.WriteTo(writer);
}
}
}
}

View File

@@ -33,4 +33,4 @@ namespace SabreTools.RedumpLib.Converters
t.WriteTo(writer);
}
}
}
}

View File

@@ -9,17 +9,17 @@ namespace SabreTools.RedumpLib.Data
/// <summary>
/// Regex matching the added field on a disc page
/// </summary>
public static Regex AddedRegex = new(@"<tr><th>Added</th><td>(.*?)</td></tr>", RegexOptions.Compiled);
public static readonly Regex AddedRegex = new(@"<tr><th>Added</th><td>(.*?)</td></tr>", RegexOptions.Compiled);
/// <summary>
/// Regex matching the barcode field on a disc page
/// </summary>
public static Regex BarcodeRegex = new(@"<tr><th>Barcode</th></tr><tr><td>(.*?)</td></tr>", RegexOptions.Compiled);
public static readonly Regex BarcodeRegex = new(@"<tr><th>Barcode</th></tr><tr><td>(.*?)</td></tr>", RegexOptions.Compiled);
/// <summary>
/// Regex matching the BCA field on a disc page
/// </summary>
public static Regex BcaRegex = new(@"<h3>BCA .*?/></h3></td><td .*?></td></tr>"
public static readonly Regex BcaRegex = new(@"<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>"
@@ -29,87 +29,87 @@ namespace SabreTools.RedumpLib.Data
/// <summary>
/// Regex matching the category field on a disc page
/// </summary>
public static Regex CategoryRegex = new(@"<tr><th>Category</th><td>(.*?)</td></tr>", RegexOptions.Compiled);
public static readonly Regex CategoryRegex = new(@"<tr><th>Category</th><td>(.*?)</td></tr>", RegexOptions.Compiled);
/// <summary>
/// Regex matching the comments field on a disc page
/// </summary>
public static Regex CommentsRegex = new(@"<tr><th>Comments</th></tr><tr><td>(.*?)</td></tr>", RegexOptions.Compiled | RegexOptions.Singleline);
public static readonly Regex CommentsRegex = new(@"<tr><th>Comments</th></tr><tr><td>(.*?)</td></tr>", RegexOptions.Compiled | RegexOptions.Singleline);
/// <summary>
/// Regex matching the contents field on a disc page
/// </summary>
public static Regex ContentsRegex = new(@"<tr><th>Contents</th></tr><tr .*?><td>(.*?)</td></tr>", RegexOptions.Compiled | RegexOptions.Singleline);
public static readonly Regex ContentsRegex = new(@"<tr><th>Contents</th></tr><tr .*?><td>(.*?)</td></tr>", RegexOptions.Compiled | RegexOptions.Singleline);
/// <summary>
/// Regex matching individual disc links on a results page
/// </summary>
public static Regex DiscRegex = new(@"<a href=""/disc/(\d+)/"">", RegexOptions.Compiled);
public static readonly Regex DiscRegex = new(@"<a href=""/disc/(\d+)/"">", RegexOptions.Compiled);
/// <summary>
/// Regex matching the disc number or letter field on a disc page
/// </summary>
public static Regex DiscNumberLetterRegex = new(@"\((.*?)\)", RegexOptions.Compiled);
public static readonly Regex DiscNumberLetterRegex = new(@"\((.*?)\)", RegexOptions.Compiled);
/// <summary>
/// Regex matching the dumpers on a disc page
/// </summary>
public static Regex DumpersRegex = new(@"<a href=""/discs/dumper/(.*?)/"">", RegexOptions.Compiled);
public static readonly Regex DumpersRegex = new(@"<a href=""/discs/dumper/(.*?)/"">", RegexOptions.Compiled);
/// <summary>
/// Regex matching the edition field on a disc page
/// </summary>
public static Regex EditionRegex = new(@"<tr><th>Edition</th><td>(.*?)</td></tr>", RegexOptions.Compiled);
public static readonly Regex EditionRegex = new(@"<tr><th>Edition</th><td>(.*?)</td></tr>", RegexOptions.Compiled);
/// <summary>
/// Regex matching the error count field on a disc page
/// </summary>
public static Regex ErrorCountRegex = new(@"<tr><th>Errors count</th><td>(.*?)</td></tr>", RegexOptions.Compiled);
public static readonly Regex ErrorCountRegex = new(@"<tr><th>Errors count</th><td>(.*?)</td></tr>", RegexOptions.Compiled);
/// <summary>
/// Regex matching the foreign title field on a disc page
/// </summary>
public static Regex ForeignTitleRegex = new(@"<h2>(.*?)</h2>", RegexOptions.Compiled);
public static readonly Regex ForeignTitleRegex = new(@"<h2>(.*?)</h2>", RegexOptions.Compiled);
/// <summary>
/// Regex matching the "full match" ID list from a WIP disc page
/// </summary>
public static Regex FullMatchRegex = new(@"<td class=""static"">full match ids: (.*?)</td>", RegexOptions.Compiled);
public static readonly Regex FullMatchRegex = new(@"<td class=""static"">full match ids: (.*?)</td>", RegexOptions.Compiled);
/// <summary>
/// Regex matching the languages field on a disc page
/// </summary>
public static Regex LanguagesRegex = new(@"<img src=""/images/languages/(.*?)\.png"" alt="".*?"" title="".*?"" />\s*", RegexOptions.Compiled);
public static readonly Regex LanguagesRegex = new(@"<img src=""/images/languages/(.*?)\.png"" alt="".*?"" title="".*?"" />\s*", RegexOptions.Compiled);
/// <summary>
/// Regex matching the last modified field on a disc page
/// </summary>
public static Regex LastModifiedRegex = new(@"<tr><th>Last modified</th><td>(.*?)</td></tr>", RegexOptions.Compiled);
public static readonly Regex LastModifiedRegex = new(@"<tr><th>Last modified</th><td>(.*?)</td></tr>", RegexOptions.Compiled);
/// <summary>
/// Regex matching the media field on a disc page
/// </summary>
public static Regex MediaRegex = new(@"<tr><th>Media</th><td>(.*?)</td></tr>", RegexOptions.Compiled);
public static readonly Regex MediaRegex = new(@"<tr><th>Media</th><td>(.*?)</td></tr>", RegexOptions.Compiled);
/// <summary>
/// Regex matching individual WIP disc links on a results page
/// </summary>
public static Regex NewDiscRegex = new(@"<a (style=.*)?href=""/newdisc/(\d+)/"">", RegexOptions.Compiled);
public static readonly Regex NewDiscRegex = new(@"<a (style=.*)?href=""/newdisc/(\d+)/"">", RegexOptions.Compiled);
/// <summary>
/// Regex matching the "partial match" ID list from a WIP disc page
/// </summary>
public static Regex PartialMatchRegex = new(@"<td class=""static"">partial match ids: (.*?)</td>", RegexOptions.Compiled);
public static readonly Regex PartialMatchRegex = new(@"<td class=""static"">partial match ids: (.*?)</td>", RegexOptions.Compiled);
/// <summary>
/// Regex matching the disc key on a PS3 disc page
/// </summary>
public static Regex PS3DiscKey = new(@"<th>Disc Key</th><th>Disc ID</th><th>Permanent Information & Control \(PIC\)</th></tr><tr><td>(.*?)</td><td>", RegexOptions.Compiled);
public static readonly Regex PS3DiscKey = new(@"<th>Disc Key</th><th>Disc ID</th><th>Permanent Information & Control \(PIC\)</th></tr><tr><td>(.*?)</td><td>", RegexOptions.Compiled);
/// <summary>
/// Regex matching the PVD field on a disc page
/// </summary>
public static Regex PvdRegex = new(@"<h3>Primary Volume Descriptor (PVD) <img .*?/></h3></td><td .*?></td></tr>"
public static readonly Regex PvdRegex = new(@"<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>"
@@ -119,57 +119,57 @@ namespace SabreTools.RedumpLib.Data
/// <summary>
/// Regex matching the region field on a disc page
/// </summary>
public static Regex RegionRegex = new(@"<tr><th>Region</th><td><a href=""/discs/region/(.*?)/"">", RegexOptions.Compiled);
public static readonly Regex RegionRegex = new(@"<tr><th>Region</th><td><a href=""/discs/region/(.*?)/"">", RegexOptions.Compiled);
/// <summary>
/// Regex matching a double-layer disc ringcode information
/// </summary>
public static Regex RingCodeDoubleRegex = new(@"", RegexOptions.Compiled | RegexOptions.Singleline); // Varies based on available fields, like Addtional Mould
public static readonly Regex RingCodeDoubleRegex = new(@"", RegexOptions.Compiled | RegexOptions.Singleline); // Varies based on available fields, like Addtional Mould
/// <summary>
/// Regex matching a single-layer disc ringcode information
/// </summary>
public static Regex RingCodeSingleRegex = new(@"", RegexOptions.Compiled | RegexOptions.Singleline); // Varies based on available fields, like Addtional Mould
public static readonly Regex RingCodeSingleRegex = new(@"", RegexOptions.Compiled | RegexOptions.Singleline); // Varies based on available fields, like Addtional Mould
/// <summary>
/// Regex matching the serial field on a disc page
/// </summary>
public static Regex SerialRegex = new(@"<tr><th>Serial</th><td>(.*?)</td></tr>", RegexOptions.Compiled);
public static readonly Regex SerialRegex = new(@"<tr><th>Serial</th><td>(.*?)</td></tr>", RegexOptions.Compiled);
/// <summary>
/// Regex matching the system field on a disc page
/// </summary>
public static Regex SystemRegex = new(@"<tr><th>System</th><td><a href=""/discs/system/(.*?)/"">", RegexOptions.Compiled);
public static readonly Regex SystemRegex = new(@"<tr><th>System</th><td><a href=""/discs/system/(.*?)/"">", RegexOptions.Compiled);
/// <summary>
/// Regex matching the title field on a disc page
/// </summary>
public static Regex TitleRegex = new(@"<h1>(.*?)</h1>", RegexOptions.Compiled);
public static readonly Regex TitleRegex = new(@"<h1>(.*?)</h1>", RegexOptions.Compiled);
/// <summary>
/// Regex matching the current nonce token for login
/// </summary>
public static Regex TokenRegex = new(@"<input type=""hidden"" name=""csrf_token"" value=""(.*?)"" />", RegexOptions.Compiled);
public static readonly Regex TokenRegex = new(@"<input type=""hidden"" name=""csrf_token"" value=""(.*?)"" />", RegexOptions.Compiled);
/// <summary>
/// Regex matching a single track on a disc page
/// </summary>
public static Regex TrackRegex = new(@"<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>", RegexOptions.Compiled | RegexOptions.Singleline);
public static readonly Regex TrackRegex = new(@"<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>", RegexOptions.Compiled | RegexOptions.Singleline);
/// <summary>
/// Regex matching the track count on a disc page
/// </summary>
public static Regex TrackCountRegex = new(@"<tr><th>Number of tracks</th><td>(.*?)</td></tr>", RegexOptions.Compiled);
public static readonly Regex TrackCountRegex = new(@"<tr><th>Number of tracks</th><td>(.*?)</td></tr>", RegexOptions.Compiled);
/// <summary>
/// Regex matching the version field on a disc page
/// </summary>
public static Regex VersionRegex = new(@"<tr><th>Version</th><td>(.*?)</td></tr>", RegexOptions.Compiled);
public static readonly Regex VersionRegex = new(@"<tr><th>Version</th><td>(.*?)</td></tr>", RegexOptions.Compiled);
/// <summary>
/// Regex matching the write offset field on a disc page
/// </summary>
public static Regex WriteOffsetRegex = new(@"<tr><th>Write offset</th><td>(.*?)</td></tr>", RegexOptions.Compiled);
public static readonly Regex WriteOffsetRegex = new(@"<tr><th>Write offset</th><td>(.*?)</td></tr>", RegexOptions.Compiled);
#endregion
@@ -306,4 +306,4 @@ namespace SabreTools.RedumpLib.Data
#endregion
}
}
}

View File

@@ -2008,6 +2008,9 @@ namespace SabreTools.RedumpLib.Data
[System(Category = SystemCategory.DiscBasedConsole, LongName = "Philips CD-i", ShortName = "cdi", HasCues = true, HasDat = true)]
PhilipsCDi,
[System(Category = SystemCategory.DiscBasedConsole, Available = false, LongName = "Playmaji Polymega")]
PlaymajiPolymega,
[System(Category = SystemCategory.DiscBasedConsole, Available = false, LongName = "Pioneer LaserActive")]
PioneerLaserActive,
@@ -2478,7 +2481,7 @@ namespace SabreTools.RedumpLib.Data
/// </summary>
/// <remarks>
/// https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2
///
///
/// Because of how Redump stores region IDs, the second letter of each
/// code is lower-cased. In any other system, both letters would be
/// capitalized properly.
@@ -3379,7 +3382,7 @@ namespace SabreTools.RedumpLib.Data
[HumanReadable(LongName = "Thailand", ShortName = "Th")]
Thailand,
// East Timor was "Tp"
// East Timor was "Tp"
[HumanReadable(LongName = "Timor-Leste (East Timor)", ShortName = "Tl")]
TimorLeste,
@@ -3595,6 +3598,10 @@ namespace SabreTools.RedumpLib.Data
[HumanReadable(ShortName = "[T:GTID]", LongName = "<b>GT Interactive ID</b>:")]
GTInteractiveID,
// This doesn't have a site tag yet
[HumanReadable(ShortName = "<b>High Sierra Volume Descriptor</b>:", LongName = "<b>High Sierra Volume Descriptor</b>:")]
HighSierraVolumeDescriptor,
// This doesn't have a site tag yet
[HumanReadable(ShortName = "<b>Internal Name</b>:", LongName = "<b>Internal Name</b>:")]
InternalName,
@@ -3602,6 +3609,10 @@ namespace SabreTools.RedumpLib.Data
[HumanReadable(ShortName = "[T:ISN]", LongName = "<b>Internal Serial</b>:")]
InternalSerialName,
// This doesn't have a site tag yet
[HumanReadable(ShortName = "<b>Interplay ID</b>:", LongName = "<b>Interplay ID</b>:")]
InterplayID,
[HumanReadable(ShortName = "[T:ISBN]", LongName = "<b>ISBN</b>:")]
ISBN,
@@ -3720,6 +3731,10 @@ namespace SabreTools.RedumpLib.Data
[HumanReadable(ShortName = "[T:TD]", LongName = "<b>Tech Demos</b>:")]
TechDemos,
// This doesn't have a site tag yet
[HumanReadable(ShortName = "<b>Title ID</b>:", LongName = "<b>Title ID</b>:")]
TitleID,
[HumanReadable(ShortName = "[T:UID]", LongName = "<b>Ubisoft ID</b>:")]
UbisoftID,

View File

@@ -159,6 +159,12 @@ namespace SabreTools.RedumpLib.Data
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/Polymega
case RedumpSystem.PlaymajiPolymega:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
break;
// https://en.wikipedia.org/wiki/LaserActive
case RedumpSystem.PioneerLaserActive:
types.Add(MediaType.CDROM);
@@ -1254,6 +1260,7 @@ namespace SabreTools.RedumpLib.Data
SiteCode.EditionNonLatin => true,
SiteCode.Filename => true,
SiteCode.Genre => true,
SiteCode.HighSierraVolumeDescriptor => true,
SiteCode.InternalName => true,
SiteCode.InternalSerialName => true,
SiteCode.ISBN => true,
@@ -1270,6 +1277,7 @@ namespace SabreTools.RedumpLib.Data
SiteCode.Series => true,
SiteCode.SSHash => true,
SiteCode.SSVersion => true,
SiteCode.TitleID => true,
SiteCode.UniversalHash => true,
SiteCode.VCD => true,
SiteCode.VFCCode => true,
@@ -1287,6 +1295,7 @@ namespace SabreTools.RedumpLib.Data
SiteCode.ElectronicArtsID => true,
SiteCode.FoxInteractiveID => true,
SiteCode.GTInteractiveID => true,
SiteCode.InterplayID => true,
SiteCode.JASRACID => true,
SiteCode.KingRecordsID => true,
SiteCode.KoeiID => true,
@@ -1358,6 +1367,7 @@ namespace SabreTools.RedumpLib.Data
SiteCode.Filename => true,
SiteCode.Games => true,
SiteCode.GameFootage => true,
SiteCode.HighSierraVolumeDescriptor => true,
SiteCode.Multisession => true,
SiteCode.NetYarozeGames => true,
SiteCode.Patches => true,

View File

@@ -0,0 +1,202 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using SabreTools.RedumpLib.Converters;
namespace SabreTools.RedumpLib.Data.Sections
{
/// <summary>
/// Common disc info section of New Disc Form
/// </summary>
public class CommonDiscInfoSection : ICloneable
{
// Name not defined by Redump
[JsonProperty(PropertyName = "d_system", DefaultValueHandling = DefaultValueHandling.Include)]
[JsonConverter(typeof(SystemConverter))]
public RedumpSystem? System { get; set; }
// Name not defined by Redump
[JsonProperty(PropertyName = "d_media", DefaultValueHandling = DefaultValueHandling.Include)]
[JsonConverter(typeof(DiscTypeConverter))]
public DiscType? Media { get; set; }
[JsonProperty(PropertyName = "d_title", DefaultValueHandling = DefaultValueHandling.Include)]
public string? Title { get; set; }
[JsonProperty(PropertyName = "d_title_foreign", DefaultValueHandling = DefaultValueHandling.Ignore)]
public string? ForeignTitleNonLatin { get; set; }
[JsonProperty(PropertyName = "d_number", NullValueHandling = NullValueHandling.Ignore)]
public string? DiscNumberLetter { get; set; }
[JsonProperty(PropertyName = "d_label", NullValueHandling = NullValueHandling.Ignore)]
public string? DiscTitle { get; set; }
[JsonProperty(PropertyName = "d_category", DefaultValueHandling = DefaultValueHandling.Include)]
[JsonConverter(typeof(DiscCategoryConverter))]
public DiscCategory? Category { get; set; }
[JsonProperty(PropertyName = "d_region", DefaultValueHandling = DefaultValueHandling.Include)]
[JsonConverter(typeof(RegionConverter))]
public Region? Region { get; set; }
[JsonProperty(PropertyName = "d_languages", DefaultValueHandling = DefaultValueHandling.Include)]
[JsonConverter(typeof(LanguageConverter))]
public Language?[]? Languages { get; set; }
[JsonProperty(PropertyName = "d_languages_selection", NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)]
[JsonConverter(typeof(LanguageSelectionConverter))]
public LanguageSelection?[]? LanguageSelection { get; set; }
[JsonProperty(PropertyName = "d_serial", NullValueHandling = NullValueHandling.Ignore)]
public string? Serial { get; set; }
[JsonProperty(PropertyName = "d_ring", NullValueHandling = NullValueHandling.Ignore)]
public string? Ring { get; private set; }
[JsonProperty(PropertyName = "d_ring_0_id", NullValueHandling = NullValueHandling.Ignore)]
public string? RingId { get; private set; }
[JsonProperty(PropertyName = "d_ring_0_ma1", DefaultValueHandling = DefaultValueHandling.Include)]
public string? Layer0MasteringRing { get; set; }
[JsonProperty(PropertyName = "d_ring_0_ma1_sid", NullValueHandling = NullValueHandling.Ignore)]
public string? Layer0MasteringSID { get; set; }
[JsonProperty(PropertyName = "d_ring_0_ts1", NullValueHandling = NullValueHandling.Ignore)]
public string? Layer0ToolstampMasteringCode { get; set; }
[JsonProperty(PropertyName = "d_ring_0_mo1_sid", NullValueHandling = NullValueHandling.Ignore)]
public string? Layer0MouldSID { get; set; }
[JsonProperty(PropertyName = "d_ring_0_mo1", NullValueHandling = NullValueHandling.Ignore)]
public string? Layer0AdditionalMould { get; set; }
[JsonProperty(PropertyName = "d_ring_0_ma2", DefaultValueHandling = DefaultValueHandling.Include)]
public string? Layer1MasteringRing { get; set; }
[JsonProperty(PropertyName = "d_ring_0_ma2_sid", NullValueHandling = NullValueHandling.Ignore)]
public string? Layer1MasteringSID { get; set; }
[JsonProperty(PropertyName = "d_ring_0_ts2", NullValueHandling = NullValueHandling.Ignore)]
public string? Layer1ToolstampMasteringCode { get; set; }
[JsonProperty(PropertyName = "d_ring_0_mo2_sid", NullValueHandling = NullValueHandling.Ignore)]
public string? Layer1MouldSID { get; set; }
[JsonProperty(PropertyName = "d_ring_0_mo2", NullValueHandling = NullValueHandling.Ignore)]
public string? Layer1AdditionalMould { get; set; }
[JsonProperty(PropertyName = "d_ring_0_ma3", DefaultValueHandling = DefaultValueHandling.Include)]
public string? Layer2MasteringRing { get; set; }
[JsonProperty(PropertyName = "d_ring_0_ma3_sid", NullValueHandling = NullValueHandling.Ignore)]
public string? Layer2MasteringSID { get; set; }
[JsonProperty(PropertyName = "d_ring_0_ts3", NullValueHandling = NullValueHandling.Ignore)]
public string? Layer2ToolstampMasteringCode { get; set; }
[JsonProperty(PropertyName = "d_ring_0_ma4", DefaultValueHandling = DefaultValueHandling.Include)]
public string? Layer3MasteringRing { get; set; }
[JsonProperty(PropertyName = "d_ring_0_ma4_sid", NullValueHandling = NullValueHandling.Ignore)]
public string? Layer3MasteringSID { get; set; }
[JsonProperty(PropertyName = "d_ring_0_ts4", NullValueHandling = NullValueHandling.Ignore)]
public string? Layer3ToolstampMasteringCode { get; set; }
[JsonProperty(PropertyName = "d_ring_0_offsets", NullValueHandling = NullValueHandling.Ignore)]
public string RingOffsetsHidden { get { return "1"; } }
[JsonProperty(PropertyName = "d_ring_0_0_id", NullValueHandling = NullValueHandling.Ignore)]
public string? RingZeroId { get; private set; }
[JsonProperty(PropertyName = "d_ring_0_0_density", NullValueHandling = NullValueHandling.Ignore)]
public string? RingZeroDensity { get; private set; }
[JsonProperty(PropertyName = "d_ring_0_0_value", NullValueHandling = NullValueHandling.Ignore)]
public string? RingWriteOffset { get; set; }
[JsonProperty(PropertyName = "d_ring_count", NullValueHandling = NullValueHandling.Ignore)]
public string RingCount { get { return "1"; } }
[JsonProperty(PropertyName = "d_barcode", NullValueHandling = NullValueHandling.Ignore)]
public string? Barcode { get; set; }
[JsonProperty(PropertyName = "d_date", NullValueHandling = NullValueHandling.Ignore)]
public string? EXEDateBuildDate { get; set; }
[JsonProperty(PropertyName = "d_errors", NullValueHandling = NullValueHandling.Ignore)]
public string? ErrorsCount { get; set; }
[JsonProperty(PropertyName = "d_comments", NullValueHandling = NullValueHandling.Ignore)]
public string? Comments { get; set; }
[JsonIgnore]
public Dictionary<SiteCode, string> CommentsSpecialFields { get; set; } = [];
[JsonProperty(PropertyName = "d_contents", NullValueHandling = NullValueHandling.Ignore)]
public string? Contents { get; set; }
[JsonIgnore]
public Dictionary<SiteCode, string> ContentsSpecialFields { get; set; } = [];
public object Clone()
{
Dictionary<SiteCode, string> commentsSpecialFields = [];
foreach (var kvp in this.CommentsSpecialFields)
{
commentsSpecialFields[kvp.Key] = kvp.Value;
}
Dictionary<SiteCode, string> contentsSpecialFields = [];
foreach (var kvp in this.ContentsSpecialFields)
{
contentsSpecialFields[kvp.Key] = kvp.Value;
}
return new CommonDiscInfoSection
{
System = this.System,
Media = this.Media,
Title = this.Title,
ForeignTitleNonLatin = this.ForeignTitleNonLatin,
DiscNumberLetter = this.DiscNumberLetter,
DiscTitle = this.DiscTitle,
Category = this.Category,
Region = this.Region,
Languages = this.Languages?.Clone() as Language?[],
LanguageSelection = this.LanguageSelection?.Clone() as LanguageSelection?[],
Serial = this.Serial,
Ring = this.Ring,
RingId = this.RingId,
Layer0MasteringRing = this.Layer0MasteringRing,
Layer0MasteringSID = this.Layer0MasteringSID,
Layer0ToolstampMasteringCode = this.Layer0ToolstampMasteringCode,
Layer0MouldSID = this.Layer0MouldSID,
Layer0AdditionalMould = this.Layer0AdditionalMould,
Layer1MasteringRing = this.Layer1MasteringRing,
Layer1MasteringSID = this.Layer1MasteringSID,
Layer1ToolstampMasteringCode = this.Layer1ToolstampMasteringCode,
Layer1MouldSID = this.Layer1MouldSID,
Layer1AdditionalMould = this.Layer1AdditionalMould,
Layer2MasteringRing = this.Layer2MasteringRing,
Layer2MasteringSID = this.Layer2MasteringSID,
Layer2ToolstampMasteringCode = this.Layer2ToolstampMasteringCode,
Layer3MasteringRing = this.Layer3MasteringRing,
Layer3MasteringSID = this.Layer3MasteringSID,
Layer3ToolstampMasteringCode = this.Layer3ToolstampMasteringCode,
RingZeroId = this.RingZeroId,
RingZeroDensity = this.RingZeroDensity,
RingWriteOffset = this.RingWriteOffset,
Barcode = this.Barcode,
EXEDateBuildDate = this.EXEDateBuildDate,
ErrorsCount = this.ErrorsCount,
Comments = this.Comments,
CommentsSpecialFields = commentsSpecialFields,
Contents = this.Contents,
ContentsSpecialFields = contentsSpecialFields,
};
}
}
}

View File

@@ -0,0 +1,56 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using SabreTools.RedumpLib.Converters;
namespace SabreTools.RedumpLib.Data.Sections
{
/// <summary>
/// Copy protection section of New Disc form
/// </summary>
public class CopyProtectionSection : ICloneable
{
[JsonProperty(PropertyName = "d_protection_a", NullValueHandling = NullValueHandling.Ignore)]
[JsonConverter(typeof(YesNoConverter))]
public YesNo? AntiModchip { get; set; }
[JsonProperty(PropertyName = "d_protection_1", NullValueHandling = NullValueHandling.Ignore)]
[JsonConverter(typeof(YesNoConverter))]
public YesNo? LibCrypt { get; set; }
[JsonProperty(PropertyName = "d_libcrypt", NullValueHandling = NullValueHandling.Ignore)]
public string? LibCryptData { get; set; }
[JsonProperty(PropertyName = "d_protection", NullValueHandling = NullValueHandling.Ignore)]
public string? Protection { get; set; }
[JsonIgnore]
public Dictionary<string, List<string>?>? FullProtections { get; set; }
[JsonProperty(PropertyName = "d_securom", NullValueHandling = NullValueHandling.Ignore)]
public string? SecuROMData { get; set; }
public object Clone()
{
Dictionary<string, List<string>?>? fullProtections = null;
if (this.FullProtections != null)
{
fullProtections = [];
foreach (var kvp in this.FullProtections)
{
fullProtections[kvp.Key] = kvp.Value;
}
}
return new CopyProtectionSection
{
AntiModchip = this.AntiModchip,
LibCrypt = this.LibCrypt,
LibCryptData = this.LibCryptData,
Protection = this.Protection,
FullProtections = fullProtections,
SecuROMData = this.SecuROMData,
};
}
}
}

View File

@@ -0,0 +1,30 @@
using System;
using Newtonsoft.Json;
namespace SabreTools.RedumpLib.Data.Sections
{
/// <summary>
/// Dumpers and status section of New Disc form (Moderator only)
/// </summary>
public class DumpersAndStatusSection : ICloneable
{
[JsonProperty(PropertyName = "d_status", NullValueHandling = NullValueHandling.Ignore)]
public DumpStatus Status { get; set; }
[JsonProperty(PropertyName = "d_dumpers", NullValueHandling = NullValueHandling.Ignore)]
public string[]? Dumpers { get; set; }
[JsonProperty(PropertyName = "d_dumpers_text", NullValueHandling = NullValueHandling.Ignore)]
public string? OtherDumpers { get; set; }
public object Clone()
{
return new DumpersAndStatusSection
{
Status = this.Status,
Dumpers = this.Dumpers?.Clone() as string[],
OtherDumpers = this.OtherDumpers,
};
}
}
}

View File

@@ -0,0 +1,63 @@
using System;
using Newtonsoft.Json;
namespace SabreTools.RedumpLib.Data.Sections
{
/// <summary>
/// Dumping info section for moderation
/// </summary>
public class DumpingInfoSection : ICloneable
{
// Name not defined by Redump -- Only used with MPF
[JsonProperty(PropertyName = "d_frontend_version", DefaultValueHandling = DefaultValueHandling.Include)]
public string? FrontendVersion { get; set; }
// Name not defined by Redump
[JsonProperty(PropertyName = "d_dumping_program", DefaultValueHandling = DefaultValueHandling.Include)]
public string? DumpingProgram { get; set; }
// Name not defined by Redump
[JsonProperty(PropertyName = "d_dumping_date", DefaultValueHandling = DefaultValueHandling.Include)]
public string? DumpingDate { get; set; }
// Name not defined by Redump
[JsonProperty(PropertyName = "d_dumping_params", DefaultValueHandling = DefaultValueHandling.Include)]
public string? DumpingParameters { get; set; }
// Name not defined by Redump
[JsonProperty(PropertyName = "d_drive_manufacturer", DefaultValueHandling = DefaultValueHandling.Include)]
public string? Manufacturer { get; set; }
// Name not defined by Redump
[JsonProperty(PropertyName = "d_drive_model", DefaultValueHandling = DefaultValueHandling.Include)]
public string? Model { get; set; }
// Name not defined by Redump
[JsonProperty(PropertyName = "d_drive_firmware", DefaultValueHandling = DefaultValueHandling.Include)]
public string? Firmware { get; set; }
// Name not defined by Redump
[JsonProperty(PropertyName = "d_reported_disc_type", DefaultValueHandling = DefaultValueHandling.Include)]
public string? ReportedDiscType { get; set; }
// Name not defined by Redump -- Only used with Redumper
[JsonProperty(PropertyName = "d_errors_c2", NullValueHandling = NullValueHandling.Ignore)]
public string? C2ErrorsCount { get; set; }
public object Clone()
{
return new DumpingInfoSection
{
FrontendVersion = this.FrontendVersion,
DumpingProgram = this.DumpingProgram,
DumpingDate = this.DumpingDate,
DumpingParameters = this.DumpingParameters,
Manufacturer = this.Manufacturer,
Model = this.Model,
Firmware = this.Firmware,
ReportedDiscType = this.ReportedDiscType,
C2ErrorsCount = this.C2ErrorsCount,
};
}
}
}

View File

@@ -0,0 +1,24 @@
using System;
using Newtonsoft.Json;
using SabreTools.RedumpLib.Converters;
namespace SabreTools.RedumpLib.Data.Sections
{
/// <summary>
/// EDC section of New Disc form (PSX only)
/// </summary>
public class EDCSection : ICloneable
{
[JsonProperty(PropertyName = "d_edc", NullValueHandling = NullValueHandling.Ignore)]
[JsonConverter(typeof(YesNoConverter))]
public YesNo? EDC { get; set; }
public object Clone()
{
return new EDCSection
{
EDC = this.EDC,
};
}
}
}

View File

@@ -0,0 +1,46 @@
using System;
using Newtonsoft.Json;
namespace SabreTools.RedumpLib.Data.Sections
{
/// <summary>
/// Extras section of New Disc form
/// </summary>
public class ExtrasSection : ICloneable
{
[JsonProperty(PropertyName = "d_pvd", NullValueHandling = NullValueHandling.Ignore)]
public string? PVD { get; set; }
[JsonProperty(PropertyName = "d_d1_key", NullValueHandling = NullValueHandling.Ignore)]
public string? DiscKey { get; set; }
[JsonProperty(PropertyName = "d_d2_key", NullValueHandling = NullValueHandling.Ignore)]
public string? DiscID { get; set; }
[JsonProperty(PropertyName = "d_pic_data", NullValueHandling = NullValueHandling.Ignore)]
public string? PIC { get; set; }
[JsonProperty(PropertyName = "d_header", NullValueHandling = NullValueHandling.Ignore)]
public string? Header { get; set; }
[JsonProperty(PropertyName = "d_bca", NullValueHandling = NullValueHandling.Ignore)]
public string? BCA { get; set; }
[JsonProperty(PropertyName = "d_ssranges", NullValueHandling = NullValueHandling.Ignore)]
public string? SecuritySectorRanges { get; set; }
public object Clone()
{
return new ExtrasSection
{
PVD = this.PVD,
DiscKey = this.DiscKey,
DiscID = this.DiscID,
PIC = this.PIC,
Header = this.Header,
BCA = this.BCA,
SecuritySectorRanges = this.SecuritySectorRanges,
};
}
}
}

View File

@@ -0,0 +1,26 @@
using System;
using Newtonsoft.Json;
namespace SabreTools.RedumpLib.Data.Sections
{
/// <summary>
/// Parent/Clone relationship section of New Disc form
/// </summary>
public class ParentCloneRelationshipSection : ICloneable
{
[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; }
public object Clone()
{
return new ParentCloneRelationshipSection
{
ParentID = this.ParentID,
RegionalParent = this.RegionalParent,
};
}
}
}

View File

@@ -0,0 +1,50 @@
using System;
using Newtonsoft.Json;
namespace SabreTools.RedumpLib.Data.Sections
{
/// <summary>
/// Size &amp; checksums section of New Disc form (DVD/BD/UMD-based)
/// </summary>
public class SizeAndChecksumsSection : ICloneable
{
[JsonProperty(PropertyName = "d_layerbreak", NullValueHandling = NullValueHandling.Ignore)]
public long Layerbreak { get; set; }
[JsonProperty(PropertyName = "d_layerbreak_2", NullValueHandling = NullValueHandling.Ignore)]
public long Layerbreak2 { get; set; }
[JsonProperty(PropertyName = "d_layerbreak_3", NullValueHandling = NullValueHandling.Ignore)]
public long Layerbreak3 { get; set; }
[JsonProperty(PropertyName = "d_pic_identifier", NullValueHandling = NullValueHandling.Ignore)]
public string? PICIdentifier { get; set; }
[JsonProperty(PropertyName = "d_size", NullValueHandling = NullValueHandling.Ignore)]
public long Size { get; set; }
[JsonProperty(PropertyName = "d_crc32", NullValueHandling = NullValueHandling.Ignore)]
public string? CRC32 { get; set; }
[JsonProperty(PropertyName = "d_md5", NullValueHandling = NullValueHandling.Ignore)]
public string? MD5 { get; set; }
[JsonProperty(PropertyName = "d_sha1", NullValueHandling = NullValueHandling.Ignore)]
public string? SHA1 { get; set; }
public object Clone()
{
return new SizeAndChecksumsSection
{
Layerbreak = this.Layerbreak,
Layerbreak2 = this.Layerbreak2,
Layerbreak3 = this.Layerbreak3,
PICIdentifier = this.PICIdentifier,
Size = this.Size,
CRC32 = this.CRC32,
MD5 = this.MD5,
SHA1 = this.SHA1,
};
}
}
}

View File

@@ -0,0 +1,34 @@
using System;
using Newtonsoft.Json;
namespace SabreTools.RedumpLib.Data.Sections
{
/// <summary>
/// Tracks and write offsets section of New Disc form (CD/GD-based)
/// </summary>
public class TracksAndWriteOffsetsSection : ICloneable
{
[JsonProperty(PropertyName = "d_tracks", NullValueHandling = NullValueHandling.Ignore)]
public string? ClrMameProData { get; set; }
[JsonProperty(PropertyName = "d_cue", NullValueHandling = NullValueHandling.Ignore)]
public string? Cuesheet { get; set; }
[JsonProperty(PropertyName = "d_offset", NullValueHandling = NullValueHandling.Ignore)]
public int[]? CommonWriteOffsets { get; set; }
[JsonProperty(PropertyName = "d_offset_text", NullValueHandling = NullValueHandling.Ignore)]
public string? OtherWriteOffsets { get; set; }
public object Clone()
{
return new TracksAndWriteOffsetsSection
{
ClrMameProData = this.ClrMameProData,
Cuesheet = this.Cuesheet,
CommonWriteOffsets = this.CommonWriteOffsets?.Clone() as int[],
OtherWriteOffsets = this.OtherWriteOffsets,
};
}
}
}

View File

@@ -0,0 +1,34 @@
using System;
using Newtonsoft.Json;
namespace SabreTools.RedumpLib.Data.Sections
{
/// <summary>
/// Version and editions section of New Disc form
/// </summary>
public class VersionAndEditionsSection : ICloneable
{
[JsonProperty(PropertyName = "d_version", NullValueHandling = NullValueHandling.Ignore)]
public string? Version { get; set; }
[JsonProperty(PropertyName = "d_version_datfile", NullValueHandling = NullValueHandling.Ignore)]
public string? VersionDatfile { get; set; }
[JsonProperty(PropertyName = "d_editions", NullValueHandling = NullValueHandling.Ignore)]
public string[]? CommonEditions { get; set; }
[JsonProperty(PropertyName = "d_editions_text", NullValueHandling = NullValueHandling.Ignore)]
public string? OtherEditions { get; set; }
public object Clone()
{
return new VersionAndEditionsSection
{
Version = this.Version,
VersionDatfile = this.VersionDatfile,
CommonEditions = this.CommonEditions,
OtherEditions = this.OtherEditions,
};
}
}
}

View File

@@ -1,10 +1,7 @@
using System;
using System.Collections.Generic;
#if NET40_OR_GREATER || NETCOREAPP
using System.Linq;
#endif
using Newtonsoft.Json;
using SabreTools.RedumpLib.Converters;
using SabreTools.RedumpLib.Data.Sections;
namespace SabreTools.RedumpLib.Data
{
@@ -41,53 +38,45 @@ namespace SabreTools.RedumpLib.Data
public DateTime? LastModified { get; set; }
[JsonProperty(PropertyName = "common_disc_info", DefaultValueHandling = DefaultValueHandling.Ignore)]
public CommonDiscInfoSection? CommonDiscInfo { get; set; } = new CommonDiscInfoSection();
public CommonDiscInfoSection CommonDiscInfo { get; set; } = new CommonDiscInfoSection();
[JsonProperty(PropertyName = "versions_and_editions", DefaultValueHandling = DefaultValueHandling.Ignore)]
public VersionAndEditionsSection? VersionAndEditions { get; set; } = new VersionAndEditionsSection();
public VersionAndEditionsSection VersionAndEditions { get; set; } = new VersionAndEditionsSection();
[JsonProperty(PropertyName = "edc", DefaultValueHandling = DefaultValueHandling.Ignore)]
public EDCSection? EDC { get; set; } = new EDCSection();
public EDCSection EDC { get; set; } = new EDCSection();
[JsonProperty(PropertyName = "parent_clone_relationship", DefaultValueHandling = DefaultValueHandling.Ignore)]
public ParentCloneRelationshipSection? ParentCloneRelationship { get; set; } = new ParentCloneRelationshipSection();
public ParentCloneRelationshipSection ParentCloneRelationship { get; set; } = new ParentCloneRelationshipSection();
[JsonProperty(PropertyName = "extras", DefaultValueHandling = DefaultValueHandling.Ignore)]
public ExtrasSection? Extras { get; set; } = new ExtrasSection();
public ExtrasSection Extras { get; set; } = new ExtrasSection();
[JsonProperty(PropertyName = "copy_protection", DefaultValueHandling = DefaultValueHandling.Ignore)]
public CopyProtectionSection? CopyProtection { get; set; } = new CopyProtectionSection();
public CopyProtectionSection CopyProtection { get; set; } = new CopyProtectionSection();
[JsonProperty(PropertyName = "dumpers_and_status", DefaultValueHandling = DefaultValueHandling.Ignore)]
public DumpersAndStatusSection? DumpersAndStatus { get; set; } = new DumpersAndStatusSection();
public DumpersAndStatusSection DumpersAndStatus { get; set; } = new DumpersAndStatusSection();
[JsonProperty(PropertyName = "tracks_and_write_offsets", DefaultValueHandling = DefaultValueHandling.Ignore)]
public TracksAndWriteOffsetsSection? TracksAndWriteOffsets { get; set; } = new TracksAndWriteOffsetsSection();
public TracksAndWriteOffsetsSection TracksAndWriteOffsets { get; set; } = new TracksAndWriteOffsetsSection();
[JsonProperty(PropertyName = "size_and_checksums", DefaultValueHandling = DefaultValueHandling.Ignore)]
public SizeAndChecksumsSection? SizeAndChecksums { get; set; } = new SizeAndChecksumsSection();
public SizeAndChecksumsSection SizeAndChecksums { get; set; } = new SizeAndChecksumsSection();
[JsonProperty(PropertyName = "dumping_info", DefaultValueHandling = DefaultValueHandling.Ignore)]
public DumpingInfoSection? DumpingInfo { get; set; } = new DumpingInfoSection();
public DumpingInfoSection DumpingInfo { get; set; } = new DumpingInfoSection();
[JsonProperty(PropertyName = "artifacts", DefaultValueHandling = DefaultValueHandling.Ignore)]
public Dictionary<string, string>? Artifacts { get; set; } = [];
public Dictionary<string, string> Artifacts { get; set; } = [];
public object Clone()
{
#if NET20 || NET35
Dictionary<string, string>? artifacts = null;
if (this.Artifacts != null)
Dictionary<string, string> artifacts = [];
foreach (var kvp in this.Artifacts)
{
artifacts = new Dictionary<string, string>();
foreach (var kvp in this.Artifacts)
{
artifacts[kvp.Key] = kvp.Value;
}
artifacts[kvp.Key] = kvp.Value;
}
#else
var artifacts = this.Artifacts?.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
#endif
return new SubmissionInfo
{
@@ -96,545 +85,18 @@ namespace SabreTools.RedumpLib.Data
PartiallyMatchedIDs = this.PartiallyMatchedIDs,
Added = this.Added,
LastModified = this.LastModified,
CommonDiscInfo = this.CommonDiscInfo?.Clone() as CommonDiscInfoSection,
VersionAndEditions = this.VersionAndEditions?.Clone() as VersionAndEditionsSection,
EDC = this.EDC?.Clone() as EDCSection,
ParentCloneRelationship = this.ParentCloneRelationship?.Clone() as ParentCloneRelationshipSection,
Extras = this.Extras?.Clone() as ExtrasSection,
CopyProtection = this.CopyProtection?.Clone() as CopyProtectionSection,
DumpersAndStatus = this.DumpersAndStatus?.Clone() as DumpersAndStatusSection,
TracksAndWriteOffsets = this.TracksAndWriteOffsets?.Clone() as TracksAndWriteOffsetsSection,
SizeAndChecksums = this.SizeAndChecksums?.Clone() as SizeAndChecksumsSection,
DumpingInfo = this.DumpingInfo?.Clone() as DumpingInfoSection,
CommonDiscInfo = this.CommonDiscInfo?.Clone() as CommonDiscInfoSection ?? new CommonDiscInfoSection(),
VersionAndEditions = this.VersionAndEditions?.Clone() as VersionAndEditionsSection ?? new VersionAndEditionsSection(),
EDC = this.EDC?.Clone() as EDCSection ?? new EDCSection(),
ParentCloneRelationship = this.ParentCloneRelationship?.Clone() as ParentCloneRelationshipSection ?? new ParentCloneRelationshipSection(),
Extras = this.Extras?.Clone() as ExtrasSection ?? new ExtrasSection(),
CopyProtection = this.CopyProtection?.Clone() as CopyProtectionSection ?? new CopyProtectionSection(),
DumpersAndStatus = this.DumpersAndStatus?.Clone() as DumpersAndStatusSection ?? new DumpersAndStatusSection(),
TracksAndWriteOffsets = this.TracksAndWriteOffsets?.Clone() as TracksAndWriteOffsetsSection ?? new TracksAndWriteOffsetsSection(),
SizeAndChecksums = this.SizeAndChecksums?.Clone() as SizeAndChecksumsSection ?? new SizeAndChecksumsSection(),
DumpingInfo = this.DumpingInfo?.Clone() as DumpingInfoSection ?? new DumpingInfoSection(),
Artifacts = artifacts,
};
}
}
/// <summary>
/// Common disc info section of New Disc Form
/// </summary>
public class CommonDiscInfoSection : ICloneable
{
// Name not defined by Redump
[JsonProperty(PropertyName = "d_system", DefaultValueHandling = DefaultValueHandling.Include)]
[JsonConverter(typeof(SystemConverter))]
public RedumpSystem? System { get; set; }
// Name not defined by Redump
[JsonProperty(PropertyName = "d_media", DefaultValueHandling = DefaultValueHandling.Include)]
[JsonConverter(typeof(DiscTypeConverter))]
public DiscType? Media { get; set; }
[JsonProperty(PropertyName = "d_title", DefaultValueHandling = DefaultValueHandling.Include)]
public string? Title { get; set; }
[JsonProperty(PropertyName = "d_title_foreign", DefaultValueHandling = DefaultValueHandling.Ignore)]
public string? ForeignTitleNonLatin { get; set; }
[JsonProperty(PropertyName = "d_number", NullValueHandling = NullValueHandling.Ignore)]
public string? DiscNumberLetter { get; set; }
[JsonProperty(PropertyName = "d_label", NullValueHandling = NullValueHandling.Ignore)]
public string? DiscTitle { get; set; }
[JsonProperty(PropertyName = "d_category", DefaultValueHandling = DefaultValueHandling.Include)]
[JsonConverter(typeof(DiscCategoryConverter))]
public DiscCategory? Category { get; set; }
[JsonProperty(PropertyName = "d_region", DefaultValueHandling = DefaultValueHandling.Include)]
[JsonConverter(typeof(RegionConverter))]
public Region? Region { get; set; }
[JsonProperty(PropertyName = "d_languages", DefaultValueHandling = DefaultValueHandling.Include)]
[JsonConverter(typeof(LanguageConverter))]
public Language?[]? Languages { get; set; }
[JsonProperty(PropertyName = "d_languages_selection", NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)]
[JsonConverter(typeof(LanguageSelectionConverter))]
public LanguageSelection?[]? LanguageSelection { get; set; }
[JsonProperty(PropertyName = "d_serial", NullValueHandling = NullValueHandling.Ignore)]
public string? Serial { get; set; }
[JsonProperty(PropertyName = "d_ring", NullValueHandling = NullValueHandling.Ignore)]
public string? Ring { get; private set; }
[JsonProperty(PropertyName = "d_ring_0_id", NullValueHandling = NullValueHandling.Ignore)]
public string? RingId { get; private set; }
[JsonProperty(PropertyName = "d_ring_0_ma1", DefaultValueHandling = DefaultValueHandling.Include)]
public string? Layer0MasteringRing { get; set; }
[JsonProperty(PropertyName = "d_ring_0_ma1_sid", NullValueHandling = NullValueHandling.Ignore)]
public string? Layer0MasteringSID { get; set; }
[JsonProperty(PropertyName = "d_ring_0_ts1", NullValueHandling = NullValueHandling.Ignore)]
public string? Layer0ToolstampMasteringCode { get; set; }
[JsonProperty(PropertyName = "d_ring_0_mo1_sid", NullValueHandling = NullValueHandling.Ignore)]
public string? Layer0MouldSID { get; set; }
[JsonProperty(PropertyName = "d_ring_0_mo1", NullValueHandling = NullValueHandling.Ignore)]
public string? Layer0AdditionalMould { get; set; }
[JsonProperty(PropertyName = "d_ring_0_ma2", DefaultValueHandling = DefaultValueHandling.Include)]
public string? Layer1MasteringRing { get; set; }
[JsonProperty(PropertyName = "d_ring_0_ma2_sid", NullValueHandling = NullValueHandling.Ignore)]
public string? Layer1MasteringSID { get; set; }
[JsonProperty(PropertyName = "d_ring_0_ts2", NullValueHandling = NullValueHandling.Ignore)]
public string? Layer1ToolstampMasteringCode { get; set; }
[JsonProperty(PropertyName = "d_ring_0_mo2_sid", NullValueHandling = NullValueHandling.Ignore)]
public string? Layer1MouldSID { get; set; }
[JsonProperty(PropertyName = "d_ring_0_mo2", NullValueHandling = NullValueHandling.Ignore)]
public string? Layer1AdditionalMould { get; set; }
[JsonProperty(PropertyName = "d_ring_0_ma3", DefaultValueHandling = DefaultValueHandling.Include)]
public string? Layer2MasteringRing { get; set; }
[JsonProperty(PropertyName = "d_ring_0_ma3_sid", NullValueHandling = NullValueHandling.Ignore)]
public string? Layer2MasteringSID { get; set; }
[JsonProperty(PropertyName = "d_ring_0_ts3", NullValueHandling = NullValueHandling.Ignore)]
public string? Layer2ToolstampMasteringCode { get; set; }
[JsonProperty(PropertyName = "d_ring_0_ma4", DefaultValueHandling = DefaultValueHandling.Include)]
public string? Layer3MasteringRing { get; set; }
[JsonProperty(PropertyName = "d_ring_0_ma4_sid", NullValueHandling = NullValueHandling.Ignore)]
public string? Layer3MasteringSID { get; set; }
[JsonProperty(PropertyName = "d_ring_0_ts4", NullValueHandling = NullValueHandling.Ignore)]
public string? Layer3ToolstampMasteringCode { get; set; }
[JsonProperty(PropertyName = "d_ring_0_offsets", NullValueHandling = NullValueHandling.Ignore)]
public string RingOffsetsHidden { get { return "1"; } }
[JsonProperty(PropertyName = "d_ring_0_0_id", NullValueHandling = NullValueHandling.Ignore)]
public string? RingZeroId { get; private set; }
[JsonProperty(PropertyName = "d_ring_0_0_density", NullValueHandling = NullValueHandling.Ignore)]
public string? RingZeroDensity { get; private set; }
[JsonProperty(PropertyName = "d_ring_0_0_value", NullValueHandling = NullValueHandling.Ignore)]
public string? RingWriteOffset { get; set; }
[JsonProperty(PropertyName = "d_ring_count", NullValueHandling = NullValueHandling.Ignore)]
public string RingCount { get { return "1"; } }
[JsonProperty(PropertyName = "d_barcode", NullValueHandling = NullValueHandling.Ignore)]
public string? Barcode { get; set; }
[JsonProperty(PropertyName = "d_date", NullValueHandling = NullValueHandling.Ignore)]
public string? EXEDateBuildDate { get; set; }
[JsonProperty(PropertyName = "d_errors", NullValueHandling = NullValueHandling.Ignore)]
public string? ErrorsCount { get; set; }
[JsonProperty(PropertyName = "d_comments", NullValueHandling = NullValueHandling.Ignore)]
public string? Comments { get; set; }
[JsonIgnore]
public Dictionary<SiteCode, string>? CommentsSpecialFields { get; set; }
[JsonProperty(PropertyName = "d_contents", NullValueHandling = NullValueHandling.Ignore)]
public string? Contents { get; set; }
[JsonIgnore]
public Dictionary<SiteCode, string>? ContentsSpecialFields { get; set; }
public object Clone()
{
#if NET20 || NET35
Dictionary<SiteCode, string>? commentsSpecialFields = null;
if (this.CommentsSpecialFields != null)
{
commentsSpecialFields = new Dictionary<SiteCode, string>();
foreach (var kvp in this.CommentsSpecialFields)
{
commentsSpecialFields[kvp.Key] = kvp.Value;
}
}
Dictionary<SiteCode, string>? contentsSpecialFields = null;
if (this.ContentsSpecialFields != null)
{
contentsSpecialFields = new Dictionary<SiteCode, string>();
foreach (var kvp in this.ContentsSpecialFields)
{
contentsSpecialFields[kvp.Key] = kvp.Value;
}
}
#else
var commentsSpecialFields = this.CommentsSpecialFields?.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
var contentsSpecialFields = this.ContentsSpecialFields?.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
#endif
return new CommonDiscInfoSection
{
System = this.System,
Media = this.Media,
Title = this.Title,
ForeignTitleNonLatin = this.ForeignTitleNonLatin,
DiscNumberLetter = this.DiscNumberLetter,
DiscTitle = this.DiscTitle,
Category = this.Category,
Region = this.Region,
Languages = this.Languages?.Clone() as Language?[],
LanguageSelection = this.LanguageSelection?.Clone() as LanguageSelection?[],
Serial = this.Serial,
Ring = this.Ring,
RingId = this.RingId,
Layer0MasteringRing = this.Layer0MasteringRing,
Layer0MasteringSID = this.Layer0MasteringSID,
Layer0ToolstampMasteringCode = this.Layer0ToolstampMasteringCode,
Layer0MouldSID = this.Layer0MouldSID,
Layer0AdditionalMould = this.Layer0AdditionalMould,
Layer1MasteringRing = this.Layer1MasteringRing,
Layer1MasteringSID = this.Layer1MasteringSID,
Layer1ToolstampMasteringCode = this.Layer1ToolstampMasteringCode,
Layer1MouldSID = this.Layer1MouldSID,
Layer1AdditionalMould = this.Layer1AdditionalMould,
Layer2MasteringRing = this.Layer2MasteringRing,
Layer2MasteringSID = this.Layer2MasteringSID,
Layer2ToolstampMasteringCode = this.Layer2ToolstampMasteringCode,
Layer3MasteringRing = this.Layer3MasteringRing,
Layer3MasteringSID = this.Layer3MasteringSID,
Layer3ToolstampMasteringCode = this.Layer3ToolstampMasteringCode,
RingZeroId = this.RingZeroId,
RingZeroDensity = this.RingZeroDensity,
RingWriteOffset = this.RingWriteOffset,
Barcode = this.Barcode,
EXEDateBuildDate = this.EXEDateBuildDate,
ErrorsCount = this.ErrorsCount,
Comments = this.Comments,
CommentsSpecialFields = commentsSpecialFields,
Contents = this.Contents,
ContentsSpecialFields = contentsSpecialFields,
};
}
}
/// <summary>
/// Version and editions section of New Disc form
/// </summary>
public class VersionAndEditionsSection : ICloneable
{
[JsonProperty(PropertyName = "d_version", NullValueHandling = NullValueHandling.Ignore)]
public string? Version { get; set; }
[JsonProperty(PropertyName = "d_version_datfile", NullValueHandling = NullValueHandling.Ignore)]
public string? VersionDatfile { get; set; }
[JsonProperty(PropertyName = "d_editions", NullValueHandling = NullValueHandling.Ignore)]
public string[]? CommonEditions { get; set; }
[JsonProperty(PropertyName = "d_editions_text", NullValueHandling = NullValueHandling.Ignore)]
public string? OtherEditions { get; set; }
public object Clone()
{
return new VersionAndEditionsSection
{
Version = this.Version,
VersionDatfile = this.VersionDatfile,
CommonEditions = this.CommonEditions,
OtherEditions = this.OtherEditions,
};
}
}
/// <summary>
/// EDC section of New Disc form (PSX only)
/// </summary>
public class EDCSection : ICloneable
{
[JsonProperty(PropertyName = "d_edc", NullValueHandling = NullValueHandling.Ignore)]
[JsonConverter(typeof(YesNoConverter))]
public YesNo? EDC { get; set; }
public object Clone()
{
return new EDCSection
{
EDC = this.EDC,
};
}
}
/// <summary>
/// Parent/Clone relationship section of New Disc form
/// </summary>
public class ParentCloneRelationshipSection : ICloneable
{
[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; }
public object Clone()
{
return new ParentCloneRelationshipSection
{
ParentID = this.ParentID,
RegionalParent = this.RegionalParent,
};
}
}
/// <summary>
/// Extras section of New Disc form
/// </summary>
public class ExtrasSection : ICloneable
{
[JsonProperty(PropertyName = "d_pvd", NullValueHandling = NullValueHandling.Ignore)]
public string? PVD { get; set; }
[JsonProperty(PropertyName = "d_d1_key", NullValueHandling = NullValueHandling.Ignore)]
public string? DiscKey { get; set; }
[JsonProperty(PropertyName = "d_d2_key", NullValueHandling = NullValueHandling.Ignore)]
public string? DiscID { get; set; }
[JsonProperty(PropertyName = "d_pic_data", NullValueHandling = NullValueHandling.Ignore)]
public string? PIC { get; set; }
[JsonProperty(PropertyName = "d_header", NullValueHandling = NullValueHandling.Ignore)]
public string? Header { get; set; }
[JsonProperty(PropertyName = "d_bca", NullValueHandling = NullValueHandling.Ignore)]
public string? BCA { get; set; }
[JsonProperty(PropertyName = "d_ssranges", NullValueHandling = NullValueHandling.Ignore)]
public string? SecuritySectorRanges { get; set; }
public object Clone()
{
return new ExtrasSection
{
PVD = this.PVD,
DiscKey = this.DiscKey,
DiscID = this.DiscID,
PIC = this.PIC,
Header = this.Header,
BCA = this.BCA,
SecuritySectorRanges = this.SecuritySectorRanges,
};
}
}
/// <summary>
/// Copy protection section of New Disc form
/// </summary>
public class CopyProtectionSection : ICloneable
{
[JsonProperty(PropertyName = "d_protection_a", NullValueHandling = NullValueHandling.Ignore)]
[JsonConverter(typeof(YesNoConverter))]
public YesNo? AntiModchip { get; set; }
[JsonProperty(PropertyName = "d_protection_1", NullValueHandling = NullValueHandling.Ignore)]
[JsonConverter(typeof(YesNoConverter))]
public YesNo? LibCrypt { get; set; }
[JsonProperty(PropertyName = "d_libcrypt", NullValueHandling = NullValueHandling.Ignore)]
public string? LibCryptData { get; set; }
[JsonProperty(PropertyName = "d_protection", NullValueHandling = NullValueHandling.Ignore)]
public string? Protection { get; set; }
[JsonIgnore]
public Dictionary<string, List<string>?>? FullProtections { get; set; }
[JsonProperty(PropertyName = "d_securom", NullValueHandling = NullValueHandling.Ignore)]
public string? SecuROMData { get; set; }
public object Clone()
{
#if NET20 || NET35
Dictionary<string, List<string>?>? fullProtections = null;
if (this.FullProtections != null)
{
fullProtections = new Dictionary<string, List<string>?>();
foreach (var kvp in this.FullProtections)
{
fullProtections[kvp.Key] = kvp.Value;
}
}
#else
var fullProtections = this.FullProtections?.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
#endif
return new CopyProtectionSection
{
AntiModchip = this.AntiModchip,
LibCrypt = this.LibCrypt,
LibCryptData = this.LibCryptData,
Protection = this.Protection,
FullProtections = fullProtections,
SecuROMData = this.SecuROMData,
};
}
}
/// <summary>
/// Dumpers and status section of New Disc form (Moderator only)
/// </summary>
public class DumpersAndStatusSection : ICloneable
{
[JsonProperty(PropertyName = "d_status", NullValueHandling = NullValueHandling.Ignore)]
public DumpStatus Status { get; set; }
[JsonProperty(PropertyName = "d_dumpers", NullValueHandling = NullValueHandling.Ignore)]
public string[]? Dumpers { get; set; }
[JsonProperty(PropertyName = "d_dumpers_text", NullValueHandling = NullValueHandling.Ignore)]
public string? OtherDumpers { get; set; }
public object Clone()
{
return new DumpersAndStatusSection
{
Status = this.Status,
Dumpers = this.Dumpers?.Clone() as string[],
OtherDumpers = this.OtherDumpers,
};
}
}
/// <summary>
/// Tracks and write offsets section of New Disc form (CD/GD-based)
/// </summary>
public class TracksAndWriteOffsetsSection : ICloneable
{
[JsonProperty(PropertyName = "d_tracks", NullValueHandling = NullValueHandling.Ignore)]
public string? ClrMameProData { get; set; }
[JsonProperty(PropertyName = "d_cue", NullValueHandling = NullValueHandling.Ignore)]
public string? Cuesheet { get; set; }
[JsonProperty(PropertyName = "d_offset", NullValueHandling = NullValueHandling.Ignore)]
public int[]? CommonWriteOffsets { get; set; }
[JsonProperty(PropertyName = "d_offset_text", NullValueHandling = NullValueHandling.Ignore)]
public string? OtherWriteOffsets { get; set; }
public object Clone()
{
return new TracksAndWriteOffsetsSection
{
ClrMameProData = this.ClrMameProData,
Cuesheet = this.Cuesheet,
CommonWriteOffsets = this.CommonWriteOffsets?.Clone() as int[],
OtherWriteOffsets = this.OtherWriteOffsets,
};
}
}
/// <summary>
/// Size &amp; checksums section of New Disc form (DVD/BD/UMD-based)
/// </summary>
public class SizeAndChecksumsSection : ICloneable
{
[JsonProperty(PropertyName = "d_layerbreak", NullValueHandling = NullValueHandling.Ignore)]
public long Layerbreak { get; set; }
[JsonProperty(PropertyName = "d_layerbreak_2", NullValueHandling = NullValueHandling.Ignore)]
public long Layerbreak2 { get; set; }
[JsonProperty(PropertyName = "d_layerbreak_3", NullValueHandling = NullValueHandling.Ignore)]
public long Layerbreak3 { get; set; }
[JsonProperty(PropertyName = "d_pic_identifier", NullValueHandling = NullValueHandling.Ignore)]
public string? PICIdentifier { get; set; }
[JsonProperty(PropertyName = "d_size", NullValueHandling = NullValueHandling.Ignore)]
public long Size { get; set; }
[JsonProperty(PropertyName = "d_crc32", NullValueHandling = NullValueHandling.Ignore)]
public string? CRC32 { get; set; }
[JsonProperty(PropertyName = "d_md5", NullValueHandling = NullValueHandling.Ignore)]
public string? MD5 { get; set; }
[JsonProperty(PropertyName = "d_sha1", NullValueHandling = NullValueHandling.Ignore)]
public string? SHA1 { get; set; }
public object Clone()
{
return new SizeAndChecksumsSection
{
Layerbreak = this.Layerbreak,
Layerbreak2 = this.Layerbreak2,
Layerbreak3 = this.Layerbreak3,
PICIdentifier = this.PICIdentifier,
Size = this.Size,
CRC32 = this.CRC32,
MD5 = this.MD5,
SHA1 = this.SHA1,
};
}
}
/// <summary>
/// Dumping info section for moderation
/// </summary>
public class DumpingInfoSection : ICloneable
{
// Name not defined by Redump -- Only used with MPF
[JsonProperty(PropertyName = "d_frontend_version", DefaultValueHandling = DefaultValueHandling.Include)]
public string? FrontendVersion { get; set; }
// Name not defined by Redump
[JsonProperty(PropertyName = "d_dumping_program", DefaultValueHandling = DefaultValueHandling.Include)]
public string? DumpingProgram { get; set; }
// Name not defined by Redump
[JsonProperty(PropertyName = "d_dumping_date", DefaultValueHandling = DefaultValueHandling.Include)]
public string? DumpingDate { get; set; }
// Name not defined by Redump
[JsonProperty(PropertyName = "d_dumping_params", DefaultValueHandling = DefaultValueHandling.Include)]
public string? DumpingParameters { get; set; }
// Name not defined by Redump
[JsonProperty(PropertyName = "d_drive_manufacturer", DefaultValueHandling = DefaultValueHandling.Include)]
public string? Manufacturer { get; set; }
// Name not defined by Redump
[JsonProperty(PropertyName = "d_drive_model", DefaultValueHandling = DefaultValueHandling.Include)]
public string? Model { get; set; }
// Name not defined by Redump
[JsonProperty(PropertyName = "d_drive_firmware", DefaultValueHandling = DefaultValueHandling.Include)]
public string? Firmware { get; set; }
// Name not defined by Redump
[JsonProperty(PropertyName = "d_reported_disc_type", DefaultValueHandling = DefaultValueHandling.Include)]
public string? ReportedDiscType { get; set; }
// Name not defined by Redump -- Only used with Redumper
[JsonProperty(PropertyName = "d_errors_c2", NullValueHandling = NullValueHandling.Ignore)]
public string? C2ErrorsCount { get; set; }
public object Clone()
{
return new DumpingInfoSection
{
FrontendVersion = this.FrontendVersion,
DumpingProgram = this.DumpingProgram,
DumpingDate = this.DumpingDate,
DumpingParameters = this.DumpingParameters,
Manufacturer = this.Manufacturer,
Model = this.Model,
Firmware = this.Firmware,
ReportedDiscType = this.ReportedDiscType,
C2ErrorsCount = this.C2ErrorsCount,
};
}
}
}

View File

@@ -6,4 +6,4 @@ namespace System.Runtime.CompilerServices
internal sealed class ExtensionAttribute : Attribute {}
}
#endif
#endif

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using SabreTools.RedumpLib.Data;
using SabreTools.RedumpLib.Data.Sections;
namespace SabreTools.RedumpLib
{
@@ -24,6 +25,7 @@ namespace SabreTools.RedumpLib
SiteCode.InternalName,
SiteCode.InternalSerialName,
SiteCode.VolumeLabel,
SiteCode.HighSierraVolumeDescriptor,
SiteCode.Multisession,
SiteCode.UniversalHash,
SiteCode.RingNonZeroDataStart,
@@ -37,6 +39,7 @@ namespace SabreTools.RedumpLib
SiteCode.SSVersion,
SiteCode.Filename,
SiteCode.TitleID,
SiteCode.Protection,
@@ -64,6 +67,7 @@ namespace SabreTools.RedumpLib
SiteCode.ElectronicArtsID,
SiteCode.FoxInteractiveID,
SiteCode.GTInteractiveID,
SiteCode.InterplayID,
SiteCode.JASRACID,
SiteCode.KingRecordsID,
SiteCode.KoeiID,
@@ -153,7 +157,7 @@ namespace SabreTools.RedumpLib
output.AppendLine();
// EDC section
FormatOutputData(output, info.EDC, info.CommonDiscInfo?.System);
FormatOutputData(output, info.EDC, info.CommonDiscInfo.System);
output.AppendLine();
// Extras section
@@ -161,11 +165,11 @@ namespace SabreTools.RedumpLib
output.AppendLine();
// Copy Protection section
FormatOutputData(output, info.CopyProtection, info.CommonDiscInfo?.System);
FormatOutputData(output, info.CopyProtection, info.CommonDiscInfo.System);
output.AppendLine();
// Tracks and Write Offsets section
if (!string.IsNullOrEmpty(info.TracksAndWriteOffsets?.ClrMameProData))
if (!string.IsNullOrEmpty(info.TracksAndWriteOffsets.ClrMameProData))
{
FormatOutputData(output, info.TracksAndWriteOffsets!);
output.AppendLine();
@@ -175,8 +179,8 @@ namespace SabreTools.RedumpLib
{
FormatOutputData(output,
info.SizeAndChecksums,
info.CommonDiscInfo?.Media.ToMediaType(),
info.CommonDiscInfo?.System,
info.CommonDiscInfo.Media.ToMediaType(),
info.CommonDiscInfo.System,
enableRedumpCompatibility);
output.AppendLine();
}
@@ -223,7 +227,7 @@ namespace SabreTools.RedumpLib
info.CommonDiscInfo.Comments = info.CommonDiscInfo.Comments.Trim();
// Wipe out the special fields dictionary
info.CommonDiscInfo.CommentsSpecialFields = null;
info.CommonDiscInfo.CommentsSpecialFields.Clear();
}
// Process the contents field
@@ -243,7 +247,7 @@ namespace SabreTools.RedumpLib
info.CommonDiscInfo.Contents = info.CommonDiscInfo.Contents.Trim();
// Wipe out the special fields dictionary
info.CommonDiscInfo.ContentsSpecialFields = null;
info.CommonDiscInfo.ContentsSpecialFields.Clear();
}
}
@@ -541,7 +545,9 @@ namespace SabreTools.RedumpLib
string prefix = string.Empty;
for (int i = 0; i < indent; i++)
{
prefix += "\t";
}
// Skip fields that need to keep internal whitespace intact
if (key != "Primary Volume Descriptor (PVD)"
@@ -556,7 +562,7 @@ namespace SabreTools.RedumpLib
value = value.Replace("<TAB>", "\t");
value = value.Replace("<Tab>", "\t");
#endif
value = value.Replace(" ", "\t");
value = value.Replace(" ", "\t");
// Sanitize whitespace around tabs
value = Regex.Replace(value, @"\s*\t\s*", "\t", RegexOptions.Compiled);
@@ -564,12 +570,18 @@ namespace SabreTools.RedumpLib
// If the value contains a newline
value = value.Replace("\r\n", "\n");
#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER
if (value.Contains('\n'))
#else
if (value.Contains("\n"))
#endif
{
output.AppendLine(prefix + key + ":"); output.AppendLine();
string[] values = value.Split('\n');
foreach (string val in values)
{
output.AppendLine(val);
}
output.AppendLine();
}
@@ -612,7 +624,9 @@ namespace SabreTools.RedumpLib
string prefix = string.Empty;
for (int i = 0; i < indent; i++)
{
prefix += "\t";
}
output.AppendLine(prefix + key + ": " + value);
}
@@ -685,13 +699,13 @@ namespace SabreTools.RedumpLib
return $"{mediaType.LongName()}-128";
else if (layerbreak2 != default && layerbreak2 != default(long))
return $"{mediaType.LongName()}-100";
else if (layerbreak != default && layerbreak != default(long) && picIdentifier == Models.PIC.Constants.DiscTypeIdentifierROMUltra)
else if (layerbreak != default && layerbreak != default(long) && picIdentifier == "BDU")
return $"{mediaType.LongName()}-66";
else if (layerbreak != default && layerbreak != default(long) && size > 53_687_063_712)
return $"{mediaType.LongName()}-66";
else if (layerbreak != default && layerbreak != default(long))
return $"{mediaType.LongName()}-50";
else if (picIdentifier == Models.PIC.Constants.DiscTypeIdentifierROMUltra)
else if (picIdentifier == "BDU")
return $"{mediaType.LongName()}-33";
else if (size > 26_843_531_856)
return $"{mediaType.LongName()}-33";

View File

@@ -2,13 +2,13 @@
<PropertyGroup>
<!-- Assembly Properties -->
<TargetFrameworks>net20;net35;net40;net452;net462;net472;net48;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0;net9.0</TargetFrameworks>
<TargetFrameworks>net20;net35;net40;net452;net462;net472;net48;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0;net9.0;net10.0;netstandard2.0;netstandard2.1</TargetFrameworks>
<IncludeSymbols>true</IncludeSymbols>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<Version>1.6.8</Version>
<Version>1.9.0</Version>
<!-- Package Properties -->
<Authors>Matt Nadareski</Authors>
@@ -33,8 +33,7 @@
<ItemGroup>
<PackageReference Include="MinAsyncBridge" Version="0.12.4" Condition="$(TargetFramework.StartsWith(`net2`)) OR $(TargetFramework.StartsWith(`net3`)) OR $(TargetFramework.StartsWith(`net40`))" />
<PackageReference Include="Net35.Actions" Version="1.4.0" Condition="$(TargetFramework.StartsWith(`net2`))" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="SabreTools.Models" Version="1.5.8" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
</ItemGroup>
</Project>
</Project>

View File

@@ -16,7 +16,7 @@ namespace SabreTools.RedumpLib
public static void NormalizeDiscType(SubmissionInfo info)
{
// If we have nothing valid, do nothing
if (info?.CommonDiscInfo?.Media == null || info?.SizeAndChecksums == null)
if (info.CommonDiscInfo.Media == null || info.SizeAndChecksums == default)
return;
switch (info.CommonDiscInfo.Media)
@@ -39,13 +39,13 @@ namespace SabreTools.RedumpLib
info.CommonDiscInfo.Media = DiscType.BD128;
else if (info.SizeAndChecksums.Layerbreak2 != default)
info.CommonDiscInfo.Media = DiscType.BD100;
else if (info.SizeAndChecksums.Layerbreak != default && info.SizeAndChecksums.PICIdentifier == Models.PIC.Constants.DiscTypeIdentifierROMUltra)
else if (info.SizeAndChecksums.Layerbreak != default && info.SizeAndChecksums.PICIdentifier == "BDU")
info.CommonDiscInfo.Media = DiscType.BD66;
else if (info.SizeAndChecksums.Layerbreak != default && info.SizeAndChecksums.Size > 50_050_629_632)
info.CommonDiscInfo.Media = DiscType.BD66;
else if (info.SizeAndChecksums.Layerbreak != default)
info.CommonDiscInfo.Media = DiscType.BD50;
else if (info.SizeAndChecksums.PICIdentifier == Models.PIC.Constants.DiscTypeIdentifierROMUltra)
else if (info.SizeAndChecksums.PICIdentifier == "BDU")
info.CommonDiscInfo.Media = DiscType.BD33;
else if (info.SizeAndChecksums.Size > 25_025_314_816)
info.CommonDiscInfo.Media = DiscType.BD33;
@@ -157,12 +157,11 @@ namespace SabreTools.RedumpLib
/// </summary>
/// <param name="rc">RedumpClient for making the connection</param>
/// <param name="info">Existing SubmissionInfo object to fill</param>
/// <param name="resultProgress">Optional result progress callback</param>
/// <returns>List of found values, if possible</returns>
public async static Task<List<int>?> ValidateUniversalHash(RedumpClient rc, SubmissionInfo info)
{
// If we don't have special fields
if (info.CommonDiscInfo?.CommentsSpecialFields == null)
if (info.CommonDiscInfo.CommentsSpecialFields == null)
return null;
// If we don't have a universal hash
@@ -171,7 +170,11 @@ namespace SabreTools.RedumpLib
return null;
// Format the universal hash for finding within the comments
#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER
string universalHashQuery = $"{universalHash[..^1]}/comments/only";
#else
string universalHashQuery = $"{universalHash.Substring(0, universalHash.Length - 1)}/comments/only";
#endif
// Get all matching IDs for the hash
var newIds = await ListSearchResults(rc, universalHashQuery, filterForwardSlashes: false);

View File

@@ -6,6 +6,11 @@ namespace SabreTools.RedumpLib.Web
{
internal class CookieWebClient : WebClient
{
/// <summary>
/// The timespan to wait before the request times out.
/// </summary>
public TimeSpan Timeout { get; set; }
// https://stackoverflow.com/questions/1777221/using-cookiecontainer-with-webclient-class
private readonly CookieContainer _container = new();
@@ -24,7 +29,11 @@ namespace SabreTools.RedumpLib.Web
return null;
// Extract the filename from the value
#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER
return headerValue[(headerValue.IndexOf("filename=") + 9)..].Replace("\"", "");
#else
return headerValue.Substring(headerValue.IndexOf("filename=") + 9).Replace("\"", "");
#endif
}
/// <inheritdoc/>
@@ -33,11 +42,11 @@ namespace SabreTools.RedumpLib.Web
WebRequest request = base.GetWebRequest(address);
if (request is HttpWebRequest webRequest)
{
webRequest.Timeout = 30 * 1000; // 30 seconds
webRequest.Timeout = (int)Timeout.TotalMilliseconds;
webRequest.CookieContainer = _container;
}
return request;
}
}
}
}

View File

@@ -18,4 +18,4 @@ namespace SabreTools.RedumpLib.Web
Thread.Sleep(delay * 100);
}
}
}
}

View File

@@ -62,4 +62,4 @@ namespace SabreTools.RedumpLib.Web
return ids;
}
}
}
}

View File

@@ -68,4 +68,4 @@ namespace SabreTools.RedumpLib.Web
return true;
}
}
}
}

View File

@@ -31,15 +31,20 @@ namespace SabreTools.RedumpLib.Web
/// <summary>
/// Maximum retry count for any operation
/// </summary>
public int RetryCount { get; private set; } = 3;
public int RetryCount { get; }
/// <summary>
/// Maximum number of seconds for a retry
/// </summary>
public int TimeoutSeconds { get; }
/// <summary>
/// Internal client for interaction
/// </summary>
#if NETFRAMEWORK
private CookieWebClient _internalClient;
#if NETFRAMEWORK || NETSTANDARD2_0_OR_GREATER
private readonly CookieWebClient _internalClient;
#else
private HttpClient _internalClient;
private readonly HttpClient _internalClient;
#endif
#endregion
@@ -47,25 +52,24 @@ namespace SabreTools.RedumpLib.Web
/// <summary>
/// Constructor
/// </summary>
public RedumpClient()
{
#if NETFRAMEWORK
_internalClient = new CookieWebClient();
#else
_internalClient = new HttpClient(new HttpClientHandler { UseCookies = true }) { Timeout = TimeSpan.FromSeconds(30) };
#endif
}
/// <summary>
/// Constructor
/// </summary>
public RedumpClient(int retryCount) : this()
public RedumpClient(int retryCount = 3, int timeoutSeconds = 30)
{
// Ensure there are a positive number of retries
if (retryCount <= 0)
retryCount = 3;
// Ensure a positive timespan
if (timeoutSeconds <= 0)
timeoutSeconds = 30;
RetryCount = retryCount;
TimeoutSeconds = timeoutSeconds;
#if NETFRAMEWORK || NETSTANDARD2_0_OR_GREATER
_internalClient = new CookieWebClient() { Timeout = TimeSpan.FromSeconds(TimeoutSeconds) };
#else
_internalClient = new HttpClient(new HttpClientHandler { UseCookies = true }) { Timeout = TimeSpan.FromSeconds(TimeoutSeconds) };
#endif
}
#region Credentials
@@ -131,7 +135,7 @@ namespace SabreTools.RedumpLib.Web
var loginPage = await DownloadString(Constants.LoginUrl);
string token = Constants.TokenRegex.Match(loginPage ?? string.Empty).Groups[1].Value;
#if NETFRAMEWORK
#if NETFRAMEWORK || NETSTANDARD2_0_OR_GREATER
// Construct the login request
_internalClient.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
_internalClient.Encoding = Encoding.UTF8;
@@ -205,7 +209,7 @@ namespace SabreTools.RedumpLib.Web
{
#if NET40
return await Task.Factory.StartNew(() => _internalClient.DownloadData(uri));
#elif NETFRAMEWORK
#elif NETFRAMEWORK || NETSTANDARD2_0_OR_GREATER
return await Task.Run(() => _internalClient.DownloadData(uri));
#else
return await _internalClient.GetByteArrayAsync(uri);
@@ -231,7 +235,7 @@ namespace SabreTools.RedumpLib.Web
#if NET40
await Task.Factory.StartNew(() => { _internalClient.DownloadFile(uri, fileName); return true; });
return _internalClient.GetLastFilename();
#elif NETFRAMEWORK
#elif NETFRAMEWORK || NETSTANDARD2_0_OR_GREATER
await Task.Run(() => _internalClient.DownloadFile(uri, fileName));
return _internalClient.GetLastFilename();
#else
@@ -271,7 +275,7 @@ namespace SabreTools.RedumpLib.Web
{
#if NET40
return await Task.Factory.StartNew(() => _internalClient.DownloadString(uri));
#elif NETFRAMEWORK
#elif NETFRAMEWORK || NETSTANDARD2_0_OR_GREATER
return await Task.Run(() => _internalClient.DownloadString(uri));
#else
return await _internalClient.GetStringAsync(uri);
@@ -362,10 +366,11 @@ namespace SabreTools.RedumpLib.Web
var value = Regex.Match(dumpsPage, @"/disc/(\d+)/sfv/").Groups[1].Value;
if (int.TryParse(value, out int id))
{
ids.Add(id);
bool downloaded = await DownloadSingleSiteID(id, outDir, false);
if (!downloaded && failOnSingle)
return ids;
ids.Add(id);
}
return ids;
@@ -382,10 +387,11 @@ namespace SabreTools.RedumpLib.Web
{
if (int.TryParse(match.Groups[1].Value, out int value))
{
ids.Add(value);
bool downloaded = await DownloadSingleSiteID(value, outDir, false);
if (!downloaded && failOnSingle)
return ids;
ids.Add(value);
}
}
catch (Exception ex)
@@ -497,7 +503,7 @@ namespace SabreTools.RedumpLib.Web
{
#if NET40
return await Task.Factory.StartNew(() => _internalClient.DownloadData(string.Format(url, system.ShortName())));
#elif NETFRAMEWORK
#elif NETFRAMEWORK || NETSTANDARD2_0_OR_GREATER
return await Task.Run(() => _internalClient.DownloadData(string.Format(url, system.ShortName())));
#else
return await _internalClient.GetByteArrayAsync(string.Format(url, system.ShortName()));
@@ -861,7 +867,7 @@ namespace SabreTools.RedumpLib.Web
/// <summary>
/// Download a set of packs
/// </summary>
/// </summary>
/// <param name="url">Base URL to download using</param>
/// <param name="systems">Systems to download packs for</param>
/// <param name="title">Name of the pack that is downloading</param>
@@ -928,4 +934,4 @@ namespace SabreTools.RedumpLib.Web
#endregion
}
}
}

View File

@@ -99,4 +99,4 @@ namespace SabreTools.RedumpLib.Web
return ids;
}
}
}
}

View File

@@ -69,7 +69,7 @@ namespace SabreTools.RedumpLib.Web
return ids;
}
/// <summary>
/// List the disc IDs associated with the given user
/// </summary>
@@ -107,4 +107,4 @@ namespace SabreTools.RedumpLib.Web
return ids;
}
}
}
}

View File

@@ -49,4 +49,4 @@ namespace SabreTools.RedumpLib.Web
return ids;
}
}
}
}

View File

@@ -1,7 +1,7 @@
#! /bin/bash
# This batch file assumes the following:
# - .NET 9.0 (or newer) SDK is installed and in PATH
# - .NET 10.0 (or newer) SDK is installed and in PATH
#
# If any of these are not satisfied, the operation may fail
# in an unpredictable way and result in an incomplete output.
@@ -47,19 +47,19 @@ echo " No archive (-a) $NO_ARCHIVE"
echo " "
# Create the build matrix arrays
FRAMEWORKS=("net9.0")
FRAMEWORKS=("net10.0")
RUNTIMES=("win-x86" "win-x64" "win-arm64" "linux-x64" "linux-arm64" "osx-x64" "osx-arm64")
# Use expanded lists, if requested
if [ $USE_ALL = true ]
then
FRAMEWORKS=("net20" "net35" "net40" "net452" "net462" "net472" "net48" "netcoreapp3.1" "net5.0" "net6.0" "net7.0" "net8.0" "net9.0")
FRAMEWORKS=("net20" "net35" "net40" "net452" "net462" "net472" "net48" "netcoreapp3.1" "net5.0" "net6.0" "net7.0" "net8.0" "net9.0" "net10.0")
fi
# Create the filter arrays
SINGLE_FILE_CAPABLE=("net5.0" "net6.0" "net7.0" "net8.0" "net9.0")
VALID_APPLE_FRAMEWORKS=("net6.0" "net7.0" "net8.0" "net9.0")
VALID_CROSS_PLATFORM_FRAMEWORKS=("netcoreapp3.1" "net5.0" "net6.0" "net7.0" "net8.0" "net9.0")
SINGLE_FILE_CAPABLE=("net5.0" "net6.0" "net7.0" "net8.0" "net9.0" "net10.0")
VALID_APPLE_FRAMEWORKS=("net6.0" "net7.0" "net8.0" "net9.0" "net10.0")
VALID_CROSS_PLATFORM_FRAMEWORKS=("netcoreapp3.1" "net5.0" "net6.0" "net7.0" "net8.0" "net9.0" "net10.0")
VALID_CROSS_PLATFORM_RUNTIMES=("win-arm64" "linux-x64" "linux-arm64" "osx-x64" "osx-arm64")
# Only build if requested

View File

@@ -1,5 +1,5 @@
# This batch file assumes the following:
# - .NET 9.0 (or newer) SDK is installed and in PATH
# - .NET 10.0 (or newer) SDK is installed and in PATH
#
# If any of these are not satisfied, the operation may fail
# in an unpredictable way and result in an incomplete output.
@@ -38,19 +38,19 @@ Write-Host " No archive (-NoArchive) $NO_ARCHIVE"
Write-Host " "
# Create the build matrix arrays
$FRAMEWORKS = @('net9.0')
$FRAMEWORKS = @('net10.0')
$RUNTIMES = @('win-x86', 'win-x64', 'win-arm64', 'linux-x64', 'linux-arm64', 'osx-x64', 'osx-arm64')
# Use expanded lists, if requested
if ($USE_ALL.IsPresent)
{
$FRAMEWORKS = @('net20', 'net35', 'net40', 'net452', 'net462', 'net472', 'net48', 'netcoreapp3.1', 'net5.0', 'net6.0', 'net7.0', 'net8.0', 'net9.0')
$FRAMEWORKS = @('net20', 'net35', 'net40', 'net452', 'net462', 'net472', 'net48', 'netcoreapp3.1', 'net5.0', 'net6.0', 'net7.0', 'net8.0', 'net9.0', 'net10.0')
}
# Create the filter arrays
$SINGLE_FILE_CAPABLE = @('net5.0', 'net6.0', 'net7.0', 'net8.0', 'net9.0')
$VALID_APPLE_FRAMEWORKS = @('net6.0', 'net7.0', 'net8.0', 'net9.0')
$VALID_CROSS_PLATFORM_FRAMEWORKS = @('netcoreapp3.1', 'net5.0', 'net6.0', 'net7.0', 'net8.0', 'net9.0')
$SINGLE_FILE_CAPABLE = @('net5.0', 'net6.0', 'net7.0', 'net8.0', 'net9.0', 'net10.0')
$VALID_APPLE_FRAMEWORKS = @('net6.0', 'net7.0', 'net8.0', 'net9.0', 'net10.0')
$VALID_CROSS_PLATFORM_FRAMEWORKS = @('netcoreapp3.1', 'net5.0', 'net6.0', 'net7.0', 'net8.0', 'net9.0', 'net10.0')
$VALID_CROSS_PLATFORM_RUNTIMES = @('win-arm64', 'linux-x64', 'linux-arm64', 'osx-x64', 'osx-arm64')
# Only build if requested