Compare commits

...

46 Commits

Author SHA1 Message Date
Matt Nadareski
301a0cb188 Bump version 2024-03-15 13:43:36 -04:00
Matt Nadareski
64231da666 Update to RedumpLib 1.3.6 2024-03-15 13:00:34 -04:00
Deterous
5f56977021 Add MPF version to Submission info (#678) 2024-03-15 09:38:02 -07:00
Deterous
436ccf7a34 Fix Redumper generic drive type (#677) 2024-03-15 06:56:54 -07:00
Matt Nadareski
ef7510804e Update packages 2024-03-14 13:29:14 -04:00
Deterous
8c61b87954 Update LibIRD to 0.9.0 (#674) 2024-03-12 21:32:20 -07:00
Deterous
17ba117949 Update LibIRD to 0.8.0 (#673) 2024-03-12 07:12:22 -07:00
Matt Nadareski
0737ba7641 Fix formatting output formatting 2024-03-09 21:36:12 -05:00
Deterous
e9dba0767e Fix Check UI deadlock (#672)
* Fix Check UI deadlock

* Add region

* Niceties
2024-03-07 02:04:07 -08:00
Deterous
2d142e9e9d Fix config access permissions (#671) 2024-03-06 23:08:37 -08:00
Matt Nadareski
7a928decff Try updating PR check action 2024-03-06 22:46:08 -05:00
Deterous
eb5409bdee Enable LibIRD for all .NET frameworks (#670) 2024-03-06 19:11:54 -08:00
Matt Nadareski
1578193068 Update packages to latest 2024-03-06 11:04:50 -05:00
Matt Nadareski
131c95e6ef Update to SabreTools.RedumpLib 1.3.5 2024-03-05 12:56:06 -05:00
Matt Nadareski
a7790a271f Use SabreTools.Hashing 2024-03-04 21:23:45 -05:00
Matt Nadareski
1b342d56ef Ensure no labels are empty (fixes #669) 2024-03-01 12:57:51 -05:00
Deterous
a500211129 Fix title normalization (#668)
* Perform title normalization properly

* Use strings for old .net
2024-03-01 06:25:16 -08:00
Deterous
4d798fa547 Hide Size in DIW if value is 0 (#664)
* Hide Size field in DIW when size=0

* Update CHANGELIST.md
2024-02-28 22:26:07 -08:00
Matt Nadareski
597ebdc973 Update changelog 2024-02-28 22:00:31 -05:00
Deterous
c6a8a9265f Add PS3 CFW support to MPF.Check (#663)
* Add PS3 CFW support to MPF.Check

* Do everything better
2024-02-28 18:59:49 -08:00
Matt Nadareski
393c53769d Don't link to AppVeyor artifacts page anymore 2024-02-27 11:33:44 -05:00
Matt Nadareski
fa21999d3f Add PR check workflow 2024-02-27 11:20:53 -05:00
Matt Nadareski
dafbb05b16 Remove GHA pull request builds 2024-02-27 11:13:07 -05:00
Matt Nadareski
1c1b23a84b Make GHA debug-only 2024-02-27 10:41:50 -05:00
Matt Nadareski
fd0fe4912d Hide layerbreaks if value is 0 (fixes #662) 2024-02-27 10:04:50 -05:00
Matt Nadareski
b5b54d13a2 Gate debug publishing behind use all flag 2024-02-27 09:57:30 -05:00
Matt Nadareski
da77987db3 Bump version 2024-02-27 09:31:10 -05:00
Deterous
774f44c8ce Pull PS3 Disc Key from redump (#656)
* Pull PS3 Disc Key from redump

* Bump RedumpLib to 1.3.3
2024-02-26 17:35:04 -08:00
Matt Nadareski
251b3754e4 Add Mattel HyperScan detection (fixes #661) 2024-02-26 13:17:46 -05:00
Matt Nadareski
963acc3336 Update to BinaryObjectScanner 3.1.0 2024-02-26 12:24:40 -05:00
Matt Nadareski
90588a0f8b Show hashes in readonly data (fixes #660) 2024-02-23 22:10:21 -05:00
Matt Nadareski
a56c212488 Change link to WIP builds in README 2024-02-23 21:18:46 -05:00
Matt Nadareski
6484ab5fe0 Remove generation, just in case 2024-02-23 21:04:17 -05:00
Matt Nadareski
1ff48258b8 Generate release notes automatically 2024-02-23 21:00:16 -05:00
Matt Nadareski
81019f9d56 Unified tag for rolling release 2024-02-23 20:57:46 -05:00
Matt Nadareski
d47c435236 Remove unnecessary empty section 2024-02-23 13:47:35 -05:00
Matt Nadareski
d59b114cba Don't omit body when setting body 2024-02-23 13:37:55 -05:00
Matt Nadareski
7f26dcba4e Use commit SHA as body of rolling releases 2024-02-23 13:35:20 -05:00
Matt Nadareski
5e2766f982 Change link to WIP builds in README 2024-02-23 13:32:26 -05:00
Matt Nadareski
c883f899bb Build artifact before upload 2024-02-23 13:28:45 -05:00
Matt Nadareski
8c9950d5fa Use newer download version 2024-02-23 13:11:33 -05:00
Matt Nadareski
3e842af273 Download all artifacts? 2024-02-23 13:06:19 -05:00
Matt Nadareski
b837623da2 Try using download-artifact 2024-02-23 13:01:03 -05:00
Matt Nadareski
6742901243 Revert artifact ID, use name? 2024-02-23 12:53:21 -05:00
Matt Nadareski
d6460a2b68 Use recommendation from upload-artifact 2024-02-23 12:46:23 -05:00
Matt Nadareski
7af59dacc6 Try fixing the artifact upload 2024-02-23 12:41:24 -05:00
38 changed files with 742 additions and 884 deletions

View File

@@ -3,8 +3,6 @@ name: MPF Check
on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
jobs:
build:
@@ -15,7 +13,6 @@ jobs:
project: [MPF.Check]
runtime: [win-x86, win-x64, linux-x64, osx-x64] #[win-x86, win-x64, win-arm64, linux-x64, linux-arm64, osx-x64]
framework: [net8.0] #[net20, net35, net40, net452, net472, net48, netcoreapp3.1, net5.0, net6.0, net7.0, net8.0]
conf: [Release, Debug]
steps:
- uses: actions/checkout@v4
@@ -29,24 +26,25 @@ jobs:
run: dotnet restore
- name: Build
run: dotnet publish ${{ matrix.project }}/${{ matrix.project }}.csproj -f ${{ matrix.framework }} -r ${{ matrix.runtime }} -c ${{ matrix.conf == 'Release' && 'Release -p:DebugType=None -p:DebugSymbols=false' || 'Debug'}} --self-contained true --version-suffix ${{ github.sha }} ${{ (startsWith(matrix.framework, 'net5') || startsWith(matrix.framework, 'net6') || startsWith(matrix.framework, 'net7') || startsWith(matrix.framework, 'net8')) && '-p:PublishSingleFile=true' || ''}}
run: dotnet publish ${{ matrix.project }}/${{ matrix.project }}.csproj -f ${{ matrix.framework }} -r ${{ matrix.runtime }} -c Debug --self-contained true --version-suffix ${{ github.sha }} ${{ (startsWith(matrix.framework, 'net5') || startsWith(matrix.framework, 'net6') || startsWith(matrix.framework, 'net7') || startsWith(matrix.framework, 'net8')) && '-p:PublishSingleFile=true' || ''}}
- name: Archive build
run: zip -r ${{ matrix.project }}_${{ matrix.framework }}_${{ matrix.runtime }}_debug.zip ${{ matrix.project }}/bin/Debug/${{ matrix.framework }}/${{ matrix.runtime }}/publish/
- name: Upload build
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.project }}_${{ matrix.framework }}_${{ matrix.runtime }}_${{ matrix.conf }}
path: ${{ matrix.project }}/bin/${{ matrix.conf }}/${{ matrix.framework }}/${{ matrix.runtime }}/publish/
name: ${{ matrix.project }}_${{ matrix.framework }}_${{ matrix.runtime }}_debug
path: ${{ matrix.project }}_${{ matrix.framework }}_${{ matrix.runtime }}_debug.zip
- name: Upload to rolling
uses: ncipollo/release-action@v1
uses: ncipollo/release-action@v1.14.0
with:
allowUpdates: True
artifacts: ${{ matrix.project }}_${{ matrix.framework }}_${{ matrix.runtime }}_${{ matrix.conf }}
generateReleaseNotes: true
omitBody: True
omitBodyDuringUpdate: True
omitNameDuringUpdate: True
artifacts: ${{ matrix.project }}_${{ matrix.framework }}_${{ matrix.runtime }}_debug.zip
body: 'Last built commit: ${{ github.sha }}'
name: 'Rolling Release'
prerelease: True
replacesArtifacts: True
tag: "check-rolling"
tag: "rolling"
updateOnlyUnreleased: True

View File

@@ -3,8 +3,6 @@ name: MPF UI
on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
jobs:
build:
@@ -15,7 +13,6 @@ jobs:
project: [MPF]
runtime: [win-x86, win-x64]
framework: [net8.0-windows] #[net40, net452, net472, net48, netcoreapp3.1, net5.0-windows, net6.0-windows, net7.0-windows, net8.0-windows]
conf: [Release, Debug]
steps:
- uses: actions/checkout@v4
@@ -29,32 +26,32 @@ jobs:
run: dotnet restore
- name: Build
run: dotnet publish ${{ matrix.project }}/${{ matrix.project }}.csproj -f ${{ matrix.framework }} -r ${{ matrix.runtime }} -c ${{ matrix.conf == 'Release' && 'Release -p:DebugType=None -p:DebugSymbols=false' || 'Debug'}} --self-contained true --version-suffix ${{ github.sha }} ${{ (startsWith(matrix.framework, 'net5') || startsWith(matrix.framework, 'net6') || startsWith(matrix.framework, 'net7') || startsWith(matrix.framework, 'net8')) && '-p:PublishSingleFile=true' || ''}}
run: dotnet publish ${{ matrix.project }}/${{ matrix.project }}.csproj -f ${{ matrix.framework }} -r ${{ matrix.runtime }} -c Debug --self-contained true --version-suffix ${{ github.sha }} ${{ (startsWith(matrix.framework, 'net5') || startsWith(matrix.framework, 'net6') || startsWith(matrix.framework, 'net7') || startsWith(matrix.framework, 'net8')) && '-p:PublishSingleFile=true' || ''}}
- name: Bundle Redumper
run: |
wget https://github.com/superg/redumper/releases/download/build_311/redumper-2024.01.08_build311-win64.zip
unzip redumper-2024.01.08_build311-win64.zip
mkdir -p MPF/bin/${{ matrix.conf }}/${{ matrix.framework }}/${{ matrix.runtime }}/publish/Programs/Redumper
mv redumper-2024.01.08_build311-win64/bin/redumper.exe MPF/bin/${{ matrix.conf }}/${{ matrix.framework }}/${{ matrix.runtime }}/publish/Programs/Redumper/
mkdir -p MPF/bin/Debug/${{ matrix.framework }}/${{ matrix.runtime }}/publish/Programs/Redumper
mv redumper-2024.01.08_build311-win64/bin/redumper.exe MPF/bin/Debug/${{ matrix.framework }}/${{ matrix.runtime }}/publish/Programs/Redumper/
- name: Archive build
run: zip -r ${{ matrix.project }}_${{ matrix.framework }}_${{ matrix.runtime }}_debug.zip ${{ matrix.project }}/bin/Debug/${{ matrix.framework }}/${{ matrix.runtime }}/publish/
- name: Upload build
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.project }}_${{ matrix.framework }}_${{ matrix.runtime }}_${{ matrix.conf }}
path: ${{ matrix.project }}/bin/${{ matrix.conf }}/${{ matrix.framework }}/${{ matrix.runtime }}/publish/
name: ${{ matrix.project }}_${{ matrix.framework }}_${{ matrix.runtime }}_debug
path: ${{ matrix.project }}_${{ matrix.framework }}_${{ matrix.runtime }}_debug.zip
- name: Upload to rolling
uses: ncipollo/release-action@v1
uses: ncipollo/release-action@v1.14.0
with:
allowUpdates: True
artifacts: "*.zip"
generateReleaseNotes: true
omitBody: True
omitBodyDuringUpdate: True
omitNameDuringUpdate: True
artifacts: ${{ matrix.project }}_${{ matrix.framework }}_${{ matrix.runtime }}_debug.zip
body: 'Last built commit: ${{ github.sha }}'
name: 'Rolling Release'
prerelease: True
removeArtifacts: True
replacesArtifacts: True
tag: "ui-rolling"
tag: "rolling"
updateOnlyUnreleased: True

23
.github/workflows/check_pr.yml vendored Normal file
View File

@@ -0,0 +1,23 @@
name: Build PR
on: [pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 8.0.x
- name: Restore dependencies
run: dotnet restore
- name: Build
run: dotnet build --no-restore
- name: Test
run: dotnet test --no-restore --verbosity normal

View File

@@ -1,4 +1,30 @@
### WIP (xxxx-xx-xx)
### 3.1.3 (2024-03-15)
- Gate debug publishing behind use all flag
- Hide layerbreaks if value is 0
- Make GHA debug-only
- Remove GHA pull request builds
- Add PR check workflow
- Don't link to AppVeyor artifacts page anymore
- Add PS3 CFW support to MPF.Check (Deterous)
- Hide size if value is 0 (Deterous)
- Fix title normalization (Deterous)
- Ensure no labels are empty
- Use SabreTools.Hashing
- Update to SabreTools.RedumpLib 1.3.5
- Update packages to latest
- Enable LibIRD for all .NET frameworks (Deterous)
- Try updating PR check action
- Fix config access persmission (Deterous)
- Fix Check UI deadlock (Deterous)
- Fix formatting output formatting
- Update LibIRD to 0.9.0 (Deterous)
- Update packages
- Fix Redumper generic drive type (Deterous)
- Add MPF version to Submission info (Deterous)
- Update to RedumpLib 1.3.6
### 3.1.2 (2024-02-27)
- Remove debugging lines from build script
- Port build script fixes from BOS
@@ -23,6 +49,25 @@
- Fix whitespace that got unwhitespaced
- Fix link in README
- Attempt to add CD to existing actions
- Try fixing the artifact upload
- Use recommendation from upload-artifact
- Revert artifact ID, use name?
- Try using download-artifact
- Download all artifacts?
- Use newer download version
- Build artifact before upload
- Change link to WIP builds in README
- Use commit SHA as body of rolling releases
- Don't omit body when setting body
- Remove unnecessary empty section
- Unified tag for rolling release
- Generate release notes automatically
- Remove generation, just in case
- Change link to WIP builds in README
- Show hashes in readonly data
- Update to BinaryObjectScanner 3.1.0
- Add Mattel HyperScan detection
- Pull PS3 Disc Key from redump (Deterous)
### 3.1.1 (2024-02-20)

View File

@@ -11,7 +11,7 @@
<Nullable>enable</Nullable>
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<VersionPrefix>3.1.1</VersionPrefix>
<VersionPrefix>3.1.3</VersionPrefix>
<!-- Package Properties -->
<Title>MPF Check</Title>
@@ -32,10 +32,10 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="BinaryObjectScanner" PrivateAssets="build; analyzers" ExcludeAssets="contentFiles" Version="3.0.2" GeneratePathProperty="true">
<PackageReference Include="BinaryObjectScanner" PrivateAssets="build; analyzers" ExcludeAssets="contentFiles" Version="3.1.1" GeneratePathProperty="true">
<IncludeAssets>runtime; compile; build; native; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="SabreTools.RedumpLib" Version="1.3.2" />
<PackageReference Include="SabreTools.RedumpLib" Version="1.3.6" />
</ItemGroup>
<ItemGroup>

View File

@@ -101,6 +101,7 @@ namespace MPF.Core.Converters
InternalProgram.CleanRip => "CleanRip",
InternalProgram.DCDumper => "DCDumper",
InternalProgram.PS3CFW => "PS3 CFW",
InternalProgram.UmdImageCreator => "UmdImageCreator",
#endregion
@@ -141,6 +142,11 @@ namespace MPF.Core.Converters
"dc"
or "dcd"
or "dcdumper" => InternalProgram.DCDumper,
"ps3cfw"
or "ps3"
or "getkey"
or "managunz"
or "multiman" => InternalProgram.PS3CFW,
"uic"
or "umd"
or "umdcreator"

View File

@@ -331,6 +331,12 @@ namespace MPF.Core.Data
return RedumpSystem.CommodoreAmigaCD32;
}
// Mattel HyperScan -- TODO: May need case-insensitivity added
if (File.Exists(Path.Combine(this.Name, "hyper.exe")))
{
return RedumpSystem.MattelHyperScan;
}
// Mattel Fisher-Price iXL
#if NET20 || NET35
if (File.Exists(Path.Combine(Path.Combine(this.Name, "iXL"), "iXLUpdater.exe")))

View File

@@ -46,6 +46,7 @@
// Verification support only
CleanRip,
DCDumper,
PS3CFW,
UmdImageCreator,
}

View File

@@ -502,15 +502,10 @@ namespace MPF.Core.Data
/// <summary>
/// Create a PS3 IRD file after dumping PS3 BD-ROM discs
/// Always returns false if not compiled with .NET Core 6 or newer
/// </summary>
public bool CreateIRDAfterDumping
{
#if NET6_0_OR_GREATER
get { return GetBooleanSetting(Settings, "CreateIRDAfterDumping", false); }
#else
get { return false; }
#endif
set { Settings["CreateIRDAfterDumping"] = value.ToString(); }
}

View File

@@ -148,6 +148,7 @@ namespace MPF.Core
// Verification support only
InternalProgram.CleanRip => new Modules.CleanRip.Parameters(parameters) { ExecutablePath = null },
InternalProgram.DCDumper => null, // TODO: Create correct parameter type when supported
InternalProgram.PS3CFW => new Modules.PS3CFW.Parameters(parameters) { ExecutablePath = null },
InternalProgram.UmdImageCreator => new Modules.UmdImageCreator.Parameters(parameters) { ExecutablePath = null },
// If no dumping program found, set to null
@@ -362,9 +363,9 @@ namespace MPF.Core
resultProgress?.Report(Result.Success("Formatting information..."));
(var formattedValues, var formatResult) = Formatter.FormatOutputData(submissionInfo, Options.EnableRedumpCompatibility);
if (formattedValues == null)
resultProgress?.Report(Result.Success(formatResult));
else
resultProgress?.Report(Result.Failure(formatResult));
else
resultProgress?.Report(Result.Success(formatResult));
// Get the filename suffix for auto-generated files
var filenameSuffix = Options.AddFilenameSuffix ? Path.GetFileNameWithoutExtension(outputFilename) : null;
@@ -424,7 +425,6 @@ namespace MPF.Core
resultProgress?.Report(Result.Failure(deleteResult));
}
#if NET6_0_OR_GREATER
// Create PS3 IRD, if required
if (Options.CreateIRDAfterDumping && System == RedumpSystem.SonyPlayStation3 && Type == MediaType.BluRay)
{
@@ -435,7 +435,6 @@ namespace MPF.Core
else
resultProgress?.Report(Result.Failure(deleteResult));
}
#endif
resultProgress?.Report(Result.Success("Submission information process complete!"));
return Result.Success();

View File

@@ -1,350 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
#if NET6_0_OR_GREATER
using System.IO.Hashing;
#endif
using System.Linq;
using System.Security.Cryptography;
using System.Threading.Tasks;
using MPF.Core.Data;
namespace MPF.Core.Hashing
{
public sealed class Hasher : IDisposable
{
#region Properties
/// <summary>
/// Hash type associated with the current state
/// </summary>
#if NETFRAMEWORK || NETCOREAPP3_1
public Hash HashType { get; private set; }
#else
public Hash HashType { get; init; }
#endif
/// <summary>
/// Current hash in bytes
/// </summary>
public byte[]? CurrentHashBytes
{
get
{
return (_hasher) switch
{
HashAlgorithm ha => ha.Hash,
NonCryptographicHashAlgorithm ncha => ncha.GetCurrentHash().Reverse().ToArray(),
_ => null,
};
}
}
/// <summary>
/// Current hash as a string
/// </summary>
public string? CurrentHashString => ByteArrayToString(CurrentHashBytes);
#endregion
#region Private Fields
/// <summary>
/// Internal hasher being used for processing
/// </summary>
/// <remarks>May be either a HashAlgorithm or NonCryptographicHashAlgorithm</remarks>
private object? _hasher;
#endregion
#region Constructors
/// <summary>
/// Constructor
/// </summary>
/// <param name="hashType">Hash type to instantiate</param>
public Hasher(Hash hashType)
{
this.HashType = hashType;
GetHasher();
}
/// <summary>
/// Generate the correct hashing class based on the hash type
/// </summary>
private void GetHasher()
{
_hasher = HashType switch
{
Hash.CRC32 => new Crc32(),
#if NET6_0_OR_GREATER
Hash.CRC64 => new Crc64(),
#endif
Hash.MD5 => MD5.Create(),
Hash.SHA1 => SHA1.Create(),
Hash.SHA256 => SHA256.Create(),
Hash.SHA384 => SHA384.Create(),
Hash.SHA512 => SHA512.Create(),
#if NET6_0_OR_GREATER
Hash.XxHash32 => new XxHash32(),
Hash.XxHash64 => new XxHash64(),
#endif
_ => null,
};
}
/// <inheritdoc/>
public void Dispose()
{
if (_hasher is IDisposable disposable)
disposable.Dispose();
}
#endregion
#region Static Hashing
/// <summary>
/// Get hashes from an input file path
/// </summary>
/// <param name="filename">Path to the input file</param>
/// <returns>True if hashing was successful, false otherwise</returns>
public static bool GetFileHashes(string filename, out long size, out string? crc32, out string? md5, out string? sha1)
{
// Set all initial values
crc32 = null; md5 = null; sha1 = null;
// Get all file hashes
var fileHashes = GetFileHashes(filename, out size);
if (fileHashes == null)
return false;
// Assign the file hashes and return
crc32 = fileHashes[Hash.CRC32];
md5 = fileHashes[Hash.MD5];
sha1 = fileHashes[Hash.SHA1];
return true;
}
/// <summary>
/// Get hashes from an input file path
/// </summary>
/// <param name="filename">Path to the input file</param>
/// <returns>Dictionary containing hashes on success, null on error</returns>
public static Dictionary<Hash, string?>? GetFileHashes(string filename, out long size)
{
// If the file doesn't exist, we can't do anything
if (!File.Exists(filename))
{
size = -1;
return null;
}
// Set the file size
size = new FileInfo(filename).Length;
// Open the input file
var input = File.OpenRead(filename);
// Return the hashes from the stream
return GetStreamHashes(input);
}
/// <summary>
/// Get hashes from an input Stream
/// </summary>
/// <param name="input">Stream to hash</param>
/// <returns>Dictionary containing hashes on success, null on error</returns>
public static Dictionary<Hash, string?>? GetStreamHashes(Stream input)
{
// Create the output dictionary
var hashDict = new Dictionary<Hash, string?>();
try
{
// Get a list of hashers to run over the buffer
var hashers = new Dictionary<Hash, Hasher>
{
{ Hash.CRC32, new Hasher(Hash.CRC32) },
#if NET6_0_OR_GREATER
{ Hash.CRC64, new Hasher(Hash.CRC64) },
#endif
{ Hash.MD5, new Hasher(Hash.MD5) },
{ Hash.SHA1, new Hasher(Hash.SHA1) },
{ Hash.SHA256, new Hasher(Hash.SHA256) },
{ Hash.SHA384, new Hasher(Hash.SHA384) },
{ Hash.SHA512, new Hasher(Hash.SHA512) },
#if NET6_0_OR_GREATER
{ Hash.XxHash32, new Hasher(Hash.XxHash32) },
{ Hash.XxHash64, new Hasher(Hash.XxHash64) },
#endif
};
// Initialize the hashing helpers
var loadBuffer = new ThreadLoadBuffer(input);
int buffersize = 3 * 1024 * 1024;
byte[] buffer0 = new byte[buffersize];
byte[] buffer1 = new byte[buffersize];
/*
Please note that some of the following code is adapted from
RomVault. This is a modified version of how RomVault does
threaded hashing. As such, some of the terminology and code
is the same, though variable names and comments may have
been tweaked to better fit this code base.
*/
// Pre load the first buffer
long refsize = input.Length;
int next = refsize > buffersize ? buffersize : (int)refsize;
input.Read(buffer0, 0, next);
int current = next;
refsize -= next;
bool bufferSelect = true;
while (current > 0)
{
// Trigger the buffer load on the second buffer
next = refsize > buffersize ? buffersize : (int)refsize;
if (next > 0)
loadBuffer.Trigger(bufferSelect ? buffer1 : buffer0, next);
byte[] buffer = bufferSelect ? buffer0 : buffer1;
#if NET20 || NET35
// Run hashers sequentially on each chunk
foreach (var h in hashers)
{
h.Value.Process(buffer, current);
}
#else
// Run hashers in parallel on each chunk
Parallel.ForEach(hashers, h => h.Value.Process(buffer, current));
#endif
// Wait for the load buffer worker, if needed
if (next > 0)
loadBuffer.Wait();
// Setup for the next hashing step
current = next;
refsize -= next;
bufferSelect = !bufferSelect;
}
// Finalize all hashing helpers
loadBuffer.Finish();
#if NET20 || NET35
foreach (var h in hashers)
{
h.Value.Terminate();
}
#else
Parallel.ForEach(hashers, h => h.Value.Terminate());
#endif
// Get the results
hashDict[Hash.CRC32] = hashers[Hash.CRC32].CurrentHashString;
#if NET6_0_OR_GREATER
hashDict[Hash.CRC64] = hashers[Hash.CRC64].CurrentHashString;
#endif
hashDict[Hash.MD5] = hashers[Hash.MD5].CurrentHashString;
hashDict[Hash.SHA1] = hashers[Hash.SHA1].CurrentHashString;
hashDict[Hash.SHA256] = hashers[Hash.SHA256].CurrentHashString;
hashDict[Hash.SHA384] = hashers[Hash.SHA384].CurrentHashString;
hashDict[Hash.SHA512] = hashers[Hash.SHA512].CurrentHashString;
#if NET6_0_OR_GREATER
hashDict[Hash.XxHash32] = hashers[Hash.XxHash32].CurrentHashString;
hashDict[Hash.XxHash64] = hashers[Hash.XxHash64].CurrentHashString;
#endif
// Dispose of the hashers
loadBuffer.Dispose();
foreach (var hasher in hashers.Values)
{
hasher.Dispose();
}
return hashDict;
}
catch (IOException)
{
return null;
}
finally
{
input.Dispose();
}
}
#endregion
#region Hashing
/// <summary>
/// Process a buffer of some length with the internal hash algorithm
/// </summary>
public void Process(byte[] buffer, int size)
{
switch (_hasher)
{
case HashAlgorithm ha:
ha.TransformBlock(buffer, 0, size, null, 0);
break;
case NonCryptographicHashAlgorithm ncha:
#if NET20 || NET35 || NET40
byte[] bufferSpan = new byte[size];
Array.Copy(buffer, bufferSpan, size);
#else
var bufferSpan = new ReadOnlySpan<byte>(buffer, 0, size);
#endif
ncha.Append(bufferSpan);
break;
}
}
/// <summary>
/// Finalize the internal hash algorigthm
/// </summary>
/// <remarks>NonCryptographicHashAlgorithm implementations do not need finalization</remarks>
public void Terminate()
{
byte[] emptyBuffer = [];
switch (_hasher)
{
case HashAlgorithm ha:
ha.TransformFinalBlock(emptyBuffer, 0, 0);
break;
}
}
#endregion
#region Helpers
/// <summary>
/// Convert a byte array to a hex string
/// </summary>
/// <param name="bytes">Byte array to convert</param>
/// <returns>Hex string representing the byte array</returns>
/// <link>http://stackoverflow.com/questions/311165/how-do-you-convert-byte-array-to-hexadecimal-string-and-vice-versa</link>
private static string? ByteArrayToString(byte[]? bytes)
{
// If we get null in, we send null out
if (bytes == null)
return null;
try
{
string hex = BitConverter.ToString(bytes);
return hex.Replace("-", string.Empty).ToLowerInvariant();
}
catch
{
return null;
}
}
#endregion
}
}

View File

@@ -1,184 +0,0 @@
#if NETFRAMEWORK || NETCOREAPP3_1 || NET5_0
/*
Copyright (c) 2012-2015 Eugene Larchenko (spct@mail.ru)
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 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.
*/
using System;
//namespace OptimizedCRC
namespace MPF.Core.Hashing
{
/// <summary>
/// Shell class to trick older versions into using CRC-32 properly
/// </summary>
internal abstract class NonCryptographicHashAlgorithm
{
#if NET20 || NET35 || NET40
/// <summary>
/// When overridden in a derived class, appends the contents of source to
/// the data already processed for the current hash computation.
/// </summary>
/// <param name="source">The data to process.</param>
public abstract void Append(byte[] source);
#else
/// <summary>
/// When overridden in a derived class, appends the contents of source to
/// the data already processed for the current hash computation.
/// </summary>
/// <param name="source">The data to process.</param>
public abstract void Append(ReadOnlySpan<byte> source);
#endif
/// <summary>
/// Gets the current computed hash value without modifying accumulated state.
/// </summary>
/// <returns>The hash value for the data already provided.</returns>
public abstract byte[] GetCurrentHash();
}
/// <remarks>
/// Some changes have been made to this code to make it more similar to the System.IO.Hashing implementations
/// </remarks>
internal class Crc32 : NonCryptographicHashAlgorithm, IDisposable
{
private const uint kCrcPoly = 0xEDB88320;
private const uint kInitial = 0xFFFFFFFF;
private const int CRC_NUM_TABLES = 8;
private static readonly uint[] Table;
static Crc32()
{
unchecked
{
Table = new uint[256 * CRC_NUM_TABLES];
int i;
for (i = 0; i < 256; i++)
{
uint r = (uint)i;
for (int j = 0; j < 8; j++)
{
r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
}
Table[i] = r;
}
for (; i < 256 * CRC_NUM_TABLES; i++)
{
uint r = Table[i - 256];
Table[i] = Table[r & 0xFF] ^ (r >> 8);
}
}
}
public uint UnsignedValue;
public Crc32()
{
Init();
}
/// <summary>
/// Reset CRC
/// </summary>
public void Init()
{
UnsignedValue = kInitial;
}
/// <inheritdoc/>
public override byte[] GetCurrentHash()
{
return BitConverter.GetBytes(~UnsignedValue);
}
/// <inheritdoc/>
#if NET20 || NET35 || NET40
public override void Append(byte[] source)
{
Update(source, 0, source.Length);
}
#else
public override void Append(ReadOnlySpan<byte> source)
{
byte[] sourceBytes = source.ToArray();
Update(sourceBytes, 0, sourceBytes.Length);
}
#endif
private void Update(byte[] data, int offset, int count)
{
_ = new ArraySegment<byte>(data, offset, count); // check arguments
if (count == 0)
{
return;
}
var table = Table;
uint crc = UnsignedValue;
for (; (offset & 7) != 0 && count != 0; count--)
{
crc = (crc >> 8) ^ table[(byte)crc ^ data[offset++]];
}
if (count >= 8)
{
/*
* Idea from 7-zip project sources (http://7-zip.org/sdk.html)
*/
int end = (count - 8) & ~7;
count -= end;
end += offset;
while (offset != end)
{
crc ^= (uint)(data[offset] + (data[offset + 1] << 8) + (data[offset + 2] << 16) + (data[offset + 3] << 24));
uint high = (uint)(data[offset + 4] + (data[offset + 5] << 8) + (data[offset + 6] << 16) + (data[offset + 7] << 24));
offset += 8;
crc = table[(byte)crc + 0x700]
^ table[(byte)(crc >>= 8) + 0x600]
^ table[(byte)(crc >>= 8) + 0x500]
^ table[/*(byte)*/(crc >> 8) + 0x400]
^ table[(byte)(high) + 0x300]
^ table[(byte)(high >>= 8) + 0x200]
^ table[(byte)(high >>= 8) + 0x100]
^ table[/*(byte)*/(high >> 8) + 0x000];
}
}
while (count-- != 0)
{
crc = (crc >> 8) ^ table[(byte)crc ^ data[offset++]];
}
UnsignedValue = crc;
}
public void Dispose()
{
UnsignedValue = 0;
}
}
}
#endif

View File

@@ -1,81 +0,0 @@
using System;
using System.IO;
using System.Threading;
//namespace Compress.ThreadReaders
namespace MPF.Core.Hashing
{
public sealed class ThreadLoadBuffer : IDisposable
{
private readonly AutoResetEvent _waitEvent;
private readonly AutoResetEvent _outEvent;
private readonly Thread _tWorker;
private byte[]? _buffer;
private int _size;
private readonly Stream _ds;
private bool _finished;
public bool errorState;
public int SizeRead;
public ThreadLoadBuffer(Stream ds)
{
_waitEvent = new AutoResetEvent(false);
_outEvent = new AutoResetEvent(false);
_finished = false;
_ds = ds;
errorState = false;
_tWorker = new Thread(MainLoop);
_tWorker.Start();
}
public void Dispose()
{
_waitEvent.Close();
_outEvent.Close();
}
private void MainLoop()
{
while (true)
{
_waitEvent.WaitOne();
if (_finished)
{
break;
}
try
{
if (_buffer != null)
SizeRead = _ds.Read(_buffer, 0, _size);
}
catch (Exception)
{
errorState = true;
}
_outEvent.Set();
}
}
public void Trigger(byte[] buffer, int size)
{
_buffer = buffer;
_size = size;
_waitEvent.Set();
}
public void Wait()
{
_outEvent.WaitOne();
}
public void Finish()
{
_finished = true;
_waitEvent.Set();
_tWorker.Join();
}
}
}

View File

@@ -1495,7 +1495,6 @@ namespace MPF.Core
return files;
}
#if NET6_0_OR_GREATER
/// <summary>
/// Create an IRD and write it to the specified output directory with optional filename suffix
/// </summary>
@@ -1528,7 +1527,12 @@ namespace MPF.Core
layerbreak = Tools.ParseLayerbreak(layerbreak);
// Create Redump-style reproducible IRD
LibIRD.ReIRD ird = await Task.Run(() => new LibIRD.ReIRD(isoPath, discKey, layerbreak, uid));
#if NET40
LibIRD.ReIRD ird = await Task.Factory.StartNew(() =>
#else
LibIRD.ReIRD ird = await Task.Run(() =>
#endif
new LibIRD.ReIRD(isoPath, discKey, layerbreak, uid));
if (pic != null)
ird.PIC = pic;
if (discID != null && ird.DiscID[15] != 0x00)
@@ -1545,7 +1549,6 @@ namespace MPF.Core
return (false, "Failed to create IRD");
}
}
#endif
#endregion
@@ -1929,14 +1932,29 @@ namespace MPF.Core
for (int i = 1; i < splitTitle.Length; i++)
{
string segment = splitTitle[i];
if (segment.EndsWith(":") || segment.EndsWith("-"))
if (!itemInserted && segment == ":")
{
itemInserted = true;
newTitleBuilder.Append($"{segment}, {firstItem}");
newTitleBuilder.Append($", {firstItem} :");
}
else if (!itemInserted && segment == "-")
{
itemInserted = true;
newTitleBuilder.Append($", {firstItem} -");
}
else if (!itemInserted && segment.EndsWith(":"))
{
itemInserted = true;
newTitleBuilder.Append($" {segment.Substring(0, segment.Length - 1)}, {firstItem}:");
}
else if (!itemInserted && segment.EndsWith("-"))
{
itemInserted = true;
newTitleBuilder.Append($" {segment.Substring(0, segment.Length - 1)}, {firstItem}-");
}
else
{
newTitleBuilder.Append($"{segment} ");
newTitleBuilder.Append($" {segment}");
}
}

View File

@@ -10,7 +10,7 @@
<Nullable>enable</Nullable>
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<VersionPrefix>3.1.1</VersionPrefix>
<VersionPrefix>3.1.3</VersionPrefix>
<!-- Package Properties -->
<Authors>Matt Nadareski;ReignStumble;Jakz</Authors>
@@ -46,23 +46,18 @@
<PackageReference Include="System.Net.Http" Version="4.3.4" />
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="6.0.0" />
</ItemGroup>
<ItemGroup Condition="$(TargetFramework.StartsWith(`net6`)) OR $(TargetFramework.StartsWith(`net7`)) OR $(TargetFramework.StartsWith(`net8`))">
<PackageReference Include="System.IO.Hashing" Version="8.0.0" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="BinaryObjectScanner" PrivateAssets="build; analyzers" ExcludeAssets="contentFiles" Version="3.0.2" GeneratePathProperty="true">
<PackageReference Include="BinaryObjectScanner" PrivateAssets="build; analyzers" ExcludeAssets="contentFiles" Version="3.1.1" GeneratePathProperty="true">
<IncludeAssets>runtime; compile; build; native; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="LibIRD" Version="0.9.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="psxt001z.Library" Version="0.21.0-beta3" />
<PackageReference Include="SabreTools.Models" Version="1.3.0" />
<PackageReference Include="SabreTools.RedumpLib" Version="1.3.2" />
<PackageReference Include="SabreTools.Serialization" Version="1.3.1" />
</ItemGroup>
<ItemGroup Condition="$(TargetFramework.StartsWith(`net6`)) OR $(TargetFramework.StartsWith(`net7`)) OR $(TargetFramework.StartsWith(`net8`))">
<PackageReference Include="LibIRD" Version="0.6.0" />
<PackageReference Include="psxt001z.Library" Version="0.21.0-beta4" />
<PackageReference Include="SabreTools.Hashing" Version="1.1.4" />
<PackageReference Include="SabreTools.Models" Version="1.4.0" />
<PackageReference Include="SabreTools.RedumpLib" Version="1.3.6" />
<PackageReference Include="SabreTools.Serialization" Version="1.4.0" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,293 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using MPF.Core.Converters;
using MPF.Core.Data;
using SabreTools.Hashing;
using SabreTools.RedumpLib;
using SabreTools.RedumpLib.Data;
namespace MPF.Core.Modules.PS3CFW
{
/// <summary>
/// Represents a generic set of PlayStation 3 Custom Firmware parameters
/// </summary>
public class Parameters : BaseParameters
{
#region Metadata
/// <inheritdoc/>
public override InternalProgram InternalProgram => InternalProgram.PS3CFW;
#endregion
/// <inheritdoc/>
public Parameters(string? parameters) : base(parameters) { }
/// <inheritdoc/>
public Parameters(RedumpSystem? system, MediaType? type, string? drivePath, string filename, int? driveSpeed, Options options)
: base(system, type, drivePath, filename, driveSpeed, options)
{
}
#region BaseParameters Implementations
/// <inheritdoc/>
public override (bool, List<string>) CheckAllOutputFilesExist(string basePath, bool preCheck)
{
var missingFiles = new List<string>();
if (this.Type != MediaType.BluRay || this.System != RedumpSystem.SonyPlayStation3)
{
missingFiles.Add("Media and system combination not supported for PS3 CFW");
}
else
{
string? getKeyBasePath = GetCFWBasePath(basePath);
if (!File.Exists($"{getKeyBasePath}.getkey.log"))
missingFiles.Add($"{getKeyBasePath}.getkey.log");
if (!File.Exists($"{getKeyBasePath}.disc.pic"))
missingFiles.Add($"{getKeyBasePath}.disc.pic");
}
return (missingFiles.Count == 0, missingFiles);
}
/// <inheritdoc/>
public override void GenerateSubmissionInfo(SubmissionInfo info, Options options, string basePath, Drive? drive, bool includeArtifacts)
{
// Ensure that required sections exist
info = Builder.EnsureAllSections(info);
info.DumpingInfo!.DumpingProgram = EnumConverter.LongName(this.InternalProgram);
// Get the Datafile information
Datafile? datafile = GeneratePS3CFWDatafile(basePath + ".iso");
// Fill in the hash data
info.TracksAndWriteOffsets!.ClrMameProData = InfoTool.GenerateDatfile(datafile);
// Get the individual hash data, as per internal
if (InfoTool.GetISOHashValues(datafile, out long size, out var crc32, out var md5, out var sha1))
{
info.SizeAndChecksums!.Size = size;
info.SizeAndChecksums.CRC32 = crc32;
info.SizeAndChecksums.MD5 = md5;
info.SizeAndChecksums.SHA1 = sha1;
}
// Get the PVD from the ISO
if (GetPVD(basePath + ".iso", out string? pvd))
info.Extras!.PVD = pvd;
// Try get the serial, version, and firmware version if a drive is provided
if (drive != null)
{
info.VersionAndEditions!.Version = InfoTool.GetPlayStation3Version(drive?.Name) ?? string.Empty;
info.CommonDiscInfo!.CommentsSpecialFields![SiteCode.InternalSerialName] = InfoTool.GetPlayStation3Serial(drive?.Name) ?? string.Empty;
string? firmwareVersion = InfoTool.GetPlayStation3FirmwareVersion(drive?.Name);
if (firmwareVersion != null)
info.CommonDiscInfo!.ContentsSpecialFields![SiteCode.Patches] = $"PS3 Firmware {firmwareVersion}";
}
// Try to determine the name of the GetKey file(s)
string? getKeyBasePath = GetCFWBasePath(basePath);
// If GenerateSubmissionInfo is run, .getkey.log existence should already be checked
if (!File.Exists(getKeyBasePath + ".getkey.log"))
return;
// Get dumping date from GetKey log date
info.DumpingInfo.DumpingDate = InfoTool.GetFileModifiedDate(getKeyBasePath + ".getkey.log")?.ToString("yyyy-MM-dd HH:mm:ss");
// TODO: Put info about abnormal PIC info beyond 132 bytes in comments?
if (File.Exists(getKeyBasePath + ".disc.pic"))
info.Extras!.PIC = GetPIC(getKeyBasePath + ".disc.pic", 264);
// Parse Disc Key, Disc ID, and PIC from the .getkey.log file
if (Utilities.Tools.ParseGetKeyLog(getKeyBasePath + ".getkey.log", out string? key, out string? id, out string? pic))
{
if (key != null)
info.Extras!.DiscKey = key.ToUpperInvariant();
if (id != null)
info.Extras!.DiscID = id.ToUpperInvariant().Substring(0, 24) + "XXXXXXXX";
if (string.IsNullOrEmpty(info.Extras!.PIC) && !string.IsNullOrEmpty(pic))
{
pic = Regex.Replace(pic, ".{32}", "$0\n");
info.Extras.PIC = pic;
}
}
// Fill in any artifacts that exist, Base64-encoded, if we need to
if (includeArtifacts)
{
info.Artifacts ??= [];
if (File.Exists(getKeyBasePath + ".disc.pic"))
info.Artifacts["discpic"] = GetBase64(GetFullFile(getKeyBasePath + ".disc.pic", binary: true)) ?? string.Empty;
if (File.Exists(getKeyBasePath + ".getkey.log"))
info.Artifacts["getkeylog"] = GetBase64(GetFullFile(getKeyBasePath + ".getkey.log")) ?? string.Empty;
}
}
/// <inheritdoc/>
public override List<string> GetLogFilePaths(string basePath)
{
var logFiles = new List<string>();
string? getKeyBasePath = GetCFWBasePath(basePath);
if (this.System != RedumpSystem.SonyPlayStation3)
return logFiles;
switch (this.Type)
{
case MediaType.BluRay:
if (File.Exists($"{getKeyBasePath}.getkey.log"))
logFiles.Add($"{getKeyBasePath}.getkey.log");
if (File.Exists($"{getKeyBasePath}.disc.pic"))
logFiles.Add($"{getKeyBasePath}.disc.pic");
break;
}
return logFiles;
}
#endregion
#region Information Extraction Methods
/// <summary>
/// Get a formatted datfile from the PS3 CFW output, if possible
/// </summary>
/// <param name="iso">Path to ISO file</param>
/// <returns></returns>
private static Datafile? GeneratePS3CFWDatafile(string iso)
{
// If the ISO file doesn't exist, we can't get info from it
if (!File.Exists(iso))
return null;
try
{
if (HashTool.GetStandardHashes(iso, out long size, out string? crc, out string? md5, out string? sha1))
{
return new Datafile
{
Games = [new Game { Roms = [new Rom { Name = Path.GetFileName(iso), Size = size.ToString(), Crc = crc, Md5 = md5, Sha1 = sha1, }] }]
};
}
return null;
}
catch
{
// We don't care what the exception is right now
return null;
}
}
// TODO: Don't hardcode 0x8320 and move this function to BaseParameters
/// <summary>
/// Get a isobuster-formatted PVD from a PS3 ISO, if possible
/// </summary>
/// <param name="isoPath">Path to ISO file</param>
/// <param name="pvd">Formatted PVD string, otherwise null</param>
/// <returns>True if PVD was successfully parsed, otherwise false</returns>
private static bool GetPVD(string isoPath, out string? pvd)
{
pvd = null;
try
{
// Get PVD bytes from ISO file
var buf = new byte[96];
using (FileStream iso = File.OpenRead(isoPath))
{
iso.Seek(0x8320, SeekOrigin.Begin);
int offset = 0;
while (offset < 96)
{
int read = iso.Read(buf, offset, buf.Length - offset);
if (read == 0)
throw new EndOfStreamException();
offset += read;
}
}
// Format PVD to isobuster standard
char[] pvdCharArray = new char[96];
for (int i = 0; i < 96; i++)
{
if (buf[i] >= 0x20 && buf[i] <= 0x7E)
pvdCharArray[i] = (char)buf[i];
else
pvdCharArray[i] = '.';
}
string pvdASCII = new string(pvdCharArray, 0, 96);
pvd = string.Empty;
for (int i = 0; i < 96; i += 16)
{
pvd += $"{(0x0320+i):X4} : {buf[i]:X2} {buf[i+1]:X2} {buf[i+2]:X2} {buf[i+3]:X2} {buf[i+4]:X2} {buf[i+5]:X2} {buf[i+6]:X2} {buf[i+7]:X2} " +
$"{buf[i+8]:X2} {buf[i+9]:X2} {buf[i+10]:X2} {buf[i+11]:X2} {buf[i+12]:X2} {buf[i+13]:X2} {buf[i+14]:X2} {buf[i+15]:X2} {pvdASCII.Substring(i, 16)}\n";
}
return true;
}
catch
{
// We don't care what the error is
return false;
}
}
/// <summary>
/// Get a formatted datfile from the PS3 CFW output, if possible
/// </summary>
/// <param name="iso">Path to ISO file</param>
/// <returns>Formatted datfile, null if not valid</returns>
private static string? GetPS3CFWDatfile(string iso)
{
// If the files don't exist, we can't get info from it
if (!File.Exists(iso))
return null;
try
{
if (HashTool.GetStandardHashes(iso, out long size, out string? crc, out string? md5, out string? sha1))
return $"<rom name=\"{Path.GetFileName(iso)}\" size=\"{size}\" crc=\"{crc}\" md5=\"{md5}\" sha1=\"{sha1}\" />";
return null;
}
catch
{
// We don't care what the exception is right now
return null;
}
}
#endregion
#region Helper Functions
/// <summary>
/// Estimate the base filename of the .getkey.log file associated with the dump
/// </summary>
/// <param name="iso">Path to ISO file</param>
/// <returns>Base filename, null if not found</returns>
private string? GetCFWBasePath(string iso)
{
string? dir = Path.GetDirectoryName(iso);
dir ??= ".";
string[] files = Directory.GetFiles(dir, "*.getkey.log");
if (files.Length != 1)
return null;
return files[0].Substring(0, files[0].Length - 11);
}
#endregion
}
}

View File

@@ -1092,7 +1092,7 @@ namespace MPF.Core.Modules.Redumper
if (options.RedumperUseGenericDriveType)
{
this[FlagStrings.DriveType] = true;
DriveTypeValue = "Generic";
DriveTypeValue = "GENERIC";
}
// Set the output paths

View File

@@ -4,7 +4,7 @@ using System.IO;
using System.Linq;
using MPF.Core.Converters;
using MPF.Core.Data;
using MPF.Core.Hashing;
using SabreTools.Hashing;
using SabreTools.RedumpLib;
using SabreTools.RedumpLib.Data;
@@ -78,7 +78,7 @@ namespace MPF.Core.Modules.UmdImageCreator
case MediaType.UMD:
info.Extras!.PVD = GetPVD(basePath + "_mainInfo.txt") ?? string.Empty;
if (Hasher.GetFileHashes(basePath + ".iso", out long filesize, out var crc32, out var md5, out var sha1))
if (HashTool.GetStandardHashes(basePath + ".iso", out long filesize, out var crc32, out var md5, out var sha1))
{
// Get the Datafile information
var datafile = new Datafile

View File

@@ -89,6 +89,10 @@ namespace MPF.Core
Version = options.AddPlaceholders ? Template.RequiredIfExistsValue : string.Empty,
OtherEditions = options.AddPlaceholders ? "(VERIFY THIS) Original" : string.Empty,
},
DumpingInfo = new DumpingInfoSection()
{
FrontendVersion = Utilities.Tools.GetCurrentVersion(),
},
};
// Ensure that required sections exist
@@ -452,8 +456,8 @@ namespace MPF.Core
break;
case RedumpSystem.SonyPlayStation3:
info.Extras!.DiscKey = options.AddPlaceholders ? Template.RequiredValue : string.Empty;
info.Extras.DiscID = options.AddPlaceholders ? Template.RequiredValue : string.Empty;
info.Extras!.DiscKey ??= options.AddPlaceholders ? Template.RequiredValue : string.Empty;
info.Extras.DiscID ??= options.AddPlaceholders ? Template.RequiredValue : string.Empty;
break;
case RedumpSystem.TomyKissSite:
@@ -724,6 +728,9 @@ namespace MPF.Core
volLabels.Add($"{label.Key} ({string.Join(", ", [.. label.Value])})");
}
// Ensure that no labels are empty
volLabels = volLabels.Where(l => !string.IsNullOrEmpty(l?.Trim())).ToList();
// Print each label separated by a comma and a space
if (volLabels.Count == 0)
return null;

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using BinaryObjectScanner;
using MPF.Core.Data;
using MPF.Core.UI.ComboBoxItems;
@@ -179,6 +180,20 @@ namespace MPF.Core.UI.ViewModels
}
private bool _checkDumpButtonEnabled;
/// <summary>
/// Indicates the status of the cancel button
/// </summary>
public bool CancelButtonEnabled
{
get => _cancelButtonEnabled;
set
{
_cancelButtonEnabled = value;
TriggerPropertyChanged(nameof(CancelButtonEnabled));
}
}
private bool _cancelButtonEnabled;
#endregion
#region List Properties
@@ -243,6 +258,7 @@ namespace MPF.Core.UI.ViewModels
MediaTypeComboBoxEnabled = true;
DumpingProgramComboBoxEnabled = true;
CheckDumpButtonEnabled = false;
CancelButtonEnabled = true;
MediaTypes = [];
Systems = RedumpSystemComboBoxItem.GenerateElements().ToList();
@@ -310,6 +326,38 @@ namespace MPF.Core.UI.ViewModels
#endregion
#region UI Control
/// <summary>
/// Enables all UI elements that should be enabled
/// </summary>
private void EnableUIElements()
{
SystemTypeComboBoxEnabled = true;
InputPathTextBoxEnabled = true;
InputPathBrowseButtonEnabled = true;
DumpingProgramComboBoxEnabled = true;
PopulateMediaType();
CheckDumpButtonEnabled = ShouldEnableCheckDumpButton();
CancelButtonEnabled = true;
}
/// <summary>
/// Disables all UI elements
/// </summary>
private void DisableUIElements()
{
SystemTypeComboBoxEnabled = false;
InputPathTextBoxEnabled = false;
InputPathBrowseButtonEnabled = false;
MediaTypeComboBoxEnabled = false;
DumpingProgramComboBoxEnabled = false;
CheckDumpButtonEnabled = false;
CancelButtonEnabled = false;
}
#endregion
#region Population
/// <summary>
@@ -354,7 +402,7 @@ namespace MPF.Core.UI.ViewModels
InternalProgram internalProgram = this.Options.InternalProgram;
// Create a static list of supported Check programs, not everything
var internalPrograms = new List<InternalProgram> { InternalProgram.Redumper, InternalProgram.DiscImageCreator, InternalProgram.Aaru, InternalProgram.CleanRip, InternalProgram.UmdImageCreator };
var internalPrograms = new List<InternalProgram> { InternalProgram.Redumper, InternalProgram.Aaru, InternalProgram.DiscImageCreator, InternalProgram.CleanRip, InternalProgram.PS3CFW, InternalProgram.UmdImageCreator };
InternalPrograms = internalPrograms.Select(ip => new Element<InternalProgram>(ip)).ToList();
// Select the current default dumping program
@@ -398,7 +446,7 @@ namespace MPF.Core.UI.ViewModels
/// Performs MPF.Check functionality
/// </summary>
/// <returns>An error message if failed, otherwise string.Empty/null</returns>
public string? CheckDump(Func<SubmissionInfo?, (bool?, SubmissionInfo?)> processUserInfo)
public async Task<string?> CheckDump(Func<SubmissionInfo?, (bool?, SubmissionInfo?)> processUserInfo)
{
if (string.IsNullOrEmpty(InputPath))
return "Invalid Input path";
@@ -406,6 +454,11 @@ namespace MPF.Core.UI.ViewModels
if (!File.Exists(this.InputPath!.Trim('"')))
return "Input Path is not a valid file";
// Disable UI while Check is running
DisableUIElements();
bool cachedCanExecuteSelectionChanged = CanExecuteSelectionChanged;
DisableEventHandlers();
// Populate an environment
var env = new DumpEnvironment(Options, Path.GetFullPath(this.InputPath.Trim('"')), null, this.CurrentSystem, this.CurrentMediaType, this.CurrentProgram, parameters: null);
@@ -416,13 +469,12 @@ namespace MPF.Core.UI.ViewModels
protectionProgress.ProgressChanged += ConsoleLogger.ProgressUpdated;
// Finally, attempt to do the output dance
#if NET40
var resultTask = env.VerifyAndSaveDumpOutput(resultProgress, protectionProgress);
resultTask.Wait();
var result = resultTask.Result;
#else
var result = env.VerifyAndSaveDumpOutput(resultProgress, protectionProgress, processUserInfo).ConfigureAwait(false).GetAwaiter().GetResult();
#endif
var result = await env.VerifyAndSaveDumpOutput(resultProgress, protectionProgress, processUserInfo);
// Reenable UI and event handlers, if necessary
EnableUIElements();
if (cachedCanExecuteSelectionChanged)
EnableEventHandlers();
return result.Message;
}

View File

@@ -1046,7 +1046,6 @@ namespace MPF.Core.UI.ViewModels
try
{
#if NET6_0_OR_GREATER
// Create Redump-style reproducible IRD
LibIRD.ReIRD ird = new(InputPath, Key, Layerbreak);
if (PIC != null)
@@ -1056,9 +1055,6 @@ namespace MPF.Core.UI.ViewModels
ird.Write(outputPath);
CreateIRDStatus = "IRD Created Successfully";
return string.Empty;
#else
return "LibIRD requires .NET Core 6 or greater.";
#endif
}
catch (Exception e)
{

View File

@@ -76,20 +76,6 @@ namespace MPF.Core.UI.ViewModels
#region Properties
/// <summary>
/// Indicates the inability to create IRDs
/// </summary>
public bool CannotCreateIRD
{
get => _cannotCreateIRD;
set
{
_cannotCreateIRD = value;
TriggerPropertyChanged(nameof(CannotCreateIRD));
}
}
private bool _cannotCreateIRD;
/// <summary>
/// Indicates the status of the check dump menu item
/// </summary>
@@ -550,13 +536,7 @@ namespace MPF.Core.UI.ViewModels
OptionsMenuItemEnabled = true;
CheckDumpMenuItemEnabled = true;
#if NET6_0_OR_GREATER
CreateIRDMenuItemEnabled = true;
CannotCreateIRD = false;
#else
CreateIRDMenuItemEnabled = false;
CannotCreateIRD = true;
#endif
SystemTypeComboBoxEnabled = true;
MediaTypeComboBoxEnabled = true;
OutputPathTextBoxEnabled = true;
@@ -1297,9 +1277,7 @@ namespace MPF.Core.UI.ViewModels
{
OptionsMenuItemEnabled = false;
CheckDumpMenuItemEnabled = false;
#if NET6_0_OR_GREATER
CreateIRDMenuItemEnabled = false;
#endif
SystemTypeComboBoxEnabled = false;
MediaTypeComboBoxEnabled = false;
OutputPathTextBoxEnabled = false;
@@ -1321,9 +1299,7 @@ namespace MPF.Core.UI.ViewModels
{
OptionsMenuItemEnabled = true;
CheckDumpMenuItemEnabled = true;
#if NET6_0_OR_GREATER
CreateIRDMenuItemEnabled = true;
#endif
SystemTypeComboBoxEnabled = true;
MediaTypeComboBoxEnabled = true;
OutputPathTextBoxEnabled = true;

View File

@@ -42,19 +42,6 @@ namespace MPF.Core.UI.ViewModels
/// <inheritdoc/>
public event PropertyChangedEventHandler? PropertyChanged;
/// <summary>
/// Used to indicate whether LibIRD is supported
/// Whether compiled with .NET Core 6 or greater
/// </summary>
public static bool CreateIRDSupported
{
#if NET6_0_OR_GREATER
get { return true; }
#else
get { return false; }
#endif
}
#endregion
#region Lists

View File

@@ -272,7 +272,8 @@ namespace MPF.Core.Utilities
}
var serializer = JsonSerializer.Create();
var reader = new StreamReader(ConfigurationPath);
var stream = File.Open(ConfigurationPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
var reader = new StreamReader(stream);
var settings = serializer.Deserialize(reader, typeof(Dictionary<string, string?>)) as Dictionary<string, string?>;
return new Options(settings);
}

View File

@@ -293,19 +293,19 @@ namespace MPF.Core.Utilities
#endregion
#region PlayStation 3
#region PlayStation 3 specific tools
/// <summary>
/// Validates a getkey log to check for presence of valid PS3 key
/// </summary>
/// <param name="logPath">Path to getkey log file</param>
/// <param name="key">Output 16 byte key, null if not valid</param>
/// <param name="key">Output key string, null if not valid</param>
/// <param name="id">Output disc ID string, null if not valid</param>
/// <param name="pic">Output PIC string, null if not valid</param>
/// <returns>True if path to log file contains valid key, false otherwise</returns>
public static bool ParseGetKeyLog(string? logPath, out byte[]? key, out byte[]? id, out byte[]? pic)
public static bool ParseGetKeyLog(string? logPath, out string? key, out string? id, out string? pic)
{
key = null;
id = null;
pic = null;
key = id = pic = null;
if (string.IsNullOrEmpty(logPath))
return false;
@@ -344,7 +344,7 @@ namespace MPF.Core.Utilities
return false;
// Convert Disc Key to byte array
key = Tools.HexStringToByteArray(discKeyStr);
key = discKeyStr;
if (key == null)
return false;
@@ -366,7 +366,7 @@ namespace MPF.Core.Utilities
discIDStr = discIDStr.Substring(0, 24) + "00000001";
// Convert Disc ID to byte array
id = Tools.HexStringToByteArray(discIDStr);
id = discIDStr;
if (id == null)
return false;
@@ -379,17 +379,17 @@ namespace MPF.Core.Utilities
// Get PIC from log
string discPICStr = "";
for (int i = 0; i < 8; i++)
for (int i = 0; i < 9; i++)
discPICStr += sr.ReadLine();
if (discPICStr == null)
return false;
// Validate PIC from log
if (discPICStr.Length != 256)
if (discPICStr.Length != 264)
return false;
// Convert PIC to byte array
pic = Tools.HexStringToByteArray(discPICStr.Substring(0, 230));
pic = discPICStr;
if (pic == null)
return false;
@@ -412,6 +412,33 @@ namespace MPF.Core.Utilities
return true;
}
/// <summary>
/// Validates a getkey log to check for presence of valid PS3 key
/// </summary>
/// <param name="logPath">Path to getkey log file</param>
/// <param name="key">Output 16 byte disc key, null if not valid</param>
/// <param name="id">Output 16 byte disc ID, null if not valid</param>
/// <param name="pic">Output 230 byte PIC, null if not valid</param>
/// <returns>True if path to log file contains valid key, false otherwise</returns>
public static bool ParseGetKeyLog(string? logPath, out byte[]? key, out byte[]? id, out byte[]? pic)
{
key = id = pic = null;
if (ParseGetKeyLog(logPath, out string? keyString, out string? idString, out string? picString))
{
if (string.IsNullOrEmpty(keyString) || string.IsNullOrEmpty(idString) || string.IsNullOrEmpty(picString) || picString!.Length < 230)
return false;
key = Tools.HexStringToByteArray(keyString);
id = Tools.HexStringToByteArray(idString);
pic = Tools.HexStringToByteArray(picString.Substring(0, 230));
return true;
}
else
{
return false;
}
}
/// <summary>
/// Validates a hexadecimal disc ID
/// </summary>

View File

@@ -14,22 +14,22 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeCoverage" Version="17.9.0-preview-23531-01" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0-preview-23531-01" />
<PackageReference Include="Microsoft.CodeCoverage" Version="17.10.0-preview-24080-01" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0-preview-24080-01" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="SabreTools.RedumpLib" Version="1.3.2" />
<PackageReference Include="xunit" Version="2.6.2" />
<PackageReference Include="SabreTools.RedumpLib" Version="1.3.6" />
<PackageReference Include="xunit" Version="2.7.0" />
<PackageReference Include="xunit.abstractions" Version="2.0.3" />
<PackageReference Include="xunit.analyzers" Version="1.6.0" />
<PackageReference Include="xunit.assert" Version="2.6.2" />
<PackageReference Include="xunit.core" Version="2.6.2" />
<PackageReference Include="xunit.extensibility.core" Version="2.6.2" />
<PackageReference Include="xunit.extensibility.execution" Version="2.6.2" />
<PackageReference Include="xunit.runner.console" Version="2.6.2">
<PackageReference Include="xunit.analyzers" Version="1.11.0" />
<PackageReference Include="xunit.assert" Version="2.7.0" />
<PackageReference Include="xunit.core" Version="2.7.0" />
<PackageReference Include="xunit.extensibility.core" Version="2.7.0" />
<PackageReference Include="xunit.extensibility.execution" Version="2.7.0" />
<PackageReference Include="xunit.runner.console" Version="2.7.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.4">
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.7">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>

View File

@@ -12,7 +12,7 @@
<Nullable>enable</Nullable>
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<VersionPrefix>3.1.1</VersionPrefix>
<VersionPrefix>3.1.3</VersionPrefix>
<UseWindowsForms>true</UseWindowsForms>
<UseWPF>true</UseWPF>
@@ -43,7 +43,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="SabreTools.RedumpLib" Version="1.3.2" />
<PackageReference Include="SabreTools.RedumpLib" Version="1.3.6" />
</ItemGroup>
<ItemGroup>

View File

@@ -117,7 +117,7 @@
<Button Name="CheckDumpButton" Height="25" Width="80" IsDefault="True" Content="Check Dump"
IsEnabled="{Binding CheckDumpButtonEnabled}" Style="{DynamicResource CustomButtonStyle}" />
<Button Name="CancelButton" Height="25" Width="80" IsCancel="True" Content="Cancel"
Style="{DynamicResource CustomButtonStyle}" />
IsEnabled="{Binding CancelButtonEnabled}" Style="{DynamicResource CustomButtonStyle}" />
<Label/>
<!-- Empty label for padding -->
</UniformGrid>

View File

@@ -209,9 +209,17 @@ namespace MPF.UI.Core.Windows
/// <summary>
/// Handler for CheckDumpButton Click event
/// </summary>
#if NET40
private void OnCheckDumpClick(object sender, EventArgs e)
{
string? errorMessage = CheckDumpViewModel.CheckDump(ShowDiscInformationWindow);
var checkTask = CheckDumpViewModel.CheckDump(ShowDiscInformationWindow);
checkTask.Wait();
string? errorMessage = checkTask.Result;
#else
private async void OnCheckDumpClick(object sender, EventArgs e)
{
string? errorMessage = await CheckDumpViewModel.CheckDump(ShowDiscInformationWindow);
#endif
if (string.IsNullOrEmpty(errorMessage))
{
bool? checkAgain = DisplayUserMessage("Check Complete", "The dump has been processed successfully! Would you like to check another dump?", 2, false);

View File

@@ -399,6 +399,23 @@
<controls:UserInput x:Name="FullyMatchedID" Label="Fully Matched ID" IsReadOnly="True"
Text="{Binding SubmissionInfo.FullyMatchedID, Mode=TwoWay}"/>
<controls:UserInput x:Name="PartiallyMatchedIDs" Label="Partially Matched ID(s)" IsReadOnly="True"/>
<controls:UserInput x:Name="HashData" Label="Hash Data" IsReadOnly="True"
Text="{Binding SubmissionInfo.TracksAndWriteOffsets.ClrMameProData, Mode=TwoWay}" TextHeight="75" TextWrapping="NoWrap"
VerticalContentAlignmentValue="Top" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"/>
<controls:UserInput x:Name="HashDataSize" Label="Size" IsReadOnly="True"
Text="{Binding SubmissionInfo.SizeAndChecksums.Size, Mode=TwoWay}"/>
<controls:UserInput x:Name="HashDataCRC" Label="CRC-32" IsReadOnly="True"
Text="{Binding SubmissionInfo.SizeAndChecksums.CRC32, Mode=TwoWay}"/>
<controls:UserInput x:Name="HashDataMD5" Label="MD5" IsReadOnly="True"
Text="{Binding SubmissionInfo.SizeAndChecksums.MD5, Mode=TwoWay}"/>
<controls:UserInput x:Name="HashDataSHA1" Label="SHA-1" IsReadOnly="True"
Text="{Binding SubmissionInfo.SizeAndChecksums.SHA1, Mode=TwoWay}"/>
<controls:UserInput x:Name="HashDataLayerbreak1" Label="Layerbreak 1" IsReadOnly="True"
Text="{Binding SubmissionInfo.SizeAndChecksums.Layerbreak, Mode=TwoWay}"/>
<controls:UserInput x:Name="HashDataLayerbreak2" Label="Layerbreak 2" IsReadOnly="True"
Text="{Binding SubmissionInfo.SizeAndChecksums.Layerbreak2, Mode=TwoWay}"/>
<controls:UserInput x:Name="HashDataLayerbreak3" Label="Layerbreak 3" IsReadOnly="True"
Text="{Binding SubmissionInfo.SizeAndChecksums.Layerbreak3, Mode=TwoWay}"/>
<controls:UserInput x:Name="AntiModchip" Label="Anti-Modchip" IsReadOnly="True"
Text="{Binding SubmissionInfo.CopyProtection.AntiModchip, Mode=TwoWay}"/>
<controls:UserInput x:Name="DiscOffset" Label="Disc Offset" IsReadOnly="True"

View File

@@ -77,6 +77,14 @@ namespace MPF.UI.Core.Windows
private UserInput? _FullyMatchedID => ItemHelper.FindChild<UserInput>(this, "FullyMatchedID");
private UserInput? _PartiallyMatchedIDs => ItemHelper.FindChild<UserInput>(this, "PartiallyMatchedIDs");
private UserInput? _HashData => ItemHelper.FindChild<UserInput>(this, "HashData");
private UserInput? _HashDataSize => ItemHelper.FindChild<UserInput>(this, "HashDataSize");
private UserInput? _HashDataCRC => ItemHelper.FindChild<UserInput>(this, "HashDataCRC");
private UserInput? _HashDataMD5 => ItemHelper.FindChild<UserInput>(this, "HashDataMD5");
private UserInput? _HashDataSHA1 => ItemHelper.FindChild<UserInput>(this, "HashDataSHA1");
private UserInput? _HashDataLayerbreak1 => ItemHelper.FindChild<UserInput>(this, "HashDataLayerbreak1");
private UserInput? _HashDataLayerbreak2 => ItemHelper.FindChild<UserInput>(this, "HashDataLayerbreak2");
private UserInput? _HashDataLayerbreak3 => ItemHelper.FindChild<UserInput>(this, "HashDataLayerbreak3");
private UserInput? _AntiModchip => ItemHelper.FindChild<UserInput>(this, "AntiModchip");
private UserInput? _DiscOffset => ItemHelper.FindChild<UserInput>(this, "DiscOffset");
private UserInput? _DMIHash => ItemHelper.FindChild<UserInput>(this, "DMIHash");
@@ -295,6 +303,22 @@ namespace MPF.UI.Core.Windows
_PartiallyMatchedIDs!.Visibility = Visibility.Collapsed;
else
_PartiallyMatchedIDs!.Text = string.Join(", ", submissionInfo.PartiallyMatchedIDs.Select(i => i.ToString()).ToArray());
if (string.IsNullOrEmpty(submissionInfo.TracksAndWriteOffsets?.ClrMameProData))
_HashData!.Visibility = Visibility.Collapsed;
if (submissionInfo.SizeAndChecksums?.Size == null || submissionInfo.SizeAndChecksums.Size == 0)
_HashDataSize!.Visibility = Visibility.Collapsed;
if (string.IsNullOrEmpty(submissionInfo.SizeAndChecksums?.CRC32))
_HashDataCRC!.Visibility = Visibility.Collapsed;
if (string.IsNullOrEmpty(submissionInfo.SizeAndChecksums?.MD5))
_HashDataMD5!.Visibility = Visibility.Collapsed;
if (string.IsNullOrEmpty(submissionInfo.SizeAndChecksums?.SHA1))
_HashDataSHA1!.Visibility = Visibility.Collapsed;
if (submissionInfo.SizeAndChecksums?.Layerbreak == null || submissionInfo.SizeAndChecksums.Layerbreak == 0)
_HashDataLayerbreak1!.Visibility = Visibility.Collapsed;
if (submissionInfo.SizeAndChecksums?.Layerbreak2 == null || submissionInfo.SizeAndChecksums.Layerbreak2 == 0)
_HashDataLayerbreak2!.Visibility = Visibility.Collapsed;
if (submissionInfo.SizeAndChecksums?.Layerbreak3 == null || submissionInfo.SizeAndChecksums.Layerbreak3 == 0)
_HashDataLayerbreak3!.Visibility = Visibility.Collapsed;
if (submissionInfo.CopyProtection?.AntiModchip == null)
_AntiModchip!.Visibility = Visibility.Collapsed;
if (submissionInfo.TracksAndWriteOffsets?.OtherWriteOffsets == null)
@@ -352,6 +376,22 @@ namespace MPF.UI.Core.Windows
PartiallyMatchedIDs.Visibility = Visibility.Collapsed;
else
PartiallyMatchedIDs.Text = string.Join(", ", submissionInfo.PartiallyMatchedIDs.Select(i => i.ToString()).ToArray());
if (string.IsNullOrEmpty(submissionInfo.TracksAndWriteOffsets?.ClrMameProData))
HashData!.Visibility = Visibility.Collapsed;
if (submissionInfo.SizeAndChecksums?.Size == null)
HashDataSize!.Visibility = Visibility.Collapsed;
if (string.IsNullOrEmpty(submissionInfo.SizeAndChecksums?.CRC32))
HashDataCRC!.Visibility = Visibility.Collapsed;
if (string.IsNullOrEmpty(submissionInfo.SizeAndChecksums?.MD5))
HashDataMD5!.Visibility = Visibility.Collapsed;
if (string.IsNullOrEmpty(submissionInfo.SizeAndChecksums?.SHA1))
HashDataSHA1!.Visibility = Visibility.Collapsed;
if (submissionInfo.SizeAndChecksums?.Layerbreak == null || submissionInfo.SizeAndChecksums.Layerbreak == 0)
HashDataLayerbreak1!.Visibility = Visibility.Collapsed;
if (submissionInfo.SizeAndChecksums?.Layerbreak2 == null || submissionInfo.SizeAndChecksums.Layerbreak2 == 0)
HashDataLayerbreak2!.Visibility = Visibility.Collapsed;
if (submissionInfo.SizeAndChecksums?.Layerbreak3 == null || submissionInfo.SizeAndChecksums.Layerbreak3 == 0)
HashDataLayerbreak3!.Visibility = Visibility.Collapsed;
if (submissionInfo.CopyProtection?.AntiModchip == null)
AntiModchip.Visibility = Visibility.Collapsed;
if (submissionInfo.TracksAndWriteOffsets?.OtherWriteOffsets == null)

View File

@@ -58,10 +58,6 @@
Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"
Foreground="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"
Template="{DynamicResource CustomMenuItemTemplate}"
ToolTip="IRD Creation is only available on .NET Core 6 or newer."
ToolTipService.InitialShowDelay="0"
ToolTipService.IsEnabled="{Binding CannotCreateIRD}"
ToolTipService.ShowOnDisabled="True"
IsEnabled="{Binding CreateIRDMenuItemEnabled}"/>
<MenuItem x:Name="OptionsMenuItem" Header="_Options" HorizontalAlignment="Left" Width="185"
Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"

View File

@@ -263,7 +263,7 @@
/>
<CheckBox VerticalAlignment="Center" Content="Create PS3 IRD After Dumping"
IsChecked="{Binding Options.CreateIRDAfterDumping}" IsEnabled="{Binding CreateIRDSupported}"
IsChecked="{Binding Options.CreateIRDAfterDumping}"
ToolTip="Automatically creates an IRD file after dumping a PS3 disc" Margin="0,4"
/>
</UniformGrid>

View File

@@ -14,9 +14,9 @@
<Nullable>enable</Nullable>
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<VersionPrefix>3.1.1</VersionPrefix>
<UseWindowsForms>true</UseWindowsForms>
<UseWPF>true</UseWPF>
<VersionPrefix>3.1.3</VersionPrefix>
<!-- Package Properties -->
<Authors>Matt Nadareski;ReignStumble;Jakz</Authors>
@@ -70,10 +70,10 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="BinaryObjectScanner" PrivateAssets="build; analyzers" ExcludeAssets="contentFiles" Version="3.0.2" GeneratePathProperty="true">
<PackageReference Include="BinaryObjectScanner" PrivateAssets="build; analyzers" ExcludeAssets="contentFiles" Version="3.1.1" GeneratePathProperty="true">
<IncludeAssets>runtime; compile; build; native; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="SabreTools.RedumpLib" Version="1.3.2" />
<PackageReference Include="SabreTools.RedumpLib" Version="1.3.6" />
</ItemGroup>
<ItemGroup>

View File

@@ -2,7 +2,7 @@
Redumper/Aaru/DiscImageCreator UI in C#
[![Build status](https://ci.appveyor.com/api/projects/status/3ldav3v0c373jeqa?svg=true)](https://ci.appveyor.com/project/mnadareski/MPF/build/artifacts)
[![Build status](https://ci.appveyor.com/api/projects/status/3ldav3v0c373jeqa?svg=true)](https://ci.appveyor.com/project/mnadareski/MPF)
[![UI Build](https://github.com/SabreTools/MPF/actions/workflows/build_ui.yml/badge.svg)](https://github.com/SabreTools/MPF/actions/workflows/build_ui.yml)
[![Check Build](https://github.com/SabreTools/MPF/actions/workflows/build_check.yml/badge.svg)](https://github.com/SabreTools/MPF/actions/workflows/build_check.yml)
@@ -12,7 +12,7 @@ This is a community project, so if you have some time and knowledge to give, we'
For the most recent stable build, download the latest release here: [Releases Page](https://github.com/SabreTools/MPF/releases)
For the latest GitHub Actions WIP build here: [GitHub Actions](https://github.com/SabreTools/MPF/actions)
For the latest WIP build here: [Rolling Release](https://github.com/SabreTools/MPF/releases/tag/rolling)
## Media Preservation Frontend UI (MPF)

View File

@@ -1,5 +1,5 @@
# version format
version: 3.1.1-{build}
version: 3.1.3-{build}
# pull request template
pull_requests:
@@ -12,9 +12,6 @@ image: Visual Studio 2022
build_script:
- dotnet build
# post-build step
after_build:
# success/failure tracking
on_success:
- ps: Invoke-RestMethod https://raw.githubusercontent.com/DiscordHooks/appveyor-discord-webhook/master/send.ps1 -o send.ps1

View File

@@ -15,9 +15,8 @@ USE_ALL=false
INCLUDE_PROGRAMS=false
NO_BUILD=false
NO_ARCHIVE=false
while getopts "upba" OPTION
do
case $OPTION in
while getopts "upba" OPTION; do
case $OPTION in
u)
USE_ALL=true
;;
@@ -41,7 +40,7 @@ done
BUILD_FOLDER=$PWD
# Set the current commit hash
COMMIT=`git log --pretty=%H -1`
COMMIT=$(git log --pretty=%H -1)
# Create the build matrix arrays
UI_FRAMEWORKS=("net8.0-windows")
@@ -50,8 +49,7 @@ CHECK_FRAMEWORKS=("net8.0")
CHECK_RUNTIMES=("win-x86" "win-x64" "linux-x64" "osx-x64")
# Use expanded lists, if requested
if [ $USE_ALL = true ]
then
if [ $USE_ALL = true ]; then
UI_FRAMEWORKS=("net40" "net452" "net462" "net472" "net48" "netcoreapp3.1" "net5.0-windows" "net6.0-windows" "net7.0-windows" "net8.0-windows")
UI_RUNTIMES=("win-x86" "win-x64")
CHECK_FRAMEWORKS=("net20" "net35" "net40" "net452" "net462" "net472" "net48" "netcoreapp3.1" "net5.0" "net6.0" "net7.0" "net8.0")
@@ -64,59 +62,60 @@ VALID_CROSS_PLATFORM_FRAMEWORKS=("netcoreapp3.1" "net5.0" "net6.0" "net7.0" "net
VALID_CROSS_PLATFORM_RUNTIMES=("win-arm64" "linux-x64" "linux-arm64" "osx-x64")
# Only build if requested
if [ $NO_BUILD = false ]
then
if [ $NO_BUILD = false ]; then
# Restore Nuget packages for all builds
echo "Restoring Nuget packages"
dotnet restore
# Build UI
for FRAMEWORK in "${UI_FRAMEWORKS[@]}"
do
for RUNTIME in "${UI_RUNTIMES[@]}"
do
for FRAMEWORK in "${UI_FRAMEWORKS[@]}"; do
for RUNTIME in "${UI_RUNTIMES[@]}"; do
# 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
if [[ ! $(echo ${VALID_CROSS_PLATFORM_FRAMEWORKS[@]} | fgrep -w $FRAMEWORK) ]]; then
if [[ $(echo ${VALID_CROSS_PLATFORM_RUNTIMES[@]} | fgrep -w $RUNTIME) ]]; then
continue
fi
fi
# Only .NET 5 and above can publish to a single file
if [[ $(echo ${SINGLE_FILE_CAPABLE[@]} | fgrep -w $FRAMEWORK) ]]
then
dotnet publish MPF/MPF.csproj -f $FRAMEWORK -r $RUNTIME -c Debug --self-contained true --version-suffix $COMMIT -p:PublishSingleFile=true
if [[ $(echo ${SINGLE_FILE_CAPABLE[@]} | fgrep -w $FRAMEWORK) ]]; then
# Only include Debug if building all
if [ $USE_ALL = true ]; then
dotnet publish MPF/MPF.csproj -f $FRAMEWORK -r $RUNTIME -c Debug --self-contained true --version-suffix $COMMIT -p:PublishSingleFile=true
fi
dotnet publish MPF/MPF.csproj -f $FRAMEWORK -r $RUNTIME -c Release --self-contained true --version-suffix $COMMIT -p:PublishSingleFile=true -p:DebugType=None -p:DebugSymbols=false
else
dotnet publish MPF/MPF.csproj -f $FRAMEWORK -r $RUNTIME -c Debug --self-contained true --version-suffix $COMMIT
# Only include Debug if building all
if [ $USE_ALL = true ]; then
dotnet publish MPF/MPF.csproj -f $FRAMEWORK -r $RUNTIME -c Debug --self-contained true --version-suffix $COMMIT
fi
dotnet publish MPF/MPF.csproj -f $FRAMEWORK -r $RUNTIME -c Release --self-contained true --version-suffix $COMMIT -p:DebugType=None -p:DebugSymbols=false
fi
done
done
# Build Check
for FRAMEWORK in "${CHECK_FRAMEWORKS[@]}"
do
for RUNTIME in "${CHECK_RUNTIMES[@]}"
do
for FRAMEWORK in "${CHECK_FRAMEWORKS[@]}"; do
for RUNTIME in "${CHECK_RUNTIMES[@]}"; do
# 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
if [[ ! $(echo ${VALID_CROSS_PLATFORM_FRAMEWORKS[@]} | fgrep -w $FRAMEWORK) ]]; then
if [[ $(echo ${VALID_CROSS_PLATFORM_RUNTIMES[@]} | fgrep -w $RUNTIME) ]]; then
continue
fi
fi
# Only .NET 5 and above can publish to a single file
if [[ $(echo ${SINGLE_FILE_CAPABLE[@]} | fgrep -w $FRAMEWORK) ]]
then
dotnet publish MPF.Check/MPF.Check.csproj -f $FRAMEWORK -r $RUNTIME -c Debug --self-contained true --version-suffix $COMMIT -p:PublishSingleFile=true
if [[ $(echo ${SINGLE_FILE_CAPABLE[@]} | fgrep -w $FRAMEWORK) ]]; then
# Only include Debug if building all
if [ $USE_ALL = true ]; then
dotnet publish MPF.Check/MPF.Check.csproj -f $FRAMEWORK -r $RUNTIME -c Debug --self-contained true --version-suffix $COMMIT -p:PublishSingleFile=true
fi
dotnet publish MPF.Check/MPF.Check.csproj -f $FRAMEWORK -r $RUNTIME -c Release --self-contained true --version-suffix $COMMIT -p:PublishSingleFile=true -p:DebugType=None -p:DebugSymbols=false
else
dotnet publish MPF.Check/MPF.Check.csproj -f $FRAMEWORK -r $RUNTIME -c Debug --self-contained true --version-suffix $COMMIT
# Only include Debug if building all
if [ $USE_ALL = true ]; then
dotnet publish MPF.Check/MPF.Check.csproj -f $FRAMEWORK -r $RUNTIME -c Debug --self-contained true --version-suffix $COMMIT
fi
dotnet publish MPF.Check/MPF.Check.csproj -f $FRAMEWORK -r $RUNTIME -c Release --self-contained true --version-suffix $COMMIT -p:DebugType=None -p:DebugSymbols=false
fi
done
@@ -124,46 +123,43 @@ then
fi
# Only create archives if requested
if [ $NO_ARCHIVE = false ]
then
if [ $NO_ARCHIVE = false ]; then
# Create UI archives
for FRAMEWORK in "${UI_FRAMEWORKS[@]}"
do
for RUNTIME in "${UI_RUNTIMES[@]}"
do
cd $BUILD_FOLDER/MPF/bin/Debug/${FRAMEWORK}/${RUNTIME}/publish/
if [ $INCLUDE_PROGRAMS = true ]
then
zip -r $BUILD_FOLDER/MPF_${FRAMEWORK}_${RUNTIME}_debug.zip .
else
zip -r $BUILD_FOLDER/MPF_${FRAMEWORK}_${RUNTIME}_debug.zip . -x 'Programs/\*'
for FRAMEWORK in "${UI_FRAMEWORKS[@]}"; do
for RUNTIME in "${UI_RUNTIMES[@]}"; do
# Only include Debug if building all
if [ $USE_ALL = true ]; then
cd $BUILD_FOLDER/MPF/bin/Debug/${FRAMEWORK}/${RUNTIME}/publish/
if [ $INCLUDE_PROGRAMS = true ]; then
zip -r $BUILD_FOLDER/MPF_${FRAMEWORK}_${RUNTIME}_debug.zip .
else
zip -r $BUILD_FOLDER/MPF_${FRAMEWORK}_${RUNTIME}_debug.zip . -x 'Programs/\*'
fi
fi
cd $BUILD_FOLDER/MPF/bin/Release/${FRAMEWORK}/${RUNTIME}/publish/
if [ $INCLUDE_PROGRAMS = true ]
then
if [ $INCLUDE_PROGRAMS = true ]; then
zip -r $BUILD_FOLDER/MPF_${FRAMEWORK}_${RUNTIME}_release.zip .
else
zip -r $BUILD_FOLDER/MPF_${FRAMEWORK}_${RUNTIME}_release.zip . -x 'Programs/\*'
zip -r $BUILD_FOLDER/MPF_${FRAMEWORK}_${RUNTIME}_release.zip . -x 'Programs/\*'
fi
done
done
# Create Check archives
for FRAMEWORK in "${CHECK_FRAMEWORKS[@]}"
do
for RUNTIME in "${CHECK_RUNTIMES[@]}"
do
for FRAMEWORK in "${CHECK_FRAMEWORKS[@]}"; do
for RUNTIME in "${CHECK_RUNTIMES[@]}"; do
# 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
if [[ ! $(echo ${VALID_CROSS_PLATFORM_FRAMEWORKS[@]} | fgrep -w $FRAMEWORK) ]]; then
if [[ $(echo ${VALID_CROSS_PLATFORM_RUNTIMES[@]} | fgrep -w $RUNTIME) ]]; then
continue
fi
fi
cd $BUILD_FOLDER/MPF.Check/bin/Debug/${FRAMEWORK}/${RUNTIME}/publish/
zip -r $BUILD_FOLDER/MPF.Check_${FRAMEWORK}_${RUNTIME}_debug.zip .
# Only include Debug if building all
if [ $USE_ALL = true ]; then
cd $BUILD_FOLDER/MPF.Check/bin/Debug/${FRAMEWORK}/${RUNTIME}/publish/
zip -r $BUILD_FOLDER/MPF.Check_${FRAMEWORK}_${RUNTIME}_debug.zip .
fi
cd $BUILD_FOLDER/MPF.Check/bin/Release/${FRAMEWORK}/${RUNTIME}/publish/
zip -r $BUILD_FOLDER/MPF.Check_${FRAMEWORK}_${RUNTIME}_release.zip .
done
@@ -171,4 +167,4 @@ then
# Reset the directory
cd $BUILD_FOLDER
fi
fi

View File

@@ -40,8 +40,7 @@ $CHECK_FRAMEWORKS = @('net8.0')
$CHECK_RUNTIMES = @('win-x86', 'win-x64', 'linux-x64', 'osx-x64')
# Use expanded lists, if requested
if ($USE_ALL.IsPresent)
{
if ($USE_ALL.IsPresent) {
$UI_FRAMEWORKS = @('net40', 'net452', 'net462', 'net472', 'net48', 'netcoreapp3.1', 'net5.0-windows', 'net6.0-windows', 'net7.0-windows', 'net8.0-windows')
$UI_RUNTIMES = @('win-x86', 'win-x64')
$CHECK_FRAMEWORKS = @('net20', 'net35', 'net40', 'net452', 'net462', 'net472', 'net48', 'netcoreapp3.1', 'net5.0', 'net6.0', 'net7.0', 'net8.0')
@@ -54,57 +53,58 @@ $VALID_CROSS_PLATFORM_FRAMEWORKS = @('netcoreapp3.1', 'net5.0', 'net6.0', 'net7.
$VALID_CROSS_PLATFORM_RUNTIMES = @('win-arm64', 'linux-x64', 'linux-arm64', 'osx-x64')
# Only build if requested
if (!$NO_BUILD.IsPresent)
{
if (!$NO_BUILD.IsPresent) {
# Restore Nuget packages for all builds
Write-Host "Restoring Nuget packages"
dotnet restore
# Build UI
foreach ($FRAMEWORK in $UI_FRAMEWORKS)
{
foreach ($RUNTIME in $UI_RUNTIMES)
{
foreach ($FRAMEWORK in $UI_FRAMEWORKS) {
foreach ($RUNTIME in $UI_RUNTIMES) {
# If we have an invalid combination of framework and runtime
if ($VALID_CROSS_PLATFORM_FRAMEWORKS -notcontains $FRAMEWORK -and $VALID_CROSS_PLATFORM_RUNTIMES -contains $RUNTIME)
{
if ($VALID_CROSS_PLATFORM_FRAMEWORKS -notcontains $FRAMEWORK -and $VALID_CROSS_PLATFORM_RUNTIMES -contains $RUNTIME) {
continue
}
# Only .NET 5 and above can publish to a single file
if ($SINGLE_FILE_CAPABLE -contains $FRAMEWORK)
{
dotnet publish MPF\MPF.csproj -f $FRAMEWORK -r $RUNTIME -c Debug --self-contained true --version-suffix $COMMIT -p:PublishSingleFile=true
if ($SINGLE_FILE_CAPABLE -contains $FRAMEWORK) {
# Only include Debug if building all
if ($USE_ALL.IsPresent) {
dotnet publish MPF\MPF.csproj -f $FRAMEWORK -r $RUNTIME -c Debug --self-contained true --version-suffix $COMMIT -p:PublishSingleFile=true
}
dotnet publish MPF\MPF.csproj -f $FRAMEWORK -r $RUNTIME -c Release --self-contained true --version-suffix $COMMIT -p:PublishSingleFile=true -p:DebugType=None -p:DebugSymbols=false
}
else
{
dotnet publish MPF\MPF.csproj -f $FRAMEWORK -r $RUNTIME -c Debug --self-contained true --version-suffix $COMMIT
else {
# Only include Debug if building all
if ($USE_ALL.IsPresent) {
dotnet publish MPF\MPF.csproj -f $FRAMEWORK -r $RUNTIME -c Debug --self-contained true --version-suffix $COMMIT
}
dotnet publish MPF\MPF.csproj -f $FRAMEWORK -r $RUNTIME -c Release --self-contained true --version-suffix $COMMIT -p:DebugType=None -p:DebugSymbols=false
}
}
}
# Build Check
foreach ($FRAMEWORK in $CHECK_FRAMEWORKS)
{
foreach ($RUNTIME in $CHECK_RUNTIMES)
{
foreach ($FRAMEWORK in $CHECK_FRAMEWORKS) {
foreach ($RUNTIME in $CHECK_RUNTIMES) {
# If we have an invalid combination of framework and runtime
if ($VALID_CROSS_PLATFORM_FRAMEWORKS -notcontains $FRAMEWORK -and $VALID_CROSS_PLATFORM_RUNTIMES -contains $RUNTIME)
{
if ($VALID_CROSS_PLATFORM_FRAMEWORKS -notcontains $FRAMEWORK -and $VALID_CROSS_PLATFORM_RUNTIMES -contains $RUNTIME) {
continue
}
# Only .NET 5 and above can publish to a single file
if ($SINGLE_FILE_CAPABLE -contains $FRAMEWORK)
{
dotnet publish MPF.Check\MPF.Check.csproj -f $FRAMEWORK -r $RUNTIME -c Debug --self-contained true --version-suffix $COMMIT -p:PublishSingleFile=true
if ($SINGLE_FILE_CAPABLE -contains $FRAMEWORK) {
# Only include Debug if building all
if ($USE_ALL.IsPresent) {
dotnet publish MPF.Check\MPF.Check.csproj -f $FRAMEWORK -r $RUNTIME -c Debug --self-contained true --version-suffix $COMMIT -p:PublishSingleFile=true
}
dotnet publish MPF.Check\MPF.Check.csproj -f $FRAMEWORK -r $RUNTIME -c Release --self-contained true --version-suffix $COMMIT -p:PublishSingleFile=true -p:DebugType=None -p:DebugSymbols=false
}
else
{
dotnet publish MPF.Check\MPF.Check.csproj -f $FRAMEWORK -r $RUNTIME -c Debug --self-contained true --version-suffix $COMMIT
else {
# Only include Debug if building all
if ($USE_ALL.IsPresent) {
dotnet publish MPF.Check\MPF.Check.csproj -f $FRAMEWORK -r $RUNTIME -c Debug --self-contained true --version-suffix $COMMIT
}
dotnet publish MPF.Check\MPF.Check.csproj -f $FRAMEWORK -r $RUNTIME -c Release --self-contained true --version-suffix $COMMIT -p:DebugType=None -p:DebugSymbols=false
}
}
@@ -112,47 +112,44 @@ if (!$NO_BUILD.IsPresent)
}
# Only create archives if requested
if (!$NO_ARCHIVE.IsPresent)
{
if (!$NO_ARCHIVE.IsPresent) {
# Create UI archives
foreach ($FRAMEWORK in $UI_FRAMEWORKS)
{
foreach ($RUNTIME in $UI_RUNTIMES)
{
Set-Location -Path $BUILD_FOLDER\MPF\bin\Debug\${FRAMEWORK}\${RUNTIME}\publish\
if ($INCLUDE_PROGRAMS.IsPresent)
{
7z a -tzip $BUILD_FOLDER\MPF_${FRAMEWORK}_${RUNTIME}_debug.zip *
}
else
{
7z a -tzip -x!Programs\* $BUILD_FOLDER\MPF_${FRAMEWORK}_${RUNTIME}_debug.zip *
foreach ($FRAMEWORK in $UI_FRAMEWORKS) {
foreach ($RUNTIME in $UI_RUNTIMES) {
# Only include Debug if building all
if ($USE_ALL.IsPresent) {
Set-Location -Path $BUILD_FOLDER\MPF\bin\Debug\${FRAMEWORK}\${RUNTIME}\publish\
if ($INCLUDE_PROGRAMS.IsPresent) {
7z a -tzip $BUILD_FOLDER\MPF_${FRAMEWORK}_${RUNTIME}_debug.zip *
}
else {
7z a -tzip -x!Programs\* $BUILD_FOLDER\MPF_${FRAMEWORK}_${RUNTIME}_debug.zip *
}
}
Set-Location -Path $BUILD_FOLDER\MPF\bin\Release\${FRAMEWORK}\${RUNTIME}\publish\
if ($INCLUDE_PROGRAMS.IsPresent)
{
if ($INCLUDE_PROGRAMS.IsPresent) {
7z a -tzip $BUILD_FOLDER\MPF_${FRAMEWORK}_${RUNTIME}_release.zip *
}
else
{
else {
7z a -tzip -x!Programs\* $BUILD_FOLDER\MPF_${FRAMEWORK}_${RUNTIME}_release.zip *
}
}
}
# Create Check archives
foreach ($FRAMEWORK in $CHECK_FRAMEWORKS)
{
foreach ($RUNTIME in $CHECK_RUNTIMES)
{
foreach ($FRAMEWORK in $CHECK_FRAMEWORKS) {
foreach ($RUNTIME in $CHECK_RUNTIMES) {
# If we have an invalid combination of framework and runtime
if ($VALID_CROSS_PLATFORM_FRAMEWORKS -notcontains $FRAMEWORK -and $VALID_CROSS_PLATFORM_RUNTIMES -contains $RUNTIME)
{
if ($VALID_CROSS_PLATFORM_FRAMEWORKS -notcontains $FRAMEWORK -and $VALID_CROSS_PLATFORM_RUNTIMES -contains $RUNTIME) {
continue
}
Set-Location -Path $BUILD_FOLDER\MPF.Check\bin\Debug\${FRAMEWORK}\${RUNTIME}\publish\
7z a -tzip $BUILD_FOLDER\MPF.Check_${FRAMEWORK}_${RUNTIME}_debug.zip *
# Only include Debug if building all
if ($USE_ALL.IsPresent) {
Set-Location -Path $BUILD_FOLDER\MPF.Check\bin\Debug\${FRAMEWORK}\${RUNTIME}\publish\
7z a -tzip $BUILD_FOLDER\MPF.Check_${FRAMEWORK}_${RUNTIME}_debug.zip *
}
Set-Location -Path $BUILD_FOLDER\MPF.Check\bin\Release\${FRAMEWORK}\${RUNTIME}\publish\
7z a -tzip $BUILD_FOLDER\MPF.Check_${FRAMEWORK}_${RUNTIME}_release.zip *
}