mirror of
https://github.com/SabreTools/SabreTools.RedumpLib.git
synced 2026-02-09 05:35:38 +00:00
Compare commits
63 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
97ea30228e | ||
|
|
675af1a619 | ||
|
|
28c3f54cc5 | ||
|
|
51486950fa | ||
|
|
1b1ba94247 | ||
|
|
c4345d0c34 | ||
|
|
b88b877672 | ||
|
|
f0c5375ac5 | ||
|
|
1f4cca7fa0 | ||
|
|
5161913d96 | ||
|
|
c10b21a485 | ||
|
|
99adad582c | ||
|
|
6956617386 | ||
|
|
b5522c5bb0 | ||
|
|
889cedb87a | ||
|
|
eba722b23a | ||
|
|
5d77af7e97 | ||
|
|
d9cb9394e0 | ||
|
|
dfb5ac762a | ||
|
|
2459165990 | ||
|
|
e16ffcb78a | ||
|
|
da27675588 | ||
|
|
0021c7653c | ||
|
|
091a32b223 | ||
|
|
f29a50c3b0 | ||
|
|
edf6e12371 | ||
|
|
146b2780c5 | ||
|
|
60ce7cbfa0 | ||
|
|
39fe46a162 | ||
|
|
a8674a21e4 | ||
|
|
65f2d53a3f | ||
|
|
0bc869543a | ||
|
|
aa7d513d2c | ||
|
|
3d35129529 | ||
|
|
ec563938ba | ||
|
|
f0f3a1a194 | ||
|
|
55f5262198 | ||
|
|
1d247b1f6f | ||
|
|
32c57736ae | ||
|
|
8ab312ba8b | ||
|
|
3ea01ca933 | ||
|
|
27d99f7429 | ||
|
|
8b147f2041 | ||
|
|
9c7a143d52 | ||
|
|
30bbef7bba | ||
|
|
17da564b00 | ||
|
|
073176cccb | ||
|
|
0434e63e34 | ||
|
|
2b75eb44cd | ||
|
|
10eecc866e | ||
|
|
84fa2f93ea | ||
|
|
5a92c0fc98 | ||
|
|
4ffc1b3160 | ||
|
|
ffa8f2b16e | ||
|
|
70e3e074cc | ||
|
|
4858b4e459 | ||
|
|
9495cd32c7 | ||
|
|
071571870e | ||
|
|
f03cd40181 | ||
|
|
ea51726645 | ||
|
|
f0633d5aa7 | ||
|
|
4c076aec0c | ||
|
|
2ec9d6a4a0 |
@@ -1,4 +1,4 @@
|
||||
name: Nuget Pack
|
||||
name: Build and Test
|
||||
|
||||
on:
|
||||
push:
|
||||
@@ -12,35 +12,26 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: 9.0.x
|
||||
|
||||
- name: Restore dependencies
|
||||
run: dotnet restore
|
||||
|
||||
- name: Build library
|
||||
run: dotnet build
|
||||
dotnet-version: |
|
||||
6.0.x
|
||||
8.0.x
|
||||
9.0.x
|
||||
|
||||
- name: Run tests
|
||||
run: dotnet test
|
||||
|
||||
- name: Pack
|
||||
run: dotnet pack
|
||||
|
||||
- name: Upload build
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: 'Nuget Package'
|
||||
path: 'SabreTools.RedumpLib/bin/Release/*.nupkg'
|
||||
- name: Run publish script
|
||||
run: ./publish-nix.sh -d
|
||||
|
||||
- name: Upload to rolling
|
||||
uses: ncipollo/release-action@v1.14.0
|
||||
with:
|
||||
allowUpdates: True
|
||||
artifacts: 'SabreTools.RedumpLib/bin/Release/*.nupkg'
|
||||
artifacts: "*.nupkg,*.snupkg"
|
||||
body: 'Last built commit: ${{ github.sha }}'
|
||||
name: 'Rolling Release'
|
||||
prerelease: True
|
||||
7
.github/workflows/check_pr.yml
vendored
7
.github/workflows/check_pr.yml
vendored
@@ -11,10 +11,13 @@ jobs:
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: 9.0.x
|
||||
dotnet-version: |
|
||||
6.0.x
|
||||
8.0.x
|
||||
9.0.x
|
||||
|
||||
- name: Build
|
||||
run: dotnet build
|
||||
|
||||
- name: Run tests
|
||||
run: dotnet test
|
||||
run: dotnet test
|
||||
|
||||
7
LICENSE
Normal file
7
LICENSE
Normal 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.
|
||||
@@ -1,5 +1,13 @@
|
||||
# SabreTools.RedumpLib
|
||||
|
||||
[](https://github.com/SabreTools/SabreTools.RedumpLib/actions/workflows/build_and_test.yml)
|
||||
|
||||
This library comprises interaction logic for [Redump](http://redump.org/). Because there is no formal API for the site, this library interacts with the site through normal HTTP methods. It includes a fairly comprehensive reference of supported parts of the site, including URLs, page information, and packs.
|
||||
|
||||
Find the link to the Nuget package [here](https://www.nuget.org/packages/SabreTools.RedumpLib).
|
||||
|
||||
## Releases
|
||||
|
||||
For the most recent stable build, download the latest release here: [Releases Page](https://github.com/SabreTools/SabreTools.RedumpLib/releases)
|
||||
|
||||
For the latest WIP build here: [Rolling Release](https://github.com/SabreTools/SabreTools.RedumpLib/releases/rolling)
|
||||
|
||||
278
RedumpTool/Program.cs
Normal file
278
RedumpTool/Program.cs
Normal file
@@ -0,0 +1,278 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using SabreTools.RedumpLib;
|
||||
using SabreTools.RedumpLib.Data;
|
||||
|
||||
namespace RedumpTool
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
// Show help if nothing is input
|
||||
if (args == null || args.Length == 0)
|
||||
{
|
||||
ShowHelp();
|
||||
return;
|
||||
}
|
||||
|
||||
// Derive the feature, if possible
|
||||
Feature feature = DeriveFeature(args[0]);
|
||||
if (feature == Feature.NONE)
|
||||
{
|
||||
ShowHelp();
|
||||
return;
|
||||
}
|
||||
|
||||
// Create a new Downloader
|
||||
var downloader = CreateDownloader(feature, args);
|
||||
if (downloader == null)
|
||||
{
|
||||
ShowHelp();
|
||||
return;
|
||||
}
|
||||
|
||||
// Run the download task
|
||||
var downloaderTask = downloader.Download();
|
||||
downloaderTask.Wait();
|
||||
|
||||
// Get the downloader task results and print, if necessary
|
||||
var downloaderResult = downloaderTask.Result;
|
||||
if (downloaderResult.Count > 0)
|
||||
{
|
||||
string processedIds = string.Join(", ", [.. downloaderResult.ConvertAll(i => i.ToString())]);
|
||||
Console.WriteLine($"Processed IDs: {processedIds}");
|
||||
}
|
||||
else if (downloaderResult.Count == 0 && downloader.Feature != Feature.Packs)
|
||||
{
|
||||
ShowHelp();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Derive the feature from the supplied argument
|
||||
/// </summary>
|
||||
/// <param name="feature">Possible feature name to derive from</param>
|
||||
/// <returns>True if the feature was set, false otherwise</returns>
|
||||
private static Feature DeriveFeature(string feature)
|
||||
{
|
||||
return feature.ToLowerInvariant() switch
|
||||
{
|
||||
"site" => Feature.Site,
|
||||
"wip" => Feature.WIP,
|
||||
"packs" => Feature.Packs,
|
||||
"user" => Feature.User,
|
||||
"search" => Feature.Quicksearch,
|
||||
"query" => Feature.Quicksearch,
|
||||
_ => Feature.NONE,
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a Downloader from a feature and a set of arguments
|
||||
/// </summary>
|
||||
/// <param name="feature">Primary feature to use</param>
|
||||
/// <param name="args">Arguments list to parse</param>
|
||||
/// <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
|
||||
try
|
||||
{
|
||||
for (int i = 1; i < args.Length; i++)
|
||||
{
|
||||
switch (args[i])
|
||||
{
|
||||
// Output directory
|
||||
case "-o":
|
||||
case "--output":
|
||||
outDir = args[++i].Trim('"');
|
||||
break;
|
||||
|
||||
// Username
|
||||
case "-u":
|
||||
case "--username":
|
||||
username = args[++i];
|
||||
break;
|
||||
|
||||
// Password
|
||||
case "-p":
|
||||
case "--password":
|
||||
password = args[++i];
|
||||
break;
|
||||
|
||||
// Minimum Redump ID
|
||||
case "-min":
|
||||
case "--minimum":
|
||||
if (!int.TryParse(args[++i], out minimumId))
|
||||
minimumId = -1;
|
||||
break;
|
||||
|
||||
// Maximum Redump ID
|
||||
case "-max":
|
||||
case "--maximum":
|
||||
if (!int.TryParse(args[++i], out maximumId))
|
||||
maximumId = -1;
|
||||
break;
|
||||
|
||||
// Quicksearch text
|
||||
case "-q":
|
||||
case "--query":
|
||||
queryString = args[++i];
|
||||
break;
|
||||
|
||||
// Packs subfolders
|
||||
case "-s":
|
||||
case "--subfolders":
|
||||
useSubfolders = true;
|
||||
break;
|
||||
|
||||
// Use last modified
|
||||
case "-n":
|
||||
case "--onlynew":
|
||||
onlyNew = true;
|
||||
break;
|
||||
|
||||
// List instead of download
|
||||
case "-l":
|
||||
case "--list":
|
||||
onlyList = true;
|
||||
break;
|
||||
|
||||
// Don't filter forward slashes from queries
|
||||
case "-ns":
|
||||
case "--noslash":
|
||||
noSlash = true;
|
||||
break;
|
||||
|
||||
// Force continuation
|
||||
case "-f":
|
||||
case "--force":
|
||||
force = true;
|
||||
break;
|
||||
|
||||
// Everything else
|
||||
default:
|
||||
Console.WriteLine($"Unrecognized flag: {args[i]}");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"An exception has occurred: {ex}");
|
||||
return null;
|
||||
}
|
||||
|
||||
// Output directory validation
|
||||
if (!onlyList && string.IsNullOrEmpty(outDir))
|
||||
{
|
||||
Console.WriteLine("No output directory set!");
|
||||
return null;
|
||||
}
|
||||
else if (!onlyList && !string.IsNullOrEmpty(outDir))
|
||||
{
|
||||
// Create the output directory, if it doesn't exist
|
||||
try
|
||||
{
|
||||
if (!Directory.Exists(outDir))
|
||||
Directory.CreateDirectory(outDir);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"An exception has occurred: {ex}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Range verification
|
||||
if (feature == Feature.Site && !onlyNew && (minimumId < 0 || maximumId < 0))
|
||||
{
|
||||
Console.WriteLine("Please enter a valid range of Redump IDs");
|
||||
return null;
|
||||
}
|
||||
else if (feature == Feature.WIP && !onlyNew && (minimumId < 0 || 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))
|
||||
{
|
||||
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 downloader;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Show the commandline help for the program
|
||||
/// </summary>
|
||||
private static void ShowHelp()
|
||||
{
|
||||
Console.WriteLine("RedumpTool - A Redump.org recovery tool");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("Usage: RedumpTool <feature> [options]");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("Common Options");
|
||||
Console.WriteLine(" -o <folder>, --output <folder> - Set the base output directory");
|
||||
Console.WriteLine(" -u <username>, --username <username> - Redump username");
|
||||
Console.WriteLine(" -p <pass>, --password <pass> - Redump password");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("site - Download pages and related files from the main site");
|
||||
Console.WriteLine(" -min <MinId>, --minimum <MinId> - Lower bound for page numbers (cannot be used with only new)");
|
||||
Console.WriteLine(" -max <MaxId>, --maximum <MaxId> - Upper bound for page numbers (cannot be used with only new)");
|
||||
Console.WriteLine(" -n, --onlynew - Use the last modified view (cannot be used with min and max)");
|
||||
Console.WriteLine(" -f, --force - Force continuing downloads until user cancels (used with only new)");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("wip - Download pages and related files from the WIP list");
|
||||
Console.WriteLine(" -min <MinId>, --minimum <MinId> - Lower bound for page numbers (cannot be used with only new)");
|
||||
Console.WriteLine(" -max <MaxId>, --maximum <MaxId> - Upper bound for page numbers (cannot be used with only new)");
|
||||
Console.WriteLine(" -n, --onlynew - Use the last modified view (cannot be used with min and max)");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("packs - Download available packs");
|
||||
Console.WriteLine(" -s, --subfolders - Download packs to named subfolders");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("user - Download pages and related files for a particular user");
|
||||
Console.WriteLine(" -n, --onlynew - Use the last modified view instead of sequential parsing");
|
||||
Console.WriteLine(" -l, --list - Only list the page IDs for that user");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("query - Download pages and related files from a Redump-compatible query");
|
||||
Console.WriteLine(" -q, --query - Redump-compatible query to run");
|
||||
Console.WriteLine(" -l, --list - Only list the page IDs for that query");
|
||||
Console.WriteLine(" -ns, --noslash - Don't replace forward slashes with '-'");
|
||||
Console.WriteLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
33
RedumpTool/RedumpTool.csproj
Normal file
33
RedumpTool/RedumpTool.csproj
Normal file
@@ -0,0 +1,33 @@
|
||||
<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>
|
||||
<OutputType>Exe</OutputType>
|
||||
<CheckEolTargetFramework>false</CheckEolTargetFramework>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<Version>1.7.5</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Support All Frameworks -->
|
||||
<PropertyGroup Condition="$(TargetFramework.StartsWith(`net2`)) OR $(TargetFramework.StartsWith(`net3`)) OR $(TargetFramework.StartsWith(`net4`))">
|
||||
<RuntimeIdentifiers>win-x86;win-x64</RuntimeIdentifiers>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="$(TargetFramework.StartsWith(`netcoreapp`)) OR $(TargetFramework.StartsWith(`net5`))">
|
||||
<RuntimeIdentifiers>win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64</RuntimeIdentifiers>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="$(TargetFramework.StartsWith(`net6`)) OR $(TargetFramework.StartsWith(`net7`)) OR $(TargetFramework.StartsWith(`net8`)) OR $(TargetFramework.StartsWith(`net9`))">
|
||||
<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>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\SabreTools.RedumpLib\SabreTools.RedumpLib.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using SabreTools.RedumpLib.Data;
|
||||
using Xunit;
|
||||
|
||||
namespace SabreTools.RedumpLib.Test
|
||||
@@ -10,7 +11,7 @@ namespace SabreTools.RedumpLib.Test
|
||||
{
|
||||
[Theory]
|
||||
[InlineData("success_complete.json", false)]
|
||||
[InlineData("success_invalid.json", false)] // Fully in valid returns a default object
|
||||
[InlineData("success_invalid.json", false)] // Fully invalid returns a default object
|
||||
[InlineData("success_partial.json", false)]
|
||||
[InlineData("fail_invalid.json", true)]
|
||||
public void CreateFromFileTest(string filename, bool expectNull)
|
||||
@@ -24,5 +25,167 @@ namespace SabreTools.RedumpLib.Test
|
||||
// Check for an expected result
|
||||
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()
|
||||
{
|
||||
SubmissionInfo? si = null;
|
||||
SubmissionInfo? seed = null;
|
||||
|
||||
var actual = Builder.InjectSubmissionInformation(si, seed);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InjectSubmissionInformation_ValidInputNullSeed_Valid()
|
||||
{
|
||||
SubmissionInfo? si = new SubmissionInfo();
|
||||
SubmissionInfo? seed = null;
|
||||
|
||||
var actual = Builder.InjectSubmissionInformation(si, seed);
|
||||
Assert.NotNull(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InjectSubmissionInformation_BothValid_Valid()
|
||||
{
|
||||
SubmissionInfo? si = new SubmissionInfo();
|
||||
SubmissionInfo? seed = new SubmissionInfo();
|
||||
|
||||
var actual = Builder.InjectSubmissionInformation(si, seed);
|
||||
Assert.NotNull(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReplaceHtmlWithSiteCodes_EmptyString_Empty()
|
||||
{
|
||||
string original = string.Empty;
|
||||
string actual = Builder.ReplaceHtmlWithSiteCodes(original);
|
||||
Assert.Empty(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReplaceHtmlWithSiteCodes_NoReplace_Identical()
|
||||
{
|
||||
string original = "<p>Nothing here will be replaced</p>";
|
||||
string actual = Builder.ReplaceHtmlWithSiteCodes(original);
|
||||
Assert.Equal(original, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReplaceHtmlWithSiteCodes_StandardCode_Replaced()
|
||||
{
|
||||
string original = "<b>ISBN</b>: 000-0-00-000000-0";
|
||||
string expected = "[T:ISBN] 000-0-00-000000-0";
|
||||
|
||||
string actual = Builder.ReplaceHtmlWithSiteCodes(original);
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReplaceHtmlWithSiteCodes_OutdatedCode_Replaced()
|
||||
{
|
||||
string original = "XMID: AB12345C";
|
||||
string expected = "<b>XMID</b>: AB12345C";
|
||||
|
||||
string actual = Builder.ReplaceHtmlWithSiteCodes(original);
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
2304
SabreTools.RedumpLib.Test/Data/ExtensionsTests.cs
Normal file
2304
SabreTools.RedumpLib.Test/Data/ExtensionsTests.cs
Normal file
File diff suppressed because it is too large
Load Diff
8
SabreTools.RedumpLib.Test/DownloaderTests.cs
Normal file
8
SabreTools.RedumpLib.Test/DownloaderTests.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace SabreTools.RedumpLib.Test
|
||||
{
|
||||
public class DownloaderTests
|
||||
{
|
||||
// Tests here will require installing and using the Moq library
|
||||
// to mock the RedumpClient type.
|
||||
}
|
||||
}
|
||||
@@ -1,201 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using SabreTools.RedumpLib.Data;
|
||||
using Xunit;
|
||||
|
||||
namespace SabreTools.RedumpLib.Test
|
||||
{
|
||||
public class EnumExtensionsTests
|
||||
{
|
||||
/// <summary>
|
||||
/// MediaType values that support drive speeds
|
||||
/// </summary>
|
||||
private static readonly MediaType?[] _supportDriveSpeeds =
|
||||
[
|
||||
MediaType.CDROM,
|
||||
MediaType.DVD,
|
||||
MediaType.GDROM,
|
||||
MediaType.HDDVD,
|
||||
MediaType.BluRay,
|
||||
MediaType.NintendoGameCubeGameDisc,
|
||||
MediaType.NintendoWiiOpticalDisc,
|
||||
];
|
||||
|
||||
/// <summary>
|
||||
/// RedumpSystem values that are considered Audio
|
||||
/// </summary>
|
||||
private static readonly RedumpSystem?[] _audioSystems =
|
||||
[
|
||||
RedumpSystem.AtariJaguarCDInteractiveMultimediaSystem,
|
||||
RedumpSystem.AudioCD,
|
||||
RedumpSystem.DVDAudio,
|
||||
RedumpSystem.HasbroiONEducationalGamingSystem,
|
||||
RedumpSystem.HasbroVideoNow,
|
||||
RedumpSystem.HasbroVideoNowColor,
|
||||
RedumpSystem.HasbroVideoNowJr,
|
||||
RedumpSystem.HasbroVideoNowXP,
|
||||
RedumpSystem.PlayStationGameSharkUpdates,
|
||||
RedumpSystem.PhilipsCDi,
|
||||
RedumpSystem.SuperAudioCD,
|
||||
];
|
||||
|
||||
/// <summary>
|
||||
/// RedumpSystem values that are considered markers
|
||||
/// </summary>
|
||||
private static readonly RedumpSystem?[] _markerSystems =
|
||||
[
|
||||
RedumpSystem.MarkerArcadeEnd,
|
||||
RedumpSystem.MarkerComputerEnd,
|
||||
RedumpSystem.MarkerDiscBasedConsoleEnd,
|
||||
RedumpSystem.MarkerOtherEnd,
|
||||
];
|
||||
|
||||
/// <summary>
|
||||
/// RedumpSystem values that are have reversed ringcodes
|
||||
/// </summary>
|
||||
private static readonly RedumpSystem?[] _reverseRingcodeSystems =
|
||||
[
|
||||
RedumpSystem.SonyPlayStation2,
|
||||
RedumpSystem.SonyPlayStation3,
|
||||
RedumpSystem.SonyPlayStation4,
|
||||
RedumpSystem.SonyPlayStation5,
|
||||
RedumpSystem.SonyPlayStationPortable,
|
||||
];
|
||||
|
||||
/// <summary>
|
||||
/// RedumpSystem values that are considered XGD
|
||||
/// </summary>
|
||||
private static readonly RedumpSystem?[] _xgdSystems =
|
||||
[
|
||||
RedumpSystem.MicrosoftXbox,
|
||||
RedumpSystem.MicrosoftXbox360,
|
||||
RedumpSystem.MicrosoftXboxOne,
|
||||
RedumpSystem.MicrosoftXboxSeriesXS,
|
||||
];
|
||||
|
||||
/// <summary>
|
||||
/// Check that all systems with reversed ringcodes are marked properly
|
||||
/// </summary>
|
||||
/// <param name="redumpSystem">RedumpSystem value to check</param>
|
||||
/// <param name="expected">The expected value to come from the check</param>
|
||||
[Theory]
|
||||
[MemberData(nameof(GenerateReversedRingcodeSystemsTestData))]
|
||||
public void HasReversedRingcodesTest(RedumpSystem? redumpSystem, bool expected)
|
||||
{
|
||||
bool actual = redumpSystem.HasReversedRingcodes();
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check that all audio systems are marked properly
|
||||
/// </summary>
|
||||
/// <param name="redumpSystem">RedumpSystem value to check</param>
|
||||
/// <param name="expected">The expected value to come from the check</param>
|
||||
[Theory]
|
||||
[MemberData(nameof(GenerateAudioSystemsTestData))]
|
||||
public void IsAudioTest(RedumpSystem? redumpSystem, bool expected)
|
||||
{
|
||||
bool actual = redumpSystem.IsAudio();
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check that all marker systems are marked properly
|
||||
/// </summary>
|
||||
/// <param name="redumpSystem">RedumpSystem value to check</param>
|
||||
/// <param name="expected">The expected value to come from the check</param>
|
||||
[Theory]
|
||||
[MemberData(nameof(GenerateMarkerSystemsTestData))]
|
||||
public void IsMarkerTest(RedumpSystem? redumpSystem, bool expected)
|
||||
{
|
||||
bool actual = redumpSystem.IsMarker();
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check that all XGD systems are marked properly
|
||||
/// </summary>
|
||||
/// <param name="redumpSystem">RedumpSystem value to check</param>
|
||||
/// <param name="expected">The expected value to come from the check</param>
|
||||
[Theory]
|
||||
[MemberData(nameof(GenerateXGDSystemsTestData))]
|
||||
public void IsXGDTest(RedumpSystem? redumpSystem, bool expected)
|
||||
{
|
||||
bool actual = redumpSystem.IsXGD();
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generate a test set of RedumpSystem values that are considered Audio
|
||||
/// </summary>
|
||||
/// <returns>MemberData-compatible list of RedumpSystem values</returns>
|
||||
public static List<object?[]> GenerateAudioSystemsTestData()
|
||||
{
|
||||
var testData = new List<object?[]>() { new object?[] { null, false } };
|
||||
foreach (RedumpSystem redumpSystem in Enum.GetValues(typeof(RedumpSystem)))
|
||||
{
|
||||
if (_audioSystems.Contains(redumpSystem))
|
||||
testData.Add([redumpSystem, true]);
|
||||
else
|
||||
testData.Add([redumpSystem, false]);
|
||||
}
|
||||
|
||||
return testData;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generate a test set of RedumpSystem values that are considered markers
|
||||
/// </summary>
|
||||
/// <returns>MemberData-compatible list of RedumpSystem values</returns>
|
||||
public static List<object?[]> GenerateMarkerSystemsTestData()
|
||||
{
|
||||
var testData = new List<object?[]>() { new object?[] { null, false } };
|
||||
foreach (RedumpSystem redumpSystem in Enum.GetValues(typeof(RedumpSystem)))
|
||||
{
|
||||
if (_markerSystems.Contains(redumpSystem))
|
||||
testData.Add([redumpSystem, true]);
|
||||
else
|
||||
testData.Add([redumpSystem, false]);
|
||||
}
|
||||
|
||||
return testData;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generate a test set of RedumpSystem values that are considered markers
|
||||
/// </summary>
|
||||
/// <returns>MemberData-compatible list of RedumpSystem values</returns>
|
||||
public static List<object?[]> GenerateReversedRingcodeSystemsTestData()
|
||||
{
|
||||
var testData = new List<object?[]>() { new object?[] { null, false } };
|
||||
foreach (RedumpSystem redumpSystem in Enum.GetValues(typeof(RedumpSystem)))
|
||||
{
|
||||
if (_reverseRingcodeSystems.Contains(redumpSystem))
|
||||
testData.Add([redumpSystem, true]);
|
||||
else
|
||||
testData.Add([redumpSystem, false]);
|
||||
}
|
||||
|
||||
return testData;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generate a test set of RedumpSystem values that are considered XGD
|
||||
/// </summary>
|
||||
/// <returns>MemberData-compatible list of RedumpSystem values</returns>
|
||||
public static List<object?[]> GenerateXGDSystemsTestData()
|
||||
{
|
||||
var testData = new List<object?[]>() { new object?[] { null, false } };
|
||||
foreach (RedumpSystem redumpSystem in Enum.GetValues(typeof(RedumpSystem)))
|
||||
{
|
||||
if (_xgdSystems.Contains(redumpSystem))
|
||||
testData.Add([redumpSystem, true]);
|
||||
else
|
||||
testData.Add([redumpSystem, false]);
|
||||
}
|
||||
|
||||
return testData;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,717 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using SabreTools.RedumpLib.Data;
|
||||
using Xunit;
|
||||
|
||||
namespace SabreTools.RedumpLib.Test
|
||||
{
|
||||
// TODO: Add tests for string-to-enum conversion
|
||||
public class ExtensionsTests
|
||||
{
|
||||
#region Cross-Enumeration
|
||||
|
||||
/// <summary>
|
||||
/// DiscType values that map to MediaType
|
||||
/// </summary>
|
||||
private static readonly DiscType?[] _mappableDiscTypes =
|
||||
[
|
||||
DiscType.BD25,
|
||||
DiscType.BD33,
|
||||
DiscType.BD50,
|
||||
DiscType.BD66,
|
||||
DiscType.BD100,
|
||||
DiscType.BD128,
|
||||
DiscType.CD,
|
||||
DiscType.DVD5,
|
||||
DiscType.DVD9,
|
||||
DiscType.GDROM,
|
||||
DiscType.HDDVDSL,
|
||||
DiscType.HDDVDDL,
|
||||
DiscType.NintendoGameCubeGameDisc,
|
||||
DiscType.NintendoWiiOpticalDiscSL,
|
||||
DiscType.NintendoWiiOpticalDiscDL,
|
||||
DiscType.NintendoWiiUOpticalDiscSL,
|
||||
DiscType.UMDSL,
|
||||
DiscType.UMDDL,
|
||||
];
|
||||
|
||||
/// <summary>
|
||||
/// MediaType values that map to DiscType
|
||||
/// </summary>
|
||||
private static readonly MediaType?[] _mappableMediaTypes =
|
||||
[
|
||||
MediaType.BluRay,
|
||||
MediaType.CDROM,
|
||||
MediaType.DVD,
|
||||
MediaType.GDROM,
|
||||
MediaType.HDDVD,
|
||||
MediaType.NintendoGameCubeGameDisc,
|
||||
MediaType.NintendoWiiOpticalDisc,
|
||||
MediaType.NintendoWiiUOpticalDisc,
|
||||
MediaType.UMD,
|
||||
];
|
||||
|
||||
/// <summary>
|
||||
/// Check that every supported system has some set of MediaTypes supported
|
||||
/// </summary>
|
||||
/// <param name="redumpSystem">RedumpSystem value to check</param>
|
||||
[Theory]
|
||||
[MemberData(nameof(GenerateRedumpSystemMappingTestData))]
|
||||
public void MediaTypesTest(RedumpSystem? redumpSystem)
|
||||
{
|
||||
var actual = redumpSystem.MediaTypes();
|
||||
Assert.NotEmpty(actual);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check that both mappable and unmappable media types output correctly
|
||||
/// </summary>
|
||||
/// <param name="mediaType">MediaType value to check</param>
|
||||
/// <param name="expectNull">True to expect a null mapping, false otherwise</param>
|
||||
[Theory]
|
||||
[MemberData(nameof(GenerateMediaTypeMappingTestData))]
|
||||
public void ToDiscTypeTest(MediaType? mediaType, bool expectNull)
|
||||
{
|
||||
DiscType? actual = mediaType.ToDiscType();
|
||||
Assert.Equal(expectNull, actual == null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check that DiscType values all map to something appropriate
|
||||
/// </summary>
|
||||
/// <param name="discType">DiscType value to check</param>
|
||||
/// <param name="expectNull">True to expect a null mapping, false otherwise</param>
|
||||
[Theory]
|
||||
[MemberData(nameof(GenerateDiscTypeMappingTestData))]
|
||||
public void ToMediaTypeTest(DiscType? discType, bool expectNull)
|
||||
{
|
||||
MediaType? actual = discType.ToMediaType();
|
||||
Assert.Equal(expectNull, actual == null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generate a test set of DiscType values
|
||||
/// </summary>
|
||||
/// <returns>MemberData-compatible list of DiscType values</returns>
|
||||
public static List<object?[]> GenerateDiscTypeMappingTestData()
|
||||
{
|
||||
var testData = new List<object?[]>() { new object?[] { null, true } };
|
||||
foreach (DiscType? discType in Enum.GetValues(typeof(DiscType)))
|
||||
{
|
||||
if (_mappableDiscTypes.Contains(discType))
|
||||
testData.Add([discType, false]);
|
||||
else
|
||||
testData.Add([discType, true]);
|
||||
}
|
||||
|
||||
return testData;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generate a test set of RedumpSystem values
|
||||
/// </summary>
|
||||
/// <returns>MemberData-compatible list of RedumpSystem values</returns>
|
||||
public static List<object?[]> GenerateRedumpSystemMappingTestData()
|
||||
{
|
||||
var testData = new List<object?[]>() { new object?[] { null } };
|
||||
foreach (RedumpSystem? redumpSystem in Enum.GetValues(typeof(RedumpSystem)))
|
||||
{
|
||||
testData.Add([redumpSystem]);
|
||||
}
|
||||
|
||||
return testData;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generate a test set of mappable media types
|
||||
/// </summary>
|
||||
/// <returns>MemberData-compatible list of MediaTypes</returns>
|
||||
public static List<object?[]> GenerateMediaTypeMappingTestData()
|
||||
{
|
||||
var testData = new List<object?[]>() { new object?[] { null, true } };
|
||||
|
||||
foreach (MediaType? mediaType in Enum.GetValues(typeof(MediaType)))
|
||||
{
|
||||
if (_mappableMediaTypes.Contains(mediaType))
|
||||
testData.Add([mediaType, false]);
|
||||
else
|
||||
testData.Add([mediaType, true]);
|
||||
}
|
||||
|
||||
return testData;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Disc Category
|
||||
|
||||
/// <summary>
|
||||
/// Check that every DiscCategory has a long name provided
|
||||
/// </summary>
|
||||
/// <param name="discCategory">DiscCategory value to check</param>
|
||||
/// <param name="expectNull">True to expect a null value, false otherwise</param>
|
||||
[Theory]
|
||||
[MemberData(nameof(GenerateDiscCategoryTestData))]
|
||||
public void DiscCategoryLongNameTest(DiscCategory? discCategory, bool expectNull)
|
||||
{
|
||||
var actual = discCategory.LongName();
|
||||
|
||||
if (expectNull)
|
||||
Assert.Null(actual);
|
||||
else
|
||||
Assert.NotNull(actual);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generate a test set of DiscCategory values
|
||||
/// </summary>
|
||||
/// <returns>MemberData-compatible list of DiscCategory values</returns>
|
||||
public static List<object?[]> GenerateDiscCategoryTestData()
|
||||
{
|
||||
var testData = new List<object?[]>() { new object?[] { null, true } };
|
||||
foreach (DiscCategory? discCategory in Enum.GetValues(typeof(DiscCategory)))
|
||||
{
|
||||
testData.Add([discCategory, false]);
|
||||
}
|
||||
|
||||
return testData;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Disc Type
|
||||
|
||||
/// <summary>
|
||||
/// Check that every DiscType has a long name provided
|
||||
/// </summary>
|
||||
/// <param name="discType">DiscType value to check</param>
|
||||
/// <param name="expectNull">True to expect a null value, false otherwise</param>
|
||||
[Theory]
|
||||
[MemberData(nameof(GenerateDiscTypeTestData))]
|
||||
public void DiscTypeLongNameTest(DiscType? discType, bool expectNull)
|
||||
{
|
||||
var actual = discType.LongName();
|
||||
|
||||
if (expectNull)
|
||||
Assert.Null(actual);
|
||||
else
|
||||
Assert.NotNull(actual);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generate a test set of DiscType values
|
||||
/// </summary>
|
||||
/// <returns>MemberData-compatible list of DiscType values</returns>
|
||||
public static List<object?[]> GenerateDiscTypeTestData()
|
||||
{
|
||||
var testData = new List<object?[]>() { new object?[] { null, true } };
|
||||
foreach (DiscType? discType in Enum.GetValues(typeof(DiscType)))
|
||||
{
|
||||
if (discType == DiscType.NONE)
|
||||
testData.Add([discType, true]);
|
||||
else
|
||||
testData.Add([discType, false]);
|
||||
}
|
||||
|
||||
return testData;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Language
|
||||
|
||||
/// <summary>
|
||||
/// Check that every Language has a long name provided
|
||||
/// </summary>
|
||||
/// <param name="language">Language value to check</param>
|
||||
/// <param name="expectNull">True to expect a null value, false otherwise</param>
|
||||
[Theory]
|
||||
[MemberData(nameof(GenerateLanguageTestData))]
|
||||
public void LanguageLongNameTest(Language? language, bool expectNull)
|
||||
{
|
||||
var actual = language.LongName();
|
||||
|
||||
if (expectNull)
|
||||
Assert.Null(actual);
|
||||
else
|
||||
Assert.NotNull(actual);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check that every Language has a short name provided
|
||||
/// </summary>
|
||||
/// <param name="language">Language value to check</param>
|
||||
/// <param name="expectNull">True to expect a null value, false otherwise</param>
|
||||
[Theory]
|
||||
[MemberData(nameof(GenerateLanguageTestData))]
|
||||
public void LanguageShortNameTest(Language? language, bool expectNull)
|
||||
{
|
||||
var actual = language.ShortName();
|
||||
|
||||
if (expectNull)
|
||||
Assert.Null(actual);
|
||||
else
|
||||
Assert.NotNull(actual);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensure that every Language that has an ISO 639-1 code is unique
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void LanguageNoDuplicateTwoLetterCodeTest()
|
||||
{
|
||||
var fullLanguages = Enum.GetValues(typeof(Language)).Cast<Language?>().ToList();
|
||||
var filteredLanguages = new Dictionary<string, Language?>();
|
||||
|
||||
int totalCount = 0;
|
||||
foreach (Language? language in fullLanguages)
|
||||
{
|
||||
var code = language.TwoLetterCode();
|
||||
if (string.IsNullOrEmpty(code))
|
||||
continue;
|
||||
|
||||
// Throw if the code already exists
|
||||
if (filteredLanguages.ContainsKey(code))
|
||||
throw new DuplicateNameException($"Code {code} already in dictionary");
|
||||
|
||||
filteredLanguages[code] = language;
|
||||
totalCount++;
|
||||
}
|
||||
|
||||
Assert.Equal(totalCount, filteredLanguages.Count);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensure that every Language that has a standard/bibliographic ISO 639-2 code is unique
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void LanguageNoDuplicateThreeLetterCodeTest()
|
||||
{
|
||||
var fullLanguages = Enum.GetValues(typeof(Language)).Cast<Language?>().ToList();
|
||||
var filteredLanguages = new Dictionary<string, Language?>();
|
||||
|
||||
int totalCount = 0;
|
||||
foreach (Language? language in fullLanguages)
|
||||
{
|
||||
var code = language.ThreeLetterCode();
|
||||
if (string.IsNullOrEmpty(code))
|
||||
continue;
|
||||
|
||||
// Throw if the code already exists
|
||||
if (filteredLanguages.ContainsKey(code))
|
||||
throw new DuplicateNameException($"Code {code} already in dictionary");
|
||||
|
||||
filteredLanguages[code] = language;
|
||||
totalCount++;
|
||||
}
|
||||
|
||||
Assert.Equal(totalCount, filteredLanguages.Count);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensure that every Language that has a terminology ISO 639-2 code is unique
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void LanguageNoDuplicateThreeLetterCodeAltTest()
|
||||
{
|
||||
var fullLanguages = Enum.GetValues(typeof(Language)).Cast<Language?>().ToList();
|
||||
var filteredLanguages = new Dictionary<string, Language?>();
|
||||
|
||||
int totalCount = 0;
|
||||
foreach (Language? language in fullLanguages)
|
||||
{
|
||||
var code = language.ThreeLetterCodeAlt();
|
||||
if (string.IsNullOrEmpty(code))
|
||||
continue;
|
||||
|
||||
// Throw if the code already exists
|
||||
if (filteredLanguages.ContainsKey(code))
|
||||
throw new DuplicateNameException($"Code {code} already in dictionary");
|
||||
|
||||
filteredLanguages[code] = language;
|
||||
totalCount++;
|
||||
}
|
||||
|
||||
Assert.Equal(totalCount, filteredLanguages.Count);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generate a test set of Language values
|
||||
/// </summary>
|
||||
/// <returns>MemberData-compatible list of Language values</returns>
|
||||
public static List<object?[]> GenerateLanguageTestData()
|
||||
{
|
||||
var testData = new List<object?[]>() { new object?[] { null, true } };
|
||||
foreach (Language? language in Enum.GetValues(typeof(Language)))
|
||||
{
|
||||
testData.Add([language, false]);
|
||||
}
|
||||
|
||||
return testData;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Language Selection
|
||||
|
||||
/// <summary>
|
||||
/// Check that every LanguageSelection has a long name provided
|
||||
/// </summary>
|
||||
/// <param name="languageSelection">LanguageSelection value to check</param>
|
||||
/// <param name="expectNull">True to expect a null value, false otherwise</param>
|
||||
[Theory]
|
||||
[MemberData(nameof(GenerateLanguageSelectionTestData))]
|
||||
public void LanguageSelectionLongNameTest(LanguageSelection? languageSelection, bool expectNull)
|
||||
{
|
||||
var actual = languageSelection.LongName();
|
||||
|
||||
if (expectNull)
|
||||
Assert.Null(actual);
|
||||
else
|
||||
Assert.NotNull(actual);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generate a test set of LanguageSelection values
|
||||
/// </summary>
|
||||
/// <returns>MemberData-compatible list of LanguageSelection values</returns>
|
||||
public static List<object?[]> GenerateLanguageSelectionTestData()
|
||||
{
|
||||
var testData = new List<object?[]>() { new object?[] { null, true } };
|
||||
foreach (LanguageSelection? languageSelection in Enum.GetValues(typeof(LanguageSelection)))
|
||||
{
|
||||
testData.Add([languageSelection, false]);
|
||||
}
|
||||
|
||||
return testData;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Media Type
|
||||
|
||||
/// <summary>
|
||||
/// Check that every MediaType has a long name provided
|
||||
/// </summary>
|
||||
/// <param name="mediaType">MediaType value to check</param>
|
||||
/// <param name="expectNull">True to expect a null value, false otherwise</param>
|
||||
[Theory]
|
||||
[MemberData(nameof(GenerateMediaTypeTestData))]
|
||||
public void MediaTypeLongNameTest(MediaType? mediaType, bool expectNull)
|
||||
{
|
||||
var actual = mediaType.LongName();
|
||||
|
||||
if (expectNull)
|
||||
Assert.Null(actual);
|
||||
else
|
||||
Assert.NotNull(actual);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check that every MediaType has a short name provided
|
||||
/// </summary>
|
||||
/// <param name="mediaType">MediaType value to check</param>
|
||||
/// <param name="expectNull">True to expect a null value, false otherwise</param>
|
||||
[Theory]
|
||||
[MemberData(nameof(GenerateMediaTypeTestData))]
|
||||
public void MediaTypeShortNameTest(MediaType? mediaType, bool expectNull)
|
||||
{
|
||||
var actual = mediaType.ShortName();
|
||||
|
||||
if (expectNull)
|
||||
Assert.Null(actual);
|
||||
else
|
||||
Assert.NotNull(actual);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generate a test set of MediaType values
|
||||
/// </summary>
|
||||
/// <returns>MemberData-compatible list of MediaType values</returns>
|
||||
public static List<object?[]> GenerateMediaTypeTestData()
|
||||
{
|
||||
var testData = new List<object?[]>() { new object?[] { null, true } };
|
||||
foreach (MediaType? mediaType in Enum.GetValues(typeof(MediaType)))
|
||||
{
|
||||
testData.Add([mediaType, false]);
|
||||
}
|
||||
|
||||
return testData;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Region
|
||||
|
||||
/// <summary>
|
||||
/// Check that every Region has a long name provided
|
||||
/// </summary>
|
||||
/// <param name="region">Region value to check</param>
|
||||
/// <param name="expectNull">True to expect a null value, false otherwise</param>
|
||||
[Theory]
|
||||
[MemberData(nameof(GenerateRegionTestData))]
|
||||
public void RegionLongNameTest(Region? region, bool expectNull)
|
||||
{
|
||||
var actual = region.LongName();
|
||||
|
||||
if (expectNull)
|
||||
Assert.Null(actual);
|
||||
else
|
||||
Assert.NotNull(actual);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check that every Region has a short name provided
|
||||
/// </summary>
|
||||
/// <param name="region">Region value to check</param>
|
||||
/// <param name="expectNull">True to expect a null value, false otherwise</param>
|
||||
[Theory]
|
||||
[MemberData(nameof(GenerateRegionTestData))]
|
||||
public void RegionShortNameTest(Region? region, bool expectNull)
|
||||
{
|
||||
var actual = region.ShortName();
|
||||
|
||||
if (expectNull)
|
||||
Assert.Null(actual);
|
||||
else
|
||||
Assert.NotNull(actual);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensure that every Language that has an ISO 639-1 code is unique
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void RegionNoDuplicateShortNameTest()
|
||||
{
|
||||
var fullRegions = Enum.GetValues(typeof(Region)).Cast<Region?>().ToList();
|
||||
var filteredRegions = new Dictionary<string, Region?>();
|
||||
|
||||
int totalCount = 0;
|
||||
foreach (Region? region in fullRegions)
|
||||
{
|
||||
var code = region.ShortName();
|
||||
if (string.IsNullOrEmpty(code))
|
||||
continue;
|
||||
|
||||
// Throw if the code already exists
|
||||
if (filteredRegions.ContainsKey(code))
|
||||
throw new DuplicateNameException($"Code {code} already in dictionary");
|
||||
|
||||
filteredRegions[code] = region;
|
||||
totalCount++;
|
||||
}
|
||||
|
||||
Assert.Equal(totalCount, filteredRegions.Count);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generate a test set of Region values
|
||||
/// </summary>
|
||||
/// <returns>MemberData-compatible list of Region values</returns>
|
||||
public static List<object?[]> GenerateRegionTestData()
|
||||
{
|
||||
var testData = new List<object?[]>() { new object?[] { null, true } };
|
||||
foreach (Region? region in Enum.GetValues(typeof(Region)))
|
||||
{
|
||||
testData.Add([region, false]);
|
||||
}
|
||||
|
||||
return testData;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Site Code
|
||||
|
||||
/// <summary>
|
||||
/// Check that every SiteCode has a long name provided
|
||||
/// </summary>
|
||||
/// <param name="siteCode">SiteCode value to check</param>
|
||||
/// <param name="expectNull">True to expect a null value, false otherwise</param>
|
||||
[Theory]
|
||||
[MemberData(nameof(GenerateSiteCodeTestData))]
|
||||
public void SiteCodeLongNameTest(SiteCode? siteCode, bool expectNull)
|
||||
{
|
||||
var actual = siteCode.LongName();
|
||||
|
||||
if (expectNull)
|
||||
Assert.Null(actual);
|
||||
else
|
||||
Assert.NotNull(actual);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check that every SiteCode has a short name provided
|
||||
/// </summary>
|
||||
/// <param name="siteCode">SiteCode value to check</param>
|
||||
/// <param name="expectNull">True to expect a null value, false otherwise</param>
|
||||
[Theory]
|
||||
[MemberData(nameof(GenerateSiteCodeTestData))]
|
||||
public void SiteCodeShortNameTest(SiteCode? siteCode, bool expectNull)
|
||||
{
|
||||
var actual = siteCode.ShortName();
|
||||
|
||||
if (expectNull)
|
||||
Assert.Null(actual);
|
||||
else
|
||||
Assert.NotNull(actual);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generate a test set of SiteCode values
|
||||
/// </summary>
|
||||
/// <returns>MemberData-compatible list of SiteCode values</returns>
|
||||
public static List<object?[]> GenerateSiteCodeTestData()
|
||||
{
|
||||
var testData = new List<object?[]>() { new object?[] { null, true } };
|
||||
foreach (SiteCode? siteCode in Enum.GetValues(typeof(SiteCode)))
|
||||
{
|
||||
testData.Add([siteCode, false]);
|
||||
}
|
||||
|
||||
return testData;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region System
|
||||
|
||||
/// <summary>
|
||||
/// Check that every RedumpSystem has a long name provided
|
||||
/// </summary>
|
||||
/// <param name="redumpSystem">RedumpSystem value to check</param>
|
||||
/// <param name="expectNull">True to expect a null value, false otherwise</param>
|
||||
[Theory]
|
||||
[MemberData(nameof(GenerateRedumpSystemTestData))]
|
||||
public void RedumpSystemLongNameTest(RedumpSystem? redumpSystem, bool expectNull)
|
||||
{
|
||||
var actual = redumpSystem.LongName();
|
||||
|
||||
if (expectNull)
|
||||
Assert.Null(actual);
|
||||
else
|
||||
Assert.NotNull(actual);
|
||||
}
|
||||
|
||||
// TODO: Re-enable the following test once non-Redump systems are accounted for
|
||||
|
||||
/// <summary>
|
||||
/// Check that every RedumpSystem has a short name provided
|
||||
/// </summary>
|
||||
/// <param name="redumpSystem">RedumpSystem value to check</param>
|
||||
/// <param name="expectNull">True to expect a null value, false otherwise</param>
|
||||
//[Theory]
|
||||
//[MemberData(nameof(GenerateRedumpSystemTestData))]
|
||||
//public void RedumpSystemShortNameTest(RedumpSystem? redumpSystem, bool expectNull)
|
||||
//{
|
||||
// string actual = redumpSystem.ShortName();
|
||||
|
||||
// if (expectNull)
|
||||
// Assert.Null(actual);
|
||||
// else
|
||||
// Assert.NotNull(actual);
|
||||
//}
|
||||
|
||||
// TODO: Test the other attributes as well
|
||||
// Most are bool checks so they're not as interesting to have unit tests around
|
||||
// SystemCategory always returns something as well, so is it worth testing?
|
||||
|
||||
/// <summary>
|
||||
/// Generate a test set of RedumpSystem values
|
||||
/// </summary>
|
||||
/// <returns>MemberData-compatible list of RedumpSystem values</returns>
|
||||
public static List<object?[]> GenerateRedumpSystemTestData()
|
||||
{
|
||||
var testData = new List<object?[]>() { new object?[] { null, true } };
|
||||
foreach (RedumpSystem? redumpSystem in Enum.GetValues(typeof(RedumpSystem)))
|
||||
{
|
||||
// We want to skip all markers for this
|
||||
if (redumpSystem.IsMarker())
|
||||
continue;
|
||||
|
||||
testData.Add([redumpSystem, false]);
|
||||
}
|
||||
|
||||
return testData;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region System Category
|
||||
|
||||
/// <summary>
|
||||
/// Check that every SystemCategory has a long name provided
|
||||
/// </summary>
|
||||
/// <param name="systemCategory">SystemCategory value to check</param>
|
||||
/// <param name="expectNull">True to expect a null value, false otherwise</param>
|
||||
[Theory]
|
||||
[MemberData(nameof(GenerateSystemCategoryTestData))]
|
||||
public void SystemCategoryLongNameTest(SystemCategory? systemCategory, bool expectNull)
|
||||
{
|
||||
var actual = systemCategory.LongName();
|
||||
|
||||
if (expectNull)
|
||||
Assert.Null(actual);
|
||||
else
|
||||
Assert.NotNull(actual);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generate a test set of SystemCategory values
|
||||
/// </summary>
|
||||
/// <returns>MemberData-compatible list of SystemCategory values</returns>
|
||||
public static List<object?[]> GenerateSystemCategoryTestData()
|
||||
{
|
||||
var testData = new List<object?[]>() { new object?[] { null, true } };
|
||||
foreach (SystemCategory? systemCategory in Enum.GetValues(typeof(SystemCategory)))
|
||||
{
|
||||
if (systemCategory == SystemCategory.NONE)
|
||||
testData.Add([systemCategory, true]);
|
||||
else
|
||||
testData.Add([systemCategory, false]);
|
||||
}
|
||||
|
||||
return testData;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Yes/No
|
||||
|
||||
/// <summary>
|
||||
/// Check that every YesNo has a long name provided
|
||||
/// </summary>
|
||||
/// <param name="yesNo">YesNo value to check</param>
|
||||
/// <param name="expectNull">True to expect a null value, false otherwise</param>
|
||||
[Theory]
|
||||
[MemberData(nameof(GenerateYesNoTestData))]
|
||||
public void YesNoLongNameTest(YesNo? yesNo, bool expectNull)
|
||||
{
|
||||
string actual = yesNo.LongName();
|
||||
|
||||
if (expectNull)
|
||||
Assert.Null(actual);
|
||||
else
|
||||
Assert.NotNull(actual);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generate a test set of YesNo values
|
||||
/// </summary>
|
||||
/// <returns>MemberData-compatible list of YesNo values</returns>
|
||||
public static List<object?[]> GenerateYesNoTestData()
|
||||
{
|
||||
var testData = new List<object?[]>() { new object?[] { null, false } };
|
||||
foreach (YesNo? yesNo in Enum.GetValues(typeof(YesNo)))
|
||||
{
|
||||
testData.Add([yesNo, false]);
|
||||
}
|
||||
|
||||
return testData;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
877
SabreTools.RedumpLib.Test/FormatterTests.cs
Normal file
877
SabreTools.RedumpLib.Test/FormatterTests.cs
Normal file
@@ -0,0 +1,877 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using SabreTools.RedumpLib.Data;
|
||||
using Xunit;
|
||||
|
||||
namespace SabreTools.RedumpLib.Test
|
||||
{
|
||||
public class FormatterTests
|
||||
{
|
||||
#region ProcessSpecialFields
|
||||
|
||||
// TODO: Write tests for ProcessSpecialFields
|
||||
|
||||
#endregion
|
||||
|
||||
#region CommonDiscInfoSection
|
||||
|
||||
// TODO: Write tests for FormatOutputData(CommonDiscInfoSection)
|
||||
|
||||
[Fact]
|
||||
public void FormatOutputData_CDINullSACNullTAWONull_Minimal()
|
||||
{
|
||||
string expected = "Common Disc Info:\n\tRegion: SPACE! (CHANGE THIS)\n\tLanguages: ADD LANGUAGES HERE (ONLY IF YOU TESTED)\n\n\tRingcode Information:\n\n\n";
|
||||
|
||||
var builder = new StringBuilder();
|
||||
CommonDiscInfoSection? section = null;
|
||||
SizeAndChecksumsSection? sac = null;
|
||||
TracksAndWriteOffsetsSection? tawo = null;
|
||||
int? fullyMatchedID = null;
|
||||
List<int>? partiallyMatchedIDs = null;
|
||||
|
||||
Formatter.FormatOutputData(builder,
|
||||
section,
|
||||
sac,
|
||||
tawo,
|
||||
fullyMatchedID,
|
||||
partiallyMatchedIDs);
|
||||
|
||||
string actual = builder.ToString();
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region VersionAndEditionsSection
|
||||
|
||||
[Fact]
|
||||
public void FormatOutputData_VAENull_Minimal()
|
||||
{
|
||||
string expected = "Version and Editions:\n";
|
||||
|
||||
var builder = new StringBuilder();
|
||||
VersionAndEditionsSection? section = null;
|
||||
|
||||
Formatter.FormatOutputData(builder, section);
|
||||
|
||||
string actual = builder.ToString();
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FormatOutputData_VAE_Formatted()
|
||||
{
|
||||
string expected = "Version and Editions:\n\tVersion: XXXXXX\n\tEdition/Release: XXXXXX\n";
|
||||
|
||||
var builder = new StringBuilder();
|
||||
VersionAndEditionsSection? section = new VersionAndEditionsSection
|
||||
{
|
||||
Version = "XXXXXX",
|
||||
OtherEditions = "XXXXXX",
|
||||
};
|
||||
|
||||
Formatter.FormatOutputData(builder, section);
|
||||
|
||||
string actual = builder.ToString();
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region EDCSection
|
||||
|
||||
[Fact]
|
||||
public void FormatOutputData_EDCNull_Minimal()
|
||||
{
|
||||
string expected = "EDC:\n";
|
||||
|
||||
var builder = new StringBuilder();
|
||||
EDCSection? section = null;
|
||||
RedumpSystem? system = RedumpSystem.SonyPlayStation;
|
||||
|
||||
Formatter.FormatOutputData(builder, section, system);
|
||||
|
||||
string actual = builder.ToString();
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FormatOutputData_EDCInvalidSystem_Empty()
|
||||
{
|
||||
string expected = string.Empty;
|
||||
|
||||
var builder = new StringBuilder();
|
||||
EDCSection? section = null;
|
||||
RedumpSystem? system = RedumpSystem.IBMPCcompatible;
|
||||
|
||||
Formatter.FormatOutputData(builder, section, system);
|
||||
|
||||
string actual = builder.ToString();
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FormatOutputData_EDC_Formatted()
|
||||
{
|
||||
string expected = "EDC:\n\tEDC: Yes\n";
|
||||
|
||||
var builder = new StringBuilder();
|
||||
EDCSection? section = new EDCSection { EDC = YesNo.Yes };
|
||||
RedumpSystem? system = RedumpSystem.SonyPlayStation;
|
||||
|
||||
Formatter.FormatOutputData(builder, section, system);
|
||||
|
||||
string actual = builder.ToString();
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ExtrasSection
|
||||
|
||||
[Fact]
|
||||
public void FormatOutputData_ExtrasNull_Empty()
|
||||
{
|
||||
string expected = string.Empty;
|
||||
|
||||
var builder = new StringBuilder();
|
||||
ExtrasSection? section = null;
|
||||
|
||||
Formatter.FormatOutputData(builder, section);
|
||||
|
||||
string actual = builder.ToString();
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FormatOutputData_ExtrasInvalid_Empty()
|
||||
{
|
||||
string expected = string.Empty;
|
||||
|
||||
var builder = new StringBuilder();
|
||||
ExtrasSection? section = new ExtrasSection
|
||||
{
|
||||
PVD = null,
|
||||
PIC = null,
|
||||
BCA = null,
|
||||
SecuritySectorRanges = null,
|
||||
};
|
||||
|
||||
Formatter.FormatOutputData(builder, section);
|
||||
|
||||
string actual = builder.ToString();
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FormatOutputData_Extras_Formatted()
|
||||
{
|
||||
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
|
||||
{
|
||||
PVD = "XXXXXX",
|
||||
DiscKey = "XXXXXX",
|
||||
DiscID = "XXXXXX",
|
||||
PIC = "XXXXXX",
|
||||
Header = "XXXXXX",
|
||||
BCA = "XXXXXX",
|
||||
SecuritySectorRanges = "XXXXXX",
|
||||
};
|
||||
|
||||
Formatter.FormatOutputData(builder, section);
|
||||
|
||||
string actual = builder.ToString();
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region CopyProtectionSection
|
||||
|
||||
[Fact]
|
||||
public void FormatOutputData_COPNull_Empty()
|
||||
{
|
||||
string expected = string.Empty;
|
||||
|
||||
var builder = new StringBuilder();
|
||||
CopyProtectionSection? section = null;
|
||||
RedumpSystem? system = RedumpSystem.IBMPCcompatible;
|
||||
|
||||
Formatter.FormatOutputData(builder, section, system);
|
||||
|
||||
string actual = builder.ToString();
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FormatOutputData_COPInvalid_Empty()
|
||||
{
|
||||
string expected = string.Empty;
|
||||
|
||||
var builder = new StringBuilder();
|
||||
CopyProtectionSection? section = new CopyProtectionSection
|
||||
{
|
||||
Protection = null,
|
||||
AntiModchip = null,
|
||||
LibCrypt = null,
|
||||
LibCryptData = null,
|
||||
SecuROMData = null,
|
||||
};
|
||||
RedumpSystem? system = RedumpSystem.IBMPCcompatible;
|
||||
|
||||
Formatter.FormatOutputData(builder, section, system);
|
||||
|
||||
string actual = builder.ToString();
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FormatOutputData_COP_Formatted()
|
||||
{
|
||||
string expected = "Copy Protection:\n\tCopy Protection: XXXXXX\n\tSubIntention Data (SecuROM/LibCrypt): XXXXXX\n";
|
||||
|
||||
var builder = new StringBuilder();
|
||||
CopyProtectionSection? section = new CopyProtectionSection
|
||||
{
|
||||
AntiModchip = YesNo.Yes,
|
||||
LibCrypt = YesNo.Yes,
|
||||
LibCryptData = "XXXXXX",
|
||||
Protection = "XXXXXX",
|
||||
SecuROMData = "XXXXXX",
|
||||
};
|
||||
RedumpSystem? system = RedumpSystem.IBMPCcompatible;
|
||||
|
||||
Formatter.FormatOutputData(builder, section, system);
|
||||
|
||||
string actual = builder.ToString();
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FormatOutputData_COPPSX_Formatted()
|
||||
{
|
||||
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
|
||||
{
|
||||
AntiModchip = YesNo.Yes,
|
||||
LibCrypt = YesNo.Yes,
|
||||
LibCryptData = "XXXXXX",
|
||||
Protection = "XXXXXX",
|
||||
SecuROMData = "XXXXXX",
|
||||
};
|
||||
RedumpSystem? system = RedumpSystem.SonyPlayStation;
|
||||
|
||||
Formatter.FormatOutputData(builder, section, system);
|
||||
|
||||
string actual = builder.ToString();
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region TracksAndWriteOffsetsSection
|
||||
|
||||
[Fact]
|
||||
public void FormatOutputData_TAWOInvalid_Minimal()
|
||||
{
|
||||
string expected = "Tracks and Write Offsets:\n\tDAT:\n\n\n\n\n";
|
||||
|
||||
var builder = new StringBuilder();
|
||||
TracksAndWriteOffsetsSection? section = new TracksAndWriteOffsetsSection();
|
||||
|
||||
Formatter.FormatOutputData(builder, section);
|
||||
|
||||
string actual = builder.ToString();
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FormatOutputData_TAWO_Formatted()
|
||||
{
|
||||
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
|
||||
{
|
||||
ClrMameProData = "XXXXXX",
|
||||
Cuesheet = "XXXXXX",
|
||||
OtherWriteOffsets = "XXXXXX",
|
||||
};
|
||||
|
||||
Formatter.FormatOutputData(builder, section);
|
||||
|
||||
string actual = builder.ToString();
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region SizeAndChecksumsSection
|
||||
|
||||
// TODO: Write tests for FormatOutputData(SizeAndChecksumsSection)
|
||||
|
||||
#endregion
|
||||
|
||||
#region DumpingInfoSection
|
||||
|
||||
[Fact]
|
||||
public void FormatOutputData_DINull_Minimal()
|
||||
{
|
||||
string expected = "Dumping Info:\n";
|
||||
|
||||
var builder = new StringBuilder();
|
||||
DumpingInfoSection? section = null;
|
||||
|
||||
Formatter.FormatOutputData(builder, section);
|
||||
|
||||
string actual = builder.ToString();
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FormatOutputData_DI_Formatted()
|
||||
{
|
||||
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
|
||||
{
|
||||
FrontendVersion = "XXXXXX",
|
||||
DumpingProgram = "XXXXXX",
|
||||
DumpingDate = "XXXXXX",
|
||||
DumpingParameters = "XXXXXX",
|
||||
Manufacturer = "XXXXXX",
|
||||
Model = "XXXXXX",
|
||||
Firmware = "XXXXXX",
|
||||
ReportedDiscType = "XXXXXX",
|
||||
C2ErrorsCount = "XXXXXX",
|
||||
};
|
||||
|
||||
Formatter.FormatOutputData(builder, section);
|
||||
|
||||
string actual = builder.ToString();
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region FormatSiteTag
|
||||
|
||||
[Fact]
|
||||
public void FormatSiteTag_NoValue_Empty()
|
||||
{
|
||||
SiteCode code = SiteCode.AlternativeTitle;
|
||||
string value = string.Empty;
|
||||
|
||||
string actual = Formatter.FormatSiteTag(code, value);
|
||||
Assert.Empty(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FormatSiteTag_Standard_Formatted()
|
||||
{
|
||||
string expected = "[T:ALT] XXXXXX";
|
||||
SiteCode code = SiteCode.AlternativeTitle;
|
||||
string value = "XXXXXX";
|
||||
|
||||
string actual = Formatter.FormatSiteTag(code, value);
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FormatSiteTag_BooleanTrue_Formatted()
|
||||
{
|
||||
string expected = "[T:VCD]";
|
||||
SiteCode code = SiteCode.VCD;
|
||||
string value = "True";
|
||||
|
||||
string actual = Formatter.FormatSiteTag(code, value);
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FormatSiteTag_BooleanFalse_Empty()
|
||||
{
|
||||
SiteCode code = SiteCode.VCD;
|
||||
string value = "XXXXXX";
|
||||
|
||||
string actual = Formatter.FormatSiteTag(code, value);
|
||||
Assert.Empty(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FormatSiteTag_Multiline_Formatted()
|
||||
{
|
||||
string expected = "[T:X]\nXXXXXX\n";
|
||||
SiteCode code = SiteCode.Extras;
|
||||
string value = "XXXXXX";
|
||||
|
||||
string actual = Formatter.FormatSiteTag(code, value);
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region GetFixedMediaType
|
||||
|
||||
[Fact]
|
||||
public void GetFixedMediaType_NullType_Null()
|
||||
{
|
||||
MediaType? mediaType = null;
|
||||
string? picIdentifier = null;
|
||||
long? size = null;
|
||||
long? layerbreak = null;
|
||||
long? layerbreak2 = null;
|
||||
long? layerbreak3 = null;
|
||||
|
||||
string? actual = Formatter.GetFixedMediaType(mediaType,
|
||||
picIdentifier,
|
||||
size,
|
||||
layerbreak,
|
||||
layerbreak2,
|
||||
layerbreak3);
|
||||
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetFixedMediaType_UnformattedType_Formatted()
|
||||
{
|
||||
string? expected = "CD-ROM";
|
||||
|
||||
MediaType? mediaType = MediaType.CDROM;
|
||||
string? picIdentifier = null;
|
||||
long? size = null;
|
||||
long? layerbreak = null;
|
||||
long? layerbreak2 = null;
|
||||
long? layerbreak3 = null;
|
||||
|
||||
string? actual = Formatter.GetFixedMediaType(mediaType,
|
||||
picIdentifier,
|
||||
size,
|
||||
layerbreak,
|
||||
layerbreak2,
|
||||
layerbreak3);
|
||||
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetFixedMediaType_DVD9_Formatted()
|
||||
{
|
||||
string? expected = "DVD-ROM-9";
|
||||
|
||||
MediaType? mediaType = MediaType.DVD;
|
||||
string? picIdentifier = null;
|
||||
long? size = null;
|
||||
long? layerbreak = 12345;
|
||||
long? layerbreak2 = null;
|
||||
long? layerbreak3 = null;
|
||||
|
||||
string? actual = Formatter.GetFixedMediaType(mediaType,
|
||||
picIdentifier,
|
||||
size,
|
||||
layerbreak,
|
||||
layerbreak2,
|
||||
layerbreak3);
|
||||
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetFixedMediaType_DVD5_Formatted()
|
||||
{
|
||||
string? expected = "DVD-ROM-5";
|
||||
|
||||
MediaType? mediaType = MediaType.DVD;
|
||||
string? picIdentifier = null;
|
||||
long? size = null;
|
||||
long? layerbreak = null;
|
||||
long? layerbreak2 = null;
|
||||
long? layerbreak3 = null;
|
||||
|
||||
string? actual = Formatter.GetFixedMediaType(mediaType,
|
||||
picIdentifier,
|
||||
size,
|
||||
layerbreak,
|
||||
layerbreak2,
|
||||
layerbreak3);
|
||||
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetFixedMediaType_BD128_Formatted()
|
||||
{
|
||||
string? expected = "BD-ROM-128";
|
||||
|
||||
MediaType? mediaType = MediaType.BluRay;
|
||||
string? picIdentifier = null;
|
||||
long? size = null;
|
||||
long? layerbreak = null;
|
||||
long? layerbreak2 = null;
|
||||
long? layerbreak3 = 12345;
|
||||
|
||||
string? actual = Formatter.GetFixedMediaType(mediaType,
|
||||
picIdentifier,
|
||||
size,
|
||||
layerbreak,
|
||||
layerbreak2,
|
||||
layerbreak3);
|
||||
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetFixedMediaType_BD100_Formatted()
|
||||
{
|
||||
string? expected = "BD-ROM-100";
|
||||
|
||||
MediaType? mediaType = MediaType.BluRay;
|
||||
string? picIdentifier = null;
|
||||
long? size = null;
|
||||
long? layerbreak = null;
|
||||
long? layerbreak2 = 12345;
|
||||
long? layerbreak3 = null;
|
||||
|
||||
string? actual = Formatter.GetFixedMediaType(mediaType,
|
||||
picIdentifier,
|
||||
size,
|
||||
layerbreak,
|
||||
layerbreak2,
|
||||
layerbreak3);
|
||||
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetFixedMediaType_BD66PIC_Formatted()
|
||||
{
|
||||
string? expected = "BD-ROM-66";
|
||||
|
||||
MediaType? mediaType = MediaType.BluRay;
|
||||
string? picIdentifier = "BDU";
|
||||
long? size = null;
|
||||
long? layerbreak = 12345;
|
||||
long? layerbreak2 = null;
|
||||
long? layerbreak3 = null;
|
||||
|
||||
string? actual = Formatter.GetFixedMediaType(mediaType,
|
||||
picIdentifier,
|
||||
size,
|
||||
layerbreak,
|
||||
layerbreak2,
|
||||
layerbreak3);
|
||||
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetFixedMediaType_BD66Size_Formatted()
|
||||
{
|
||||
string? expected = "BD-ROM-66";
|
||||
|
||||
MediaType? mediaType = MediaType.BluRay;
|
||||
string? picIdentifier = null;
|
||||
long? size = 53_687_063_713;
|
||||
long? layerbreak = 12345;
|
||||
long? layerbreak2 = null;
|
||||
long? layerbreak3 = null;
|
||||
|
||||
string? actual = Formatter.GetFixedMediaType(mediaType,
|
||||
picIdentifier,
|
||||
size,
|
||||
layerbreak,
|
||||
layerbreak2,
|
||||
layerbreak3);
|
||||
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetFixedMediaType_BD50_Formatted()
|
||||
{
|
||||
string? expected = "BD-ROM-50";
|
||||
|
||||
MediaType? mediaType = MediaType.BluRay;
|
||||
string? picIdentifier = null;
|
||||
long? size = null;
|
||||
long? layerbreak = 12345;
|
||||
long? layerbreak2 = null;
|
||||
long? layerbreak3 = null;
|
||||
|
||||
string? actual = Formatter.GetFixedMediaType(mediaType,
|
||||
picIdentifier,
|
||||
size,
|
||||
layerbreak,
|
||||
layerbreak2,
|
||||
layerbreak3);
|
||||
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetFixedMediaType_BD33PIC_Formatted()
|
||||
{
|
||||
string? expected = "BD-ROM-33";
|
||||
|
||||
MediaType? mediaType = MediaType.BluRay;
|
||||
string? picIdentifier = "BDU";
|
||||
long? size = null;
|
||||
long? layerbreak = null;
|
||||
long? layerbreak2 = null;
|
||||
long? layerbreak3 = null;
|
||||
|
||||
string? actual = Formatter.GetFixedMediaType(mediaType,
|
||||
picIdentifier,
|
||||
size,
|
||||
layerbreak,
|
||||
layerbreak2,
|
||||
layerbreak3);
|
||||
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetFixedMediaType_BD33Size_Formatted()
|
||||
{
|
||||
string? expected = "BD-ROM-33";
|
||||
|
||||
MediaType? mediaType = MediaType.BluRay;
|
||||
string? picIdentifier = null;
|
||||
long? size = 26_843_531_857;
|
||||
long? layerbreak = null;
|
||||
long? layerbreak2 = null;
|
||||
long? layerbreak3 = null;
|
||||
|
||||
string? actual = Formatter.GetFixedMediaType(mediaType,
|
||||
picIdentifier,
|
||||
size,
|
||||
layerbreak,
|
||||
layerbreak2,
|
||||
layerbreak3);
|
||||
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetFixedMediaType_BD25_Formatted()
|
||||
{
|
||||
string? expected = "BD-ROM-25";
|
||||
|
||||
MediaType? mediaType = MediaType.BluRay;
|
||||
string? picIdentifier = null;
|
||||
long? size = null;
|
||||
long? layerbreak = null;
|
||||
long? layerbreak2 = null;
|
||||
long? layerbreak3 = null;
|
||||
|
||||
string? actual = Formatter.GetFixedMediaType(mediaType,
|
||||
picIdentifier,
|
||||
size,
|
||||
layerbreak,
|
||||
layerbreak2,
|
||||
layerbreak3);
|
||||
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetFixedMediaType_HDDVDDL_Formatted()
|
||||
{
|
||||
string? expected = "HD-DVD-ROM-DL";
|
||||
|
||||
MediaType? mediaType = MediaType.HDDVD;
|
||||
string? picIdentifier = null;
|
||||
long? size = null;
|
||||
long? layerbreak = 12345;
|
||||
long? layerbreak2 = null;
|
||||
long? layerbreak3 = null;
|
||||
|
||||
string? actual = Formatter.GetFixedMediaType(mediaType,
|
||||
picIdentifier,
|
||||
size,
|
||||
layerbreak,
|
||||
layerbreak2,
|
||||
layerbreak3);
|
||||
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetFixedMediaType_HDDVDSL_Formatted()
|
||||
{
|
||||
string? expected = "HD-DVD-ROM-SL";
|
||||
|
||||
MediaType? mediaType = MediaType.HDDVD;
|
||||
string? picIdentifier = null;
|
||||
long? size = null;
|
||||
long? layerbreak = null;
|
||||
long? layerbreak2 = null;
|
||||
long? layerbreak3 = null;
|
||||
|
||||
string? actual = Formatter.GetFixedMediaType(mediaType,
|
||||
picIdentifier,
|
||||
size,
|
||||
layerbreak,
|
||||
layerbreak2,
|
||||
layerbreak3);
|
||||
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetFixedMediaType_UMDDL_Formatted()
|
||||
{
|
||||
string? expected = "UMD-DL";
|
||||
|
||||
MediaType? mediaType = MediaType.UMD;
|
||||
string? picIdentifier = null;
|
||||
long? size = null;
|
||||
long? layerbreak = 12345;
|
||||
long? layerbreak2 = null;
|
||||
long? layerbreak3 = null;
|
||||
|
||||
string? actual = Formatter.GetFixedMediaType(mediaType,
|
||||
picIdentifier,
|
||||
size,
|
||||
layerbreak,
|
||||
layerbreak2,
|
||||
layerbreak3);
|
||||
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetFixedMediaType_UMDSL_Formatted()
|
||||
{
|
||||
string? expected = "UMD-SL";
|
||||
|
||||
MediaType? mediaType = MediaType.UMD;
|
||||
string? picIdentifier = null;
|
||||
long? size = null;
|
||||
long? layerbreak = null;
|
||||
long? layerbreak2 = null;
|
||||
long? layerbreak3 = null;
|
||||
|
||||
string? actual = Formatter.GetFixedMediaType(mediaType,
|
||||
picIdentifier,
|
||||
size,
|
||||
layerbreak,
|
||||
layerbreak2,
|
||||
layerbreak3);
|
||||
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region OrderCommentTags
|
||||
|
||||
[Fact]
|
||||
public void OrderCommentTags_Empty_Empty()
|
||||
{
|
||||
Dictionary<SiteCode, string> tags = [];
|
||||
var actual = Formatter.OrderCommentTags(tags);
|
||||
Assert.Empty(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void OrderCommentTags_NoMatch_Empty()
|
||||
{
|
||||
var tags = new Dictionary<SiteCode, string>
|
||||
{
|
||||
{ SiteCode.Applications, "XXXXXX" },
|
||||
};
|
||||
var actual = Formatter.OrderCommentTags(tags);
|
||||
Assert.Empty(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void OrderCommentTags_All_Ordered()
|
||||
{
|
||||
Dictionary<SiteCode, string> tags = [];
|
||||
foreach (SiteCode code in Enum.GetValues<SiteCode>())
|
||||
{
|
||||
tags[code] = "XXXXXX";
|
||||
}
|
||||
|
||||
var actual = Formatter.OrderCommentTags(tags);
|
||||
|
||||
Assert.NotEmpty(actual);
|
||||
var actualCodes = actual.Select(kvp => kvp.Key);
|
||||
Assert.True(Formatter.OrderedCommentCodes.SequenceEqual(actualCodes));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region OrderContentTags
|
||||
|
||||
[Fact]
|
||||
public void OrderContentTags_Empty_Empty()
|
||||
{
|
||||
Dictionary<SiteCode, string> tags = [];
|
||||
var actual = Formatter.OrderContentTags(tags);
|
||||
Assert.Empty(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void OrderContentTags_NoMatch_Empty()
|
||||
{
|
||||
var tags = new Dictionary<SiteCode, string>
|
||||
{
|
||||
{ SiteCode.AlternativeTitle, "XXXXXX" },
|
||||
};
|
||||
var actual = Formatter.OrderContentTags(tags);
|
||||
Assert.Empty(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void OrderContentTags_All_Ordered()
|
||||
{
|
||||
Dictionary<SiteCode, string> tags = [];
|
||||
foreach (SiteCode code in Enum.GetValues<SiteCode>())
|
||||
{
|
||||
tags[code] = "XXXXXX";
|
||||
}
|
||||
|
||||
var actual = Formatter.OrderContentTags(tags);
|
||||
|
||||
Assert.NotEmpty(actual);
|
||||
var actualCodes = actual.Select(kvp => kvp.Key);
|
||||
Assert.True(Formatter.OrderedContentCodes.SequenceEqual(actualCodes));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region RemoveConsecutiveEmptyLines
|
||||
|
||||
[Fact]
|
||||
public void RemoveConsecutiveEmptyLines_Linux_Removed()
|
||||
{
|
||||
string expected = "data\n\nbase";
|
||||
string newlines = "data\n\n\n\n\n\n\n\n\n\nbase";
|
||||
|
||||
string actual = Formatter.RemoveConsecutiveEmptyLines(newlines);
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RemoveConsecutiveEmptyLines_Windows_Removed()
|
||||
{
|
||||
string expected = "data\r\n\r\nbase";
|
||||
string newlines = "data\r\n\r\n\r\n\r\n\r\nbase";
|
||||
|
||||
string actual = Formatter.RemoveConsecutiveEmptyLines(newlines);
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net6.0;net8.0;net9.0</TargetFrameworks>
|
||||
<TargetFrameworks>net8.0;net9.0</TargetFrameworks>
|
||||
<CheckEolTargetFramework>false</CheckEolTargetFramework>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
@@ -24,20 +24,20 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.CodeCoverage" Version="17.11.1" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
|
||||
<PackageReference Include="xunit" Version="2.9.2" />
|
||||
<PackageReference Include="Microsoft.CodeCoverage" Version="18.0.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.0.0" />
|
||||
<PackageReference Include="xunit" Version="2.9.3" />
|
||||
<PackageReference Include="xunit.abstractions" Version="2.0.3" />
|
||||
<PackageReference Include="xunit.analyzers" Version="1.17.0" />
|
||||
<PackageReference Include="xunit.assert" Version="2.9.2" />
|
||||
<PackageReference Include="xunit.core" Version="2.9.2" />
|
||||
<PackageReference Include="xunit.extensibility.core" Version="2.9.2" />
|
||||
<PackageReference Include="xunit.extensibility.execution" Version="2.9.2" />
|
||||
<PackageReference Include="xunit.runner.console" Version="2.9.2">
|
||||
<PackageReference Include="xunit.analyzers" Version="1.24.0" />
|
||||
<PackageReference Include="xunit.assert" Version="2.9.3" />
|
||||
<PackageReference Include="xunit.core" Version="2.9.3" />
|
||||
<PackageReference Include="xunit.extensibility.core" Version="2.9.3" />
|
||||
<PackageReference Include="xunit.extensibility.execution" Version="2.9.3" />
|
||||
<PackageReference Include="xunit.runner.console" Version="2.9.3">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2">
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.5">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
|
||||
@@ -161,6 +161,7 @@ namespace SabreTools.RedumpLib.Test
|
||||
{
|
||||
DumpingProgram = "DiscImageCreator 20500101",
|
||||
DumpingDate = DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss"),
|
||||
DumpingParameters = "cd dvd bd sacd fd hdd",
|
||||
Manufacturer = "ATAPI",
|
||||
Model = "Optical Drive",
|
||||
Firmware = "1.23",
|
||||
|
||||
304
SabreTools.RedumpLib.Test/ValidatorTests.cs
Normal file
304
SabreTools.RedumpLib.Test/ValidatorTests.cs
Normal file
@@ -0,0 +1,304 @@
|
||||
using SabreTools.RedumpLib.Data;
|
||||
using Xunit;
|
||||
|
||||
namespace SabreTools.RedumpLib.Test
|
||||
{
|
||||
public class ValidatorTests
|
||||
{
|
||||
// Most tests here will require installing and using the Moq library
|
||||
// to mock the RedumpClient type.
|
||||
|
||||
[Fact]
|
||||
public void NormalizeDiscType_InvalidMedia_Untouched()
|
||||
{
|
||||
SubmissionInfo si = new SubmissionInfo
|
||||
{
|
||||
CommonDiscInfo = new CommonDiscInfoSection { Media = null }
|
||||
};
|
||||
|
||||
Validator.NormalizeDiscType(si);
|
||||
|
||||
Assert.Null(si.CommonDiscInfo.Media);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NormalizeDiscType_InvalidSizeChecksums_Untouched()
|
||||
{
|
||||
DiscType expected = DiscType.CD;
|
||||
SubmissionInfo si = new SubmissionInfo
|
||||
{
|
||||
CommonDiscInfo = new CommonDiscInfoSection { Media = DiscType.CD },
|
||||
SizeAndChecksums = null,
|
||||
};
|
||||
|
||||
Validator.NormalizeDiscType(si);
|
||||
|
||||
Assert.Equal(expected, si.CommonDiscInfo.Media);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NormalizeDiscType_UnformattedType_Fixed()
|
||||
{
|
||||
DiscType expected = DiscType.CD;
|
||||
SubmissionInfo si = new SubmissionInfo
|
||||
{
|
||||
CommonDiscInfo = new CommonDiscInfoSection { Media = DiscType.CD },
|
||||
SizeAndChecksums = new SizeAndChecksumsSection(),
|
||||
};
|
||||
|
||||
Validator.NormalizeDiscType(si);
|
||||
|
||||
Assert.Equal(expected, si.CommonDiscInfo.Media);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(DiscType.DVD5)]
|
||||
[InlineData(DiscType.DVD9)]
|
||||
public void NormalizeDiscType_DVD9_Fixed(DiscType type)
|
||||
{
|
||||
DiscType expected = DiscType.DVD9;
|
||||
SubmissionInfo si = new SubmissionInfo
|
||||
{
|
||||
CommonDiscInfo = new CommonDiscInfoSection { Media = type },
|
||||
SizeAndChecksums = new SizeAndChecksumsSection { Layerbreak = 12345 },
|
||||
};
|
||||
|
||||
Validator.NormalizeDiscType(si);
|
||||
|
||||
Assert.Equal(expected, si.CommonDiscInfo.Media);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(DiscType.DVD5)]
|
||||
[InlineData(DiscType.DVD9)]
|
||||
public void NormalizeDiscType_DVD5_Fixed(DiscType type)
|
||||
{
|
||||
DiscType expected = DiscType.DVD5;
|
||||
SubmissionInfo si = new SubmissionInfo
|
||||
{
|
||||
CommonDiscInfo = new CommonDiscInfoSection { Media = type },
|
||||
SizeAndChecksums = new SizeAndChecksumsSection(),
|
||||
};
|
||||
|
||||
Validator.NormalizeDiscType(si);
|
||||
|
||||
Assert.Equal(expected, si.CommonDiscInfo.Media);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(DiscType.BD25)]
|
||||
[InlineData(DiscType.BD33)]
|
||||
[InlineData(DiscType.BD50)]
|
||||
[InlineData(DiscType.BD66)]
|
||||
[InlineData(DiscType.BD100)]
|
||||
[InlineData(DiscType.BD128)]
|
||||
public void NormalizeDiscType_BD128_Fixed(DiscType type)
|
||||
{
|
||||
DiscType expected = DiscType.BD128;
|
||||
SubmissionInfo si = new SubmissionInfo
|
||||
{
|
||||
CommonDiscInfo = new CommonDiscInfoSection { Media = type },
|
||||
SizeAndChecksums = new SizeAndChecksumsSection { Layerbreak3 = 12345 },
|
||||
};
|
||||
|
||||
Validator.NormalizeDiscType(si);
|
||||
|
||||
Assert.Equal(expected, si.CommonDiscInfo.Media);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(DiscType.BD25)]
|
||||
[InlineData(DiscType.BD33)]
|
||||
[InlineData(DiscType.BD50)]
|
||||
[InlineData(DiscType.BD66)]
|
||||
[InlineData(DiscType.BD100)]
|
||||
[InlineData(DiscType.BD128)]
|
||||
public void NormalizeDiscType_BD100_Fixed(DiscType type)
|
||||
{
|
||||
DiscType expected = DiscType.BD100;
|
||||
SubmissionInfo si = new SubmissionInfo
|
||||
{
|
||||
CommonDiscInfo = new CommonDiscInfoSection { Media = type },
|
||||
SizeAndChecksums = new SizeAndChecksumsSection { Layerbreak2 = 12345 },
|
||||
};
|
||||
|
||||
Validator.NormalizeDiscType(si);
|
||||
|
||||
Assert.Equal(expected, si.CommonDiscInfo.Media);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(DiscType.BD25)]
|
||||
[InlineData(DiscType.BD33)]
|
||||
[InlineData(DiscType.BD50)]
|
||||
[InlineData(DiscType.BD66)]
|
||||
[InlineData(DiscType.BD100)]
|
||||
[InlineData(DiscType.BD128)]
|
||||
public void NormalizeDiscType_BD66PIC_Fixed(DiscType type)
|
||||
{
|
||||
DiscType expected = DiscType.BD66;
|
||||
SubmissionInfo si = new SubmissionInfo
|
||||
{
|
||||
CommonDiscInfo = new CommonDiscInfoSection { Media = type },
|
||||
SizeAndChecksums = new SizeAndChecksumsSection
|
||||
{
|
||||
Layerbreak = 12345,
|
||||
PICIdentifier = "BDU",
|
||||
},
|
||||
};
|
||||
|
||||
Validator.NormalizeDiscType(si);
|
||||
|
||||
Assert.Equal(expected, si.CommonDiscInfo.Media);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(DiscType.BD25)]
|
||||
[InlineData(DiscType.BD33)]
|
||||
[InlineData(DiscType.BD50)]
|
||||
[InlineData(DiscType.BD66)]
|
||||
[InlineData(DiscType.BD100)]
|
||||
[InlineData(DiscType.BD128)]
|
||||
public void NormalizeDiscType_BD66Size_Fixed(DiscType type)
|
||||
{
|
||||
DiscType expected = DiscType.BD66;
|
||||
SubmissionInfo si = new SubmissionInfo
|
||||
{
|
||||
CommonDiscInfo = new CommonDiscInfoSection { Media = type },
|
||||
SizeAndChecksums = new SizeAndChecksumsSection
|
||||
{
|
||||
Layerbreak = 12345,
|
||||
Size = 50_050_629_633,
|
||||
},
|
||||
};
|
||||
|
||||
Validator.NormalizeDiscType(si);
|
||||
|
||||
Assert.Equal(expected, si.CommonDiscInfo.Media);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(DiscType.BD25)]
|
||||
[InlineData(DiscType.BD33)]
|
||||
[InlineData(DiscType.BD50)]
|
||||
[InlineData(DiscType.BD66)]
|
||||
[InlineData(DiscType.BD100)]
|
||||
[InlineData(DiscType.BD128)]
|
||||
public void NormalizeDiscType_BD50_Fixed(DiscType type)
|
||||
{
|
||||
DiscType expected = DiscType.BD50;
|
||||
SubmissionInfo si = new SubmissionInfo
|
||||
{
|
||||
CommonDiscInfo = new CommonDiscInfoSection { Media = type },
|
||||
SizeAndChecksums = new SizeAndChecksumsSection { Layerbreak = 12345 },
|
||||
};
|
||||
|
||||
Validator.NormalizeDiscType(si);
|
||||
|
||||
Assert.Equal(expected, si.CommonDiscInfo.Media);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(DiscType.BD25)]
|
||||
[InlineData(DiscType.BD33)]
|
||||
[InlineData(DiscType.BD50)]
|
||||
[InlineData(DiscType.BD66)]
|
||||
[InlineData(DiscType.BD100)]
|
||||
[InlineData(DiscType.BD128)]
|
||||
public void NormalizeDiscType_BD33PIC_Fixed(DiscType type)
|
||||
{
|
||||
DiscType expected = DiscType.BD33;
|
||||
SubmissionInfo si = new SubmissionInfo
|
||||
{
|
||||
CommonDiscInfo = new CommonDiscInfoSection { Media = type },
|
||||
SizeAndChecksums = new SizeAndChecksumsSection
|
||||
{
|
||||
PICIdentifier = "BDU",
|
||||
},
|
||||
};
|
||||
|
||||
Validator.NormalizeDiscType(si);
|
||||
|
||||
Assert.Equal(expected, si.CommonDiscInfo.Media);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(DiscType.BD25)]
|
||||
[InlineData(DiscType.BD33)]
|
||||
[InlineData(DiscType.BD50)]
|
||||
[InlineData(DiscType.BD66)]
|
||||
[InlineData(DiscType.BD100)]
|
||||
[InlineData(DiscType.BD128)]
|
||||
public void NormalizeDiscType_BD33Size_Fixed(DiscType type)
|
||||
{
|
||||
DiscType expected = DiscType.BD33;
|
||||
SubmissionInfo si = new SubmissionInfo
|
||||
{
|
||||
CommonDiscInfo = new CommonDiscInfoSection { Media = type },
|
||||
SizeAndChecksums = new SizeAndChecksumsSection
|
||||
{
|
||||
Size = 25_025_314_817,
|
||||
},
|
||||
};
|
||||
|
||||
Validator.NormalizeDiscType(si);
|
||||
|
||||
Assert.Equal(expected, si.CommonDiscInfo.Media);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(DiscType.BD25)]
|
||||
[InlineData(DiscType.BD33)]
|
||||
[InlineData(DiscType.BD50)]
|
||||
[InlineData(DiscType.BD66)]
|
||||
[InlineData(DiscType.BD100)]
|
||||
[InlineData(DiscType.BD128)]
|
||||
public void NormalizeDiscType_BD25_Fixed(DiscType type)
|
||||
{
|
||||
DiscType expected = DiscType.BD25;
|
||||
SubmissionInfo si = new SubmissionInfo
|
||||
{
|
||||
CommonDiscInfo = new CommonDiscInfoSection { Media = type },
|
||||
SizeAndChecksums = new SizeAndChecksumsSection(),
|
||||
};
|
||||
|
||||
Validator.NormalizeDiscType(si);
|
||||
|
||||
Assert.Equal(expected, si.CommonDiscInfo.Media);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(DiscType.UMDSL)]
|
||||
[InlineData(DiscType.UMDDL)]
|
||||
public void NormalizeDiscType_UMDDL_Fixed(DiscType type)
|
||||
{
|
||||
DiscType expected = DiscType.UMDDL;
|
||||
SubmissionInfo si = new SubmissionInfo
|
||||
{
|
||||
CommonDiscInfo = new CommonDiscInfoSection { Media = type },
|
||||
SizeAndChecksums = new SizeAndChecksumsSection { Layerbreak = 12345 },
|
||||
};
|
||||
|
||||
Validator.NormalizeDiscType(si);
|
||||
|
||||
Assert.Equal(expected, si.CommonDiscInfo.Media);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(DiscType.UMDSL)]
|
||||
[InlineData(DiscType.UMDDL)]
|
||||
public void NormalizeDiscType_UMDSL_Fixed(DiscType type)
|
||||
{
|
||||
DiscType expected = DiscType.UMDSL;
|
||||
SubmissionInfo si = new SubmissionInfo
|
||||
{
|
||||
CommonDiscInfo = new CommonDiscInfoSection { Media = type },
|
||||
SizeAndChecksums = new SizeAndChecksumsSection(),
|
||||
};
|
||||
|
||||
Validator.NormalizeDiscType(si);
|
||||
|
||||
Assert.Equal(expected, si.CommonDiscInfo.Media);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SabreTools.RedumpLib", "Sab
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SabreTools.RedumpLib.Test", "SabreTools.RedumpLib.Test\SabreTools.RedumpLib.Test.csproj", "{63519DEA-0C3D-4F0E-95EB-E9B6E1D55378}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RedumpTool", "RedumpTool\RedumpTool.csproj", "{556F7AA0-00D7-4D5B-96EB-D436FEFD9810}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -24,5 +26,9 @@ Global
|
||||
{63519DEA-0C3D-4F0E-95EB-E9B6E1D55378}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{63519DEA-0C3D-4F0E-95EB-E9B6E1D55378}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{63519DEA-0C3D-4F0E-95EB-E9B6E1D55378}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{556F7AA0-00D7-4D5B-96EB-D436FEFD9810}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{556F7AA0-00D7-4D5B-96EB-D436FEFD9810}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{556F7AA0-00D7-4D5B-96EB-D436FEFD9810}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{556F7AA0-00D7-4D5B-96EB-D436FEFD9810}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
@@ -44,4 +44,4 @@ namespace SabreTools.RedumpLib.Attributes
|
||||
return attributes[0] as HumanReadableAttribute;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,4 +22,4 @@ namespace SabreTools.RedumpLib.Attributes
|
||||
/// </summary>
|
||||
public string? ShortName { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,4 +23,4 @@ namespace SabreTools.RedumpLib.Attributes
|
||||
/// </summary>
|
||||
public string? ThreeLetterCodeAlt { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,4 +52,4 @@ namespace SabreTools.RedumpLib.Attributes
|
||||
/// </summary>
|
||||
public bool HasSbi { get; set; } = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
@@ -458,36 +458,8 @@ namespace SabreTools.RedumpLib
|
||||
addToLast = siteCode.IsMultiLine();
|
||||
|
||||
// Skip certain site codes because of data issues
|
||||
switch (siteCode)
|
||||
{
|
||||
// Multiple
|
||||
case SiteCode.InternalSerialName:
|
||||
case SiteCode.Multisession:
|
||||
case SiteCode.VolumeLabel:
|
||||
continue;
|
||||
|
||||
// Audio CD
|
||||
case SiteCode.RingNonZeroDataStart:
|
||||
case SiteCode.UniversalHash:
|
||||
continue;
|
||||
|
||||
// Microsoft Xbox and Xbox 360
|
||||
case SiteCode.DMIHash:
|
||||
case SiteCode.PFIHash:
|
||||
case SiteCode.SSHash:
|
||||
case SiteCode.SSVersion:
|
||||
case SiteCode.XMID:
|
||||
case SiteCode.XeMID:
|
||||
continue;
|
||||
|
||||
// Microsoft Xbox One and Series X/S
|
||||
case SiteCode.Filename:
|
||||
continue;
|
||||
|
||||
// Nintendo Gamecube
|
||||
case SiteCode.InternalName:
|
||||
continue;
|
||||
}
|
||||
if (ShouldSkipSiteCode(siteCode))
|
||||
continue;
|
||||
|
||||
// If we don't already have this site code, add it to the dictionary
|
||||
if (!info.CommonDiscInfo.CommentsSpecialFields!.ContainsKey(siteCode.Value))
|
||||
@@ -503,14 +475,14 @@ namespace SabreTools.RedumpLib
|
||||
// If we didn't find a known tag, just add the line, just in case
|
||||
if (!foundTag)
|
||||
{
|
||||
if (addToLast && lastSiteCode != null)
|
||||
if (addToLast && lastSiteCode != null && !ShouldSkipSiteCode(lastSiteCode))
|
||||
{
|
||||
if (!string.IsNullOrEmpty(info.CommonDiscInfo.CommentsSpecialFields![lastSiteCode.Value]))
|
||||
info.CommonDiscInfo.CommentsSpecialFields[lastSiteCode.Value] += "\n";
|
||||
|
||||
info.CommonDiscInfo.CommentsSpecialFields[lastSiteCode.Value] += commentLine;
|
||||
}
|
||||
else
|
||||
else if (!addToLast || lastSiteCode == null)
|
||||
{
|
||||
newComments += $"{commentLine}\n";
|
||||
}
|
||||
@@ -591,14 +563,14 @@ namespace SabreTools.RedumpLib
|
||||
// If we didn't find a known tag, just add the line, just in case
|
||||
if (!foundTag)
|
||||
{
|
||||
if (addToLast && lastSiteCode != null)
|
||||
if (addToLast && lastSiteCode != null && !ShouldSkipSiteCode(lastSiteCode))
|
||||
{
|
||||
if (!string.IsNullOrEmpty(info.CommonDiscInfo.ContentsSpecialFields![lastSiteCode.Value]))
|
||||
info.CommonDiscInfo.ContentsSpecialFields[lastSiteCode.Value] += "\n";
|
||||
|
||||
info.CommonDiscInfo.ContentsSpecialFields[lastSiteCode.Value] += contentLine;
|
||||
}
|
||||
else
|
||||
else if (!addToLast || lastSiteCode == null)
|
||||
{
|
||||
newContents += $"{contentLine}\n";
|
||||
}
|
||||
@@ -653,6 +625,7 @@ namespace SabreTools.RedumpLib
|
||||
info.TracksAndWriteOffsets ??= new TracksAndWriteOffsetsSection();
|
||||
info.SizeAndChecksums ??= new SizeAndChecksumsSection();
|
||||
info.DumpingInfo ??= new DumpingInfoSection();
|
||||
info.Artifacts ??= [];
|
||||
|
||||
// Ensure special dictionaries
|
||||
info.CommonDiscInfo.CommentsSpecialFields ??= [];
|
||||
@@ -666,11 +639,11 @@ namespace SabreTools.RedumpLib
|
||||
/// </summary>
|
||||
/// <param name="info">Existing submission information</param>
|
||||
/// <param name="seed">User-supplied submission information</param>
|
||||
public static void InjectSubmissionInformation(SubmissionInfo? info, SubmissionInfo? seed)
|
||||
public static SubmissionInfo? InjectSubmissionInformation(SubmissionInfo? info, SubmissionInfo? seed)
|
||||
{
|
||||
// If we have any invalid info
|
||||
if (seed == null)
|
||||
return;
|
||||
return info;
|
||||
|
||||
// Ensure that required sections exist
|
||||
info = EnsureAllSections(info);
|
||||
@@ -728,6 +701,48 @@ namespace SabreTools.RedumpLib
|
||||
// Info that only overwrites if supplied
|
||||
if (!string.IsNullOrEmpty(seed.CopyProtection.Protection)) info.CopyProtection.Protection = seed.CopyProtection.Protection;
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determine if a site code should be skipped on pulling
|
||||
/// </summary>
|
||||
private static bool ShouldSkipSiteCode(SiteCode? siteCode)
|
||||
{
|
||||
return siteCode switch
|
||||
{
|
||||
// Multiple
|
||||
SiteCode.HighSierraVolumeDescriptor
|
||||
or SiteCode.InternalSerialName
|
||||
or SiteCode.Multisession
|
||||
or SiteCode.VolumeLabel => true,
|
||||
|
||||
// Audio CD
|
||||
SiteCode.RingNonZeroDataStart
|
||||
or SiteCode.RingPerfectAudioOffset
|
||||
or SiteCode.UniversalHash => true,
|
||||
|
||||
// Microsoft Xbox and Xbox 360
|
||||
SiteCode.DMIHash
|
||||
or SiteCode.PFIHash
|
||||
or SiteCode.SSHash
|
||||
or SiteCode.SSVersion
|
||||
or SiteCode.XMID
|
||||
or SiteCode.XeMID => true,
|
||||
|
||||
// Microsoft Xbox One and Series X/S
|
||||
SiteCode.Filename => true,
|
||||
SiteCode.TitleID => true,
|
||||
|
||||
// Nintendo Gamecube
|
||||
SiteCode.InternalName => true,
|
||||
|
||||
// Protection
|
||||
SiteCode.Protection => true,
|
||||
|
||||
_ => false,
|
||||
};
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -739,9 +754,10 @@ namespace SabreTools.RedumpLib
|
||||
/// </summary>
|
||||
/// <param name="text">Text block to process</param>
|
||||
/// <returns>Processed text block, if possible</returns>
|
||||
private static string ReplaceHtmlWithSiteCodes(this string text)
|
||||
internal static string ReplaceHtmlWithSiteCodes(this string text)
|
||||
{
|
||||
if (string.IsNullOrEmpty(text))
|
||||
// Empty strings are ignored
|
||||
if (text.Length == 0)
|
||||
return text;
|
||||
|
||||
foreach (SiteCode? siteCode in Enum.GetValues(typeof(SiteCode)))
|
||||
|
||||
@@ -33,4 +33,4 @@ namespace SabreTools.RedumpLib.Converters
|
||||
t.WriteTo(writer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,4 +33,4 @@ namespace SabreTools.RedumpLib.Converters
|
||||
t.WriteTo(writer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -53,4 +53,4 @@ namespace SabreTools.RedumpLib.Converters
|
||||
array.WriteTo(writer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -53,4 +53,4 @@ namespace SabreTools.RedumpLib.Converters
|
||||
array.WriteTo(writer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,4 +33,4 @@ namespace SabreTools.RedumpLib.Converters
|
||||
t.WriteTo(writer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,4 +33,4 @@ namespace SabreTools.RedumpLib.Converters
|
||||
t.WriteTo(writer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,4 +33,4 @@ namespace SabreTools.RedumpLib.Converters
|
||||
t.WriteTo(writer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,18 +4,17 @@ namespace SabreTools.RedumpLib.Data
|
||||
{
|
||||
public static class Constants
|
||||
{
|
||||
// TODO: Add RegexOptions.Compiled
|
||||
#region Regular Expressions
|
||||
|
||||
/// <summary>
|
||||
/// Regex matching the added field on a disc page
|
||||
/// </summary>
|
||||
public static Regex AddedRegex = new(@"<tr><th>Added</th><td>(.*?)</td></tr>");
|
||||
public static 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>");
|
||||
public static Regex BarcodeRegex = new(@"<tr><th>Barcode</th></tr><tr><td>(.*?)</td></tr>", RegexOptions.Compiled);
|
||||
|
||||
/// <summary>
|
||||
/// Regex matching the BCA field on a disc page
|
||||
@@ -25,87 +24,87 @@ namespace SabreTools.RedumpLib.Data
|
||||
+ "<tr><td>(?<row1number>.*?)</td><td>(?<row1contents>.*?)</td><td>(?<row1ascii>.*?)</td></tr>"
|
||||
+ "<tr><td>(?<row2number>.*?)</td><td>(?<row2contents>.*?)</td><td>(?<row2ascii>.*?)</td></tr>"
|
||||
+ "<tr><td>(?<row3number>.*?)</td><td>(?<row3contents>.*?)</td><td>(?<row3ascii>.*?)</td></tr>"
|
||||
+ "<tr><td>(?<row4number>.*?)</td><td>(?<row4contents>.*?)</td><td>(?<row4ascii>.*?)</td></tr>", RegexOptions.Singleline);
|
||||
+ "<tr><td>(?<row4number>.*?)</td><td>(?<row4contents>.*?)</td><td>(?<row4ascii>.*?)</td></tr>", RegexOptions.Compiled | RegexOptions.Singleline);
|
||||
|
||||
/// <summary>
|
||||
/// Regex matching the category field on a disc page
|
||||
/// </summary>
|
||||
public static Regex CategoryRegex = new(@"<tr><th>Category</th><td>(.*?)</td></tr>");
|
||||
public static 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.Singleline);
|
||||
public static 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.Singleline);
|
||||
public static 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+)/"">");
|
||||
public static 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(@"\((.*?)\)");
|
||||
public static Regex DiscNumberLetterRegex = new(@"\((.*?)\)", RegexOptions.Compiled);
|
||||
|
||||
/// <summary>
|
||||
/// Regex matching the dumpers on a disc page
|
||||
/// </summary>
|
||||
public static Regex DumpersRegex = new(@"<a href=""/discs/dumper/(.*?)/"">");
|
||||
public static 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>");
|
||||
public static 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>");
|
||||
public static 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>");
|
||||
public static 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>");
|
||||
public static 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*");
|
||||
public static 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>");
|
||||
public static 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>");
|
||||
public static 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+)/"">");
|
||||
public static 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>");
|
||||
public static 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>");
|
||||
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);
|
||||
|
||||
/// <summary>
|
||||
/// Regex matching the PVD field on a disc page
|
||||
@@ -115,62 +114,62 @@ namespace SabreTools.RedumpLib.Data
|
||||
+ @"<tr><td>Creation</td><td>(?<creationbytes>.*?)</td><td>(?<creationdate>.*?)</td><td>(?<creationtime>.*?)</td><td>(?<creationtimezone>.*?)</td></tr>"
|
||||
+ @"<tr><td>Modification</td><td>(?<modificationbytes>.*?)</td><td>(?<modificationdate>.*?)</td><td>(?<modificationtime>.*?)</td><td>(?<modificationtimezone>.*?)</td></tr>"
|
||||
+ @"<tr><td>Expiration</td><td>(?<expirationbytes>.*?)</td><td>(?<expirationdate>.*?)</td><td>(?<expirationtime>.*?)</td><td>(?<expirationtimezone>.*?)</td></tr>"
|
||||
+ @"<tr><td>Effective</td><td>(?<effectivebytes>.*?)</td><td>(?<effectivedate>.*?)</td><td>(?<effectivetime>.*?)</td><td>(?<effectivetimezone>.*?)</td></tr>", RegexOptions.Singleline);
|
||||
+ @"<tr><td>Effective</td><td>(?<effectivebytes>.*?)</td><td>(?<effectivedate>.*?)</td><td>(?<effectivetime>.*?)</td><td>(?<effectivetimezone>.*?)</td></tr>", RegexOptions.Compiled | RegexOptions.Singleline);
|
||||
|
||||
/// <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/(.*?)/"">");
|
||||
public static 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.Singleline); // Varies based on available fields, like Addtional Mould
|
||||
public static 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.Singleline); // Varies based on available fields, like Addtional Mould
|
||||
public static 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>");
|
||||
public static 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/(.*?)/"">");
|
||||
public static 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>");
|
||||
public static 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=""(.*?)"" />");
|
||||
public static 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.Singleline);
|
||||
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);
|
||||
|
||||
/// <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>");
|
||||
public static 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>");
|
||||
public static 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>");
|
||||
public static Regex WriteOffsetRegex = new(@"<tr><th>Write offset</th><td>(.*?)</td></tr>", RegexOptions.Compiled);
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -307,4 +306,4 @@ namespace SabreTools.RedumpLib.Data
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -281,7 +281,7 @@ namespace SabreTools.RedumpLib.Data
|
||||
[Language(LongName = "Bini; Edo", ThreeLetterCode = "bin")]
|
||||
Bini,
|
||||
|
||||
[Language(LongName = "Bislama", TwoLetterCode = "bla", ThreeLetterCode = "bis")]
|
||||
[Language(LongName = "Bislama", TwoLetterCode = "bi", ThreeLetterCode = "bis")]
|
||||
Bislama,
|
||||
|
||||
// Blin; Bilin
|
||||
@@ -2008,8 +2008,8 @@ namespace SabreTools.RedumpLib.Data
|
||||
[System(Category = SystemCategory.DiscBasedConsole, LongName = "Philips CD-i", ShortName = "cdi", HasCues = true, HasDat = true)]
|
||||
PhilipsCDi,
|
||||
|
||||
[System(Category = SystemCategory.DiscBasedConsole, LongName = "Philips CD-i Digital Video", ShortName = "cdi-video", IsBanned = true)]
|
||||
PhilipsCDiDigitalVideo,
|
||||
[System(Category = SystemCategory.DiscBasedConsole, Available = false, LongName = "Playmaji Polymega")]
|
||||
PlaymajiPolymega,
|
||||
|
||||
[System(Category = SystemCategory.DiscBasedConsole, Available = false, LongName = "Pioneer LaserActive")]
|
||||
PioneerLaserActive,
|
||||
@@ -2488,8 +2488,105 @@ namespace SabreTools.RedumpLib.Data
|
||||
/// </remarks>
|
||||
public enum Region
|
||||
{
|
||||
// TODO: Should "regions" and multi-country sets be phased out?
|
||||
// TODO: Should "regions" be moved to the end?
|
||||
#region Aggregates - Redump Only
|
||||
|
||||
[HumanReadable(LongName = "Asia", ShortName = "A")]
|
||||
Asia,
|
||||
|
||||
[HumanReadable(LongName = "Asia, Europe", ShortName = "A,E")]
|
||||
AsiaEurope,
|
||||
|
||||
[HumanReadable(LongName = "Asia, USA", ShortName = "A,U")]
|
||||
AsiaUSA,
|
||||
|
||||
[HumanReadable(LongName = "Australia, Germany", ShortName = "Au,G")]
|
||||
AustraliaGermany,
|
||||
|
||||
[HumanReadable(LongName = "Australia, New Zealand", ShortName = "Au,Nz")]
|
||||
AustraliaNewZealand,
|
||||
|
||||
[HumanReadable(LongName = "Austria, Switzerland", ShortName = "At,Ch")]
|
||||
AustriaSwitzerland,
|
||||
|
||||
[HumanReadable(LongName = "Belgium, Netherlands", ShortName = "Be,N")]
|
||||
BelgiumNetherlands,
|
||||
|
||||
[HumanReadable(LongName = "Europe", ShortName = "E")]
|
||||
Europe,
|
||||
|
||||
[HumanReadable(LongName = "Europe, Asia", ShortName = "E,A")]
|
||||
EuropeAsia,
|
||||
|
||||
[HumanReadable(LongName = "Europe, Australia", ShortName = "E,Au")]
|
||||
EuropeAustralia,
|
||||
|
||||
[HumanReadable(LongName = "Europe, Canada", ShortName = "E,Ca")]
|
||||
EuropeCanada,
|
||||
|
||||
[HumanReadable(LongName = "Europe, Germany", ShortName = "E,G")]
|
||||
EuropeGermany,
|
||||
|
||||
[HumanReadable(LongName = "Export", ShortName = "Ex")]
|
||||
Export,
|
||||
|
||||
[HumanReadable(LongName = "France, Spain", ShortName = "F,S")]
|
||||
FranceSpain,
|
||||
|
||||
[HumanReadable(LongName = "Greater China", ShortName = "GC")]
|
||||
GreaterChina,
|
||||
|
||||
[HumanReadable(LongName = "Japan, Asia", ShortName = "J,A")]
|
||||
JapanAsia,
|
||||
|
||||
[HumanReadable(LongName = "Japan, Europe", ShortName = "J,E")]
|
||||
JapanEurope,
|
||||
|
||||
[HumanReadable(LongName = "Japan, Korea", ShortName = "J,K")]
|
||||
JapanKorea,
|
||||
|
||||
[HumanReadable(LongName = "Japan, USA", ShortName = "J,U")]
|
||||
JapanUSA,
|
||||
|
||||
[HumanReadable(LongName = "Latin America", ShortName = "LAm")]
|
||||
LatinAmerica,
|
||||
|
||||
[HumanReadable(LongName = "Scandinavia", ShortName = "Sca")]
|
||||
Scandinavia,
|
||||
|
||||
[HumanReadable(LongName = "Spain, Portugal", ShortName = "S,Pt")]
|
||||
SpainPortugal,
|
||||
|
||||
[HumanReadable(LongName = "UK, Australia", ShortName = "Uk,Au")]
|
||||
UKAustralia,
|
||||
|
||||
[HumanReadable(LongName = "USA, Asia", ShortName = "U,A")]
|
||||
USAAsia,
|
||||
|
||||
[HumanReadable(LongName = "USA, Australia", ShortName = "U,Au")]
|
||||
USAAustralia,
|
||||
|
||||
[HumanReadable(LongName = "USA, Brazil", ShortName = "U,B")]
|
||||
USABrazil,
|
||||
|
||||
[HumanReadable(LongName = "USA, Canada", ShortName = "U,Ca")]
|
||||
USACanada,
|
||||
|
||||
[HumanReadable(LongName = "USA, Europe", ShortName = "U,E")]
|
||||
USAEurope,
|
||||
|
||||
[HumanReadable(LongName = "USA, Germany", ShortName = "U,G")]
|
||||
USAGermany,
|
||||
|
||||
[HumanReadable(LongName = "USA, Japan", ShortName = "U,J")]
|
||||
USAJapan,
|
||||
|
||||
[HumanReadable(LongName = "USA, Korea", ShortName = "U,K")]
|
||||
USAKorea,
|
||||
|
||||
[HumanReadable(LongName = "World", ShortName = "W")]
|
||||
World,
|
||||
|
||||
#endregion
|
||||
|
||||
#region A
|
||||
|
||||
@@ -2535,30 +2632,12 @@ namespace SabreTools.RedumpLib.Data
|
||||
[HumanReadable(LongName = "Ascension Island", ShortName = "Ac")]
|
||||
AscensionIsland,
|
||||
|
||||
[HumanReadable(LongName = "Asia", ShortName = "A")]
|
||||
Asia,
|
||||
|
||||
[HumanReadable(LongName = "Asia, Europe", ShortName = "A,E")]
|
||||
AsiaEurope,
|
||||
|
||||
[HumanReadable(LongName = "Asia, USA", ShortName = "A,U")]
|
||||
AsiaUSA,
|
||||
|
||||
[HumanReadable(LongName = "Australia", ShortName = "Au")]
|
||||
Australia,
|
||||
|
||||
[HumanReadable(LongName = "Australia, Germany", ShortName = "Au,G")]
|
||||
AustraliaGermany,
|
||||
|
||||
[HumanReadable(LongName = "Australia, New Zealand", ShortName = "Au,Nz")]
|
||||
AustraliaNewZealand,
|
||||
|
||||
[HumanReadable(LongName = "Austria", ShortName = "At")]
|
||||
Austria,
|
||||
|
||||
[HumanReadable(LongName = "Austria, Switzerland", ShortName = "At,Ch")]
|
||||
AustriaSwitzerland,
|
||||
|
||||
[HumanReadable(LongName = "Azerbaijan", ShortName = "Az")]
|
||||
Azerbaijan,
|
||||
|
||||
@@ -2584,9 +2663,6 @@ namespace SabreTools.RedumpLib.Data
|
||||
[HumanReadable(LongName = "Belgium", ShortName = "Be")]
|
||||
Belgium,
|
||||
|
||||
[HumanReadable(LongName = "Belgium, Netherlands", ShortName = "Be,N")]
|
||||
BelgiumNetherlands,
|
||||
|
||||
[HumanReadable(LongName = "Belize", ShortName = "Bz")]
|
||||
Belize,
|
||||
|
||||
@@ -2767,21 +2843,6 @@ namespace SabreTools.RedumpLib.Data
|
||||
[HumanReadable(LongName = "Ethiopia", ShortName = "Et")]
|
||||
Ethiopia,
|
||||
|
||||
[HumanReadable(LongName = "Europe", ShortName = "E")]
|
||||
Europe,
|
||||
|
||||
[HumanReadable(LongName = "Europe, Asia", ShortName = "E,A")]
|
||||
EuropeAsia,
|
||||
|
||||
[HumanReadable(LongName = "Europe, Australia", ShortName = "E,Au")]
|
||||
EuropeAustralia,
|
||||
|
||||
[HumanReadable(LongName = "Europe, Canada", ShortName = "E,Ca")]
|
||||
EuropeCanada,
|
||||
|
||||
[HumanReadable(LongName = "Europe, Germany", ShortName = "E,G")]
|
||||
EuropeGermany,
|
||||
|
||||
// Commented out to avoid confusion
|
||||
//[HumanReadable(LongName = "European Union", ShortName = "Eu")]
|
||||
//EuropeanUnion,
|
||||
@@ -2790,9 +2851,6 @@ namespace SabreTools.RedumpLib.Data
|
||||
//[HumanReadable(LongName = "Eurozone", ShortName = "Ez")]
|
||||
//Eurozone,
|
||||
|
||||
[HumanReadable(LongName = "Export", ShortName = "Ex")]
|
||||
Export,
|
||||
|
||||
#endregion
|
||||
|
||||
#region F
|
||||
@@ -2821,9 +2879,6 @@ namespace SabreTools.RedumpLib.Data
|
||||
//[HumanReadable(LongName = "France, Metropolitan", ShortName = "Fx")]
|
||||
//FranceMetropolitan,
|
||||
|
||||
[HumanReadable(LongName = "France, Spain", ShortName = "F,S")]
|
||||
FranceSpain,
|
||||
|
||||
[HumanReadable(LongName = "French Guiana", ShortName = "Gf")]
|
||||
FrenchGuiana,
|
||||
|
||||
@@ -2856,9 +2911,6 @@ namespace SabreTools.RedumpLib.Data
|
||||
[HumanReadable(LongName = "Gibraltar", ShortName = "Gi")]
|
||||
Gibraltar,
|
||||
|
||||
[HumanReadable(LongName = "Greater China", ShortName = "GC")]
|
||||
GreaterChina,
|
||||
|
||||
[HumanReadable(LongName = "Greece", ShortName = "Gr")]
|
||||
Greece,
|
||||
|
||||
@@ -2958,18 +3010,6 @@ namespace SabreTools.RedumpLib.Data
|
||||
[HumanReadable(LongName = "Japan", ShortName = "J")]
|
||||
Japan,
|
||||
|
||||
[HumanReadable(LongName = "Japan, Asia", ShortName = "J,A")]
|
||||
JapanAsia,
|
||||
|
||||
[HumanReadable(LongName = "Japan, Europe", ShortName = "J,E")]
|
||||
JapanEurope,
|
||||
|
||||
[HumanReadable(LongName = "Japan, Korea", ShortName = "J,K")]
|
||||
JapanKorea,
|
||||
|
||||
[HumanReadable(LongName = "Japan, USA", ShortName = "J,U")]
|
||||
JapanUSA,
|
||||
|
||||
[HumanReadable(LongName = "Jersey", ShortName = "Je")]
|
||||
Jersey,
|
||||
|
||||
@@ -3009,9 +3049,6 @@ namespace SabreTools.RedumpLib.Data
|
||||
[HumanReadable(LongName = "(Laos) Lao People's Democratic Republic", ShortName = "La")]
|
||||
Laos,
|
||||
|
||||
[HumanReadable(LongName = "Latin America", ShortName = "LAm")]
|
||||
LatinAmerica,
|
||||
|
||||
[HumanReadable(LongName = "Latvia", ShortName = "Lv")]
|
||||
Latvia,
|
||||
|
||||
@@ -3264,9 +3301,6 @@ namespace SabreTools.RedumpLib.Data
|
||||
[HumanReadable(LongName = "Saudi Arabia", ShortName = "Sa")]
|
||||
SaudiArabia,
|
||||
|
||||
[HumanReadable(LongName = "Scandinavia", ShortName = "Sca")]
|
||||
Scandinavia,
|
||||
|
||||
[HumanReadable(LongName = "Senegal", ShortName = "Sn")]
|
||||
Senegal,
|
||||
|
||||
@@ -3310,9 +3344,6 @@ namespace SabreTools.RedumpLib.Data
|
||||
[HumanReadable(LongName = "Spain", ShortName = "S")]
|
||||
Spain,
|
||||
|
||||
[HumanReadable(LongName = "Spain, Portugal", ShortName = "S,Pt")]
|
||||
SpainPortugal,
|
||||
|
||||
[HumanReadable(LongName = "Sri Lanka", ShortName = "Lk")]
|
||||
SriLanka,
|
||||
|
||||
@@ -3397,9 +3428,6 @@ namespace SabreTools.RedumpLib.Data
|
||||
[HumanReadable(LongName = "UK", ShortName = "Uk")]
|
||||
UnitedKingdom,
|
||||
|
||||
[HumanReadable(LongName = "UK, Australia", ShortName = "Uk,Au")]
|
||||
UKAustralia,
|
||||
|
||||
[HumanReadable(LongName = "Ukraine", ShortName = "Ue")]
|
||||
Ukraine,
|
||||
|
||||
@@ -3424,30 +3452,6 @@ namespace SabreTools.RedumpLib.Data
|
||||
[HumanReadable(LongName = "USA", ShortName = "U")]
|
||||
UnitedStatesOfAmerica,
|
||||
|
||||
[HumanReadable(LongName = "USA, Asia", ShortName = "U,A")]
|
||||
USAAsia,
|
||||
|
||||
[HumanReadable(LongName = "USA, Australia", ShortName = "U,Au")]
|
||||
USAAustralia,
|
||||
|
||||
[HumanReadable(LongName = "USA, Brazil", ShortName = "U,B")]
|
||||
USABrazil,
|
||||
|
||||
[HumanReadable(LongName = "USA, Canada", ShortName = "U,Ca")]
|
||||
USACanada,
|
||||
|
||||
[HumanReadable(LongName = "USA, Europe", ShortName = "U,E")]
|
||||
USAEurope,
|
||||
|
||||
[HumanReadable(LongName = "USA, Germany", ShortName = "U,G")]
|
||||
USAGermany,
|
||||
|
||||
[HumanReadable(LongName = "USA, Japan", ShortName = "U,J")]
|
||||
USAJapan,
|
||||
|
||||
[HumanReadable(LongName = "USA, Korea", ShortName = "U,K")]
|
||||
USAKorea,
|
||||
|
||||
[HumanReadable(LongName = "USSR", ShortName = "Su")]
|
||||
USSR,
|
||||
|
||||
@@ -3483,9 +3487,6 @@ namespace SabreTools.RedumpLib.Data
|
||||
[HumanReadable(LongName = "Western Sahara", ShortName = "Eh")]
|
||||
WesternSahara,
|
||||
|
||||
[HumanReadable(LongName = "World", ShortName = "W")]
|
||||
World,
|
||||
|
||||
#endregion
|
||||
|
||||
#region Y
|
||||
@@ -3526,7 +3527,7 @@ namespace SabreTools.RedumpLib.Data
|
||||
[HumanReadable(ShortName = "[T:ALTF]", LongName = "<b>Alternative Foreign Title</b>:")]
|
||||
AlternativeForeignTitle,
|
||||
|
||||
// TODO: This doesn't have a site tag yet
|
||||
// This doesn't have a site tag yet
|
||||
[HumanReadable(ShortName = "<b>Applications</b>:", LongName = "<b>Applications</b>:")]
|
||||
Applications,
|
||||
|
||||
@@ -3536,30 +3537,38 @@ namespace SabreTools.RedumpLib.Data
|
||||
[HumanReadable(ShortName = "[T:BBFC]", LongName = "<b>BBFC Reg. No.</b>:")]
|
||||
BBFCRegistrationNumber,
|
||||
|
||||
// TODO: This doesn't have a site tag yet
|
||||
// This doesn't have a site tag yet
|
||||
[HumanReadable(ShortName = "<b>Bethesda ID</b>:", LongName = "<b>Bethesda ID</b>:")]
|
||||
BethesdaID,
|
||||
|
||||
// TODO: This doesn't have a site tag yet
|
||||
// This doesn't have a site tag yet
|
||||
[HumanReadable(ShortName = "<b>CD Projekt ID</b>:", LongName = "<b>CD Projekt ID</b>:")]
|
||||
CDProjektID,
|
||||
|
||||
// TODO: This doesn't have a site tag yet
|
||||
// This doesn't have a site tag yet
|
||||
[HumanReadable(ShortName = "<b>Compatible OS</b>:", LongName = "<b>Compatible OS</b>:")]
|
||||
CompatibleOS,
|
||||
|
||||
// TODO: This doesn't have a site tag yet
|
||||
// This doesn't have a site tag yet
|
||||
[HumanReadable(ShortName = "<b>Disc Hologram ID</b>:", LongName = "<b>Disc Hologram ID</b>:")]
|
||||
DiscHologramID,
|
||||
|
||||
// TODO: This doesn't have a site tag yet
|
||||
// This doesn't have a site tag yet
|
||||
[HumanReadable(ShortName = "<b>Disc Title (non-Latin)</b>:", LongName = "<b>Disc Title (non-Latin)</b>:")]
|
||||
DiscTitleNonLatin,
|
||||
|
||||
// This doesn't have a site tag yet
|
||||
[HumanReadable(ShortName = "<b>DMI</b>:", LongName = "<b>DMI</b>:")]
|
||||
DMIHash,
|
||||
|
||||
[HumanReadable(ShortName = "[T:DNAS]", LongName = "<b>DNAS Disc ID</b>:")]
|
||||
DNASDiscID,
|
||||
|
||||
// TODO: This doesn't have a site tag yet
|
||||
// This doesn't have a site tag yet
|
||||
[HumanReadable(ShortName = "<b>Edition (non-Latin)</b>:", LongName = "<b>Edition (non-Latin)</b>:")]
|
||||
EditionNonLatin,
|
||||
|
||||
// This doesn't have a site tag yet
|
||||
[HumanReadable(ShortName = "<b>Eidos ID</b>:", LongName = "<b>Eidos ID</b>:")]
|
||||
EidosID,
|
||||
|
||||
@@ -3569,7 +3578,7 @@ namespace SabreTools.RedumpLib.Data
|
||||
[HumanReadable(ShortName = "[T:X]", LongName = "<b>Extras</b>:")]
|
||||
Extras,
|
||||
|
||||
// TODO: This doesn't have a site tag yet
|
||||
// This doesn't have a site tag yet
|
||||
[HumanReadable(ShortName = "<b>Filename</b>:", LongName = "<b>Filename</b>:")]
|
||||
Filename,
|
||||
|
||||
@@ -3579,7 +3588,7 @@ namespace SabreTools.RedumpLib.Data
|
||||
[HumanReadable(ShortName = "[T:GF]", LongName = "<b>Game Footage</b>:")]
|
||||
GameFootage,
|
||||
|
||||
// TODO: This doesn't have a site tag yet
|
||||
// This doesn't have a site tag yet
|
||||
[HumanReadable(ShortName = "<b>Games</b>:", LongName = "<b>Games</b>:")]
|
||||
Games,
|
||||
|
||||
@@ -3589,13 +3598,21 @@ namespace SabreTools.RedumpLib.Data
|
||||
[HumanReadable(ShortName = "[T:GTID]", LongName = "<b>GT Interactive ID</b>:")]
|
||||
GTInteractiveID,
|
||||
|
||||
// TODO: This doesn't have a site tag yet
|
||||
// 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,
|
||||
|
||||
[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,
|
||||
|
||||
@@ -3614,14 +3631,18 @@ namespace SabreTools.RedumpLib.Data
|
||||
[HumanReadable(ShortName = "[T:KID]", LongName = "<b>Konami ID</b>:")]
|
||||
KonamiID,
|
||||
|
||||
// This doesn't have a site tag yet
|
||||
[HumanReadable(ShortName = "<b>Logs Link</b>:", LongName = "<b>Logs Link</b>:")]
|
||||
LogsLink,
|
||||
|
||||
[HumanReadable(ShortName = "[T:LAID]", LongName = "<b>Lucas Arts ID</b>:")]
|
||||
LucasArtsID,
|
||||
|
||||
// TODO: This doesn't have a site tag yet
|
||||
// This doesn't have a site tag yet
|
||||
[HumanReadable(ShortName = "<b>Microsoft ID</b>:", LongName = "<b>Microsoft ID</b>:")]
|
||||
MicrosoftID,
|
||||
|
||||
// TODO: This doesn't have a site tag yet
|
||||
// This doesn't have a site tag yet
|
||||
[HumanReadable(ShortName = "<b>Multisession</b>:", LongName = "<b>Multisession</b>:")]
|
||||
Multisession,
|
||||
|
||||
@@ -3643,7 +3664,12 @@ namespace SabreTools.RedumpLib.Data
|
||||
[HumanReadable(ShortName = "[T:P]", LongName = "<b>Patches</b>:")]
|
||||
Patches,
|
||||
|
||||
// TODO: This doesn't have a site tag yet
|
||||
// This doesn't have a site tag yet
|
||||
/// <remarks>No text value after</remarks>
|
||||
[HumanReadable(ShortName = "PC/Mac Hybrid", LongName = "PC/Mac Hybrid")]
|
||||
PCMacHybrid,
|
||||
|
||||
// This doesn't have a site tag yet
|
||||
[HumanReadable(ShortName = "<b>PFI</b>:", LongName = "<b>PFI</b>:")]
|
||||
PFIHash,
|
||||
|
||||
@@ -3653,16 +3679,25 @@ namespace SabreTools.RedumpLib.Data
|
||||
[HumanReadable(ShortName = "[T:PCID]", LongName = "<b>Pony Canyon ID</b>:")]
|
||||
PonyCanyonID,
|
||||
|
||||
/// <remarks>No text value after</remarks>
|
||||
[HumanReadable(ShortName = "[T:PT2]", LongName = "<b>Postgap type</b>: Form 2")]
|
||||
PostgapType,
|
||||
|
||||
[HumanReadable(ShortName = "[T:PPN]", LongName = "<b>PPN</b>:")]
|
||||
PPN,
|
||||
|
||||
// TODO: This doesn't have a site tag yet
|
||||
// This doesn't have a site tag for some systems yet
|
||||
[HumanReadable(ShortName = "<b>Protection</b>:", LongName = "<b>Protection</b>:")]
|
||||
Protection,
|
||||
|
||||
// This doesn't have a site tag yet
|
||||
[HumanReadable(ShortName = "<b>Ring non-zero data start</b>:", LongName = "<b>Ring non-zero data start</b>:")]
|
||||
RingNonZeroDataStart,
|
||||
|
||||
// This doesn't have a site tag yet
|
||||
[HumanReadable(ShortName = "<b>Ring Perfect Audio Offset</b>:", LongName = "<b>Ring Perfect Audio Offset</b>:")]
|
||||
RingPerfectAudioOffset,
|
||||
|
||||
[HumanReadable(ShortName = "[T:RD]", LongName = "<b>Rolling Demos</b>:")]
|
||||
RollingDemos,
|
||||
|
||||
@@ -3678,15 +3713,15 @@ namespace SabreTools.RedumpLib.Data
|
||||
[HumanReadable(ShortName = "[T:S]", LongName = "<b>Series</b>:")]
|
||||
Series,
|
||||
|
||||
// TODO: This doesn't have a site tag yet
|
||||
// This doesn't have a site tag yet
|
||||
[HumanReadable(ShortName = "<b>Sierra ID</b>:", LongName = "<b>Sierra ID</b>:")]
|
||||
SierraID,
|
||||
|
||||
// TODO: This doesn't have a site tag yet
|
||||
// This doesn't have a site tag yet
|
||||
[HumanReadable(ShortName = "<b>SS</b>:", LongName = "<b>SS</b>:")]
|
||||
SSHash,
|
||||
|
||||
// TODO: This doesn't have a site tag yet
|
||||
// This doesn't have a site tag yet
|
||||
[HumanReadable(ShortName = "<b>SS version</b>:", LongName = "<b>SS version</b>:")]
|
||||
SSVersion,
|
||||
|
||||
@@ -3696,10 +3731,14 @@ 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,
|
||||
|
||||
// TODO: This doesn't have a site tag yet
|
||||
// This doesn't have a site tag yet
|
||||
[HumanReadable(ShortName = "<b>Universal Hash (SHA-1)</b>:", LongName = "<b>Universal Hash (SHA-1)</b>:")]
|
||||
UniversalHash,
|
||||
|
||||
@@ -3715,14 +3754,15 @@ namespace SabreTools.RedumpLib.Data
|
||||
[HumanReadable(ShortName = "[T:VOL]", LongName = "<b>Volume Label</b>:")]
|
||||
VolumeLabel,
|
||||
|
||||
/// <remarks>No text value after</remarks>
|
||||
[HumanReadable(ShortName = "[T:VCD]", LongName = "<b>V-CD</b>")]
|
||||
VCD,
|
||||
|
||||
// TODO: This doesn't have a site tag yet
|
||||
// This doesn't have a site tag yet
|
||||
[HumanReadable(ShortName = "<b>XeMID</b>:", LongName = "<b>XeMID</b>:")]
|
||||
XeMID,
|
||||
|
||||
// TODO: This doesn't have a site tag yet
|
||||
// This doesn't have a site tag yet
|
||||
[HumanReadable(ShortName = "<b>XMID</b>:", LongName = "<b>XMID</b>:")]
|
||||
XMID,
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,8 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
#if NET40_OR_GREATER || NETCOREAPP
|
||||
using System.Linq;
|
||||
#endif
|
||||
using Newtonsoft.Json;
|
||||
using SabreTools.RedumpLib.Converters;
|
||||
|
||||
@@ -75,7 +72,6 @@ namespace SabreTools.RedumpLib.Data
|
||||
|
||||
public object Clone()
|
||||
{
|
||||
#if NET20 || NET35
|
||||
Dictionary<string, string>? artifacts = null;
|
||||
if (this.Artifacts != null)
|
||||
{
|
||||
@@ -85,9 +81,6 @@ namespace SabreTools.RedumpLib.Data
|
||||
artifacts[kvp.Key] = kvp.Value;
|
||||
}
|
||||
}
|
||||
#else
|
||||
var artifacts = this.Artifacts?.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
|
||||
#endif
|
||||
|
||||
return new SubmissionInfo
|
||||
{
|
||||
@@ -249,7 +242,6 @@ namespace SabreTools.RedumpLib.Data
|
||||
|
||||
public object Clone()
|
||||
{
|
||||
#if NET20 || NET35
|
||||
Dictionary<SiteCode, string>? commentsSpecialFields = null;
|
||||
if (this.CommentsSpecialFields != null)
|
||||
{
|
||||
@@ -269,10 +261,6 @@ namespace SabreTools.RedumpLib.Data
|
||||
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
|
||||
{
|
||||
@@ -455,7 +443,6 @@ namespace SabreTools.RedumpLib.Data
|
||||
|
||||
public object Clone()
|
||||
{
|
||||
#if NET20 || NET35
|
||||
Dictionary<string, List<string>?>? fullProtections = null;
|
||||
if (this.FullProtections != null)
|
||||
{
|
||||
@@ -465,9 +452,6 @@ namespace SabreTools.RedumpLib.Data
|
||||
fullProtections[kvp.Key] = kvp.Value;
|
||||
}
|
||||
}
|
||||
#else
|
||||
var fullProtections = this.FullProtections?.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
|
||||
#endif
|
||||
|
||||
return new CopyProtectionSection
|
||||
{
|
||||
|
||||
9
SabreTools.RedumpLib/ExtensionAttribute.cs
Normal file
9
SabreTools.RedumpLib/ExtensionAttribute.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
#if NET20
|
||||
|
||||
namespace System.Runtime.CompilerServices
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method)]
|
||||
internal sealed class ExtensionAttribute : Attribute {}
|
||||
}
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,17 +1,19 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<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;netstandard2.0;netstandard2.1</TargetFrameworks>
|
||||
<IncludeSymbols>true</IncludeSymbols>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<Version>1.5.2</Version>
|
||||
<Version>1.7.5</Version>
|
||||
|
||||
<!-- Package Properties -->
|
||||
<Authors>Matt Nadareski</Authors>
|
||||
<Description>Code to interact with redump.org</Description>
|
||||
<Copyright>Copyright (c) Matt Nadareski 2020-2024</Copyright>
|
||||
<Copyright>Copyright (c) Matt Nadareski 2020-2025</Copyright>
|
||||
<PackageProjectUrl>https://github.com/SabreTools/</PackageProjectUrl>
|
||||
<PackageReadmeFile>README.md</PackageReadmeFile>
|
||||
<RepositoryUrl>https://github.com/SabreTools/SabreTools.RedumpLib</RepositoryUrl>
|
||||
@@ -20,35 +22,18 @@
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Support All Frameworks -->
|
||||
<PropertyGroup Condition="$(TargetFramework.StartsWith(`net2`)) OR $(TargetFramework.StartsWith(`net3`)) OR $(TargetFramework.StartsWith(`net4`))">
|
||||
<RuntimeIdentifiers>win-x86;win-x64</RuntimeIdentifiers>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="$(TargetFramework.StartsWith(`netcoreapp`)) OR $(TargetFramework.StartsWith(`net5`))">
|
||||
<RuntimeIdentifiers>win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64</RuntimeIdentifiers>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="$(TargetFramework.StartsWith(`net6`)) OR $(TargetFramework.StartsWith(`net7`)) OR $(TargetFramework.StartsWith(`net8`)) OR $(TargetFramework.StartsWith(`net9`))">
|
||||
<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>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<InternalsVisibleTo Include="SabreTools.RedumpLib.Test" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="../README.md" Pack="true" PackagePath="" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Support for old .NET versions -->
|
||||
<ItemGroup Condition="$(TargetFramework.StartsWith(`net2`))">
|
||||
<PackageReference Include="Net30.LinqBridge" Version="1.3.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="$(TargetFramework.StartsWith(`net2`)) OR $(TargetFramework.StartsWith(`net3`)) OR $(TargetFramework.StartsWith(`net40`))">
|
||||
<PackageReference Include="MinAsyncBridge" Version="0.12.4" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="SabreTools.Models" Version="1.5.0" />
|
||||
<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.4" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
@@ -21,6 +21,14 @@ namespace SabreTools.RedumpLib
|
||||
|
||||
switch (info.CommonDiscInfo.Media)
|
||||
{
|
||||
case DiscType.DVD5:
|
||||
case DiscType.DVD9:
|
||||
if (info.SizeAndChecksums.Layerbreak != default)
|
||||
info.CommonDiscInfo.Media = DiscType.DVD9;
|
||||
else
|
||||
info.CommonDiscInfo.Media = DiscType.DVD5;
|
||||
break;
|
||||
|
||||
case DiscType.BD25:
|
||||
case DiscType.BD33:
|
||||
case DiscType.BD50:
|
||||
@@ -31,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 == SabreTools.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 == SabreTools.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;
|
||||
@@ -45,14 +53,6 @@ namespace SabreTools.RedumpLib
|
||||
info.CommonDiscInfo.Media = DiscType.BD25;
|
||||
break;
|
||||
|
||||
case DiscType.DVD5:
|
||||
case DiscType.DVD9:
|
||||
if (info.SizeAndChecksums.Layerbreak != default)
|
||||
info.CommonDiscInfo.Media = DiscType.DVD9;
|
||||
else
|
||||
info.CommonDiscInfo.Media = DiscType.DVD5;
|
||||
break;
|
||||
|
||||
case DiscType.HDDVDSL:
|
||||
case DiscType.HDDVDDL:
|
||||
if (info.SizeAndChecksums.Layerbreak != default)
|
||||
@@ -157,7 +157,6 @@ 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)
|
||||
{
|
||||
|
||||
@@ -32,9 +32,12 @@ namespace SabreTools.RedumpLib.Web
|
||||
{
|
||||
WebRequest request = base.GetWebRequest(address);
|
||||
if (request is HttpWebRequest webRequest)
|
||||
{
|
||||
webRequest.Timeout = 30 * 1000; // 30 seconds
|
||||
webRequest.CookieContainer = _container;
|
||||
}
|
||||
|
||||
return request;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,4 +18,4 @@ namespace SabreTools.RedumpLib.Web
|
||||
Thread.Sleep(delay * 100);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,4 +62,4 @@ namespace SabreTools.RedumpLib.Web
|
||||
return ids;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,4 +68,4 @@ namespace SabreTools.RedumpLib.Web
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace SabreTools.RedumpLib.Web
|
||||
/// <summary>
|
||||
/// Internal client for interaction
|
||||
/// </summary>
|
||||
#if NETFRAMEWORK
|
||||
#if NETFRAMEWORK || NETSTANDARD2_0_OR_GREATER
|
||||
private CookieWebClient _internalClient;
|
||||
#else
|
||||
private HttpClient _internalClient;
|
||||
@@ -49,10 +49,10 @@ namespace SabreTools.RedumpLib.Web
|
||||
/// </summary>
|
||||
public RedumpClient()
|
||||
{
|
||||
#if NETFRAMEWORK
|
||||
#if NETFRAMEWORK || NETSTANDARD2_0_OR_GREATER
|
||||
_internalClient = new CookieWebClient();
|
||||
#else
|
||||
_internalClient = new HttpClient(new HttpClientHandler { UseCookies = true });
|
||||
_internalClient = new HttpClient(new HttpClientHandler { UseCookies = true }) { Timeout = TimeSpan.FromSeconds(30) };
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -131,7 +131,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 +205,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 +231,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 +271,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);
|
||||
@@ -497,7 +497,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()));
|
||||
@@ -928,4 +928,4 @@ namespace SabreTools.RedumpLib.Web
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,4 +99,4 @@ namespace SabreTools.RedumpLib.Web
|
||||
return ids;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,4 +49,4 @@ namespace SabreTools.RedumpLib.Web
|
||||
return ids;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
119
publish-nix.sh
Normal file → Executable file
119
publish-nix.sh
Normal file → Executable file
@@ -7,13 +7,24 @@
|
||||
# in an unpredictable way and result in an incomplete output.
|
||||
|
||||
# Optional parameters
|
||||
USE_ALL=false
|
||||
INCLUDE_DEBUG=false
|
||||
NO_BUILD=false
|
||||
while getopts "uba" OPTION
|
||||
do
|
||||
NO_ARCHIVE=false
|
||||
while getopts "udba" OPTION; do
|
||||
case $OPTION in
|
||||
u)
|
||||
USE_ALL=true
|
||||
;;
|
||||
d)
|
||||
INCLUDE_DEBUG=true
|
||||
;;
|
||||
b)
|
||||
NO_BUILD=true
|
||||
;;
|
||||
a)
|
||||
NO_ARCHIVE=true
|
||||
;;
|
||||
*)
|
||||
echo "Invalid option provided"
|
||||
exit 1
|
||||
@@ -24,6 +35,33 @@ done
|
||||
# Set the current directory as a variable
|
||||
BUILD_FOLDER=$PWD
|
||||
|
||||
# Set the current commit hash
|
||||
COMMIT=`git log --pretty=%H -1`
|
||||
|
||||
# Output the selected options
|
||||
echo "Selected Options:"
|
||||
echo " Use all frameworks (-u) $USE_ALL"
|
||||
echo " Include debug builds (-d) $INCLUDE_DEBUG"
|
||||
echo " No build (-b) $NO_BUILD"
|
||||
echo " No archive (-a) $NO_ARCHIVE"
|
||||
echo " "
|
||||
|
||||
# Create the build matrix arrays
|
||||
FRAMEWORKS=("net9.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")
|
||||
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")
|
||||
VALID_CROSS_PLATFORM_RUNTIMES=("win-arm64" "linux-x64" "linux-arm64" "osx-x64" "osx-arm64")
|
||||
|
||||
# Only build if requested
|
||||
if [ $NO_BUILD = false ]
|
||||
then
|
||||
@@ -33,4 +71,81 @@ then
|
||||
|
||||
# Create Nuget Package
|
||||
dotnet pack SabreTools.RedumpLib/SabreTools.RedumpLib.csproj --output $BUILD_FOLDER
|
||||
|
||||
# Build Tool
|
||||
for FRAMEWORK in "${FRAMEWORKS[@]}"; do
|
||||
for RUNTIME in "${RUNTIMES[@]}"; do
|
||||
# Output the current build
|
||||
echo "===== Build Tool - $FRAMEWORK, $RUNTIME ====="
|
||||
|
||||
# If we have an invalid combination of framework and runtime
|
||||
if [[ ! $(echo ${VALID_CROSS_PLATFORM_FRAMEWORKS[@]} | fgrep -w $FRAMEWORK) ]]; then
|
||||
if [[ $(echo ${VALID_CROSS_PLATFORM_RUNTIMES[@]} | fgrep -w $RUNTIME) ]]; then
|
||||
echo "Skipped due to invalid combination"
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
|
||||
# If we have Apple silicon but an unsupported framework
|
||||
if [[ ! $(echo ${VALID_APPLE_FRAMEWORKS[@]} | fgrep -w $FRAMEWORK) ]]; then
|
||||
if [ $RUNTIME = "osx-arm64" ]; then
|
||||
echo "Skipped due to no Apple Silicon support"
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
|
||||
# Only .NET 5 and above can publish to a single file
|
||||
if [[ $(echo ${SINGLE_FILE_CAPABLE[@]} | fgrep -w $FRAMEWORK) ]]; then
|
||||
# Only include Debug if set
|
||||
if [ $INCLUDE_DEBUG = true ]; then
|
||||
dotnet publish RedumpTool/RedumpTool.csproj -f $FRAMEWORK -r $RUNTIME -c Debug --self-contained true --version-suffix $COMMIT -p:PublishSingleFile=true
|
||||
fi
|
||||
dotnet publish RedumpTool/RedumpTool.csproj -f $FRAMEWORK -r $RUNTIME -c Release --self-contained true --version-suffix $COMMIT -p:PublishSingleFile=true -p:DebugType=None -p:DebugSymbols=false
|
||||
else
|
||||
# Only include Debug if set
|
||||
if [ $INCLUDE_DEBUG = true ]; then
|
||||
dotnet publish RedumpTool/RedumpTool.csproj -f $FRAMEWORK -r $RUNTIME -c Debug --self-contained true --version-suffix $COMMIT
|
||||
fi
|
||||
dotnet publish RedumpTool/RedumpTool.csproj -f $FRAMEWORK -r $RUNTIME -c Release --self-contained true --version-suffix $COMMIT -p:DebugType=None -p:DebugSymbols=false
|
||||
fi
|
||||
done
|
||||
done
|
||||
fi
|
||||
|
||||
# Only create archives if requested
|
||||
if [ $NO_ARCHIVE = false ]; then
|
||||
# Create Tool archives
|
||||
for FRAMEWORK in "${FRAMEWORKS[@]}"; do
|
||||
for RUNTIME in "${RUNTIMES[@]}"; do
|
||||
# Output the current build
|
||||
echo "===== Archive Tool - $FRAMEWORK, $RUNTIME ====="
|
||||
|
||||
# If we have an invalid combination of framework and runtime
|
||||
if [[ ! $(echo ${VALID_CROSS_PLATFORM_FRAMEWORKS[@]} | fgrep -w $FRAMEWORK) ]]; then
|
||||
if [[ $(echo ${VALID_CROSS_PLATFORM_RUNTIMES[@]} | fgrep -w $RUNTIME) ]]; then
|
||||
echo "Skipped due to invalid combination"
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
|
||||
# If we have Apple silicon but an unsupported framework
|
||||
if [[ ! $(echo ${VALID_APPLE_FRAMEWORKS[@]} | fgrep -w $FRAMEWORK) ]]; then
|
||||
if [ $RUNTIME = "osx-arm64" ]; then
|
||||
echo "Skipped due to no Apple Silicon support"
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
|
||||
# Only include Debug if set
|
||||
if [ $INCLUDE_DEBUG = true ]; then
|
||||
cd $BUILD_FOLDER/RedumpTool/bin/Debug/${FRAMEWORK}/${RUNTIME}/publish/
|
||||
zip -r $BUILD_FOLDER/RedumpTool_${FRAMEWORK}_${RUNTIME}_debug.zip .
|
||||
fi
|
||||
cd $BUILD_FOLDER/RedumpTool/bin/Release/${FRAMEWORK}/${RUNTIME}/publish/
|
||||
zip -r $BUILD_FOLDER/RedumpTool_${FRAMEWORK}_${RUNTIME}_release.zip .
|
||||
done
|
||||
done
|
||||
|
||||
# Reset the directory
|
||||
cd $BUILD_FOLDER
|
||||
fi
|
||||
111
publish-win.ps1
111
publish-win.ps1
@@ -6,14 +6,53 @@
|
||||
|
||||
# Optional parameters
|
||||
param(
|
||||
[Parameter(Mandatory = $false)]
|
||||
[Alias("UseAll")]
|
||||
[switch]$USE_ALL,
|
||||
|
||||
[Parameter(Mandatory = $false)]
|
||||
[Alias("IncludeDebug")]
|
||||
[switch]$INCLUDE_DEBUG,
|
||||
|
||||
[Parameter(Mandatory = $false)]
|
||||
[Alias("NoBuild")]
|
||||
[switch]$NO_BUILD
|
||||
[switch]$NO_BUILD,
|
||||
|
||||
[Parameter(Mandatory = $false)]
|
||||
[Alias("NoArchive")]
|
||||
[switch]$NO_ARCHIVE
|
||||
)
|
||||
|
||||
# Set the current directory as a variable
|
||||
$BUILD_FOLDER = $PSScriptRoot
|
||||
|
||||
# Set the current commit hash
|
||||
$COMMIT = git log --pretty=format:"%H" -1
|
||||
|
||||
# Output the selected options
|
||||
Write-Host "Selected Options:"
|
||||
Write-Host " Use all frameworks (-UseAll) $USE_ALL"
|
||||
Write-Host " Include debug builds (-IncludeDebug) $INCLUDE_DEBUG"
|
||||
Write-Host " No build (-NoBuild) $NO_BUILD"
|
||||
Write-Host " No archive (-NoArchive) $NO_ARCHIVE"
|
||||
Write-Host " "
|
||||
|
||||
# Create the build matrix arrays
|
||||
$FRAMEWORKS = @('net9.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')
|
||||
}
|
||||
|
||||
# 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')
|
||||
$VALID_CROSS_PLATFORM_RUNTIMES = @('win-arm64', 'linux-x64', 'linux-arm64', 'osx-x64', 'osx-arm64')
|
||||
|
||||
# Only build if requested
|
||||
if (!$NO_BUILD.IsPresent)
|
||||
{
|
||||
@@ -23,4 +62,74 @@ if (!$NO_BUILD.IsPresent)
|
||||
|
||||
# Create Nuget Package
|
||||
dotnet pack SabreTools.RedumpLib\SabreTools.RedumpLib.csproj --output $BUILD_FOLDER
|
||||
|
||||
# Build Tool
|
||||
foreach ($FRAMEWORK in $FRAMEWORKS) {
|
||||
foreach ($RUNTIME in $RUNTIMES) {
|
||||
# Output the current build
|
||||
Write-Host "===== Build Tool - $FRAMEWORK, $RUNTIME ====="
|
||||
|
||||
# If we have an invalid combination of framework and runtime
|
||||
if ($VALID_CROSS_PLATFORM_FRAMEWORKS -notcontains $FRAMEWORK -and $VALID_CROSS_PLATFORM_RUNTIMES -contains $RUNTIME) {
|
||||
Write-Host "Skipped due to invalid combination"
|
||||
continue
|
||||
}
|
||||
|
||||
# If we have Apple silicon but an unsupported framework
|
||||
if ($VALID_APPLE_FRAMEWORKS -notcontains $FRAMEWORK -and $RUNTIME -eq 'osx-arm64') {
|
||||
Write-Host "Skipped due to no Apple Silicon support"
|
||||
continue
|
||||
}
|
||||
|
||||
# Only .NET 5 and above can publish to a single file
|
||||
if ($SINGLE_FILE_CAPABLE -contains $FRAMEWORK) {
|
||||
# Only include Debug if set
|
||||
if ($INCLUDE_DEBUG.IsPresent) {
|
||||
dotnet publish RedumpTool\RedumpTool.csproj -f $FRAMEWORK -r $RUNTIME -c Debug --self-contained true --version-suffix $COMMIT -p:PublishSingleFile=true
|
||||
}
|
||||
dotnet publish RedumpTool\RedumpTool.csproj -f $FRAMEWORK -r $RUNTIME -c Release --self-contained true --version-suffix $COMMIT -p:PublishSingleFile=true -p:DebugType=None -p:DebugSymbols=false
|
||||
}
|
||||
else {
|
||||
# Only include Debug if set
|
||||
if ($INCLUDE_DEBUG.IsPresent) {
|
||||
dotnet publish RedumpTool\RedumpTool.csproj -f $FRAMEWORK -r $RUNTIME -c Debug --self-contained true --version-suffix $COMMIT
|
||||
}
|
||||
dotnet publish RedumpTool\RedumpTool.csproj -f $FRAMEWORK -r $RUNTIME -c Release --self-contained true --version-suffix $COMMIT -p:DebugType=None -p:DebugSymbols=false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Only create archives if requested
|
||||
if (!$NO_ARCHIVE.IsPresent) {
|
||||
# Create Tool archives
|
||||
foreach ($FRAMEWORK in $FRAMEWORKS) {
|
||||
foreach ($RUNTIME in $RUNTIMES) {
|
||||
# Output the current build
|
||||
Write-Host "===== Archive Tool - $FRAMEWORK, $RUNTIME ====="
|
||||
|
||||
# If we have an invalid combination of framework and runtime
|
||||
if ($VALID_CROSS_PLATFORM_FRAMEWORKS -notcontains $FRAMEWORK -and $VALID_CROSS_PLATFORM_RUNTIMES -contains $RUNTIME) {
|
||||
Write-Host "Skipped due to invalid combination"
|
||||
continue
|
||||
}
|
||||
|
||||
# If we have Apple silicon but an unsupported framework
|
||||
if ($VALID_APPLE_FRAMEWORKS -notcontains $FRAMEWORK -and $RUNTIME -eq 'osx-arm64') {
|
||||
Write-Host "Skipped due to no Apple Silicon support"
|
||||
continue
|
||||
}
|
||||
|
||||
# Only include Debug if set
|
||||
if ($INCLUDE_DEBUG.IsPresent) {
|
||||
Set-Location -Path $BUILD_FOLDER\RedumpTool\bin\Debug\${FRAMEWORK}\${RUNTIME}\publish\
|
||||
7z a -tzip $BUILD_FOLDER\RedumpTool_${FRAMEWORK}_${RUNTIME}_debug.zip *
|
||||
}
|
||||
Set-Location -Path $BUILD_FOLDER\RedumpTool\bin\Release\${FRAMEWORK}\${RUNTIME}\publish\
|
||||
7z a -tzip $BUILD_FOLDER\RedumpTool_${FRAMEWORK}_${RUNTIME}_release.zip *
|
||||
}
|
||||
}
|
||||
|
||||
# Reset the directory
|
||||
Set-Location -Path $PSScriptRoot
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user