Make fully and partially matching IDs more apparent

Add write offset as read-only field
This commit is contained in:
Matt Nadareski
2022-03-12 21:09:51 -08:00
parent 5f8625a384
commit 09fcd384ab
7 changed files with 74 additions and 38 deletions

View File

@@ -26,6 +26,8 @@
- Return faster on empty protection sets
- Remove redundant check around volume label
- Fix tabs in Games and Videos boxes
- Make fully and partially matching IDs more apparent
- Add write offset as read-only field
### 2.3 (2022-02-05)
- Start overhauling Redump information pulling, again

View File

@@ -644,7 +644,7 @@ namespace MPF.Library
info.SizeAndChecksums.Layerbreak3),
1);
AddIfExists(output, Template.CategoryField, info.CommonDiscInfo.Category.LongName(), 1);
AddIfExists(output, Template.MatchingIDsField, info.MatchedIDs, 1);
AddIfExists(output, Template.MatchingIDsField, info.PartiallyMatchedIDs, 1);
AddIfExists(output, Template.RegionField, info.CommonDiscInfo.Region.LongName() ?? "SPACE! (CHANGE THIS)", 1);
AddIfExists(output, Template.LanguagesField, (info.CommonDiscInfo.Languages ?? new Language?[] { null }).Select(l => l.LongName() ?? "SILENCE! (CHANGE THIS)").ToArray(), 1);
AddIfExists(output, Template.PlaystationLanguageSelectionViaField, (info.CommonDiscInfo.LanguageSelection ?? new LanguageSelection?[] { }).Select(l => l.LongName()).ToArray(), 1);
@@ -1603,7 +1603,7 @@ namespace MPF.Library
{
// Set the current dumper based on username
info.DumpersAndStatus.Dumpers = new string[] { options.RedumpUsername };
info.MatchedIDs = new List<int>();
info.PartiallyMatchedIDs = new List<int>();
using (RedumpWebClient wc = new RedumpWebClient())
{
@@ -1620,38 +1620,59 @@ namespace MPF.Library
return;
}
// Loop through all of the hashdata to find matching IDs
// Setup the full-track checks
bool allFound = true;
List<int> fullyMatchedIDs = null;
// Loop through all of the hashdata to find matching IDs
resultProgress?.Report(Result.Success("Finding disc matches on Redump..."));
string[] splitData = info.TracksAndWriteOffsets.ClrMameProData.Split('\n');
foreach (string hashData in splitData)
{
allFound &= ValidateSingleTrack(wc, info, hashData, resultProgress);
(bool singleFound, List<int> foundIds) = ValidateSingleTrack(wc, info, hashData, resultProgress);
// Ensure that all tracks are found
allFound &= singleFound;
// If we found a track, only keep track of distinct found tracks
if (singleFound && foundIds != null)
{
if (fullyMatchedIDs == null)
fullyMatchedIDs = foundIds;
else
fullyMatchedIDs = fullyMatchedIDs.Intersect(foundIds).ToList();
}
}
resultProgress?.Report(Result.Success("Match finding complete! " + (info.MatchedIDs.Count > 0
? "Matched IDs: " + string.Join(",", info.MatchedIDs)
// Make sure we only have unique IDs
info.PartiallyMatchedIDs = info.PartiallyMatchedIDs
.Distinct()
.OrderBy(id => id)
.ToList();
resultProgress?.Report(Result.Success("Match finding complete! " + (fullyMatchedIDs.Count > 0
? "Fully Matched IDs: " + string.Join(",", fullyMatchedIDs)
: "No matches found")));
// Exit early if one failed or there are no matched IDs
if (!allFound || info.MatchedIDs.Count == 0)
if (!allFound || fullyMatchedIDs.Count == 0)
return;
// Find the first matched ID where the track count matches, we can grab a bunch of info from it
int totalMatchedIDsCount = info.MatchedIDs.Count;
int totalMatchedIDsCount = fullyMatchedIDs.Count;
for (int i = 0; i < totalMatchedIDsCount; i++)
{
// Skip if the track count doesn't match
if (!ValidateTrackCount(wc, info.MatchedIDs[i], splitData.Length))
if (!ValidateTrackCount(wc, fullyMatchedIDs[i], splitData.Length))
continue;
// Fill in the fields from the existing ID
resultProgress?.Report(Result.Success($"Filling fields from existing ID {info.MatchedIDs[i]}..."));
FillFromId(wc, info, info.MatchedIDs[0]);
resultProgress?.Report(Result.Success($"Filling fields from existing ID {fullyMatchedIDs[i]}..."));
FillFromId(wc, info, fullyMatchedIDs[i]);
resultProgress?.Report(Result.Success("Information filling complete!"));
// Set the matched IDs to just the current
info.MatchedIDs = new List<int> { info.MatchedIDs[i] };
// Set the fully matched ID to the current
info.FullyMatchedID = fullyMatchedIDs[i];
break;
}
}
@@ -1736,14 +1757,14 @@ namespace MPF.Library
/// <param name="info">Existing SubmissionInfo object to fill</param>
/// <param name="hashData">DAT-formatted hash data to parse out</param>
/// <param name="resultProgress">Optional result progress callback</param>
/// <returns>True if the track was found, false otherwise</returns>
private static bool ValidateSingleTrack(RedumpWebClient wc, SubmissionInfo info, string hashData, IProgress<Result> resultProgress = null)
/// <returns>True if the track was found, false otherwise; List of found values, if possible</returns>
private static (bool, List<int>) ValidateSingleTrack(RedumpWebClient wc, SubmissionInfo info, string hashData, IProgress<Result> resultProgress = null)
{
// If the line isn't parseable, we can't validate
if (!GetISOHashValues(hashData, out long _, out string _, out string _, out string sha1))
{
resultProgress?.Report(Result.Failure("Line could not be parsed for hash data"));
return false;
return (false, null);
}
// Get all matching IDs for the track
@@ -1753,25 +1774,20 @@ namespace MPF.Library
if (newIds == null)
{
resultProgress?.Report(Result.Failure("There was an unknown error retrieving information from Redump"));
return false;
return (false, null);
}
// If no IDs match any track, then we don't match a disc at all
// If no IDs match any track, just return
if (!newIds.Any())
{
info.MatchedIDs = new List<int>();
return false;
}
return (false, null);
// If we have multiple tracks, only take IDs that are in common
if (info.MatchedIDs.Any())
info.MatchedIDs = info.MatchedIDs.Intersect(newIds).ToList();
// If we're on the first track, all IDs are added
// Join the list of found IDs to the existing list, if possible
if (info.PartiallyMatchedIDs.Any())
info.PartiallyMatchedIDs.AddRange(newIds);
else
info.MatchedIDs = newIds;
info.PartiallyMatchedIDs = newIds;
return true;
return (true, newIds);
}
/// <summary>

View File

@@ -42,7 +42,8 @@ namespace MPF.Test.RedumpLib
var submissionInfo = new SubmissionInfo()
{
SchemaVersion = 1,
MatchedIDs = new List<int> { 0, 1, 2, 3 },
FullyMatchedID = 3,
PartiallyMatchedIDs = new List<int> { 0, 1, 2, 3 },
Added = DateTime.UtcNow,
LastModified = DateTime.UtcNow,

View File

@@ -266,14 +266,22 @@ namespace MPF.GUI.ViewModels
/// </summary>
private void HideReadOnlyFields()
{
if (SubmissionInfo?.MatchedIDs == null)
Parent.MatchedIDs.Visibility = Visibility.Collapsed;
if (SubmissionInfo?.FullyMatchedID == null)
Parent.FullyMatchedID.Visibility = Visibility.Collapsed;
else
Parent.MatchedIDs.Text = string.Join(", ", SubmissionInfo.MatchedIDs);
Parent.FullyMatchedID.Text = SubmissionInfo.FullyMatchedID.ToString();
if (SubmissionInfo?.PartiallyMatchedIDs == null)
Parent.PartiallyMatchedIDs.Visibility = Visibility.Collapsed;
else
Parent.PartiallyMatchedIDs.Text = string.Join(", ", SubmissionInfo.PartiallyMatchedIDs);
if (SubmissionInfo?.CopyProtection?.AntiModchip == null)
Parent.AntiModchip.Visibility = Visibility.Collapsed;
else
Parent.AntiModchip.Text = SubmissionInfo.CopyProtection.AntiModchip.LongName();
if (SubmissionInfo?.TracksAndWriteOffsets?.OtherWriteOffsets == null)
Parent.DiscOffset.Visibility = Visibility.Collapsed;
else
Parent.DiscOffset.Text = SubmissionInfo.TracksAndWriteOffsets.OtherWriteOffsets;
if (SubmissionInfo?.CommonDiscInfo?.CommentsSpecialFields.Keys.Contains(SiteCode.DMIHash) != true)
Parent.DMIHash.Visibility = Visibility.Collapsed;
if (string.IsNullOrWhiteSpace(SubmissionInfo?.CommonDiscInfo?.ErrorsCount))

View File

@@ -282,7 +282,8 @@ namespace MPF.GUI.ViewModels
var submissionInfo = new SubmissionInfo()
{
SchemaVersion = 1,
MatchedIDs = new List<int> { 0, 1, 2, 3 },
FullyMatchedID = 3,
PartiallyMatchedIDs = new List<int> { 0, 1, 2, 3 },
Added = DateTime.UtcNow,
LastModified = DateTime.UtcNow,

View File

@@ -335,8 +335,10 @@
<TabItem Header="Read-Only Info" Style="{DynamicResource CustomTabItemStyle}">
<ScrollViewer CanContentScroll="False" VerticalScrollBarVisibility="Auto" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" MaxHeight="500">
<StackPanel Orientation="Vertical">
<controls:UserInput x:Name="MatchedIDs" Label="Matched ID(s)" IsReadOnly="True"/>
<controls:UserInput x:Name="FullyMatchedID" Label="Fully Matched ID" IsReadOnly="True"/>
<controls:UserInput x:Name="PartiallyMatchedIDs" Label="Partially Matched ID(s)" IsReadOnly="True"/>
<controls:UserInput x:Name="AntiModchip" Label="Anti-Modchip" IsReadOnly="True"/>
<controls:UserInput x:Name="DiscOffset" Label="Disc Offset" IsReadOnly="True"/>
<controls:UserInput x:Name="DMIHash" Label="DMI Hash" IsReadOnly="True"/>
<controls:UserInput x:Name="EDC" Label="EDC" IsReadOnly="True"/>
<controls:UserInput x:Name="ErrorsCount" Label="Error(s) Count" IsReadOnly="True"

View File

@@ -15,10 +15,16 @@ namespace RedumpLib.Data
public int SchemaVersion { get; set; } = 1;
/// <summary>
/// List of matched Redump IDs
/// Fully matched Redump ID
/// </summary>
[JsonIgnore]
public List<int> MatchedIDs { get; set; }
public int? FullyMatchedID { get; set; }
/// <summary>
/// List of partially matched Redump IDs
/// </summary>
[JsonIgnore]
public List<int> PartiallyMatchedIDs { get; set; }
/// <summary>
/// DateTime of when the disc was added
@@ -67,7 +73,7 @@ namespace RedumpLib.Data
return new SubmissionInfo
{
SchemaVersion = this.SchemaVersion,
MatchedIDs = this.MatchedIDs,
PartiallyMatchedIDs = this.PartiallyMatchedIDs,
Added = this.Added,
LastModified = this.LastModified,
CommonDiscInfo = this.CommonDiscInfo?.Clone() as CommonDiscInfoSection,