Take care of some TODO items

This commit is contained in:
Matt Nadareski
2024-03-12 11:53:58 -04:00
parent 6ec0c970cb
commit f9c207cf09
11 changed files with 255 additions and 150 deletions

View File

@@ -57,7 +57,9 @@ namespace SabreTools.DatFiles
} }
if (item.ContainsKey(Models.Metadata.Header.ImagesKey)) if (item.ContainsKey(Models.Metadata.Header.ImagesKey))
{ {
// TODO: Add to internal model var images = item.Read<Models.OfflineList.Images>(Models.Metadata.Header.ImagesKey);
if (images != null)
Header.SetFieldValue<Models.OfflineList.Images?>(Models.Metadata.Header.ImagesKey, images);
} }
if (item.ContainsKey(Models.Metadata.Header.InfosKey)) if (item.ContainsKey(Models.Metadata.Header.InfosKey))
{ {
@@ -358,6 +360,17 @@ namespace SabreTools.DatFiles
if (machine.GetStringFieldValue(Models.Metadata.Machine.SupportedKey) != null) if (machine.GetStringFieldValue(Models.Metadata.Machine.SupportedKey) != null)
machine.SetFieldValue<string?>(Models.Metadata.Machine.SupportedKey, machine.GetStringFieldValue(Models.Metadata.Machine.SupportedKey).AsEnumValue<Supported>().AsStringValue()); machine.SetFieldValue<string?>(Models.Metadata.Machine.SupportedKey, machine.GetStringFieldValue(Models.Metadata.Machine.SupportedKey).AsEnumValue<Supported>().AsStringValue());
// Handle Trurip object, if it exists
if (item.ContainsKey(Models.Metadata.Machine.TruripKey))
{
var truripItem = item.Read<Models.Logiqx.Trurip>(Models.Metadata.Machine.TruripKey);
if (truripItem != null)
{
var trurip = new DatItems.Trurip(truripItem);
machine.SetFieldValue<DatItems.Trurip>(Models.Metadata.Machine.TruripKey, trurip);
}
}
// Convert items in the machine // Convert items in the machine
if (item.ContainsKey(Models.Metadata.Machine.AdjusterKey)) if (item.ContainsKey(Models.Metadata.Machine.AdjusterKey))
{ {
@@ -489,10 +502,6 @@ namespace SabreTools.DatFiles
var items = ReadItemArray<Models.Metadata.Sound>(item, Models.Metadata.Machine.SoundKey); var items = ReadItemArray<Models.Metadata.Sound>(item, Models.Metadata.Machine.SoundKey);
ProcessItems(items, machine, filename, indexId, statsOnly); ProcessItems(items, machine, filename, indexId, statsOnly);
} }
if (item.ContainsKey(Models.Metadata.Machine.TruripKey))
{
// TODO: Figure out what this maps to
}
if (item.ContainsKey(Models.Metadata.Machine.VideoKey)) if (item.ContainsKey(Models.Metadata.Machine.VideoKey))
{ {
var items = ReadItemArray<Models.Metadata.Video>(item, Models.Metadata.Machine.VideoKey); var items = ReadItemArray<Models.Metadata.Video>(item, Models.Metadata.Machine.VideoKey);

View File

@@ -57,8 +57,8 @@ namespace SabreTools.DatFiles
// Convert subheader values // Convert subheader values
if (Header.CanOpenSpecified) if (Header.CanOpenSpecified)
header[Models.Metadata.Header.CanOpenKey] = new Models.OfflineList.CanOpen { Extension = Header.GetStringArrayFieldValue(Models.Metadata.Header.CanOpenKey) }; header[Models.Metadata.Header.CanOpenKey] = new Models.OfflineList.CanOpen { Extension = Header.GetStringArrayFieldValue(Models.Metadata.Header.CanOpenKey) };
// if (Header.ImagesSpecified) if (Header.ImagesSpecified)
// // TODO: Add to internal model header[Models.Metadata.Header.ImagesKey] = Header.GetFieldValue<Models.OfflineList.Images>(Models.Metadata.Header.ImagesKey);
if (Header.InfosSpecified) if (Header.InfosSpecified)
{ {
var infoItem = new Models.OfflineList.Infos(); var infoItem = new Models.OfflineList.Infos();
@@ -210,6 +210,22 @@ namespace SabreTools.DatFiles
// Create a machine to hold everything // Create a machine to hold everything
var machine = items[0].GetFieldValue<DatItems.Machine>(DatItems.DatItem.MachineKey)!.GetInternalClone(); var machine = items[0].GetFieldValue<DatItems.Machine>(DatItems.DatItem.MachineKey)!.GetInternalClone();
// Handle Trurip object, if it exists
if (machine.ContainsKey(Models.Metadata.Machine.TruripKey))
{
var trurip = machine.Read<DatItems.Trurip>(Models.Metadata.Machine.TruripKey);
if (trurip != null)
{
var truripItem = trurip.ConvertToLogiqx();
truripItem.Publisher = machine.ReadString(Models.Metadata.Machine.PublisherKey);
truripItem.Year = machine.ReadString(Models.Metadata.Machine.YearKey);
truripItem.Players = machine.ReadString(Models.Metadata.Machine.PlayersKey);
truripItem.Source = machine.ReadString(Models.Metadata.Machine.SourceFileKey);
truripItem.CloneOf = machine.ReadString(Models.Metadata.Machine.CloneOfKey);
machine[Models.Metadata.Machine.TruripKey] = truripItem;
}
}
// Loop through and convert the items to respective lists // Loop through and convert the items to respective lists
for (int index = 0; index < items.Count; index++) for (int index = 0; index < items.Count; index++)
{ {
@@ -271,8 +287,7 @@ namespace SabreTools.DatFiles
AppendToMachineKey(machine, Models.Metadata.Machine.DiskKey, diskItem); AppendToMachineKey(machine, Models.Metadata.Machine.DiskKey, diskItem);
break; break;
case DatItems.Formats.Display display: case DatItems.Formats.Display display:
// TODO: Handle cases where it's actually a Video var displayItem = ProcessItem(display);
var displayItem = display.GetInternalClone();
EnsureMachineKey<Models.Metadata.Display?>(machine, Models.Metadata.Machine.DisplayKey); EnsureMachineKey<Models.Metadata.Display?>(machine, Models.Metadata.Machine.DisplayKey);
AppendToMachineKey(machine, Models.Metadata.Machine.DisplayKey, displayItem); AppendToMachineKey(machine, Models.Metadata.Machine.DisplayKey, displayItem);
break; break;
@@ -501,6 +516,20 @@ namespace SabreTools.DatFiles
return diskItem; return diskItem;
} }
/// <summary>
/// Convert Display information
/// </summary>
/// <param name="item">Item to convert</param>
/// <param name="machine">Machine to use for Part and DiskArea</param>
private static Models.Metadata.Display ProcessItem(DatItems.Formats.Display item)
{
var displayItem = item.GetInternalClone();
// TODO: Handle cases where it's actually a Video
return displayItem;
}
/// <summary> /// <summary>
/// Convert Input information /// Convert Input information
/// </summary> /// </summary>

View File

@@ -259,7 +259,6 @@ namespace SabreTools.DatFiles
else if ((size == 0 || size == null) else if ((size == 0 || size == null)
&& (string.IsNullOrEmpty(rom.GetStringFieldValue(Models.Metadata.Rom.CRCKey)) || rom.HasZeroHash())) && (string.IsNullOrEmpty(rom.GetStringFieldValue(Models.Metadata.Rom.CRCKey)) || rom.HasZeroHash()))
{ {
// TODO: All instances of Hash.DeepHashes should be made into 0x0 eventually
rom.SetFieldValue<string?>(Models.Metadata.Rom.SizeKey, Constants.SizeZero.ToString()); rom.SetFieldValue<string?>(Models.Metadata.Rom.SizeKey, Constants.SizeZero.ToString());
rom.SetFieldValue<string?>(Models.Metadata.Rom.CRCKey, Constants.CRCZero); rom.SetFieldValue<string?>(Models.Metadata.Rom.CRCKey, Constants.CRCZero);
rom.SetFieldValue<string?>(Models.Metadata.Rom.MD5Key, Constants.MD5Zero); rom.SetFieldValue<string?>(Models.Metadata.Rom.MD5Key, Constants.MD5Zero);

View File

@@ -82,16 +82,6 @@ namespace SabreTools.DatFiles
#region Fields #region Fields
[JsonIgnore]
public bool InfosSpecified
{
get
{
var infos = GetFieldValue<OfflineListInfo[]?>(Models.Metadata.Header.InfosKey);
return infos != null && infos.Length > 0;
}
}
[JsonIgnore] [JsonIgnore]
public bool CanOpenSpecified public bool CanOpenSpecified
{ {
@@ -102,6 +92,25 @@ namespace SabreTools.DatFiles
} }
} }
[JsonIgnore]
public bool ImagesSpecified
{
get
{
return GetFieldValue<Models.OfflineList.Images?>(Models.Metadata.Header.ImagesKey) != null;
}
}
[JsonIgnore]
public bool InfosSpecified
{
get
{
var infos = GetFieldValue<OfflineListInfo[]?>(Models.Metadata.Header.InfosKey);
return infos != null && infos.Length > 0;
}
}
[JsonIgnore] [JsonIgnore]
public bool NewDatSpecified public bool NewDatSpecified
{ {
@@ -302,6 +311,7 @@ namespace SabreTools.DatFiles
header.SetFieldValue<string?>(Models.Metadata.Header.HomepageKey, GetStringFieldValue(Models.Metadata.Header.HomepageKey)); header.SetFieldValue<string?>(Models.Metadata.Header.HomepageKey, GetStringFieldValue(Models.Metadata.Header.HomepageKey));
header.SetFieldValue<string?>(Models.Metadata.Header.IdKey, GetStringFieldValue(Models.Metadata.Header.IdKey)); header.SetFieldValue<string?>(Models.Metadata.Header.IdKey, GetStringFieldValue(Models.Metadata.Header.IdKey));
header.SetFieldValue<OfflineListInfo[]?>(Models.Metadata.Header.InfosKey, GetFieldValue<OfflineListInfo[]?>(Models.Metadata.Header.InfosKey)); // TODO: Perform a deep clone header.SetFieldValue<OfflineListInfo[]?>(Models.Metadata.Header.InfosKey, GetFieldValue<OfflineListInfo[]?>(Models.Metadata.Header.InfosKey)); // TODO: Perform a deep clone
header.SetFieldValue<Models.OfflineList.Images?>(Models.Metadata.Header.ImagesKey, GetFieldValue<Models.OfflineList.Images?>(Models.Metadata.Header.ImagesKey)); // TODO: Perform a deep clone
header.SetFieldValue<DepotInformation?>(DatHeader.InputDepotKey, GetFieldValue<DepotInformation?>(DatHeader.InputDepotKey)?.Clone() as DepotInformation); header.SetFieldValue<DepotInformation?>(DatHeader.InputDepotKey, GetFieldValue<DepotInformation?>(DatHeader.InputDepotKey)?.Clone() as DepotInformation);
header.SetFieldValue<DepotInformation?>(DatHeader.OutputDepotKey, GetFieldValue<DepotInformation?>(DatHeader.OutputDepotKey)?.Clone() as DepotInformation); header.SetFieldValue<DepotInformation?>(DatHeader.OutputDepotKey, GetFieldValue<DepotInformation?>(DatHeader.OutputDepotKey)?.Clone() as DepotInformation);
header.SetFieldValue<bool?>(Models.Metadata.Header.LockBiosModeKey, GetBoolFieldValue(Models.Metadata.Header.LockBiosModeKey)); header.SetFieldValue<bool?>(Models.Metadata.Header.LockBiosModeKey, GetBoolFieldValue(Models.Metadata.Header.LockBiosModeKey));

View File

@@ -13,9 +13,17 @@ namespace SabreTools.DatFiles.Formats
try try
{ {
// Deserialize the input file // Deserialize the input file
// TODO: Support M1 DATs again
var mame = new Serialization.Files.Listxml().Deserialize(filename); var mame = new Serialization.Files.Listxml().Deserialize(filename);
var metadata = new Serialization.CrossModel.Listxml().Serialize(mame); Models.Metadata.MetadataFile? metadata;
if (mame == null)
{
var m1 = new Serialization.Files.M1().Deserialize(filename);
metadata = new Serialization.CrossModel.M1().Serialize(m1);
}
else
{
metadata = new Serialization.CrossModel.Listxml().Serialize(mame);
}
// Convert to the internal format // Convert to the internal format
ConvertMetadata(metadata, filename, indexId, keep, statsOnly); ConvertMetadata(metadata, filename, indexId, keep, statsOnly);

View File

@@ -6,10 +6,6 @@ using Newtonsoft.Json;
/// </summary> /// </summary>
namespace SabreTools.DatItems.Formats namespace SabreTools.DatItems.Formats
{ {
#region DatItem
#region OpenMSX
/// <summary> /// <summary>
/// Represents the OpenMSX original value /// Represents the OpenMSX original value
/// </summary> /// </summary>
@@ -36,8 +32,4 @@ namespace SabreTools.DatItems.Formats
[JsonIgnore] [JsonIgnore]
private readonly Models.Metadata.Original _internal = []; private readonly Models.Metadata.Original _internal = [];
} }
#endregion
#endregion //DatItem
} }

View File

@@ -33,77 +33,6 @@ namespace SabreTools.DatItems
#region Fields #region Fields
// TODO: Should this be a separate object for TruRip?
#region Logiqx EmuArc
/// <summary>
/// Title ID
/// </summary>
[JsonProperty("titleid", DefaultValueHandling = DefaultValueHandling.Ignore)]
[XmlElement("titleid")]
public string? TitleID { get; set; } = null;
/// <summary>
/// Machine developer
/// </summary>
[JsonProperty("developer", DefaultValueHandling = DefaultValueHandling.Ignore)]
[XmlElement("developer")]
public string? Developer { get; set; } = null;
/// <summary>
/// Game genre
/// </summary>
[JsonProperty("genre", DefaultValueHandling = DefaultValueHandling.Ignore)]
[XmlElement("genre")]
public string? Genre { get; set; } = null;
/// <summary>
/// Game subgenre
/// </summary>
[JsonProperty("subgenre", DefaultValueHandling = DefaultValueHandling.Ignore)]
[XmlElement("subgenre")]
public string? Subgenre { get; set; } = null;
/// <summary>
/// Game ratings
/// </summary>
[JsonProperty("ratings", DefaultValueHandling = DefaultValueHandling.Ignore)]
[XmlElement("ratings")]
public string? Ratings { get; set; } = null;
/// <summary>
/// Game score
/// </summary>
[JsonProperty("score", DefaultValueHandling = DefaultValueHandling.Ignore)]
[XmlElement("score")]
public string? Score { get; set; } = null;
/// <summary>
/// Is the machine enabled
/// </summary>
[JsonProperty("enabled", DefaultValueHandling = DefaultValueHandling.Ignore)]
[XmlElement("enabled")]
public string? Enabled { get; set; } = null; // bool?
/// <summary>
/// Does the game have a CRC check
/// </summary>
[JsonProperty("hascrc", DefaultValueHandling = DefaultValueHandling.Ignore)]
[XmlElement("hascrc")]
public bool? Crc { get; set; } = null;
[JsonIgnore]
public bool CrcSpecified { get { return Crc != null; } }
/// <summary>
/// Machine relations
/// </summary>
[JsonProperty("relatedto", DefaultValueHandling = DefaultValueHandling.Ignore)]
[XmlElement("relatedto")]
public string? RelatedTo { get; set; } = null;
#endregion
/// <summary> /// <summary>
/// Internal Machine model /// Internal Machine model
/// </summary> /// </summary>
@@ -112,6 +41,28 @@ namespace SabreTools.DatItems
#endregion #endregion
#region Constructors
public Machine() { }
public Machine(Models.Metadata.Machine machine)
{
// Get all fields to automatically copy without processing
var nonItemFields = TypeHelper.GetConstants(typeof(Models.Metadata.Machine));
if (nonItemFields == null)
return;
// Populate the internal machine from non-filter fields
_machine = [];
foreach (string fieldName in nonItemFields)
{
if (machine.ContainsKey(fieldName))
_machine[fieldName] = machine[fieldName];
}
}
#endregion
#region Accessors #region Accessors
/// <summary> /// <summary>
@@ -230,28 +181,6 @@ namespace SabreTools.DatItems
#endregion #endregion
#region Constructors
public Machine() { }
public Machine(Models.Metadata.Machine machine)
{
// Get all fields to automatically copy without processing
var nonItemFields = TypeHelper.GetConstants(typeof(Models.Metadata.Machine));
if (nonItemFields == null)
return;
// Populate the internal machine from non-filter fields
_machine = [];
foreach (string fieldName in nonItemFields)
{
if (machine.ContainsKey(fieldName))
_machine[fieldName] = machine[fieldName];
}
}
#endregion
#region Cloning methods #region Cloning methods
/// <summary> /// <summary>
@@ -262,25 +191,7 @@ namespace SabreTools.DatItems
{ {
return new Machine() return new Machine()
{ {
#region Common
_machine = this._machine.Clone() as Models.Metadata.Machine ?? [], _machine = this._machine.Clone() as Models.Metadata.Machine ?? [],
#endregion
#region Logiqx EmuArc
TitleID = this.TitleID,
Developer = this.Developer,
Genre = this.Genre,
Subgenre = this.Subgenre,
Ratings = this.Ratings,
Score = this.Score,
Enabled = this.Enabled,
Crc = this.Crc,
RelatedTo = this.RelatedTo,
#endregion
}; };
} }

View File

@@ -0,0 +1,146 @@
using System;
using System.Xml.Serialization;
using Newtonsoft.Json;
using SabreTools.Core.Tools;
namespace SabreTools.DatItems
{
/// <summary>
/// Represents TruRip/EmuArc-specific values on a machine
/// </summary>
[JsonObject("trurip"), XmlRoot("trurip")]
public sealed class Trurip : ICloneable
{
#region Fields
/// <summary>
/// Title ID
/// </summary>
[JsonProperty("titleid", DefaultValueHandling = DefaultValueHandling.Ignore)]
[XmlElement("titleid")]
public string? TitleID { get; set; } = null;
/// <summary>
/// Machine developer
/// </summary>
[JsonProperty("developer", DefaultValueHandling = DefaultValueHandling.Ignore)]
[XmlElement("developer")]
public string? Developer { get; set; } = null;
/// <summary>
/// Game genre
/// </summary>
[JsonProperty("genre", DefaultValueHandling = DefaultValueHandling.Ignore)]
[XmlElement("genre")]
public string? Genre { get; set; } = null;
/// <summary>
/// Game subgenre
/// </summary>
[JsonProperty("subgenre", DefaultValueHandling = DefaultValueHandling.Ignore)]
[XmlElement("subgenre")]
public string? Subgenre { get; set; } = null;
/// <summary>
/// Game ratings
/// </summary>
[JsonProperty("ratings", DefaultValueHandling = DefaultValueHandling.Ignore)]
[XmlElement("ratings")]
public string? Ratings { get; set; } = null;
/// <summary>
/// Game score
/// </summary>
[JsonProperty("score", DefaultValueHandling = DefaultValueHandling.Ignore)]
[XmlElement("score")]
public string? Score { get; set; } = null;
/// <summary>
/// Is the machine enabled
/// </summary>
[JsonProperty("enabled", DefaultValueHandling = DefaultValueHandling.Ignore)]
[XmlElement("enabled")]
public string? Enabled { get; set; } = null; // bool?
/// <summary>
/// Does the game have a CRC check
/// </summary>
[JsonProperty("hascrc", DefaultValueHandling = DefaultValueHandling.Ignore)]
[XmlElement("hascrc")]
public bool? Crc { get; set; } = null;
[JsonIgnore]
public bool CrcSpecified { get { return Crc != null; } }
/// <summary>
/// Machine relations
/// </summary>
[JsonProperty("relatedto", DefaultValueHandling = DefaultValueHandling.Ignore)]
[XmlElement("relatedto")]
public string? RelatedTo { get; set; } = null;
#endregion
#region Constructors
public Trurip() { }
public Trurip(Models.Logiqx.Trurip trurip)
{
TitleID = trurip.TitleID;
Developer = trurip.Developer;
Genre = trurip.Genre;
Subgenre = trurip.Subgenre;
Ratings = trurip.Ratings;
Score = trurip.Score;
Enabled = trurip.Enabled;
Crc = trurip.CRC.AsYesNo();
RelatedTo = trurip.RelatedTo;
}
#endregion
#region Cloning methods
/// <summary>
/// Create a clone of the current object
/// </summary>
/// <returns>New object with the same values as the current one</returns>
public object Clone()
{
return new Trurip()
{
TitleID = this.TitleID,
Developer = this.Developer,
Genre = this.Genre,
Subgenre = this.Subgenre,
Ratings = this.Ratings,
Score = this.Score,
Enabled = this.Enabled,
Crc = this.Crc,
RelatedTo = this.RelatedTo,
};
}
/// <summary>
/// Convert to the internal Logiqx model
/// </summary>
public Models.Logiqx.Trurip ConvertToLogiqx()
{
return new Models.Logiqx.Trurip()
{
TitleID = this.TitleID,
Developer = this.Developer,
Genre = this.Genre,
Subgenre = this.Subgenre,
Ratings = this.Ratings,
Score = this.Score,
Enabled = this.Enabled,
CRC = this.Crc.FromYesNo(),
RelatedTo = this.RelatedTo,
};
}
#endregion
}
}

View File

@@ -38,7 +38,7 @@ namespace SabreTools.Filter
filters.Add(new FilterObject(filterString)); filters.Add(new FilterObject(filterString));
} }
this.Filters = filters.ToArray(); this.Filters = [.. filters];
} }
/// <summary> /// <summary>

View File

@@ -404,8 +404,6 @@ namespace SabreTools.Test.Core
Assert.Equal(expected, actual); Assert.Equal(expected, actual);
} }
// TODO: Write new test for all supported DatHeaderField values
[Theory] [Theory]
[InlineData(DeviceType.NULL, null)] [InlineData(DeviceType.NULL, null)]
[InlineData(DeviceType.Unknown, "unknown")] [InlineData(DeviceType.Unknown, "unknown")]

View File

@@ -1,19 +1,18 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using Microsoft.Data.Sqlite;
using SabreTools.Core; using SabreTools.Core;
using SabreTools.Core.Tools; using SabreTools.Core.Tools;
using SabreTools.DatFiles; using SabreTools.DatFiles;
using SabreTools.DatTools; using SabreTools.DatTools;
using SabreTools.FileTypes; using SabreTools.FileTypes;
using SabreTools.Filtering; using SabreTools.Filtering;
using SabreTools.Hashing;
using SabreTools.Help; using SabreTools.Help;
using SabreTools.IO; using SabreTools.IO;
using SabreTools.Logging; using SabreTools.Logging;
using SabreTools.Reports; using SabreTools.Reports;
using Microsoft.Data.Sqlite;
using SabreTools.Hashing;
namespace SabreTools.Features namespace SabreTools.Features
{ {
@@ -2238,11 +2237,15 @@ Some special strings that can be used:
{ {
// Populate filters // Populate filters
List<string> filterPairs = GetList(features, FilterListValue); List<string> filterPairs = GetList(features, FilterListValue);
var filterRunner = new Filter.FilterRunner(filterPairs.ToArray());
// TODO: Support this use case somehow
// Include 'of" in game filters // Include 'of" in game filters
//filter.MachineFilter.IncludeOfInGame = GetBoolean(features, MatchOfTagsValue); bool matchOfTags = GetBoolean(features, MatchOfTagsValue);
if (matchOfTags)
{
// TODO: Support this use case somehow
}
var filterRunner = new Filter.FilterRunner(filterPairs.ToArray());
return filterRunner; return filterRunner;
} }