Add Aaruformat validation and media item type (#29)

* Initial `media` and AaruFormat code

* But... why?

* Fix AIF reading

* Fix D2D, Logiqx cleanup

* Minor cleanup

* Final cleanup round
This commit is contained in:
Matt Nadareski
2020-08-27 16:57:22 -07:00
committed by GitHub
parent 3b481de3b9
commit 4d0a3f55eb
51 changed files with 2853 additions and 908 deletions

View File

@@ -175,13 +175,13 @@ namespace SabreTools.Library.DatFiles
// If we have a "null" game (created by DATFromDir or something similar), log it to file
if (item.ItemType == ItemType.Rom
&& ((Rom)item).Size == -1
&& ((Rom)item).CRC == "null")
&& (item as Rom).Size == -1
&& (item as Rom).CRC == "null")
{
Globals.Logger.Verbose($"Empty folder found: {item.Machine.Name}");
item.Name = (item.Name == "null" ? "-" : item.Name);
((Rom)item).Size = Constants.SizeZero;
(item as Rom).Size = Constants.SizeZero;
}
// Set the new data to compare against
@@ -255,7 +255,7 @@ namespace SabreTools.Library.DatFiles
private bool WriteDatItem(SeparatedValueWriter svw, DatItem datItem, bool ignoreblanks = false)
{
// If we are in ignore blanks mode AND we have a blank (0-size) rom, skip
if (ignoreblanks && (datItem.ItemType == ItemType.Rom && (((Rom)datItem).Size == 0 || ((Rom)datItem).Size == -1)))
if (ignoreblanks && (datItem.ItemType == ItemType.Rom && ((datItem as Rom).Size == 0 || (datItem as Rom).Size == -1)))
return true;
try

View File

@@ -262,33 +262,8 @@ namespace SabreTools.Library.DatFiles
containsItems = true;
string itemKey = cmpr.InternalName;
ItemType itemType = ItemType.Rom;
switch (itemKey)
{
case "archive":
itemType = ItemType.Archive;
break;
case "biosset":
itemType = ItemType.BiosSet;
break;
case "chip":
itemType = ItemType.Chip;
break;
case "disk":
itemType = ItemType.Disk;
break;
case "release":
itemType = ItemType.Release;
break;
case "rom":
itemType = ItemType.Rom;
break;
case "sample":
itemType = ItemType.Sample;
break;
}
// Create the proper DatItem based on the type
ItemType itemType = itemKey.AsItemType() ?? ItemType.Rom;
DatItem item = DatItem.Create(itemType);
// Then populate it with information
@@ -318,9 +293,9 @@ namespace SabreTools.Library.DatFiles
if (item.ItemType == ItemType.Rom)
{
if (Int64.TryParse(attrVal, out long size))
((Rom)item).Size = size;
(item as Rom).Size = size;
else
((Rom)item).Size = -1;
(item as Rom).Size = -1;
}
break;
@@ -330,99 +305,97 @@ namespace SabreTools.Library.DatFiles
break;
case "md5":
if (item.ItemType == ItemType.Rom)
if (item.ItemType == ItemType.Disk)
(item as Disk).MD5 = attrVal;
else if (item.ItemType == ItemType.Media)
(item as Media).MD5 = attrVal;
else if (item.ItemType == ItemType.Rom)
(item as Rom).MD5 = attrVal;
else if (item.ItemType == ItemType.Disk)
((Disk)item).MD5 = attrVal;
break;
#if NET_FRAMEWORK
case "ripemd160":
if (item.ItemType == ItemType.Rom)
(item as Rom).RIPEMD160 = attrVal;
else if (item.ItemType == ItemType.Disk)
((Disk)item).RIPEMD160 = attrVal;
break;
#endif
case "sha1":
if (item.ItemType == ItemType.Rom)
if (item.ItemType == ItemType.Disk)
(item as Disk).SHA1 = attrVal;
else if (item.ItemType == ItemType.Media)
(item as Media).SHA1 = attrVal;
else if (item.ItemType == ItemType.Rom)
(item as Rom).SHA1 = attrVal;
else if (item.ItemType == ItemType.Disk)
((Disk)item).SHA1 = attrVal;
break;
case "sha256":
if (item.ItemType == ItemType.Rom)
((Rom)item).SHA256 = attrVal;
else if (item.ItemType == ItemType.Disk)
((Disk)item).SHA256 = attrVal;
if (item.ItemType == ItemType.Media)
(item as Media).SHA256 = attrVal;
else if (item.ItemType == ItemType.Rom)
(item as Rom).SHA256 = attrVal;
break;
case "sha384":
if (item.ItemType == ItemType.Rom)
((Rom)item).SHA384 = attrVal;
else if (item.ItemType == ItemType.Disk)
((Disk)item).SHA384 = attrVal;
(item as Rom).SHA384 = attrVal;
break;
case "sha512":
if (item.ItemType == ItemType.Rom)
((Rom)item).SHA512 = attrVal;
else if (item.ItemType == ItemType.Disk)
((Disk)item).SHA512 = attrVal;
(item as Rom).SHA512 = attrVal;
break;
case "status":
ItemStatus tempFlagStatus = attrVal.AsItemStatus();
if (item.ItemType == ItemType.Rom)
((Rom)item).ItemStatus = tempFlagStatus;
else if (item.ItemType == ItemType.Disk)
((Disk)item).ItemStatus = tempFlagStatus;
if (item.ItemType == ItemType.Disk)
(item as Disk).ItemStatus = tempFlagStatus;
else if (item.ItemType == ItemType.Rom)
(item as Rom).ItemStatus = tempFlagStatus;
break;
case "date":
if (item.ItemType == ItemType.Rom)
((Rom)item).Date = attrVal;
else if (item.ItemType == ItemType.Release)
((Release)item).Date = attrVal;
if (item.ItemType == ItemType.Release)
(item as Release).Date = attrVal;
else if (item.ItemType == ItemType.Rom)
(item as Rom).Date = attrVal;
break;
case "default":
if (item.ItemType == ItemType.BiosSet)
((BiosSet)item).Default = attrVal.AsYesNo();
(item as BiosSet).Default = attrVal.AsYesNo();
else if (item.ItemType == ItemType.Release)
((Release)item).Default = attrVal.AsYesNo();
(item as Release).Default = attrVal.AsYesNo();
break;
case "description":
if (item.ItemType == ItemType.BiosSet)
((BiosSet)item).Description = attrVal;
(item as BiosSet).Description = attrVal;
break;
case "region":
if (item.ItemType == ItemType.Release)
((Release)item).Region = attrVal;
(item as Release).Region = attrVal;
break;
case "language":
if (item.ItemType == ItemType.Release)
((Release)item).Language = attrVal;
(item as Release).Language = attrVal;
break;
case "tag":
if (item.ItemType == ItemType.Chip)
((Chip)item).Tag = attrVal;
(item as Chip).Tag = attrVal;
break;
case "type":
if (item.ItemType == ItemType.Chip)
((Chip)item).ChipType = attrVal;
(item as Chip).ChipType = attrVal;
break;
case "clock":
if (item.ItemType == ItemType.Chip)
((Chip)item).Clock = attrVal;
(item as Chip).Clock = attrVal;
break;
}
@@ -707,17 +680,21 @@ namespace SabreTools.Library.DatFiles
cmpw.WriteStartElement("disk");
cmpw.WriteRequiredAttributeString("name", disk.Name);
cmpw.WriteOptionalAttributeString("md5", disk.MD5?.ToLowerInvariant());
#if NET_FRAMEWORK
cmpw.WriteOptionalAttributeString("ripemd160", disk.RIPEMD160?.ToLowerInvariant());
#endif
cmpw.WriteOptionalAttributeString("sha1", disk.SHA1?.ToLowerInvariant());
cmpw.WriteOptionalAttributeString("sha256", disk.SHA256?.ToLowerInvariant());
cmpw.WriteOptionalAttributeString("sha384", disk.SHA384?.ToLowerInvariant());
cmpw.WriteOptionalAttributeString("sha512", disk.SHA512?.ToLowerInvariant());
cmpw.WriteOptionalAttributeString("flags", disk.ItemStatus.FromItemStatus(false));
cmpw.WriteEndElement();
break;
case ItemType.Media:
var media = datItem as Media;
cmpw.WriteStartElement("media");
cmpw.WriteRequiredAttributeString("name", media.Name);
cmpw.WriteOptionalAttributeString("md5", media.MD5?.ToLowerInvariant());
cmpw.WriteOptionalAttributeString("sha1", media.SHA1?.ToLowerInvariant());
cmpw.WriteOptionalAttributeString("sha256", media.SHA256?.ToLowerInvariant());
cmpw.WriteEndElement();
break;
case ItemType.Release:
var release = datItem as Release;
cmpw.WriteStartElement("release");

View File

@@ -1986,100 +1986,92 @@ namespace SabreTools.Library.DatFiles
return key;
}
// If we have a Rom or a Disk, clean the hash data
if (item.ItemType == ItemType.Rom)
// If we have a Disk, Media, or Rom, clean the hash data
if (item.ItemType == ItemType.Disk)
{
Rom itemRom = (Rom)item;
Disk disk = item as Disk;
// If the file has aboslutely no hashes, skip and log
if (disk.ItemStatus != ItemStatus.Nodump
&& string.IsNullOrWhiteSpace(disk.MD5)
&& string.IsNullOrWhiteSpace(disk.SHA1))
{
Globals.Logger.Verbose($"Incomplete entry for '{disk.Name}' will be output as nodump");
disk.ItemStatus = ItemStatus.Nodump;
}
item = disk;
}
else if (item.ItemType == ItemType.Rom)
{
Rom rom = item as Rom;
// If we have the case where there is SHA-1 and nothing else, we don't fill in any other part of the data
if (itemRom.Size == -1
&& string.IsNullOrWhiteSpace(itemRom.CRC)
&& string.IsNullOrWhiteSpace(itemRom.MD5)
if (rom.Size == -1
&& string.IsNullOrWhiteSpace(rom.CRC)
&& string.IsNullOrWhiteSpace(rom.MD5)
#if NET_FRAMEWORK
&& string.IsNullOrWhiteSpace(itemRom.RIPEMD160)
&& string.IsNullOrWhiteSpace(rom.RIPEMD160)
#endif
&& !string.IsNullOrWhiteSpace(itemRom.SHA1)
&& string.IsNullOrWhiteSpace(itemRom.SHA256)
&& string.IsNullOrWhiteSpace(itemRom.SHA384)
&& string.IsNullOrWhiteSpace(itemRom.SHA512))
&& !string.IsNullOrWhiteSpace(rom.SHA1)
&& string.IsNullOrWhiteSpace(rom.SHA256)
&& string.IsNullOrWhiteSpace(rom.SHA384)
&& string.IsNullOrWhiteSpace(rom.SHA512))
{
// No-op, just catch it so it doesn't go further
Globals.Logger.Verbose($"{Header.FileName}: Entry with only SHA-1 found - '{itemRom.Name}'");
Globals.Logger.Verbose($"{Header.FileName}: Entry with only SHA-1 found - '{rom.Name}'");
}
// If we have a rom and it's missing size AND the hashes match a 0-byte file, fill in the rest of the info
else if ((itemRom.Size == 0 || itemRom.Size == -1)
&& ((itemRom.CRC == Constants.CRCZero || string.IsNullOrWhiteSpace(itemRom.CRC))
|| itemRom.MD5 == Constants.MD5Zero
else if ((rom.Size == 0 || rom.Size == -1)
&& ((rom.CRC == Constants.CRCZero || string.IsNullOrWhiteSpace(rom.CRC))
|| rom.MD5 == Constants.MD5Zero
#if NET_FRAMEWORK
|| itemRom.RIPEMD160 == Constants.RIPEMD160Zero
|| rom.RIPEMD160 == Constants.RIPEMD160Zero
#endif
|| itemRom.SHA1 == Constants.SHA1Zero
|| itemRom.SHA256 == Constants.SHA256Zero
|| itemRom.SHA384 == Constants.SHA384Zero
|| itemRom.SHA512 == Constants.SHA512Zero))
|| rom.SHA1 == Constants.SHA1Zero
|| rom.SHA256 == Constants.SHA256Zero
|| rom.SHA384 == Constants.SHA384Zero
|| rom.SHA512 == Constants.SHA512Zero))
{
// TODO: All instances of Hash.DeepHashes should be made into 0x0 eventually
itemRom.Size = Constants.SizeZero;
itemRom.CRC = Constants.CRCZero;
itemRom.MD5 = Constants.MD5Zero;
rom.Size = Constants.SizeZero;
rom.CRC = Constants.CRCZero;
rom.MD5 = Constants.MD5Zero;
#if NET_FRAMEWORK
itemRom.RIPEMD160 = null;
//itemRom.RIPEMD160 = Constants.RIPEMD160Zero;
rom.RIPEMD160 = null; // Constants.RIPEMD160Zero;
#endif
itemRom.SHA1 = Constants.SHA1Zero;
itemRom.SHA256 = null;
//itemRom.SHA256 = Constants.SHA256Zero;
itemRom.SHA384 = null;
//itemRom.SHA384 = Constants.SHA384Zero;
itemRom.SHA512 = null;
//itemRom.SHA512 = Constants.SHA512Zero;
rom.SHA1 = Constants.SHA1Zero;
rom.SHA256 = null; // Constants.SHA256Zero;
rom.SHA384 = null; // Constants.SHA384Zero;
rom.SHA512 = null; // Constants.SHA512Zero;
}
// If the file has no size and it's not the above case, skip and log
else if (itemRom.ItemStatus != ItemStatus.Nodump && (itemRom.Size == 0 || itemRom.Size == -1))
else if (rom.ItemStatus != ItemStatus.Nodump && (rom.Size == 0 || rom.Size == -1))
{
Globals.Logger.Verbose($"{Header.FileName}: Incomplete entry for '{itemRom.Name}' will be output as nodump");
itemRom.ItemStatus = ItemStatus.Nodump;
Globals.Logger.Verbose($"{Header.FileName}: Incomplete entry for '{rom.Name}' will be output as nodump");
rom.ItemStatus = ItemStatus.Nodump;
}
// If the file has a size but aboslutely no hashes, skip and log
else if (itemRom.ItemStatus != ItemStatus.Nodump
&& itemRom.Size > 0
&& string.IsNullOrWhiteSpace(itemRom.CRC)
&& string.IsNullOrWhiteSpace(itemRom.MD5)
else if (rom.ItemStatus != ItemStatus.Nodump
&& rom.Size > 0
&& string.IsNullOrWhiteSpace(rom.CRC)
&& string.IsNullOrWhiteSpace(rom.MD5)
#if NET_FRAMEWORK
&& string.IsNullOrWhiteSpace(itemRom.RIPEMD160)
&& string.IsNullOrWhiteSpace(rom.RIPEMD160)
#endif
&& string.IsNullOrWhiteSpace(itemRom.SHA1)
&& string.IsNullOrWhiteSpace(itemRom.SHA256)
&& string.IsNullOrWhiteSpace(itemRom.SHA384)
&& string.IsNullOrWhiteSpace(itemRom.SHA512))
&& string.IsNullOrWhiteSpace(rom.SHA1)
&& string.IsNullOrWhiteSpace(rom.SHA256)
&& string.IsNullOrWhiteSpace(rom.SHA384)
&& string.IsNullOrWhiteSpace(rom.SHA512))
{
Globals.Logger.Verbose($"{Header.FileName}: Incomplete entry for '{itemRom.Name}' will be output as nodump");
itemRom.ItemStatus = ItemStatus.Nodump;
Globals.Logger.Verbose($"{Header.FileName}: Incomplete entry for '{rom.Name}' will be output as nodump");
rom.ItemStatus = ItemStatus.Nodump;
}
item = itemRom;
}
else if (item.ItemType == ItemType.Disk)
{
Disk itemDisk = (Disk)item;
// If the file has aboslutely no hashes, skip and log
if (itemDisk.ItemStatus != ItemStatus.Nodump
&& string.IsNullOrWhiteSpace(itemDisk.MD5)
#if NET_FRAMEWORK
&& string.IsNullOrWhiteSpace(itemDisk.RIPEMD160)
#endif
&& string.IsNullOrWhiteSpace(itemDisk.SHA1)
&& string.IsNullOrWhiteSpace(itemDisk.SHA256)
&& string.IsNullOrWhiteSpace(itemDisk.SHA384)
&& string.IsNullOrWhiteSpace(itemDisk.SHA512))
{
Globals.Logger.Verbose($"Incomplete entry for '{itemDisk.Name}' will be output as nodump");
itemDisk.ItemStatus = ItemStatus.Nodump;
}
item = itemDisk;
item = rom;
}
// Get the key and add the file
@@ -2349,7 +2341,13 @@ namespace SabreTools.Library.DatFiles
private void ProcessFile(string item, string basePath, Hash omitFromScan, bool addDate, TreatAsFiles asFiles)
{
Globals.Logger.Verbose($"'{Path.GetFileName(item)}' treated like a file");
BaseFile baseFile = FileExtensions.GetInfo(item, omitFromScan: omitFromScan, date: addDate, header: Header.HeaderSkipper, chdsAsFiles: asFiles.HasFlag(TreatAsFiles.CHDs));
BaseFile baseFile = FileExtensions.GetInfo(
item,
omitFromScan: omitFromScan,
date: addDate,
header: Header.HeaderSkipper,
aaruFormatAsFiles: asFiles.HasFlag(TreatAsFiles.AaruFormats),
chdsAsFiles: asFiles.HasFlag(TreatAsFiles.CHDs));
ProcessFileHelper(item, DatItem.Create(baseFile), basePath, string.Empty);
}
@@ -2362,8 +2360,9 @@ namespace SabreTools.Library.DatFiles
/// <param name="parent">Parent game to be used</param>
private void ProcessFileHelper(string item, DatItem datItem, string basepath, string parent)
{
// If we somehow got something other than a Rom or Disk, cancel out
if (datItem.ItemType != ItemType.Rom && datItem.ItemType != ItemType.Disk)
// If we didn't get an accepted parsed type somehow, cancel out
List<ItemType> parsed = new List<ItemType> { ItemType.Disk, ItemType.Media, ItemType.Rom };
if (!parsed.Contains(datItem.ItemType))
return;
try
@@ -2401,7 +2400,7 @@ namespace SabreTools.Library.DatFiles
private void SetDatItemInfo(DatItem datItem, string item, string parent, string basepath)
{
// Get the data to be added as game and item names
string gamename, romname;
string machineName, itemName;
// If the parent is blank, then we have a non-archive file
if (string.IsNullOrWhiteSpace(parent))
@@ -2409,15 +2408,15 @@ namespace SabreTools.Library.DatFiles
// If we have a SuperDAT, we want anything that's not the base path as the game, and the file as the rom
if (Header.Type == "SuperDAT")
{
gamename = Path.GetDirectoryName(item.Remove(0, basepath.Length));
romname = Path.GetFileName(item);
machineName = Path.GetDirectoryName(item.Remove(0, basepath.Length));
itemName = Path.GetFileName(item);
}
// Otherwise, we want just the top level folder as the game, and the file as everything else
else
{
gamename = item.Remove(0, basepath.Length).Split(Path.DirectorySeparatorChar)[0];
romname = item.Remove(0, (Path.Combine(basepath, gamename).Length));
machineName = item.Remove(0, basepath.Length).Split(Path.DirectorySeparatorChar)[0];
itemName = item.Remove(0, (Path.Combine(basepath, machineName).Length));
}
}
@@ -2427,36 +2426,58 @@ namespace SabreTools.Library.DatFiles
// If we have a SuperDAT, we want the archive name as the game, and the file as everything else (?)
if (Header.Type == "SuperDAT")
{
gamename = parent;
romname = datItem.Name;
machineName = parent;
itemName = datItem.Name;
}
// Otherwise, we want the archive name as the game, and the file as everything else
else
{
gamename = parent;
romname = datItem.Name;
machineName = parent;
itemName = datItem.Name;
}
}
// Sanitize the names
gamename = gamename.Trim(Path.DirectorySeparatorChar);
romname = romname?.Trim(Path.DirectorySeparatorChar) ?? string.Empty;
machineName = machineName.Trim(Path.DirectorySeparatorChar);
itemName = itemName?.Trim(Path.DirectorySeparatorChar) ?? string.Empty;
if (!string.IsNullOrWhiteSpace(gamename) && string.IsNullOrWhiteSpace(romname))
if (!string.IsNullOrWhiteSpace(machineName) && string.IsNullOrWhiteSpace(itemName))
{
romname = gamename;
gamename = "Default";
itemName = machineName;
machineName = "Default";
}
// Update rom information
datItem.Name = romname;
datItem.Machine.Name = gamename;
datItem.Machine.Description = gamename;
// Update machine information
datItem.Machine.Name = machineName;
datItem.Machine.Description = machineName;
// If we have a Disk, then the ".chd" extension needs to be removed
if (datItem.ItemType == ItemType.Disk)
datItem.Name = datItem.Name.Replace(".chd", string.Empty);
if (datItem.ItemType == ItemType.Disk && datItem.Name.EndsWith(".chd"))
{
datItem.Name = itemName.Substring(0, itemName.Length - 4);
}
// If we have a Media, then the extension needs to be removed
else if (datItem.ItemType == ItemType.Media)
{
if (datItem.Name.EndsWith(".dicf"))
datItem.Name = itemName.Substring(0, itemName.Length - 5);
else if (datItem.Name.EndsWith(".aaru"))
datItem.Name = itemName.Substring(0, itemName.Length - 5);
else if (datItem.Name.EndsWith(".aaruformat"))
datItem.Name = itemName.Substring(0, itemName.Length - 11);
else if (datItem.Name.EndsWith(".aaruf"))
datItem.Name = itemName.Substring(0, itemName.Length - 6);
else if (datItem.Name.EndsWith(".aif"))
datItem.Name = itemName.Substring(0, itemName.Length - 3);
}
// All others leave the extension alone
else
{
datItem.Name = itemName;
}
}
#endregion
@@ -2617,6 +2638,8 @@ namespace SabreTools.Library.DatFiles
bool usedInternally;
if (Items[hash][0].ItemType == ItemType.Disk)
usedInternally = RebuildIndividualFile(new Disk(fileinfo), foundpath, outDir, date, inverse, outputFormat, updateDat, false /* isZip */);
else if (Items[hash][0].ItemType == ItemType.Media)
usedInternally = RebuildIndividualFile(new Media(fileinfo), foundpath, outDir, date, inverse, outputFormat, updateDat, false /* isZip */);
else
usedInternally = RebuildIndividualFile(new Rom(fileinfo), foundpath, outDir, date, inverse, outputFormat, updateDat, false /* isZip */);
@@ -2810,11 +2833,17 @@ namespace SabreTools.Library.DatFiles
// Scan the file externally
// TODO: All instances of Hash.DeepHashes should be made into 0x0 eventually
BaseFile externalFileInfo = FileExtensions.GetInfo(file, omitFromScan: (quickScan ? Hash.SecureHashes : Hash.DeepHashes),
header: Header.HeaderSkipper, chdsAsFiles: asFiles.HasFlag(TreatAsFiles.CHDs));
BaseFile externalFileInfo = FileExtensions.GetInfo(
file,
omitFromScan: (quickScan ? Hash.SecureHashes : Hash.DeepHashes),
header: Header.HeaderSkipper,
aaruFormatAsFiles: asFiles.HasFlag(TreatAsFiles.AaruFormats),
chdsAsFiles: asFiles.HasFlag(TreatAsFiles.CHDs));
DatItem externalDatItem = null;
if (externalFileInfo.Type == FileType.CHD)
if (externalFileInfo.Type == FileType.AaruFormat)
externalDatItem = new Media(externalFileInfo);
else if (externalFileInfo.Type == FileType.CHD)
externalDatItem = new Disk(externalFileInfo);
else if (externalFileInfo.Type == FileType.None)
externalDatItem = new Rom(externalFileInfo);
@@ -2844,10 +2873,16 @@ namespace SabreTools.Library.DatFiles
if (entries == null && File.Exists(file))
{
// TODO: All instances of Hash.DeepHashes should be made into 0x0 eventually
BaseFile internalFileInfo = FileExtensions.GetInfo(file, omitFromScan: (quickScan ? Hash.SecureHashes : Hash.DeepHashes), chdsAsFiles: asFiles.HasFlag(TreatAsFiles.CHDs));
BaseFile internalFileInfo = FileExtensions.GetInfo(
file,
omitFromScan: (quickScan ? Hash.SecureHashes : Hash.DeepHashes),
aaruFormatAsFiles: asFiles.HasFlag(TreatAsFiles.AaruFormats),
chdsAsFiles: asFiles.HasFlag(TreatAsFiles.CHDs));
DatItem internalDatItem = null;
if (internalFileInfo.Type == FileType.CHD)
if (internalFileInfo.Type == FileType.AaruFormat)
internalDatItem = new Media(internalFileInfo);
else if (internalFileInfo.Type == FileType.CHD)
internalDatItem = new Disk(internalFileInfo);
else if (internalFileInfo.Type == FileType.None)
internalDatItem = new Rom(internalFileInfo);
@@ -2894,21 +2929,23 @@ namespace SabreTools.Library.DatFiles
// Set the initial output value
bool rebuilt = false;
// If the DatItem is a Disk, force rebuilding to a folder except if TGZ or TXZ
if (datItem.ItemType == ItemType.Disk
// If the DatItem is a Disk or Media, force rebuilding to a folder except if TGZ or TXZ
if ((datItem.ItemType == ItemType.Disk || datItem.ItemType == ItemType.Media)
&& !(outputFormat == OutputFormat.TorrentGzip || outputFormat == OutputFormat.TorrentGzipRomba)
&& !(outputFormat == OutputFormat.TorrentXZ || outputFormat == OutputFormat.TorrentXZRomba))
{
outputFormat = OutputFormat.Folder;
}
// If we have a disk, change it into a Rom for later use
// If we have a disk or media, change it into a Rom for later use
if (datItem.ItemType == ItemType.Disk)
datItem = ((Disk)datItem).ConvertToRom();
datItem = (datItem as Disk).ConvertToRom();
if (datItem.ItemType == ItemType.Media)
datItem = (datItem as Media).ConvertToRom();
// Prepopluate a few key strings
string crc = ((Rom)datItem).CRC ?? string.Empty;
string sha1 = ((Rom)datItem).SHA1 ?? string.Empty;
string crc = (datItem as Rom).CRC ?? string.Empty;
string sha1 = (datItem as Rom).SHA1 ?? string.Empty;
// Find if the file has duplicates in the DAT
List<DatItem> dupes = Items.GetDuplicates(datItem, remove: updateDat);
@@ -3027,7 +3064,7 @@ namespace SabreTools.Library.DatFiles
Folder outputArchive = Folder.Create(outputFormat);
// Now rebuild to the output file
outputArchive.Write(fileStream, outDir, (Rom)item, date: date, depth: Header.OutputDepot.Depth);
outputArchive.Write(fileStream, outDir, item as Rom, date: date, depth: Header.OutputDepot.Depth);
}
// Close the input stream
@@ -3094,8 +3131,8 @@ namespace SabreTools.Library.DatFiles
Folder outputArchive = Folder.Create(outputFormat);
// Now rebuild to the output file
eitherSuccess |= outputArchive.Write(transformStream, outDir, (Rom)item, date: date, depth: Header.OutputDepot.Depth);
eitherSuccess |= outputArchive.Write(fileStream, outDir, (Rom)datItem, date: date, depth: Header.OutputDepot.Depth);
eitherSuccess |= outputArchive.Write(transformStream, outDir, item as Rom, date: date, depth: Header.OutputDepot.Depth);
eitherSuccess |= outputArchive.Write(fileStream, outDir, datItem as Rom, date: date, depth: Header.OutputDepot.Depth);
// Now add the success of either rebuild
rebuilt &= eitherSuccess;
@@ -3253,13 +3290,17 @@ namespace SabreTools.Library.DatFiles
var keys = Items.SortedKeys.ToList();
foreach (string key in keys)
{
List<DatItem> roms = Items[key];
foreach (DatItem rom in roms)
List<DatItem> items = Items[key];
foreach (DatItem datItem in items)
{
if (rom.Source.Index == 99)
if (datItem.Source.Index == 99)
{
if (rom.ItemType == ItemType.Disk || rom.ItemType == ItemType.Rom)
matched.Items.Add(((Disk)rom).SHA1, rom);
if (datItem.ItemType == ItemType.Disk)
matched.Items.Add((datItem as Disk).SHA1, datItem);
else if (datItem.ItemType == ItemType.Media)
matched.Items.Add((datItem as Media).SHA1, datItem);
else if (datItem.ItemType == ItemType.Rom)
matched.Items.Add((datItem as Rom).SHA1, datItem);
}
}
}
@@ -3269,9 +3310,9 @@ namespace SabreTools.Library.DatFiles
{
foreach (string key in Items.Keys)
{
List<DatItem> roms = Items[key];
List<DatItem> newroms = DatItem.Merge(roms);
foreach (Rom rom in newroms)
List<DatItem> items = Items[key];
List<DatItem> newItems = DatItem.Merge(items);
foreach (Rom rom in newItems)
{
if (rom.Source.Index == 99)
matched.Items.Add($"{rom.Size}-{rom.CRC}", rom);
@@ -3414,59 +3455,61 @@ namespace SabreTools.Library.DatFiles
List<DatItem> items = Items[key];
foreach (DatItem item in items)
{
// If the file is not a Rom or Disk, continue
if (item.ItemType != ItemType.Disk && item.ItemType != ItemType.Rom)
// If the file is not a Disk, Media, or Rom, continue
if (item.ItemType != ItemType.Disk && item.ItemType != ItemType.Media && item.ItemType != ItemType.Rom)
return;
// If the file is a nodump
if ((item.ItemType == ItemType.Rom && ((Rom)item).ItemStatus == ItemStatus.Nodump)
|| (item.ItemType == ItemType.Disk && ((Disk)item).ItemStatus == ItemStatus.Nodump))
if ((item.ItemType == ItemType.Rom && (item as Rom).ItemStatus == ItemStatus.Nodump)
|| (item.ItemType == ItemType.Disk && (item as Disk).ItemStatus == ItemStatus.Nodump))
{
nodump.Items.Add(key, item);
}
// If the file has a SHA-512
else if ((item.ItemType == ItemType.Rom && !string.IsNullOrWhiteSpace(((Rom)item).SHA512))
|| (item.ItemType == ItemType.Disk && !string.IsNullOrWhiteSpace(((Disk)item).SHA512)))
else if ((item.ItemType == ItemType.Rom && !string.IsNullOrWhiteSpace((item as Rom).SHA512)))
{
sha512.Items.Add(key, item);
}
// If the file has a SHA-384
else if ((item.ItemType == ItemType.Rom && !string.IsNullOrWhiteSpace(((Rom)item).SHA384))
|| (item.ItemType == ItemType.Disk && !string.IsNullOrWhiteSpace(((Disk)item).SHA384)))
else if ((item.ItemType == ItemType.Rom && !string.IsNullOrWhiteSpace((item as Rom).SHA384)))
{
sha384.Items.Add(key, item);
}
// If the file has a SHA-256
else if ((item.ItemType == ItemType.Rom && !string.IsNullOrWhiteSpace(((Rom)item).SHA256))
|| (item.ItemType == ItemType.Disk && !string.IsNullOrWhiteSpace(((Disk)item).SHA256)))
else if ((item.ItemType == ItemType.Media && !string.IsNullOrWhiteSpace((item as Media).SHA256))
|| (item.ItemType == ItemType.Rom && !string.IsNullOrWhiteSpace((item as Rom).SHA256)))
{
sha256.Items.Add(key, item);
}
// If the file has a SHA-1
else if ((item.ItemType == ItemType.Rom && !string.IsNullOrWhiteSpace(((Rom)item).SHA1))
|| (item.ItemType == ItemType.Disk && !string.IsNullOrWhiteSpace(((Disk)item).SHA1)))
else if ((item.ItemType == ItemType.Disk && !string.IsNullOrWhiteSpace((item as Disk).SHA1))
|| (item.ItemType == ItemType.Media && !string.IsNullOrWhiteSpace((item as Media).SHA1))
|| (item.ItemType == ItemType.Rom && !string.IsNullOrWhiteSpace((item as Rom).SHA1)))
{
sha1.Items.Add(key, item);
}
#if NET_FRAMEWORK
// If the file has a RIPEMD160
else if ((item.ItemType == ItemType.Rom && !string.IsNullOrWhiteSpace(((Rom)item).RIPEMD160))
|| (item.ItemType == ItemType.Disk && !string.IsNullOrWhiteSpace(((Disk)item).RIPEMD160)))
else if ((item.ItemType == ItemType.Rom && !string.IsNullOrWhiteSpace((item as Rom).RIPEMD160)))
{
ripemd160.Items.Add(key, item);
}
#endif
// If the file has an MD5
else if ((item.ItemType == ItemType.Rom && !string.IsNullOrWhiteSpace(((Rom)item).MD5))
|| (item.ItemType == ItemType.Disk && !string.IsNullOrWhiteSpace(((Disk)item).MD5)))
else if ((item.ItemType == ItemType.Disk && !string.IsNullOrWhiteSpace((item as Disk).MD5))
|| (item.ItemType == ItemType.Media && !string.IsNullOrWhiteSpace((item as Media).MD5)
|| (item.ItemType == ItemType.Rom && !string.IsNullOrWhiteSpace((item as Rom).MD5)))
)
{
md5.Items.Add(key, item);
}
// If the file has a CRC
else if ((item.ItemType == ItemType.Rom && !string.IsNullOrWhiteSpace(((Rom)item).CRC)))
else if ((item.ItemType == ItemType.Rom && !string.IsNullOrWhiteSpace((item as Rom).CRC)))
{
crc.Items.Add(key, item);
}
else
{
other.Items.Add(key, item);
@@ -3617,11 +3660,11 @@ namespace SabreTools.Library.DatFiles
lessDat.Items.Add(key, item);
// If the file is a Rom and less than the radix, put it in the "lesser" dat
else if (item.ItemType == ItemType.Rom && ((Rom)item).Size < radix)
else if (item.ItemType == ItemType.Rom && (item as Rom).Size < radix)
lessDat.Items.Add(key, item);
// If the file is a Rom and greater than or equal to the radix, put it in the "greater" dat
else if (item.ItemType == ItemType.Rom && ((Rom)item).Size >= radix)
else if (item.ItemType == ItemType.Rom && (item as Rom).Size >= radix)
greaterEqualDat.Items.Add(key, item);
}
});
@@ -3645,16 +3688,21 @@ namespace SabreTools.Library.DatFiles
// Create each of the respective output DATs
Globals.Logger.User("Creating and populating new DATs");
DatFile romdat = Create(Header.CloneStandard());
romdat.Header.FileName += " (ROM)";
romdat.Header.Name += " (ROM)";
romdat.Header.Description += " (ROM)";
DatFile diskdat = Create(Header.CloneStandard());
diskdat.Header.FileName += " (Disk)";
diskdat.Header.Name += " (Disk)";
diskdat.Header.Description += " (Disk)";
DatFile mediadat = Create(Header.CloneStandard());
mediadat.Header.FileName += " (Media)";
mediadat.Header.Name += " (Media)";
mediadat.Header.Description += " (Media)";
DatFile romdat = Create(Header.CloneStandard());
romdat.Header.FileName += " (Rom)";
romdat.Header.Name += " (Rom)";
romdat.Header.Description += " (Rom)";
DatFile sampledat = Create(Header.CloneStandard());
sampledat.Header.FileName += " (Sample)";
sampledat.Header.Name += " (Sample)";
@@ -3666,14 +3714,18 @@ namespace SabreTools.Library.DatFiles
List<DatItem> items = Items[key];
foreach (DatItem item in items)
{
// If the file is a Rom
if (item.ItemType == ItemType.Rom)
romdat.Items.Add(key, item);
// If the file is a Disk
else if (item.ItemType == ItemType.Disk)
if (item.ItemType == ItemType.Disk)
diskdat.Items.Add(key, item);
// If the file is a Media
else if (item.ItemType == ItemType.Media)
mediadat.Items.Add(key, item);
// If the file is a Rom
else if (item.ItemType == ItemType.Rom)
romdat.Items.Add(key, item);
// If the file is a Sample
else if (item.ItemType == ItemType.Sample)
sampledat.Items.Add(key, item);
@@ -3683,8 +3735,9 @@ namespace SabreTools.Library.DatFiles
// Now, output all of the files to the output directory
Globals.Logger.User("DAT information created, outputting new files");
bool success = true;
success &= romdat.Write(outDir);
success &= diskdat.Write(outDir);
success &= mediadat.Write(outDir);
success &= romdat.Write(outDir);
success &= sampledat.Write(outDir);
return success;
@@ -3843,28 +3896,40 @@ namespace SabreTools.Library.DatFiles
// If we're in Depot mode, take care of that instead
if (Header.OutputDepot?.IsActive ?? false)
{
if (item.ItemType == ItemType.Rom)
if (item.ItemType == ItemType.Disk)
{
Rom romItem = item as Rom;
Disk disk = item as Disk;
// We can only write out if there's a SHA-1
if (!string.IsNullOrWhiteSpace(romItem.SHA1))
if (!string.IsNullOrWhiteSpace(disk.SHA1))
{
name = PathExtensions.GetDepotPath(romItem.SHA1, Header.OutputDepot.Depth).Replace('\\', '/');
item.Name = $"{pre}{name}{post}";
}
}
else if (item.ItemType == ItemType.Disk)
{
Disk diskItem = item as Disk;
// We can only write out if there's a SHA-1
if (!string.IsNullOrWhiteSpace(diskItem.SHA1))
{
name = PathExtensions.GetDepotPath(diskItem.SHA1, Header.OutputDepot.Depth).Replace('\\', '/');
name = PathExtensions.GetDepotPath(disk.SHA1, Header.OutputDepot.Depth).Replace('\\', '/');
item.Name = pre + name + post;
}
}
else if (item.ItemType == ItemType.Media)
{
Media media = item as Media;
// We can only write out if there's a SHA-1
if (!string.IsNullOrWhiteSpace(media.SHA1))
{
name = PathExtensions.GetDepotPath(media.SHA1, Header.OutputDepot.Depth).Replace('\\', '/');
item.Name = pre + name + post;
}
}
else if (item.ItemType == ItemType.Rom)
{
Rom rom = item as Rom;
// We can only write out if there's a SHA-1
if (!string.IsNullOrWhiteSpace(rom.SHA1))
{
name = PathExtensions.GetDepotPath(rom.SHA1, Header.OutputDepot.Depth).Replace('\\', '/');
item.Name = $"{pre}{name}{post}";
}
}
return;
}
@@ -3926,29 +3991,29 @@ namespace SabreTools.Library.DatFiles
fix = (Header.Quotes ? "\"" : string.Empty) + Header.Postfix;
// Ensure we have the proper values for replacement
if (item.ItemType == ItemType.Rom)
if (item.ItemType == ItemType.Disk)
{
crc = ((Rom)item).CRC ?? string.Empty;
md5 = ((Rom)item).MD5 ?? string.Empty;
#if NET_FRAMEWORK
ripemd160 = ((Rom)item).RIPEMD160 ?? string.Empty;
#endif
sha1 = ((Rom)item).SHA1 ?? string.Empty;
sha256 = ((Rom)item).SHA256 ?? string.Empty;
sha384 = ((Rom)item).SHA384 ?? string.Empty;
sha512 = ((Rom)item).SHA512 ?? string.Empty;
size = ((Rom)item).Size.ToString();
md5 = (item as Disk).MD5 ?? string.Empty;
sha1 = (item as Disk).SHA1 ?? string.Empty;
}
else if (item.ItemType == ItemType.Disk)
else if (item.ItemType == ItemType.Media)
{
md5 = ((Disk)item).MD5 ?? string.Empty;
md5 = (item as Media).MD5 ?? string.Empty;
sha1 = (item as Media).SHA1 ?? string.Empty;
sha256 = (item as Media).SHA256 ?? string.Empty;
}
else if (item.ItemType == ItemType.Rom)
{
crc = (item as Rom).CRC ?? string.Empty;
md5 = (item as Rom).MD5 ?? string.Empty;
#if NET_FRAMEWORK
ripemd160 = ((Disk)item).RIPEMD160 ?? string.Empty;
ripemd160 = (item as Rom).RIPEMD160 ?? string.Empty;
#endif
sha1 = ((Disk)item).SHA1 ?? string.Empty;
sha256 = ((Disk)item).SHA256 ?? string.Empty;
sha384 = ((Disk)item).SHA384 ?? string.Empty;
sha512 = ((Disk)item).SHA512 ?? string.Empty;
sha1 = (item as Rom).SHA1 ?? string.Empty;
sha256 = (item as Rom).SHA256 ?? string.Empty;
sha384 = (item as Rom).SHA384 ?? string.Empty;
sha512 = (item as Rom).SHA512 ?? string.Empty;
size = (item as Rom).Size.ToString();
}
// Now do bulk replacement where possible

View File

@@ -7,7 +7,6 @@ using System.Text;
using SabreTools.Library.Data;
using SabreTools.Library.DatItems;
using SabreTools.Library.IO;
using SabreTools.Library.Tools;
namespace SabreTools.Library.DatFiles
{
@@ -324,22 +323,22 @@ namespace SabreTools.Library.DatFiles
// If we have a "null" game (created by DATFromDir or something similar), log it to file
if (rom.ItemType == ItemType.Rom
&& ((Rom)rom).Size == -1
&& ((Rom)rom).CRC == "null")
&& (rom as Rom).Size == -1
&& (rom as Rom).CRC == "null")
{
Globals.Logger.Verbose($"Empty folder found: {rom.Machine.Name}");
rom.Name = (rom.Name == "null" ? "-" : rom.Name);
((Rom)rom).Size = Constants.SizeZero;
((Rom)rom).CRC = ((Rom)rom).CRC == "null" ? Constants.CRCZero : null;
((Rom)rom).MD5 = ((Rom)rom).MD5 == "null" ? Constants.MD5Zero : null;
(rom as Rom).Size = Constants.SizeZero;
(rom as Rom).CRC = (rom as Rom).CRC == "null" ? Constants.CRCZero : null;
(rom as Rom).MD5 = (rom as Rom).MD5 == "null" ? Constants.MD5Zero : null;
#if NET_FRAMEWORK
((Rom)rom).RIPEMD160 = ((Rom)rom).RIPEMD160 == "null" ? Constants.RIPEMD160Zero : null;
(rom as Rom).RIPEMD160 = (rom as Rom).RIPEMD160 == "null" ? Constants.RIPEMD160Zero : null;
#endif
((Rom)rom).SHA1 = ((Rom)rom).SHA1 == "null" ? Constants.SHA1Zero : null;
((Rom)rom).SHA256 = ((Rom)rom).SHA256 == "null" ? Constants.SHA256Zero : null;
((Rom)rom).SHA384 = ((Rom)rom).SHA384 == "null" ? Constants.SHA384Zero : null;
((Rom)rom).SHA512 = ((Rom)rom).SHA512 == "null" ? Constants.SHA512Zero : null;
(rom as Rom).SHA1 = (rom as Rom).SHA1 == "null" ? Constants.SHA1Zero : null;
(rom as Rom).SHA256 = (rom as Rom).SHA256 == "null" ? Constants.SHA256Zero : null;
(rom as Rom).SHA384 = (rom as Rom).SHA384 == "null" ? Constants.SHA384Zero : null;
(rom as Rom).SHA512 = (rom as Rom).SHA512 == "null" ? Constants.SHA512Zero : null;
}
// Now, output the rom data

View File

@@ -255,5 +255,6 @@ namespace SabreTools.Library.DatFiles
{
CHDs = 1 << 0,
Archives = 1 << 1,
AaruFormats = 1 << 2,
}
}

View File

@@ -6,7 +6,6 @@ using System.Text;
using SabreTools.Library.Data;
using SabreTools.Library.DatItems;
using SabreTools.Library.IO;
using SabreTools.Library.Tools;
namespace SabreTools.Library.DatFiles
{
@@ -205,6 +204,14 @@ namespace SabreTools.Library.DatFiles
name += disk.Name;
break;
case ItemType.Media:
var media = datItem as Media;
if (Header.GameName)
name = $"{media.Machine.Name}{Path.DirectorySeparatorChar}";
name += media.Name;
break;
case ItemType.Rom:
var rom = datItem as Rom;
if (Header.GameName)
@@ -239,6 +246,12 @@ namespace SabreTools.Library.DatFiles
fields[1] = name;
break;
case ItemType.Media:
var media = datItem as Media;
fields[0] = media.MD5;
fields[1] = name;
break;
case ItemType.Rom:
var rom = datItem as Rom;
fields[0] = rom.MD5;
@@ -252,12 +265,6 @@ namespace SabreTools.Library.DatFiles
case Hash.RIPEMD160:
switch (datItem.ItemType)
{
case ItemType.Disk:
var disk = datItem as Disk;
fields[0] = disk.RIPEMD160;
fields[1] = name;
break;
case ItemType.Rom:
var rom = datItem as Rom;
fields[0] = rom.RIPEMD160;
@@ -276,6 +283,12 @@ namespace SabreTools.Library.DatFiles
fields[1] = name;
break;
case ItemType.Media:
var media = datItem as Media;
fields[0] = media.SHA1;
fields[1] = name;
break;
case ItemType.Rom:
var rom = datItem as Rom;
fields[0] = rom.SHA1;
@@ -288,9 +301,9 @@ namespace SabreTools.Library.DatFiles
case Hash.SHA256:
switch (datItem.ItemType)
{
case ItemType.Disk:
var disk = datItem as Disk;
fields[0] = disk.SHA256;
case ItemType.Media:
var media = datItem as Media;
fields[0] = media.SHA256;
fields[1] = name;
break;
@@ -306,12 +319,6 @@ namespace SabreTools.Library.DatFiles
case Hash.SHA384:
switch (datItem.ItemType)
{
case ItemType.Disk:
var disk = datItem as Disk;
fields[0] = disk.SHA384;
fields[1] = name;
break;
case ItemType.Rom:
var rom = datItem as Rom;
fields[0] = rom.SHA384;
@@ -324,12 +331,6 @@ namespace SabreTools.Library.DatFiles
case Hash.SHA512:
switch (datItem.ItemType)
{
case ItemType.Disk:
var disk = datItem as Disk;
fields[0] = disk.SHA512;
fields[1] = name;
break;
case ItemType.Rom:
var rom = datItem as Rom;
fields[0] = rom.SHA512;

View File

@@ -100,6 +100,12 @@ namespace SabreTools.Library.DatFiles
[JsonIgnore]
public long DiskCount { get; private set; } = 0;
/// <summary>
/// Number of Media items
/// </summary>
[JsonIgnore]
public long MediaCount { get; private set; } = 0;
/// <summary>
/// Number of Release items
/// </summary>
@@ -399,46 +405,46 @@ namespace SabreTools.Library.DatFiles
break;
case ItemType.Disk:
DiskCount += 1;
if (((Disk)item).ItemStatus != ItemStatus.Nodump)
if ((item as Disk).ItemStatus != ItemStatus.Nodump)
{
MD5Count += (string.IsNullOrWhiteSpace(((Disk)item).MD5) ? 0 : 1);
#if NET_FRAMEWORK
RIPEMD160Count += (string.IsNullOrWhiteSpace(((Disk)item).RIPEMD160) ? 0 : 1);
#endif
SHA1Count += (string.IsNullOrWhiteSpace(((Disk)item).SHA1) ? 0 : 1);
SHA256Count += (string.IsNullOrWhiteSpace(((Disk)item).SHA256) ? 0 : 1);
SHA384Count += (string.IsNullOrWhiteSpace(((Disk)item).SHA384) ? 0 : 1);
SHA512Count += (string.IsNullOrWhiteSpace(((Disk)item).SHA512) ? 0 : 1);
MD5Count += (string.IsNullOrWhiteSpace((item as Disk).MD5) ? 0 : 1);
SHA1Count += (string.IsNullOrWhiteSpace((item as Disk).SHA1) ? 0 : 1);
}
BaddumpCount += (((Disk)item).ItemStatus == ItemStatus.BadDump ? 1 : 0);
GoodCount += (((Disk)item).ItemStatus == ItemStatus.Good ? 1 : 0);
NodumpCount += (((Disk)item).ItemStatus == ItemStatus.Nodump ? 1 : 0);
VerifiedCount += (((Disk)item).ItemStatus == ItemStatus.Verified ? 1 : 0);
BaddumpCount += ((item as Disk).ItemStatus == ItemStatus.BadDump ? 1 : 0);
GoodCount += ((item as Disk).ItemStatus == ItemStatus.Good ? 1 : 0);
NodumpCount += ((item as Disk).ItemStatus == ItemStatus.Nodump ? 1 : 0);
VerifiedCount += ((item as Disk).ItemStatus == ItemStatus.Verified ? 1 : 0);
break;
case ItemType.Media:
MediaCount += 1;
MD5Count += (string.IsNullOrWhiteSpace((item as Media).MD5) ? 0 : 1);
SHA1Count += (string.IsNullOrWhiteSpace((item as Media).SHA1) ? 0 : 1);
SHA256Count += (string.IsNullOrWhiteSpace((item as Media).SHA256) ? 0 : 1);
break;
case ItemType.Release:
ReleaseCount += 1;
break;
case ItemType.Rom:
RomCount += 1;
if (((Rom)item).ItemStatus != ItemStatus.Nodump)
if ((item as Rom).ItemStatus != ItemStatus.Nodump)
{
TotalSize += ((Rom)item).Size;
CRCCount += (string.IsNullOrWhiteSpace(((Rom)item).CRC) ? 0 : 1);
MD5Count += (string.IsNullOrWhiteSpace(((Rom)item).MD5) ? 0 : 1);
TotalSize += (item as Rom).Size;
CRCCount += (string.IsNullOrWhiteSpace((item as Rom).CRC) ? 0 : 1);
MD5Count += (string.IsNullOrWhiteSpace((item as Rom).MD5) ? 0 : 1);
#if NET_FRAMEWORK
RIPEMD160Count += (string.IsNullOrWhiteSpace(((Rom)item).RIPEMD160) ? 0 : 1);
RIPEMD160Count += (string.IsNullOrWhiteSpace((item as Rom).RIPEMD160) ? 0 : 1);
#endif
SHA1Count += (string.IsNullOrWhiteSpace(((Rom)item).SHA1) ? 0 : 1);
SHA256Count += (string.IsNullOrWhiteSpace(((Rom)item).SHA256) ? 0 : 1);
SHA384Count += (string.IsNullOrWhiteSpace(((Rom)item).SHA384) ? 0 : 1);
SHA512Count += (string.IsNullOrWhiteSpace(((Rom)item).SHA512) ? 0 : 1);
SHA1Count += (string.IsNullOrWhiteSpace((item as Rom).SHA1) ? 0 : 1);
SHA256Count += (string.IsNullOrWhiteSpace((item as Rom).SHA256) ? 0 : 1);
SHA384Count += (string.IsNullOrWhiteSpace((item as Rom).SHA384) ? 0 : 1);
SHA512Count += (string.IsNullOrWhiteSpace((item as Rom).SHA512) ? 0 : 1);
}
BaddumpCount += (((Rom)item).ItemStatus == ItemStatus.BadDump ? 1 : 0);
GoodCount += (((Rom)item).ItemStatus == ItemStatus.Good ? 1 : 0);
NodumpCount += (((Rom)item).ItemStatus == ItemStatus.Nodump ? 1 : 0);
VerifiedCount += (((Rom)item).ItemStatus == ItemStatus.Verified ? 1 : 0);
BaddumpCount += ((item as Rom).ItemStatus == ItemStatus.BadDump ? 1 : 0);
GoodCount += ((item as Rom).ItemStatus == ItemStatus.Good ? 1 : 0);
NodumpCount += ((item as Rom).ItemStatus == ItemStatus.Nodump ? 1 : 0);
VerifiedCount += ((item as Rom).ItemStatus == ItemStatus.Verified ? 1 : 0);
break;
case ItemType.Sample:
SampleCount += 1;
@@ -456,7 +462,9 @@ namespace SabreTools.Library.DatFiles
ArchiveCount += stats.ArchiveCount;
BiosSetCount += stats.BiosSetCount;
ChipCount += stats.ChipCount;
DiskCount += stats.DiskCount;
MediaCount += stats.MediaCount;
ReleaseCount += stats.ReleaseCount;
RomCount += stats.RomCount;
SampleCount += stats.SampleCount;
@@ -522,46 +530,46 @@ namespace SabreTools.Library.DatFiles
break;
case ItemType.Disk:
DiskCount -= 1;
if (((Disk)item).ItemStatus != ItemStatus.Nodump)
if ((item as Disk).ItemStatus != ItemStatus.Nodump)
{
MD5Count -= (string.IsNullOrWhiteSpace(((Disk)item).MD5) ? 0 : 1);
#if NET_FRAMEWORK
RIPEMD160Count -= (string.IsNullOrWhiteSpace(((Disk)item).RIPEMD160) ? 0 : 1);
#endif
SHA1Count -= (string.IsNullOrWhiteSpace(((Disk)item).SHA1) ? 0 : 1);
SHA256Count -= (string.IsNullOrWhiteSpace(((Disk)item).SHA256) ? 0 : 1);
SHA384Count -= (string.IsNullOrWhiteSpace(((Disk)item).SHA384) ? 0 : 1);
SHA512Count -= (string.IsNullOrWhiteSpace(((Disk)item).SHA512) ? 0 : 1);
MD5Count -= (string.IsNullOrWhiteSpace((item as Disk).MD5) ? 0 : 1);
SHA1Count -= (string.IsNullOrWhiteSpace((item as Disk).SHA1) ? 0 : 1);
}
BaddumpCount -= (((Disk)item).ItemStatus == ItemStatus.BadDump ? 1 : 0);
GoodCount -= (((Disk)item).ItemStatus == ItemStatus.Good ? 1 : 0);
NodumpCount -= (((Disk)item).ItemStatus == ItemStatus.Nodump ? 1 : 0);
VerifiedCount -= (((Disk)item).ItemStatus == ItemStatus.Verified ? 1 : 0);
BaddumpCount -= ((item as Disk).ItemStatus == ItemStatus.BadDump ? 1 : 0);
GoodCount -= ((item as Disk).ItemStatus == ItemStatus.Good ? 1 : 0);
NodumpCount -= ((item as Disk).ItemStatus == ItemStatus.Nodump ? 1 : 0);
VerifiedCount -= ((item as Disk).ItemStatus == ItemStatus.Verified ? 1 : 0);
break;
case ItemType.Media:
MediaCount -= 1;
MD5Count -= (string.IsNullOrWhiteSpace((item as Media).MD5) ? 0 : 1);
SHA1Count -= (string.IsNullOrWhiteSpace((item as Media).SHA1) ? 0 : 1);
SHA256Count -= (string.IsNullOrWhiteSpace((item as Media).SHA256) ? 0 : 1);
break;
case ItemType.Release:
ReleaseCount -= 1;
break;
case ItemType.Rom:
RomCount -= 1;
if (((Rom)item).ItemStatus != ItemStatus.Nodump)
if ((item as Rom).ItemStatus != ItemStatus.Nodump)
{
TotalSize -= ((Rom)item).Size;
CRCCount -= (string.IsNullOrWhiteSpace(((Rom)item).CRC) ? 0 : 1);
MD5Count -= (string.IsNullOrWhiteSpace(((Rom)item).MD5) ? 0 : 1);
TotalSize -= (item as Rom).Size;
CRCCount -= (string.IsNullOrWhiteSpace((item as Rom).CRC) ? 0 : 1);
MD5Count -= (string.IsNullOrWhiteSpace((item as Rom).MD5) ? 0 : 1);
#if NET_FRAMEWORK
RIPEMD160Count -= (string.IsNullOrWhiteSpace(((Rom)item).RIPEMD160) ? 0 : 1);
RIPEMD160Count -= (string.IsNullOrWhiteSpace((item as Rom).RIPEMD160) ? 0 : 1);
#endif
SHA1Count -= (string.IsNullOrWhiteSpace(((Rom)item).SHA1) ? 0 : 1);
SHA256Count -= (string.IsNullOrWhiteSpace(((Rom)item).SHA256) ? 0 : 1);
SHA384Count -= (string.IsNullOrWhiteSpace(((Rom)item).SHA384) ? 0 : 1);
SHA512Count -= (string.IsNullOrWhiteSpace(((Rom)item).SHA512) ? 0 : 1);
SHA1Count -= (string.IsNullOrWhiteSpace((item as Rom).SHA1) ? 0 : 1);
SHA256Count -= (string.IsNullOrWhiteSpace((item as Rom).SHA256) ? 0 : 1);
SHA384Count -= (string.IsNullOrWhiteSpace((item as Rom).SHA384) ? 0 : 1);
SHA512Count -= (string.IsNullOrWhiteSpace((item as Rom).SHA512) ? 0 : 1);
}
BaddumpCount -= (((Rom)item).ItemStatus == ItemStatus.BadDump ? 1 : 0);
GoodCount -= (((Rom)item).ItemStatus == ItemStatus.Good ? 1 : 0);
NodumpCount -= (((Rom)item).ItemStatus == ItemStatus.Nodump ? 1 : 0);
VerifiedCount -= (((Rom)item).ItemStatus == ItemStatus.Verified ? 1 : 0);
BaddumpCount -= ((item as Rom).ItemStatus == ItemStatus.BadDump ? 1 : 0);
GoodCount -= ((item as Rom).ItemStatus == ItemStatus.Good ? 1 : 0);
NodumpCount -= ((item as Rom).ItemStatus == ItemStatus.Nodump ? 1 : 0);
VerifiedCount -= ((item as Rom).ItemStatus == ItemStatus.Verified ? 1 : 0);
break;
case ItemType.Sample:
SampleCount -= 1;
@@ -817,29 +825,29 @@ namespace SabreTools.Library.DatFiles
private Field GetBestAvailable()
{
// If all items are supposed to have a SHA-512, we bucket by that
if (RomCount + DiskCount - NodumpCount == SHA512Count)
if (DiskCount + MediaCount + RomCount - NodumpCount == SHA512Count)
return Field.DatItem_SHA512;
// If all items are supposed to have a SHA-384, we bucket by that
else if (RomCount + DiskCount - NodumpCount == SHA384Count)
else if (DiskCount + MediaCount + RomCount - NodumpCount == SHA384Count)
return Field.DatItem_SHA384;
// If all items are supposed to have a SHA-256, we bucket by that
else if (RomCount + DiskCount - NodumpCount == SHA256Count)
else if (DiskCount + MediaCount + RomCount - NodumpCount == SHA256Count)
return Field.DatItem_SHA256;
// If all items are supposed to have a SHA-1, we bucket by that
else if (RomCount + DiskCount - NodumpCount == SHA1Count)
else if (DiskCount + MediaCount + RomCount - NodumpCount == SHA1Count)
return Field.DatItem_SHA1;
#if NET_FRAMEWORK
// If all items are supposed to have a RIPEMD160, we bucket by that
else if (RomCount + DiskCount - NodumpCount == RIPEMD160Count)
else if (DiskCount + MediaCount + RomCount - NodumpCount == RIPEMD160Count)
return Field.DatItem_RIPEMD160;
#endif
// If all items are supposed to have a MD5, we bucket by that
else if (RomCount + DiskCount - NodumpCount == MD5Count)
else if (DiskCount + MediaCount + RomCount - NodumpCount == MD5Count)
return Field.DatItem_MD5;
// Otherwise, we bucket by CRC
@@ -856,7 +864,9 @@ namespace SabreTools.Library.DatFiles
ArchiveCount = 0;
BiosSetCount = 0;
ChipCount = 0;
DiskCount = 0;
MediaCount = 0;
ReleaseCount = 0;
RomCount = 0;
SampleCount = 0;

View File

@@ -238,6 +238,9 @@ namespace SabreTools.Library.DatFiles
case ItemType.Disk:
datItem = datItemObj.ToObject<Disk>();
break;
case ItemType.Media:
datItem = datItemObj.ToObject<Media>();
break;
case ItemType.Release:
datItem = datItemObj.ToObject<Release>();
break;
@@ -322,22 +325,22 @@ namespace SabreTools.Library.DatFiles
// If we have a "null" game (created by DATFromDir or something similar), log it to file
if (rom.ItemType == ItemType.Rom
&& ((Rom)rom).Size == -1
&& ((Rom)rom).CRC == "null")
&& (rom as Rom).Size == -1
&& (rom as Rom).CRC == "null")
{
Globals.Logger.Verbose($"Empty folder found: {rom.Machine.Name}");
rom.Name = (rom.Name == "null" ? "-" : rom.Name);
((Rom)rom).Size = Constants.SizeZero;
((Rom)rom).CRC = ((Rom)rom).CRC == "null" ? Constants.CRCZero : null;
((Rom)rom).MD5 = ((Rom)rom).MD5 == "null" ? Constants.MD5Zero : null;
(rom as Rom).Size = Constants.SizeZero;
(rom as Rom).CRC = (rom as Rom).CRC == "null" ? Constants.CRCZero : null;
(rom as Rom).MD5 = (rom as Rom).MD5 == "null" ? Constants.MD5Zero : null;
#if NET_FRAMEWORK
((Rom)rom).RIPEMD160 = ((Rom)rom).RIPEMD160 == "null" ? Constants.RIPEMD160Zero : null;
(rom as Rom).RIPEMD160 = (rom as Rom).RIPEMD160 == "null" ? Constants.RIPEMD160Zero : null;
#endif
((Rom)rom).SHA1 = ((Rom)rom).SHA1 == "null" ? Constants.SHA1Zero : null;
((Rom)rom).SHA256 = ((Rom)rom).SHA256 == "null" ? Constants.SHA256Zero : null;
((Rom)rom).SHA384 = ((Rom)rom).SHA384 == "null" ? Constants.SHA384Zero : null;
((Rom)rom).SHA512 = ((Rom)rom).SHA512 == "null" ? Constants.SHA512Zero : null;
(rom as Rom).SHA1 = (rom as Rom).SHA1 == "null" ? Constants.SHA1Zero : null;
(rom as Rom).SHA256 = (rom as Rom).SHA256 == "null" ? Constants.SHA256Zero : null;
(rom as Rom).SHA384 = (rom as Rom).SHA384 == "null" ? Constants.SHA384Zero : null;
(rom as Rom).SHA512 = (rom as Rom).SHA512 == "null" ? Constants.SHA512Zero : null;
}
// Now, output the rom data

View File

@@ -318,19 +318,19 @@ namespace SabreTools.Library.DatFiles
// If we have a "null" game (created by DATFromDir or something similar), log it to file
if (rom.ItemType == ItemType.Rom
&& ((Rom)rom).Size == -1
&& ((Rom)rom).CRC == "null")
&& (rom as Rom).Size == -1
&& (rom as Rom).CRC == "null")
{
Globals.Logger.Verbose($"Empty folder found: {rom.Machine.Name}");
rom.Name = (rom.Name == "null" ? "-" : rom.Name);
((Rom)rom).Size = Constants.SizeZero;
((Rom)rom).CRC = ((Rom)rom).CRC == "null" ? Constants.CRCZero : null;
((Rom)rom).MD5 = ((Rom)rom).MD5 == "null" ? Constants.MD5Zero : null;
((Rom)rom).SHA1 = ((Rom)rom).SHA1 == "null" ? Constants.SHA1Zero : null;
((Rom)rom).SHA256 = ((Rom)rom).SHA256 == "null" ? Constants.SHA256Zero : null;
((Rom)rom).SHA384 = ((Rom)rom).SHA384 == "null" ? Constants.SHA384Zero : null;
((Rom)rom).SHA512 = ((Rom)rom).SHA512 == "null" ? Constants.SHA512Zero : null;
(rom as Rom).Size = Constants.SizeZero;
(rom as Rom).CRC = (rom as Rom).CRC == "null" ? Constants.CRCZero : null;
(rom as Rom).MD5 = (rom as Rom).MD5 == "null" ? Constants.MD5Zero : null;
(rom as Rom).SHA1 = (rom as Rom).SHA1 == "null" ? Constants.SHA1Zero : null;
(rom as Rom).SHA256 = (rom as Rom).SHA256 == "null" ? Constants.SHA256Zero : null;
(rom as Rom).SHA384 = (rom as Rom).SHA384 == "null" ? Constants.SHA384Zero : null;
(rom as Rom).SHA512 = (rom as Rom).SHA512 == "null" ? Constants.SHA512Zero : null;
}
// Now, output the rom data

View File

@@ -230,13 +230,7 @@ namespace SabreTools.Library.DatFiles
{
Name = reader.GetAttribute("name"),
MD5 = reader.GetAttribute("md5"),
#if NET_FRAMEWORK
RIPEMD160 = reader.GetAttribute("ripemd160"),
#endif
SHA1 = reader.GetAttribute("sha1"),
SHA256 = reader.GetAttribute("sha256"),
SHA384 = reader.GetAttribute("sha384"),
SHA512 = reader.GetAttribute("sha512"),
MergeTag = reader.GetAttribute("merge"),
Region = reader.GetAttribute("region"),
Index = reader.GetAttribute("index"),
@@ -1560,13 +1554,7 @@ namespace SabreTools.Library.DatFiles
xtw.WriteStartElement("disk");
xtw.WriteRequiredAttributeString("name", disk.Name);
xtw.WriteOptionalAttributeString("md5", disk.MD5?.ToLowerInvariant());
#if NET_FRAMEWORK
xtw.WriteOptionalAttributeString("ripemd160", disk.RIPEMD160?.ToLowerInvariant());
#endif
xtw.WriteOptionalAttributeString("sha1", disk.SHA1?.ToLowerInvariant());
xtw.WriteOptionalAttributeString("sha256", disk.SHA256?.ToLowerInvariant());
xtw.WriteOptionalAttributeString("sha384", disk.SHA384?.ToLowerInvariant());
xtw.WriteOptionalAttributeString("sha512", disk.SHA512?.ToLowerInvariant());
xtw.WriteOptionalAttributeString("merge", disk.MergeTag);
xtw.WriteOptionalAttributeString("region", disk.Region);
xtw.WriteOptionalAttributeString("index", disk.Index);

View File

@@ -237,13 +237,13 @@ namespace SabreTools.Library.DatFiles
if (Header.System == null)
Header.System = reader.GetAttribute("plugin");
if (Header.RomMode == null)
if (Header.RomMode == MergingFlag.None)
Header.RomMode = reader.GetAttribute("rommode").AsMergingFlag();
if (Header.BiosMode == null)
if (Header.BiosMode == MergingFlag.None)
Header.BiosMode = reader.GetAttribute("biosmode").AsMergingFlag();
if (Header.SampleMode == null)
if (Header.SampleMode == MergingFlag.None)
Header.SampleMode = reader.GetAttribute("samplemode").AsMergingFlag();
if (Header.LockRomMode == null)
@@ -372,6 +372,128 @@ namespace SabreTools.Library.DatFiles
reader.Skip();
break;
case "archive":
containsItems = true;
DatItem archive = new Archive
{
Name = reader.GetAttribute("name"),
Source = new Source
{
Index = indexId,
Name = filename,
},
};
archive.CopyMachineInformation(machine);
// Now process and add the archive
key = ParseAddHelper(archive);
reader.Read();
break;
case "biosset":
containsItems = true;
DatItem biosSet = new BiosSet
{
Name = reader.GetAttribute("name"),
Description = reader.GetAttribute("description"),
Default = reader.GetAttribute("default").AsYesNo(),
Source = new Source
{
Index = indexId,
Name = filename,
},
};
biosSet.CopyMachineInformation(machine);
// Now process and add the biosSet
key = ParseAddHelper(biosSet);
reader.Read();
break;
case "chip":
containsItems = true;
DatItem chip = new Chip
{
Name = reader.GetAttribute("name"),
Tag = reader.GetAttribute("tag"),
ChipType = reader.GetAttribute("type"),
Clock = reader.GetAttribute("clock"),
Source = new Source
{
Index = indexId,
Name = filename,
},
};
chip.CopyMachineInformation(machine);
// Now process and add the chip
key = ParseAddHelper(chip);
reader.Read();
break;
case "disk":
containsItems = true;
DatItem disk = new Disk
{
Name = reader.GetAttribute("name"),
MD5 = reader.GetAttribute("md5"),
SHA1 = reader.GetAttribute("sha1"),
MergeTag = reader.GetAttribute("merge"),
ItemStatus = reader.GetAttribute("status").AsItemStatus(),
Source = new Source
{
Index = indexId,
Name = filename,
},
};
disk.CopyMachineInformation(machine);
// Now process and add the disk
key = ParseAddHelper(disk);
reader.Read();
break;
case "media":
containsItems = true;
DatItem media = new Media
{
Name = reader.GetAttribute("name"),
MD5 = reader.GetAttribute("md5"),
SHA1 = reader.GetAttribute("sha1"),
SHA256 = reader.GetAttribute("sha256"),
Source = new Source
{
Index = indexId,
Name = filename,
},
};
media.CopyMachineInformation(machine);
// Now process and add the media
key = ParseAddHelper(media);
reader.Read();
break;
case "release":
containsItems = true;
@@ -386,36 +508,12 @@ namespace SabreTools.Library.DatFiles
release.CopyMachineInformation(machine);
// Now process and add the rom
// Now process and add the release
key = ParseAddHelper(release);
reader.Read();
break;
case "biosset":
containsItems = true;
DatItem biosset = new BiosSet
{
Name = reader.GetAttribute("name"),
Description = reader.GetAttribute("description"),
Default = reader.GetAttribute("default").AsYesNo(),
Source = new Source
{
Index = indexId,
Name = filename,
},
};
biosset.CopyMachineInformation(machine);
// Now process and add the rom
key = ParseAddHelper(biosset);
reader.Read();
break;
case "rom":
containsItems = true;
@@ -452,42 +550,10 @@ namespace SabreTools.Library.DatFiles
reader.Read();
break;
case "disk":
containsItems = true;
DatItem disk = new Disk
{
Name = reader.GetAttribute("name"),
MD5 = reader.GetAttribute("md5"),
#if NET_FRAMEWORK
RIPEMD160 = reader.GetAttribute("ripemd160"),
#endif
SHA1 = reader.GetAttribute("sha1"),
SHA256 = reader.GetAttribute("sha256"),
SHA384 = reader.GetAttribute("sha384"),
SHA512 = reader.GetAttribute("sha512"),
MergeTag = reader.GetAttribute("merge"),
ItemStatus = reader.GetAttribute("status").AsItemStatus(),
Source = new Source
{
Index = indexId,
Name = filename,
},
};
disk.CopyMachineInformation(machine);
// Now process and add the rom
key = ParseAddHelper(disk);
reader.Read();
break;
case "sample":
containsItems = true;
DatItem samplerom = new Sample
DatItem sample = new Sample
{
Name = reader.GetAttribute("name"),
@@ -498,57 +564,10 @@ namespace SabreTools.Library.DatFiles
},
};
samplerom.CopyMachineInformation(machine);
sample.CopyMachineInformation(machine);
// Now process and add the rom
key = ParseAddHelper(samplerom);
reader.Read();
break;
case "archive":
containsItems = true;
DatItem archiverom = new Archive
{
Name = reader.GetAttribute("name"),
Source = new Source
{
Index = indexId,
Name = filename,
},
};
archiverom.CopyMachineInformation(machine);
// Now process and add the rom
key = ParseAddHelper(archiverom);
reader.Read();
break;
case "chip":
containsItems = true;
DatItem chiprom = new Chip
{
Name = reader.GetAttribute("name"),
Tag = reader.GetAttribute("tag"),
ChipType = reader.GetAttribute("type"),
Clock = reader.GetAttribute("clock"),
Source = new Source
{
Index = indexId,
Name = filename,
},
};
chiprom.CopyMachineInformation(machine);
// Now process and add the rom
key = ParseAddHelper(chiprom);
// Now process and add the sample
key = ParseAddHelper(sample);
reader.Read();
break;
@@ -729,22 +748,22 @@ namespace SabreTools.Library.DatFiles
// If we have a "null" game (created by DATFromDir or something similar), log it to file
if (rom.ItemType == ItemType.Rom
&& ((Rom)rom).Size == -1
&& ((Rom)rom).CRC == "null")
&& (rom as Rom).Size == -1
&& (rom as Rom).CRC == "null")
{
Globals.Logger.Verbose($"Empty folder found: {rom.Machine.Name}");
rom.Name = (rom.Name == "null" ? "-" : rom.Name);
((Rom)rom).Size = Constants.SizeZero;
((Rom)rom).CRC = ((Rom)rom).CRC == "null" ? Constants.CRCZero : null;
((Rom)rom).MD5 = ((Rom)rom).MD5 == "null" ? Constants.MD5Zero : null;
(rom as Rom).Size = Constants.SizeZero;
(rom as Rom).CRC = (rom as Rom).CRC == "null" ? Constants.CRCZero : null;
(rom as Rom).MD5 = (rom as Rom).MD5 == "null" ? Constants.MD5Zero : null;
#if NET_FRAMEWORK
((Rom)rom).RIPEMD160 = ((Rom)rom).RIPEMD160 == "null" ? Constants.RIPEMD160Zero : null;
(rom as Rom).RIPEMD160 = (rom as Rom).RIPEMD160 == "null" ? Constants.RIPEMD160Zero : null;
#endif
((Rom)rom).SHA1 = ((Rom)rom).SHA1 == "null" ? Constants.SHA1Zero : null;
((Rom)rom).SHA256 = ((Rom)rom).SHA256 == "null" ? Constants.SHA256Zero : null;
((Rom)rom).SHA384 = ((Rom)rom).SHA384 == "null" ? Constants.SHA384Zero : null;
((Rom)rom).SHA512 = ((Rom)rom).SHA512 == "null" ? Constants.SHA512Zero : null;
(rom as Rom).SHA1 = (rom as Rom).SHA1 == "null" ? Constants.SHA1Zero : null;
(rom as Rom).SHA256 = (rom as Rom).SHA256 == "null" ? Constants.SHA256Zero : null;
(rom as Rom).SHA384 = (rom as Rom).SHA384 == "null" ? Constants.SHA384Zero : null;
(rom as Rom).SHA512 = (rom as Rom).SHA512 == "null" ? Constants.SHA512Zero : null;
}
// Now, output the rom data
@@ -1008,17 +1027,21 @@ namespace SabreTools.Library.DatFiles
xtw.WriteStartElement("disk");
xtw.WriteRequiredAttributeString("name", disk.Name);
xtw.WriteOptionalAttributeString("md5", disk.MD5?.ToLowerInvariant());
#if NET_FRAMEWORK
xtw.WriteOptionalAttributeString("ripemd160", disk.RIPEMD160?.ToLowerInvariant());
#endif
xtw.WriteOptionalAttributeString("sha1", disk.SHA1?.ToLowerInvariant());
xtw.WriteOptionalAttributeString("sha256", disk.SHA256?.ToLowerInvariant());
xtw.WriteOptionalAttributeString("sha384", disk.SHA384?.ToLowerInvariant());
xtw.WriteOptionalAttributeString("sha512", disk.SHA512?.ToLowerInvariant());
xtw.WriteOptionalAttributeString("status", disk.ItemStatus.FromItemStatus(false));
xtw.WriteEndElement();
break;
case ItemType.Media:
var media = datItem as Media;
xtw.WriteStartElement("media");
xtw.WriteRequiredAttributeString("name", media.Name);
xtw.WriteOptionalAttributeString("md5", media.MD5?.ToLowerInvariant());
xtw.WriteOptionalAttributeString("sha1", media.SHA1?.ToLowerInvariant());
xtw.WriteOptionalAttributeString("sha256", media.SHA256?.ToLowerInvariant());
xtw.WriteEndElement();
break;
case ItemType.Release:
var release = datItem as Release;
xtw.WriteStartElement("release");

View File

@@ -87,8 +87,8 @@ namespace SabreTools.Library.DatFiles
// If we have a "null" game (created by DATFromDir or something similar), log it to file
if (rom.ItemType == ItemType.Rom
&& ((Rom)rom).Size == -1
&& ((Rom)rom).CRC == "null")
&& (rom as Rom).Size == -1
&& (rom as Rom).CRC == "null")
{
Globals.Logger.Verbose($"Empty folder found: {rom.Machine.Name}");
lastgame = rom.Machine.Name;

View File

@@ -644,8 +644,6 @@ namespace SabreTools.Library.DatFiles
reader.ReadElementContentAsString().ToLowerInvariant()));
break;
// TODO: Should I support the "custom" romMD5 and romSHA1 tags I write out?
default:
reader.Read();
break;
@@ -727,22 +725,22 @@ namespace SabreTools.Library.DatFiles
// If we have a "null" game (created by DATFromDir or something similar), log it to file
if (rom.ItemType == ItemType.Rom
&& ((Rom)rom).Size == -1
&& ((Rom)rom).CRC == "null")
&& (rom as Rom).Size == -1
&& (rom as Rom).CRC == "null")
{
Globals.Logger.Verbose($"Empty folder found: {rom.Machine.Name}");
rom.Name = (rom.Name == "null" ? "-" : rom.Name);
((Rom)rom).Size = Constants.SizeZero;
((Rom)rom).CRC = ((Rom)rom).CRC == "null" ? Constants.CRCZero : null;
((Rom)rom).MD5 = ((Rom)rom).MD5 == "null" ? Constants.MD5Zero : null;
(rom as Rom).Size = Constants.SizeZero;
(rom as Rom).CRC = (rom as Rom).CRC == "null" ? Constants.CRCZero : null;
(rom as Rom).MD5 = (rom as Rom).MD5 == "null" ? Constants.MD5Zero : null;
#if NET_FRAMEWORK
((Rom)rom).RIPEMD160 = ((Rom)rom).RIPEMD160 == "null" ? Constants.RIPEMD160Zero : null;
(rom as Rom).RIPEMD160 = (rom as Rom).RIPEMD160 == "null" ? Constants.RIPEMD160Zero : null;
#endif
((Rom)rom).SHA1 = ((Rom)rom).SHA1 == "null" ? Constants.SHA1Zero : null;
((Rom)rom).SHA256 = ((Rom)rom).SHA256 == "null" ? Constants.SHA256Zero : null;
((Rom)rom).SHA384 = ((Rom)rom).SHA384 == "null" ? Constants.SHA384Zero : null;
((Rom)rom).SHA512 = ((Rom)rom).SHA512 == "null" ? Constants.SHA512Zero : null;
(rom as Rom).SHA1 = (rom as Rom).SHA1 == "null" ? Constants.SHA1Zero : null;
(rom as Rom).SHA256 = (rom as Rom).SHA256 == "null" ? Constants.SHA256Zero : null;
(rom as Rom).SHA384 = (rom as Rom).SHA384 == "null" ? Constants.SHA384Zero : null;
(rom as Rom).SHA512 = (rom as Rom).SHA512 == "null" ? Constants.SHA512Zero : null;
}
// Now, output the rom data
@@ -929,29 +927,7 @@ namespace SabreTools.Library.DatFiles
xtw.WriteElementString("sourceRom", "None");
xtw.WriteElementString("language", "0");
if (datItem.ItemType == ItemType.Disk)
{
var disk = datItem as Disk;
xtw.WriteStartElement("files");
if (!string.IsNullOrWhiteSpace(disk.MD5))
{
xtw.WriteStartElement("romMD5");
xtw.WriteAttributeString("extension", ".chd");
xtw.WriteString(disk.MD5?.ToUpperInvariant());
xtw.WriteEndElement();
}
else if (!string.IsNullOrWhiteSpace(disk.SHA1))
{
xtw.WriteStartElement("romSHA1");
xtw.WriteAttributeString("extension", ".chd");
xtw.WriteString(disk.SHA1?.ToUpperInvariant());
xtw.WriteEndElement();
}
// End files
xtw.WriteEndElement();
}
else if (datItem.ItemType == ItemType.Rom)
if (datItem.ItemType == ItemType.Rom)
{
var rom = datItem as Rom;
string tempext = "." + PathExtensions.GetNormalizedExtension(rom.Name);
@@ -964,20 +940,6 @@ namespace SabreTools.Library.DatFiles
xtw.WriteString(rom.CRC?.ToUpperInvariant());
xtw.WriteEndElement();
}
else if (!string.IsNullOrWhiteSpace(rom.MD5))
{
xtw.WriteStartElement("romMD5");
xtw.WriteRequiredAttributeString("extension", tempext);
xtw.WriteString(rom.MD5?.ToUpperInvariant());
xtw.WriteEndElement();
}
else if (!string.IsNullOrWhiteSpace(rom.SHA1))
{
xtw.WriteStartElement("romSHA1");
xtw.WriteRequiredAttributeString("extension", tempext);
xtw.WriteString(rom.SHA1?.ToUpperInvariant());
xtw.WriteEndElement();
}
// End files
xtw.WriteEndElement();

View File

@@ -572,8 +572,8 @@ namespace SabreTools.Library.DatFiles
// If we have a "null" game (created by DATFromDir or something similar), log it to file
if (rom.ItemType == ItemType.Rom
&& ((Rom)rom).Size == -1
&& ((Rom)rom).CRC == "null")
&& (rom as Rom).Size == -1
&& (rom as Rom).CRC == "null")
{
Globals.Logger.Verbose($"Empty folder found: {rom.Machine.Name}");

View File

@@ -419,22 +419,22 @@ namespace SabreTools.Library.DatFiles
// If we have a "null" game (created by DATFromDir or something similar), log it to file
if (rom.ItemType == ItemType.Rom
&& ((Rom)rom).Size == -1
&& ((Rom)rom).CRC == "null")
&& (rom as Rom).Size == -1
&& (rom as Rom).CRC == "null")
{
Globals.Logger.Verbose($"Empty folder found: {rom.Machine.Name}");
rom.Name = (rom.Name == "null" ? "-" : rom.Name);
((Rom)rom).Size = Constants.SizeZero;
((Rom)rom).CRC = ((Rom)rom).CRC == "null" ? Constants.CRCZero : null;
((Rom)rom).MD5 = ((Rom)rom).MD5 == "null" ? Constants.MD5Zero : null;
(rom as Rom).Size = Constants.SizeZero;
(rom as Rom).CRC = (rom as Rom).CRC == "null" ? Constants.CRCZero : null;
(rom as Rom).MD5 = (rom as Rom).MD5 == "null" ? Constants.MD5Zero : null;
#if NET_FRAMEWORK
((Rom)rom).RIPEMD160 = ((Rom)rom).RIPEMD160 == "null" ? Constants.RIPEMD160Zero : null;
(rom as Rom).RIPEMD160 = (rom as Rom).RIPEMD160 == "null" ? Constants.RIPEMD160Zero : null;
#endif
((Rom)rom).SHA1 = ((Rom)rom).SHA1 == "null" ? Constants.SHA1Zero : null;
((Rom)rom).SHA256 = ((Rom)rom).SHA256 == "null" ? Constants.SHA256Zero : null;
((Rom)rom).SHA384 = ((Rom)rom).SHA384 == "null" ? Constants.SHA384Zero : null;
((Rom)rom).SHA512 = ((Rom)rom).SHA512 == "null" ? Constants.SHA512Zero : null;
(rom as Rom).SHA1 = (rom as Rom).SHA1 == "null" ? Constants.SHA1Zero : null;
(rom as Rom).SHA256 = (rom as Rom).SHA256 == "null" ? Constants.SHA256Zero : null;
(rom as Rom).SHA384 = (rom as Rom).SHA384 == "null" ? Constants.SHA384Zero : null;
(rom as Rom).SHA512 = (rom as Rom).SHA512 == "null" ? Constants.SHA512Zero : null;
}
// Now, output the rom data

View File

@@ -404,14 +404,24 @@ namespace SabreTools.Library.DatFiles
{
Name = reader.GetAttribute("name"),
MD5 = reader.GetAttribute("md5"),
#if NET_FRAMEWORK
RIPEMD160 = reader.GetAttribute("ripemd160"),
#endif
SHA1 = reader.GetAttribute("sha1"),
ItemStatus = its,
Source = new Source
{
Index = indexId,
Name = filename,
},
};
break;
case "media":
datItem = new Media
{
Name = reader.GetAttribute("name"),
MD5 = reader.GetAttribute("md5"),
SHA1 = reader.GetAttribute("sha1"),
SHA256 = reader.GetAttribute("sha256"),
SHA384 =reader.GetAttribute("sha384"),
SHA512 = reader.GetAttribute("sha512"),
ItemStatus = its,
Source = new Source
{
@@ -628,8 +638,8 @@ namespace SabreTools.Library.DatFiles
// If we have a "null" game (created by DATFromDir or something similar), log it to file
if (rom.ItemType == ItemType.Rom
&& ((Rom)rom).Size == -1
&& ((Rom)rom).CRC == "null")
&& (rom as Rom).Size == -1
&& (rom as Rom).CRC == "null")
{
Globals.Logger.Verbose($"Empty folder found: {rom.Machine.Name}");
@@ -888,13 +898,7 @@ namespace SabreTools.Library.DatFiles
xtw.WriteAttributeString("type", "disk");
xtw.WriteRequiredAttributeString("name", disk.Name);
xtw.WriteOptionalAttributeString("md5", disk.MD5?.ToLowerInvariant());
#if NET_FRAMEWORK
xtw.WriteOptionalAttributeString("ripemd160", disk.RIPEMD160?.ToLowerInvariant());
#endif
xtw.WriteOptionalAttributeString("sha1", disk.SHA1?.ToLowerInvariant());
xtw.WriteOptionalAttributeString("sha256", disk.SHA256?.ToLowerInvariant());
xtw.WriteOptionalAttributeString("sha384", disk.SHA384?.ToLowerInvariant());
xtw.WriteOptionalAttributeString("sha512", disk.SHA512?.ToLowerInvariant());
if (disk.ItemStatus != ItemStatus.None)
{
xtw.WriteStartElement("flags");
@@ -910,6 +914,17 @@ namespace SabreTools.Library.DatFiles
xtw.WriteEndElement();
break;
case ItemType.Media:
var media = datItem as Media;
xtw.WriteStartElement("file");
xtw.WriteAttributeString("type", "media");
xtw.WriteRequiredAttributeString("name", media.Name);
xtw.WriteOptionalAttributeString("md5", media.MD5?.ToLowerInvariant());
xtw.WriteOptionalAttributeString("sha1", media.SHA1?.ToLowerInvariant());
xtw.WriteOptionalAttributeString("sha256", media.SHA256?.ToLowerInvariant());
xtw.WriteEndElement();
break;
case ItemType.Release:
var release = datItem as Release;
xtw.WriteStartElement("file");

View File

@@ -152,8 +152,8 @@ namespace SabreTools.Library.DatFiles
// If we have a "null" game (created by DATFromDir or something similar), log it to file
if (rom.ItemType == ItemType.Rom
&& ((Rom)rom).Size == -1
&& ((Rom)rom).CRC == "null")
&& (rom as Rom).Size == -1
&& (rom as Rom).CRC == "null")
{
Globals.Logger.Verbose($"Empty folder found: {rom.Machine.Name}");
}
@@ -257,14 +257,30 @@ namespace SabreTools.Library.DatFiles
fields[8] = string.Empty;
fields[9] = string.Empty;
fields[10] = disk.MD5.ToLowerInvariant();
//fields[11] = disk.RIPEMD160?.ToLowerInvariant();
//fields[11] = string.Empty;
fields[11] = disk.SHA1.ToLowerInvariant();
fields[12] = disk.SHA256.ToLowerInvariant();
//fields[13] = disk.SHA384?.ToLowerInvariant();
//fields[14] = disk.SHA512?.ToLowerInvariant();
fields[12] = string.Empty;
//fields[13] = string.Empty;
//fields[14] = string.Empty;
fields[13] = disk.ItemStatus.ToString();
break;
case ItemType.Media:
var media = datItem as Media;
fields[5] = "media";
fields[6] = string.Empty;
fields[7] = media.Name;
fields[8] = string.Empty;
fields[9] = string.Empty;
fields[10] = media.MD5.ToLowerInvariant();
//fields[11] = string.Empty;
fields[11] = media.SHA1.ToLowerInvariant();
fields[12] = media.SHA256?.ToLowerInvariant();
//fields[13] = string.Empty;
//fields[14] = string.Empty;
fields[13] = string.Empty;
break;
case ItemType.Rom:
var rom = datItem as Rom;
fields[5] = "rom";

View File

@@ -516,13 +516,7 @@ namespace SabreTools.Library.DatFiles
{
Name = reader.GetAttribute("name"),
MD5 = reader.GetAttribute("md5"),
#if NET_FRAMEWORK
RIPEMD160 = reader.GetAttribute("ripemd160"),
#endif
SHA1 = reader.GetAttribute("sha1"),
SHA256 = reader.GetAttribute("sha256"),
SHA384 = reader.GetAttribute("sha384"),
SHA512 = reader.GetAttribute("sha512"),
ItemStatus = reader.GetAttribute("status").AsItemStatus(),
Writable = reader.GetAttribute("writable").AsYesNo(),
@@ -652,8 +646,8 @@ namespace SabreTools.Library.DatFiles
// If we have a "null" game (created by DATFromDir or something similar), log it to file
if (rom.ItemType == ItemType.Rom
&& ((Rom)rom).Size == -1
&& ((Rom)rom).CRC == "null")
&& (rom as Rom).Size == -1
&& (rom as Rom).CRC == "null")
{
Globals.Logger.Verbose($"Empty folder found: {rom.Machine.Name}");
@@ -870,13 +864,7 @@ namespace SabreTools.Library.DatFiles
xtw.WriteStartElement("disk");
xtw.WriteRequiredAttributeString("name", disk.Name);
xtw.WriteOptionalAttributeString("md5", disk.MD5?.ToLowerInvariant());
#if NET_FRAMEWORK
xtw.WriteOptionalAttributeString("ripemd160", disk.RIPEMD160?.ToLowerInvariant());
#endif
xtw.WriteOptionalAttributeString("sha1", disk.SHA1?.ToLowerInvariant());
xtw.WriteOptionalAttributeString("sha256", disk.SHA256?.ToLowerInvariant());
xtw.WriteOptionalAttributeString("sha384", disk.SHA384?.ToLowerInvariant());
xtw.WriteOptionalAttributeString("sha512", disk.SHA512?.ToLowerInvariant());
xtw.WriteOptionalAttributeString("status", disk.ItemStatus.FromItemStatus(false));
xtw.WriteOptionalAttributeString("writable", disk.Writable.FromYesNo());
xtw.WriteEndElement();

View File

@@ -245,13 +245,7 @@ namespace SabreTools.Library.DatItems
// Disk
Field.DatItem_MD5,
#if NET_FRAMEWORK
Field.DatItem_RIPEMD160,
#endif
Field.DatItem_SHA1,
Field.DatItem_SHA256,
Field.DatItem_SHA384,
Field.DatItem_SHA512,
Field.DatItem_Merge,
Field.DatItem_Region,
Field.DatItem_Index,
@@ -259,6 +253,9 @@ namespace SabreTools.Library.DatItems
Field.DatItem_Status,
Field.DatItem_Optional,
// Media
Field.DatItem_SHA256,
// Release
Field.DatItem_Language,
Field.DatItem_Date,
@@ -267,6 +264,11 @@ namespace SabreTools.Library.DatItems
Field.DatItem_Bios,
Field.DatItem_Size,
Field.DatItem_CRC,
#if NET_FRAMEWORK
Field.DatItem_RIPEMD160,
#endif
Field.DatItem_SHA384,
Field.DatItem_SHA512,
Field.DatItem_Offset,
Field.DatItem_Inverted,
@@ -448,6 +450,9 @@ namespace SabreTools.Library.DatItems
case ItemType.Disk:
return new Disk();
case ItemType.Media:
return new Media();
case ItemType.Release:
return new Release();
@@ -484,6 +489,9 @@ namespace SabreTools.Library.DatItems
{
switch (baseFile.Type)
{
case FileType.AaruFormat:
return new Media(baseFile);
case FileType.CHD:
return new Disk(baseFile);
@@ -1016,8 +1024,8 @@ namespace SabreTools.Library.DatItems
{
DatItem file = infiles[f];
// If we don't have a Rom or a Disk, we skip checking for duplicates
if (file.ItemType != ItemType.Rom && file.ItemType != ItemType.Disk)
// If we don't have a Dis, Media, or Rom, we skip checking for duplicates
if (file.ItemType != ItemType.Disk && file.ItemType != ItemType.Media && file.ItemType != ItemType.Rom)
continue;
// If it's a nodump, add and skip
@@ -1057,9 +1065,11 @@ namespace SabreTools.Library.DatItems
saveditem = lastrom;
pos = i;
// Disks and Roms have more information to fill
// Disks, Media, and Roms have more information to fill
if (file.ItemType == ItemType.Disk)
(saveditem as Disk).FillMissingInformation(file as Disk);
else if (file.ItemType == ItemType.Media)
(saveditem as Media).FillMissingInformation(file as Media);
else if (file.ItemType == ItemType.Rom)
(saveditem as Rom).FillMissingInformation(file as Rom);
@@ -1142,7 +1152,7 @@ namespace SabreTools.Library.DatItems
{
Globals.Logger.Verbose($"Name duplicate found for '{datItem.Name}'");
if (datItem.ItemType == ItemType.Disk || datItem.ItemType == ItemType.Rom)
if (datItem.ItemType == ItemType.Disk || datItem.ItemType == ItemType.Media || datItem.ItemType == ItemType.Rom)
{
datItem.Name += GetDuplicateSuffix(datItem);
#if NET_FRAMEWORK
@@ -1192,6 +1202,8 @@ namespace SabreTools.Library.DatItems
{
if (datItem.ItemType == ItemType.Disk)
return (datItem as Disk).GetDuplicateSuffix();
else if (datItem.ItemType == ItemType.Media)
return (datItem as Media).GetDuplicateSuffix();
else if (datItem.ItemType == ItemType.Rom)
return (datItem as Rom).GetDuplicateSuffix();
@@ -1215,10 +1227,11 @@ namespace SabreTools.Library.DatItems
{
if (x.Machine.Name == y.Machine.Name)
{
// Special case for comparing a Disk or Rom to another item type
if ((x.ItemType == ItemType.Disk || x.ItemType == ItemType.Rom) ^ (y.ItemType == ItemType.Disk || y.ItemType == ItemType.Rom))
// Special case for comparing a Disk, Media, or Rom to another item type
if ((x.ItemType == ItemType.Disk || x.ItemType == ItemType.Media || x.ItemType == ItemType.Rom)
^ (y.ItemType == ItemType.Disk || y.ItemType == ItemType.Media || x.ItemType == ItemType.Rom))
{
if (x.ItemType == ItemType.Disk || x.ItemType == ItemType.Rom)
if (x.ItemType == ItemType.Disk || x.ItemType == ItemType.Media || x.ItemType == ItemType.Rom)
return -1;
else
return 1;

View File

@@ -18,13 +18,7 @@ namespace SabreTools.Library.DatItems
#region Private instance variables
private byte[] _md5; // 16 bytes
#if NET_FRAMEWORK
private byte[] _ripemd160; // 20 bytes
#endif
private byte[] _sha1; // 20 bytes
private byte[] _sha256; // 32 bytes
private byte[] _sha384; // 48 bytes
private byte[] _sha512; // 64 bytes
#endregion
@@ -40,18 +34,6 @@ namespace SabreTools.Library.DatItems
set { _md5 = Utilities.StringToByteArray(Sanitizer.CleanMD5(value)); }
}
#if NET_FRAMEWORK
/// <summary>
/// Data RIPEMD160 hash
/// </summary>
[JsonProperty("ripemd160", DefaultValueHandling = DefaultValueHandling.Ignore)]
public string RIPEMD160
{
get { return _ripemd160.IsNullOrEmpty() ? null : Utilities.ByteArrayToString(_ripemd160); }
set { _ripemd160 = Utilities.StringToByteArray(Sanitizer.CleanRIPEMD160(value)); }
}
#endif
/// <summary>
/// Data SHA-1 hash
/// </summary>
@@ -62,36 +44,6 @@ namespace SabreTools.Library.DatItems
set { _sha1 = Utilities.StringToByteArray(Sanitizer.CleanSHA1(value)); }
}
/// <summary>
/// Data SHA-256 hash
/// </summary>
[JsonProperty("sha256", DefaultValueHandling = DefaultValueHandling.Ignore)]
public string SHA256
{
get { return _sha256.IsNullOrEmpty() ? null : Utilities.ByteArrayToString(_sha256); }
set { _sha256 = Utilities.StringToByteArray(Sanitizer.CleanSHA256(value)); }
}
/// <summary>
/// Data SHA-384 hash
/// </summary>
[JsonProperty("sha384", DefaultValueHandling = DefaultValueHandling.Ignore)]
public string SHA384
{
get { return _sha384.IsNullOrEmpty() ? null : Utilities.ByteArrayToString(_sha384); }
set { _sha384 = Utilities.StringToByteArray(Sanitizer.CleanSHA384(value)); }
}
/// <summary>
/// Data SHA-512 hash
/// </summary>
[JsonProperty("sha512", DefaultValueHandling = DefaultValueHandling.Ignore)]
public string SHA512
{
get { return _sha512.IsNullOrEmpty() ? null : Utilities.ByteArrayToString(_sha512); }
set { _sha512 = Utilities.StringToByteArray(Sanitizer.CleanSHA512(value)); }
}
/// <summary>
/// Disk name to merge from parent
/// </summary>
@@ -146,23 +98,9 @@ namespace SabreTools.Library.DatItems
if (mappings.Keys.Contains(Field.DatItem_MD5))
MD5 = mappings[Field.DatItem_MD5];
#if NET_FRAMEWORK
if (mappings.Keys.Contains(Field.DatItem_RIPEMD160))
RIPEMD160 = mappings[Field.DatItem_RIPEMD160];
#endif
if (mappings.Keys.Contains(Field.DatItem_SHA1))
SHA1 = mappings[Field.DatItem_SHA1];
if (mappings.Keys.Contains(Field.DatItem_SHA256))
SHA256 = mappings[Field.DatItem_SHA256];
if (mappings.Keys.Contains(Field.DatItem_SHA384))
SHA384 = mappings[Field.DatItem_SHA384];
if (mappings.Keys.Contains(Field.DatItem_SHA512))
SHA512 = mappings[Field.DatItem_SHA512];
if (mappings.Keys.Contains(Field.DatItem_Merge))
MergeTag = mappings[Field.DatItem_Merge];
@@ -198,20 +136,14 @@ namespace SabreTools.Library.DatItems
}
/// <summary>
/// Create a Rom object from a BaseFile
/// Create a Disk object from a BaseFile
/// </summary>
/// <param name="baseFile"></param>
public Disk(BaseFile baseFile)
{
Name = baseFile.Filename;
_md5 = baseFile.MD5;
#if NET_FRAMEWORK
_ripemd160 = baseFile.RIPEMD160;
#endif
_sha1 = baseFile.SHA1;
_sha256 = baseFile.SHA256;
_sha384 = baseFile.SHA384;
_sha512 = baseFile.SHA512;
ItemType = ItemType.Disk;
DupeType = 0x00;
@@ -253,13 +185,7 @@ namespace SabreTools.Library.DatItems
Remove = this.Remove,
_md5 = this._md5,
#if NET_FRAMEWORK
_ripemd160 = this._ripemd160,
#endif
_sha1 = this._sha1,
_sha256 = this._sha256,
_sha384 = this._sha384,
_sha512 = this._sha512,
MergeTag = this.MergeTag,
Region = this.Region,
Index = this.Index,
@@ -277,7 +203,7 @@ namespace SabreTools.Library.DatItems
{
var rom = new Rom()
{
Name = this.Name,
Name = this.Name + ".chd",
ItemType = ItemType.Rom,
DupeType = this.DupeType,
@@ -308,15 +234,8 @@ namespace SabreTools.Library.DatItems
ItemStatus = this.ItemStatus,
Optional = this.Optional,
CRC = null,
MD5 = this.MD5,
#if NET_FRAMEWORK
RIPEMD160 = this.RIPEMD160,
#endif
SHA1 = this.SHA1,
SHA256 = this.SHA256,
SHA384 = this.SHA384,
SHA512 = this.SHA512,
};
return rom;
@@ -363,22 +282,8 @@ namespace SabreTools.Library.DatItems
if (_md5.IsNullOrEmpty() && !other._md5.IsNullOrEmpty())
_md5 = other._md5;
#if NET_FRAMEWORK
if (_ripemd160.IsNullOrEmpty() && !other._ripemd160.IsNullOrEmpty())
_ripemd160 = other._ripemd160;
#endif
if (_sha1.IsNullOrEmpty() && !other._sha1.IsNullOrEmpty())
_sha1 = other._sha1;
if (_sha256.IsNullOrEmpty() && !other._sha256.IsNullOrEmpty())
_sha256 = other._sha256;
if (_sha384.IsNullOrEmpty() && !other._sha384.IsNullOrEmpty())
_sha384 = other._sha384;
if (_sha512.IsNullOrEmpty() && !other._sha512.IsNullOrEmpty())
_sha512 = other._sha512;
}
/// <summary>
@@ -391,12 +296,6 @@ namespace SabreTools.Library.DatItems
return $"_{MD5}";
else if (!_sha1.IsNullOrEmpty())
return $"_{SHA1}";
else if (!_sha256.IsNullOrEmpty())
return $"_{SHA256}";
else if (!_sha384.IsNullOrEmpty())
return $"_{SHA384}";
else if (!_sha512.IsNullOrEmpty())
return $"_{SHA512}";
else
return "_1";
}
@@ -409,13 +308,7 @@ namespace SabreTools.Library.DatItems
private bool HasCommonHash(Disk other)
{
return !(_md5.IsNullOrEmpty() ^ other._md5.IsNullOrEmpty())
#if NET_FRAMEWORK
|| !(_ripemd160.IsNullOrEmpty() || other._ripemd160.IsNullOrEmpty())
#endif
|| !(_sha1.IsNullOrEmpty() ^ other._sha1.IsNullOrEmpty())
|| !(_sha256.IsNullOrEmpty() ^ other._sha256.IsNullOrEmpty())
|| !(_sha384.IsNullOrEmpty() ^ other._sha384.IsNullOrEmpty())
|| !(_sha512.IsNullOrEmpty() ^ other._sha512.IsNullOrEmpty());
|| !(_sha1.IsNullOrEmpty() ^ other._sha1.IsNullOrEmpty());
}
/// <summary>
@@ -425,13 +318,7 @@ namespace SabreTools.Library.DatItems
private bool HasHashes()
{
return !_md5.IsNullOrEmpty()
#if NET_FRAMEWORK
|| !_ripemd160.IsNullOrEmpty()
#endif
|| !_sha1.IsNullOrEmpty()
|| !_sha256.IsNullOrEmpty()
|| !_sha384.IsNullOrEmpty()
|| !_sha512.IsNullOrEmpty();
|| !_sha1.IsNullOrEmpty();
}
/// <summary>
@@ -451,13 +338,7 @@ namespace SabreTools.Library.DatItems
// Return if all hashes match according to merge rules
return ConditionalHashEquals(_md5, other._md5)
#if NET_FRAMEWORK
&& ConditionalHashEquals(_ripemd160, other._ripemd160)
#endif
&& ConditionalHashEquals(_sha1, other._sha1)
&& ConditionalHashEquals(_sha256, other._sha256)
&& ConditionalHashEquals(_sha384, other._sha384)
&& ConditionalHashEquals(_sha512, other._sha512);
&& ConditionalHashEquals(_sha1, other._sha1);
}
#endregion
@@ -481,38 +362,12 @@ namespace SabreTools.Library.DatItems
if (filter.DatItem_MD5.MatchesNegativeSet(MD5) == true)
return false;
#if NET_FRAMEWORK
// Filter on RIPEMD160
if (filter.DatItem_RIPEMD160.MatchesPositiveSet(RIPEMD160) == false)
return false;
if (filter.DatItem_RIPEMD160.MatchesNegativeSet(RIPEMD160) == true)
return false;
#endif
// Filter on SHA-1
if (filter.DatItem_SHA1.MatchesPositiveSet(SHA1) == false)
return false;
if (filter.DatItem_SHA1.MatchesNegativeSet(SHA1) == true)
return false;
// Filter on SHA-256
if (filter.DatItem_SHA256.MatchesPositiveSet(SHA256) == false)
return false;
if (filter.DatItem_SHA256.MatchesNegativeSet(SHA256) == true)
return false;
// Filter on SHA-384
if (filter.DatItem_SHA384.MatchesPositiveSet(SHA384) == false)
return false;
if (filter.DatItem_SHA384.MatchesNegativeSet(SHA384) == true)
return false;
// Filter on SHA-512
if (filter.DatItem_SHA512.MatchesPositiveSet(SHA512) == false)
return false;
if (filter.DatItem_SHA512.MatchesNegativeSet(SHA512) == true)
return false;
// Filter on merge tag
if (filter.DatItem_Merge.MatchesPositiveSet(MergeTag) == false)
return false;
@@ -561,23 +416,9 @@ namespace SabreTools.Library.DatItems
if (fields.Contains(Field.DatItem_MD5))
MD5 = null;
#if NET_FRAMEWORK
if (fields.Contains(Field.DatItem_RIPEMD160))
RIPEMD160 = null;
#endif
if (fields.Contains(Field.DatItem_SHA1))
SHA1 = null;
if (fields.Contains(Field.DatItem_SHA256))
SHA256 = null;
if (fields.Contains(Field.DatItem_SHA384))
SHA384 = null;
if (fields.Contains(Field.DatItem_SHA512))
SHA512 = null;
if (fields.Contains(Field.DatItem_Merge))
MergeTag = null;
@@ -620,28 +461,10 @@ namespace SabreTools.Library.DatItems
key = MD5;
break;
#if NET_FRAMEWORK
case Field.DatItem_RIPEMD160:
key = RIPEMD160;
break;
#endif
case Field.DatItem_SHA1:
key = SHA1;
break;
case Field.DatItem_SHA256:
key = SHA256;
break;
case Field.DatItem_SHA384:
key = SHA384;
break;
case Field.DatItem_SHA512:
key = SHA512;
break;
// Let the base handle generic stuff
default:
return base.GetKey(bucketedBy, lower, norename);
@@ -678,38 +501,12 @@ namespace SabreTools.Library.DatItems
MD5 = newItem.MD5;
}
#if NET_FRAMEWORK
if (fields.Contains(Field.DatItem_RIPEMD160))
{
if (string.IsNullOrEmpty(RIPEMD160) && !string.IsNullOrEmpty(newItem.RIPEMD160))
RIPEMD160 = newItem.RIPEMD160;
}
#endif
if (fields.Contains(Field.DatItem_SHA1))
{
if (string.IsNullOrEmpty(SHA1) && !string.IsNullOrEmpty(newItem.SHA1))
SHA1 = newItem.SHA1;
}
if (fields.Contains(Field.DatItem_SHA256))
{
if (string.IsNullOrEmpty(SHA256) && !string.IsNullOrEmpty(newItem.SHA256))
SHA256 = newItem.SHA256;
}
if (fields.Contains(Field.DatItem_SHA384))
{
if (string.IsNullOrEmpty(SHA384) && !string.IsNullOrEmpty(newItem.SHA384))
SHA384 = newItem.SHA384;
}
if (fields.Contains(Field.DatItem_SHA512))
{
if (string.IsNullOrEmpty(SHA512) && !string.IsNullOrEmpty(newItem.SHA512))
SHA512 = newItem.SHA512;
}
if (fields.Contains(Field.DatItem_Merge))
MergeTag = newItem.MergeTag;

View File

@@ -398,13 +398,7 @@ namespace SabreTools.Library.DatItems
// Disk
DatItem_MD5,
#if NET_FRAMEWORK
DatItem_RIPEMD160,
#endif
DatItem_SHA1,
DatItem_SHA256,
DatItem_SHA384,
DatItem_SHA512,
DatItem_Merge,
DatItem_Region,
DatItem_Index,
@@ -412,6 +406,9 @@ namespace SabreTools.Library.DatItems
DatItem_Status,
DatItem_Optional,
// Media
DatItem_SHA256,
// Release
DatItem_Language,
DatItem_Date,
@@ -420,6 +417,11 @@ namespace SabreTools.Library.DatItems
DatItem_Bios,
DatItem_Size,
DatItem_CRC,
#if NET_FRAMEWORK
DatItem_RIPEMD160,
#endif
DatItem_SHA384,
DatItem_SHA512,
DatItem_Offset,
DatItem_Inverted,
@@ -458,6 +460,7 @@ namespace SabreTools.Library.DatItems
BiosSet = 4,
Archive = 5,
Chip = 6,
Media = 7,
Blank = 99, // This is not a real type, only used internally
}

View File

@@ -0,0 +1,431 @@
using System.Collections.Generic;
using System.Linq;
using SabreTools.Library.Data;
using SabreTools.Library.FileTypes;
using SabreTools.Library.Filtering;
using SabreTools.Library.Tools;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace SabreTools.Library.DatItems
{
/// <summary>
/// Represents Aaruformat images which use internal hashes
/// </summary>
[JsonObject("media")]
public class Media : DatItem
{
#region Private instance variables
private byte[] _md5; // 16 bytes
private byte[] _sha1; // 20 bytes
private byte[] _sha256; // 32 bytes
// TODO: Implement SpamSum
#endregion
#region Fields
/// <summary>
/// Data MD5 hash
/// </summary>
[JsonProperty("md5", DefaultValueHandling = DefaultValueHandling.Ignore)]
public string MD5
{
get { return _md5.IsNullOrEmpty() ? null : Utilities.ByteArrayToString(_md5); }
set { _md5 = Utilities.StringToByteArray(Sanitizer.CleanMD5(value)); }
}
/// <summary>
/// Data SHA-1 hash
/// </summary>
[JsonProperty("sha1", DefaultValueHandling = DefaultValueHandling.Ignore)]
public string SHA1
{
get { return _sha1.IsNullOrEmpty() ? null : Utilities.ByteArrayToString(_sha1); }
set { _sha1 = Utilities.StringToByteArray(Sanitizer.CleanSHA1(value)); }
}
/// <summary>
/// Data SHA-256 hash
/// </summary>
[JsonProperty("sha256", DefaultValueHandling = DefaultValueHandling.Ignore)]
public string SHA256
{
get { return _sha256.IsNullOrEmpty() ? null : Utilities.ByteArrayToString(_sha256); }
set { _sha256 = Utilities.StringToByteArray(Sanitizer.CleanSHA256(value)); }
}
#endregion
#region Accessors
/// <summary>
/// Set fields with given values
/// </summary>
/// <param name="mappings">Mappings dictionary</param>
public override void SetFields(Dictionary<Field, string> mappings)
{
// Set base fields
base.SetFields(mappings);
// Handle Media-specific fields
if (mappings.Keys.Contains(Field.DatItem_MD5))
MD5 = mappings[Field.DatItem_MD5];
if (mappings.Keys.Contains(Field.DatItem_SHA1))
SHA1 = mappings[Field.DatItem_SHA1];
if (mappings.Keys.Contains(Field.DatItem_SHA256))
SHA256 = mappings[Field.DatItem_SHA256];
}
#endregion
#region Constructors
/// <summary>
/// Create a default, empty Media object
/// </summary>
public Media()
{
Name = string.Empty;
ItemType = ItemType.Media;
DupeType = 0x00;
}
/// <summary>
/// Create a Media object from a BaseFile
/// </summary>
/// <param name="baseFile"></param>
public Media(BaseFile baseFile)
{
Name = baseFile.Filename;
_md5 = baseFile.MD5;
_sha1 = baseFile.SHA1;
_sha256 = baseFile.SHA256;
ItemType = ItemType.Media;
DupeType = 0x00;
}
#endregion
#region Cloning Methods
public override object Clone()
{
return new Media()
{
Name = this.Name,
ItemType = this.ItemType,
DupeType = this.DupeType,
AltName = this.AltName,
AltTitle = this.AltTitle,
Original = this.Original,
OpenMSXSubType = this.OpenMSXSubType,
OpenMSXType = this.OpenMSXType,
Remark = this.Remark,
Boot = this.Boot,
Part = this.Part,
Features = this.Features,
AreaName = this.AreaName,
AreaSize = this.AreaSize,
AreaWidth = this.AreaWidth,
AreaEndianness = this.AreaEndianness,
Value = this.Value,
LoadFlag = this.LoadFlag,
Machine = this.Machine.Clone() as Machine,
Source = this.Source.Clone() as Source,
Remove = this.Remove,
_md5 = this._md5,
_sha1 = this._sha1,
_sha256 = this._sha256,
};
}
/// <summary>
/// Convert a disk to the closest Rom approximation
/// </summary>
/// <returns></returns>
public Rom ConvertToRom()
{
var rom = new Rom()
{
Name = this.Name + ".aif",
ItemType = ItemType.Rom,
DupeType = this.DupeType,
AltName = this.AltName,
AltTitle = this.AltTitle,
Original = this.Original,
OpenMSXSubType = this.OpenMSXSubType,
OpenMSXType = this.OpenMSXType,
Remark = this.Remark,
Boot = this.Boot,
Part = this.Part,
Features = this.Features,
AreaName = this.AreaName,
AreaSize = this.AreaSize,
AreaWidth = this.AreaWidth,
AreaEndianness = this.AreaEndianness,
Value = this.Value,
LoadFlag = this.LoadFlag,
Machine = this.Machine.Clone() as Machine,
Source = this.Source.Clone() as Source,
Remove = this.Remove,
MD5 = this.MD5,
SHA1 = this.SHA1,
SHA256 = this.SHA256,
};
return rom;
}
#endregion
#region Comparision Methods
public override bool Equals(DatItem other)
{
bool dupefound = false;
// If we don't have a Media, return false
if (ItemType != other.ItemType)
return dupefound;
// Otherwise, treat it as a Media
Media newOther = other as Media;
// If we get a partial match
if (HashMatch(newOther))
dupefound = true;
return dupefound;
}
/// <summary>
/// Fill any missing size and hash information from another Media
/// </summary>
/// <param name="other">Media to fill information from</param>
public void FillMissingInformation(Media other)
{
if (_md5.IsNullOrEmpty() && !other._md5.IsNullOrEmpty())
_md5 = other._md5;
if (_sha1.IsNullOrEmpty() && !other._sha1.IsNullOrEmpty())
_sha1 = other._sha1;
if (_sha256.IsNullOrEmpty() && !other._sha256.IsNullOrEmpty())
_sha256 = other._sha256;
}
/// <summary>
/// Get unique duplicate suffix on name collision
/// </summary>
/// <returns>String representing the suffix</returns>
public string GetDuplicateSuffix()
{
if (!_md5.IsNullOrEmpty())
return $"_{MD5}";
else if (!_sha1.IsNullOrEmpty())
return $"_{SHA1}";
else if (!_sha256.IsNullOrEmpty())
return $"_{SHA256}";
else
return "_1";
}
/// <summary>
/// Returns if there are no, non-empty hashes in common with another Media
/// </summary>
/// <param name="other">Media to compare against</param>
/// <returns>True if at least one hash is not mutually exclusive, false otherwise</returns>
private bool HasCommonHash(Media other)
{
return !(_md5.IsNullOrEmpty() ^ other._md5.IsNullOrEmpty())
|| !(_sha1.IsNullOrEmpty() ^ other._sha1.IsNullOrEmpty())
|| !(_sha256.IsNullOrEmpty() ^ other._sha256.IsNullOrEmpty());
}
/// <summary>
/// Returns if the Media contains any hashes
/// </summary>
/// <returns>True if any hash exists, false otherwise</returns>
private bool HasHashes()
{
return !_md5.IsNullOrEmpty()
|| !_sha1.IsNullOrEmpty()
|| !_sha256.IsNullOrEmpty();
}
/// <summary>
/// Returns if any hashes are common with another Media
/// </summary>
/// <param name="other">Media to compare against</param>
/// <returns>True if any hashes are in common, false otherwise</returns>
private bool HashMatch(Media other)
{
// If either have no hashes, we return false, otherwise this would be a false positive
if (!HasHashes() || !other.HasHashes())
return false;
// If neither have hashes in common, we return false, otherwise this would be a false positive
if (!HasCommonHash(other))
return false;
// Return if all hashes match according to merge rules
return ConditionalHashEquals(_md5, other._md5)
&& ConditionalHashEquals(_sha1, other._sha1)
&& ConditionalHashEquals(_sha256, other._sha256);
}
#endregion
#region Filtering
/// <summary>
/// Check to see if a DatItem passes the filter
/// </summary>
/// <param name="filter">Filter to check against</param>
/// <returns>True if the item passed the filter, false otherwise</returns>
public override bool PassesFilter(Filter filter)
{
// Check common fields first
if (!base.PassesFilter(filter))
return false;
// Filter on MD5
if (filter.DatItem_MD5.MatchesPositiveSet(MD5) == false)
return false;
if (filter.DatItem_MD5.MatchesNegativeSet(MD5) == true)
return false;
// Filter on SHA-1
if (filter.DatItem_SHA1.MatchesPositiveSet(SHA1) == false)
return false;
if (filter.DatItem_SHA1.MatchesNegativeSet(SHA1) == true)
return false;
// Filter on SHA-256
if (filter.DatItem_SHA256.MatchesPositiveSet(SHA256) == false)
return false;
if (filter.DatItem_SHA256.MatchesNegativeSet(SHA256) == true)
return false;
return true;
}
/// <summary>
/// Remove fields from the DatItem
/// </summary>
/// <param name="fields">List of Fields to remove</param>
public override void RemoveFields(List<Field> fields)
{
// Remove common fields first
base.RemoveFields(fields);
// Remove the fields
if (fields.Contains(Field.DatItem_MD5))
MD5 = null;
if (fields.Contains(Field.DatItem_SHA1))
SHA1 = null;
if (fields.Contains(Field.DatItem_SHA256))
SHA256 = null;
}
#endregion
#region Sorting and Merging
/// <summary>
/// Get the dictionary key that should be used for a given item and bucketing type
/// </summary>
/// <param name="bucketedBy">Field enum representing what key to get</param>
/// <param name="lower">True if the key should be lowercased (default), false otherwise</param>
/// <param name="norename">True if games should only be compared on game and file name, false if system and source are counted</param>
/// <returns>String representing the key to be used for the DatItem</returns>
public override string GetKey(Field bucketedBy, bool lower = true, bool norename = true)
{
// Set the output key as the default blank string
string key = string.Empty;
// Now determine what the key should be based on the bucketedBy value
switch (bucketedBy)
{
case Field.DatItem_MD5:
key = MD5;
break;
case Field.DatItem_SHA1:
key = SHA1;
break;
case Field.DatItem_SHA256:
key = SHA256;
break;
// Let the base handle generic stuff
default:
return base.GetKey(bucketedBy, lower, norename);
}
// Double and triple check the key for corner cases
if (key == null)
key = string.Empty;
return key;
}
/// <summary>
/// Replace fields from another item
/// </summary>
/// <param name="item">DatItem to pull new information from</param>
/// <param name="fields">List of Fields representing what should be updated</param>
public override void ReplaceFields(DatItem item, List<Field> fields)
{
// Replace common fields first
base.ReplaceFields(item, fields);
// If we don't have a Media to replace from, ignore specific fields
if (item.ItemType != ItemType.Media)
return;
// Cast for easier access
Media newItem = item as Media;
// Replace the fields
if (fields.Contains(Field.DatItem_MD5))
{
if (string.IsNullOrEmpty(MD5) && !string.IsNullOrEmpty(newItem.MD5))
MD5 = newItem.MD5;
}
if (fields.Contains(Field.DatItem_SHA1))
{
if (string.IsNullOrEmpty(SHA1) && !string.IsNullOrEmpty(newItem.SHA1))
SHA1 = newItem.SHA1;
}
if (fields.Contains(Field.DatItem_SHA256))
{
if (string.IsNullOrEmpty(SHA256) && !string.IsNullOrEmpty(newItem.SHA256))
SHA256 = newItem.SHA256;
}
}
#endregion
}
}

View File

@@ -478,6 +478,7 @@ namespace SabreTools.Library.Data
public static readonly byte[] A7800SignatureV1 = { 0x41, 0x54, 0x41, 0x52, 0x49, 0x37, 0x38, 0x30, 0x30 }; // Offset 0x01
public static readonly byte[] A7800SignatureV2 = { 0x41, 0x43, 0x54, 0x55, 0x41, 0x4c, 0x20, 0x43, 0x41, 0x52, 0x54, 0x20, 0x44, 0x41,
0x54, 0x41, 0x20, 0x53, 0x54, 0x41, 0x52, 0x54, 0x53, 0x20, 0x48, 0x45, 0x52, 0x45 }; // Offset 0x64
public static readonly byte[] AaruFormatSignature = { 0x41, 0x41, 0x52, 0x55, 0x46, 0x52, 0x4d, 0x54 };
public static readonly byte[] BZ2Signature = { 0x42, 0x5a, 0x68 };
public static readonly byte[] CabinetSignature = { 0x4d, 0x53, 0x43, 0x46 };
public static readonly byte[] CHDSignature = { 0x4d, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x48, 0x44 };

View File

@@ -0,0 +1,41 @@
using System.IO;
using System.Text;
namespace SabreTools.Library.FileTypes.Aaru
{
/// <summary>
/// Checksum entry, followed by checksum data itself
/// </summary>
/// <see cref="https://github.com/aaru-dps/Aaru/blob/master/Aaru.Images/AaruFormat/Structs.cs" />
public class ChecksumEntry
{
/// <summary>Checksum algorithm</summary>
public AaruChecksumAlgorithm type;
/// <summary>Length in bytes of checksum that follows this structure</summary>
public uint length;
/// <summary>Checksum that follows this structure</summary>
public byte[] checksum;
/// <summary>
/// Read a stream as an v
/// </summary>
/// <param name="stream">ChecksumEntry as a stream</param>
/// <returns>Populated ChecksumEntry, null on failure</returns>
public static ChecksumEntry Deserialize(Stream stream)
{
ChecksumEntry checksumEntry = new ChecksumEntry();
using (BinaryReader br = new BinaryReader(stream, Encoding.Default, true))
{
checksumEntry.type = (AaruChecksumAlgorithm)br.ReadByte();
checksumEntry.length = br.ReadUInt32();
if (checksumEntry.length == 0)
return null;
checksumEntry.checksum = br.ReadBytes((int)checksumEntry.length);
}
return checksumEntry;
}
}
}

View File

@@ -0,0 +1,39 @@
using System.IO;
using System.Text;
namespace SabreTools.Library.FileTypes.Aaru
{
/// <summary>
/// Checksum block, contains a checksum of all user data sectors
/// (except for optical discs that is 2352 bytes raw sector if available
/// </summary>
/// <see cref="https://github.com/aaru-dps/Aaru/blob/master/Aaru.Images/AaruFormat/Structs.cs" />
public class ChecksumHeader
{
/// <summary>Identifier, <see cref="BlockType.ChecksumBlock" /></summary>
public AaruBlockType identifier;
/// <summary>Length in bytes of the block</summary>
public uint length;
/// <summary>How many checksums follow</summary>
public byte entries;
/// <summary>
/// Read a stream as an ChecksumHeader
/// </summary>
/// <param name="stream">ChecksumHeader as a stream</param>
/// <returns>Populated ChecksumHeader, null on failure</returns>
public static ChecksumHeader Deserialize(Stream stream)
{
ChecksumHeader checksumHeader = new ChecksumHeader();
using (BinaryReader br = new BinaryReader(stream, Encoding.Default, true))
{
checksumHeader.identifier = (AaruBlockType)br.ReadUInt32();
checksumHeader.length = br.ReadUInt32();
checksumHeader.entries = br.ReadByte();
}
return checksumHeader;
}
}
}

View File

@@ -0,0 +1,38 @@
using System.IO;
using System.Text;
namespace SabreTools.Library.FileTypes.Aaru
{
/// <summary>
/// Index entry
/// </summary>
/// <see cref="https://github.com/aaru-dps/Aaru/blob/master/Aaru.Images/AaruFormat/Structs.cs" />
public class IndexEntry
{
/// <summary>Type of item pointed by this entry</summary>
public AaruBlockType blockType;
/// <summary>Type of data contained by the block pointed by this entry</summary>
public AaruDataType dataType;
/// <summary>Offset in file where item is stored</summary>
public ulong offset;
/// <summary>
/// Read a stream as an IndexHeader
/// </summary>
/// <param name="stream">IndexHeader as a stream</param>
/// <returns>Populated IndexHeader, null on failure</returns>
public static IndexEntry Deserialize(Stream stream)
{
IndexEntry indexEntry = new IndexEntry();
using (BinaryReader br = new BinaryReader(stream, Encoding.Default, true))
{
indexEntry.blockType = (AaruBlockType)br.ReadUInt32();
indexEntry.dataType = (AaruDataType)br.ReadUInt16();
indexEntry.offset = br.ReadUInt64();
}
return indexEntry;
}
}
}

View File

@@ -0,0 +1,38 @@
using System.IO;
using System.Text;
namespace SabreTools.Library.FileTypes.Aaru
{
/// <summary>
/// Header for the index, followed by entries
/// </summary>
/// <see cref="https://github.com/aaru-dps/Aaru/blob/master/Aaru.Images/AaruFormat/Structs.cs" />
public class IndexHeader
{
/// <summary>Identifier, <see cref="BlockType.Index" /></summary>
public AaruBlockType identifier;
/// <summary>How many entries follow this header</summary>
public ushort entries;
/// <summary>CRC64-ECMA of the index</summary>
public ulong crc64;
/// <summary>
/// Read a stream as an IndexHeader
/// </summary>
/// <param name="stream">IndexHeader as a stream</param>
/// <returns>Populated IndexHeader, null on failure</returns>
public static IndexHeader Deserialize(Stream stream)
{
IndexHeader indexHeader = new IndexHeader();
using (BinaryReader br = new BinaryReader(stream, Encoding.Default, true))
{
indexHeader.identifier = (AaruBlockType)br.ReadUInt32();
indexHeader.entries = br.ReadUInt16();
indexHeader.crc64 = br.ReadUInt64();
}
return indexHeader;
}
}
}

View File

@@ -0,0 +1,229 @@
using System;
using System.IO;
using System.Text;
using SabreTools.Library.Data;
using SabreTools.Library.FileTypes.Aaru;
using SabreTools.Library.IO;
namespace SabreTools.Library.FileTypes
{
/// <summary>
/// AaruFormat code is based on the Aaru project
/// See https://github.com/aaru-dps/Aaru/tree/master/Aaru.Images/AaruFormat
/// </summary>
public class AaruFormat : BaseFile
{
#region Private instance variables
#region Header
protected ulong Identifier; // 'AARUFRMT' (0x544D524655524141)
protected string Application; // Name of application that created image
protected byte ImageMajorVersion; // Image format major version
protected byte ImageMinorVersion; // Image format minor version
protected byte ApplicationMajorVersion; // Major version of application that created image
protected byte ApplicationMinorVersion; // Minor version of application that created image
protected AaruMediaType MediaType; // Media type contained in image
protected ulong IndexOffset; // Offset to index
protected long CreationTime; // Windows filetime of creation time
protected long LastWrittenTime; // Windows filetime of last written time
#endregion
#region Internal Values
protected IndexHeader IndexHeader;
protected IndexEntry[] IndexEntries;
#endregion
#region Hashes
// TODO: Support SpamSum
#endregion
#endregion // Private instance variables
#region Constructors
/// <summary>
/// Create a new AaruFormat from an input file
/// </summary>
/// <param name="filename">Filename respresenting the AaruFormat file</param>
public static AaruFormat Create(string filename)
{
using (FileStream fs = FileExtensions.TryOpenRead(filename))
{
return Create(fs);
}
}
/// <summary>
/// Create a new AaruFormat from an input stream
/// </summary>
/// <param name="aarustream">Stream representing the AaruFormat file</param>
public static AaruFormat Create(Stream aarustream)
{
try
{
// Validate that this is actually a valid AaruFormat (by magic string alone)
bool validated = ValidateHeader(aarustream);
aarustream.Seek(-8, SeekOrigin.Current); // Seek back to start
if (!validated)
return null;
// Read and retrun the current AaruFormat
AaruFormat generated = Deserialize(aarustream);
if (generated != null)
generated.Type = FileType.AaruFormat;
return generated;
}
catch
{
return null;
}
}
#endregion
#region Header Parsing
/// <summary>
/// Validate we start with the right magic number
/// </summary>
public static bool ValidateHeader(Stream aarustream)
{
// Read the magic string
byte[] magicBytes = new byte[8];
int read = aarustream.Read(magicBytes, 0, 8);
// If we didn't read the magic fully, we don't have an AaruFormat
if (read < 8)
return false;
// If the bytes don't match, we don't have an AaruFormat
if (!magicBytes.StartsWith(Constants.AaruFormatSignature))
return false;
return true;
}
/// <summary>
/// Read a stream as an AaruFormat
/// </summary>
/// <param name="stream">AaruFormat file as a stream</param>
/// <returns>Populated AaruFormat file, null on failure</returns>
public static AaruFormat Deserialize(Stream stream)
{
try
{
AaruFormat aif = new AaruFormat();
using (BinaryReader br = new BinaryReader(stream, Encoding.Default, true))
{
aif.Identifier = br.ReadUInt64();
aif.Application = Encoding.Unicode.GetString(br.ReadBytes(64), 0, 64);
aif.ImageMajorVersion = br.ReadByte();
aif.ImageMinorVersion = br.ReadByte();
aif.ApplicationMajorVersion = br.ReadByte();
aif.ApplicationMinorVersion = br.ReadByte();
aif.MediaType = (AaruMediaType)br.ReadUInt32();
aif.IndexOffset = br.ReadUInt64();
aif.CreationTime = br.ReadInt64();
aif.LastWrittenTime = br.ReadInt64();
// If the offset is bigger than the stream, we can't read it
if (aif.IndexOffset > (ulong)stream.Length)
return null;
// Otherwise, we read in the index header
stream.Seek((long)aif.IndexOffset, SeekOrigin.Begin);
aif.IndexHeader = IndexHeader.Deserialize(stream);
if (aif.IndexHeader.entries == 0)
return null;
// Get the list of entries
aif.IndexEntries = new IndexEntry[aif.IndexHeader.entries];
for (ushort index = 0; index < aif.IndexHeader.entries; index++)
{
aif.IndexEntries[index] = IndexEntry.Deserialize(stream);
switch (aif.IndexEntries[index].blockType)
{
// We don't do anything with these block types currently
case AaruBlockType.DataBlock:
case AaruBlockType.DeDuplicationTable:
case AaruBlockType.Index:
case AaruBlockType.Index2:
case AaruBlockType.GeometryBlock:
case AaruBlockType.MetadataBlock:
case AaruBlockType.TracksBlock:
case AaruBlockType.CicmBlock:
case AaruBlockType.DataPositionMeasurementBlock:
case AaruBlockType.SnapshotBlock:
case AaruBlockType.ParentBlock:
case AaruBlockType.DumpHardwareBlock:
case AaruBlockType.TapeFileBlock:
case AaruBlockType.TapePartitionBlock:
case AaruBlockType.CompactDiscIndexesBlock:
// No-op
break;
// Read in all available hashes
case AaruBlockType.ChecksumBlock:
// If the offset is bigger than the stream, we can't read it
if (aif.IndexEntries[index].offset > (ulong)stream.Length)
return null;
// Otherwise, we read in the block
stream.Seek((long)aif.IndexEntries[index].offset, SeekOrigin.Begin);
ChecksumHeader checksumHeader = ChecksumHeader.Deserialize(stream);
if (checksumHeader.entries == 0)
return null;
// Read through each and pick out the ones we care about
for (byte entry = 0; entry < checksumHeader.entries; entry++)
{
ChecksumEntry checksumEntry = ChecksumEntry.Deserialize(stream);
if (checksumEntry == null)
continue;
switch (checksumEntry.type)
{
case AaruChecksumAlgorithm.Invalid:
break;
case AaruChecksumAlgorithm.Md5:
aif.MD5 = checksumEntry.checksum;
break;
case AaruChecksumAlgorithm.Sha1:
aif.SHA1 = checksumEntry.checksum;
break;
case AaruChecksumAlgorithm.Sha256:
aif.SHA256 = checksumEntry.checksum;
break;
case AaruChecksumAlgorithm.SpamSum:
// TODO: Support SpamSum
break;
}
}
// Once we got hashes, we return early
return aif;
}
}
}
return aif;
}
catch
{
// We don't care what the error was at this point
return null;
}
}
#endregion
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -362,9 +362,9 @@ namespace SabreTools.Library.FileTypes
if (rom.ItemType == ItemType.Rom)
{
if (date && !string.IsNullOrWhiteSpace(((Rom)rom).Date))
if (date && !string.IsNullOrWhiteSpace((rom as Rom).Date))
{
File.SetCreationTime(fileName, DateTime.Parse(((Rom)rom).Date));
File.SetCreationTime(fileName, DateTime.Parse((rom as Rom).Date));
}
}

View File

@@ -204,7 +204,7 @@ namespace SabreTools.Library.FileTypes
else
{
Stream entryStream = entry.OpenEntryStream();
BaseFile rarEntryRom = entryStream.GetInfo(entry.Size, omitFromScan);
BaseFile rarEntryRom = entryStream.GetInfo(size: entry.Size, omitFromScan: omitFromScan);
rarEntryRom.Filename = entry.Key;
rarEntryRom.Parent = gamename;
rarEntryRom.Date = entry.LastModifiedTime?.ToString("yyyy/MM/dd hh:mm:ss");

View File

@@ -316,7 +316,7 @@ namespace SabreTools.Library.FileTypes
// Otherwise, use the stream directly
else
{
BaseFile zipEntryRom = readStream.GetInfo((long)zf.UncompressedSize(i), omitFromScan, true);
BaseFile zipEntryRom = readStream.GetInfo(size: (long)zf.UncompressedSize(i), omitFromScan: omitFromScan, keepReadOpen: true);
zipEntryRom.Filename = zf.Filename(i);
zipEntryRom.Parent = gamename;
found.Add(zipEntryRom);

View File

@@ -209,7 +209,7 @@ namespace SabreTools.Library.FileTypes
else
{
Stream entryStream = entry.OpenEntryStream();
BaseFile tarEntryRom = entryStream.GetInfo(entry.Size, omitFromScan);
BaseFile tarEntryRom = entryStream.GetInfo(size: entry.Size, omitFromScan: omitFromScan);
tarEntryRom.Filename = entry.Key;
tarEntryRom.Parent = gamename;
tarEntryRom.Date = entry.LastModifiedTime?.ToString("yyyy/MM/dd hh:mm:ss");

View File

@@ -319,7 +319,7 @@ namespace SabreTools.Library.FileTypes
// Otherwise, use the stream directly
else
{
BaseFile zipEntryRom = readStream.GetInfo((long)zf.UncompressedSize(i), omitFromScan, true);
BaseFile zipEntryRom = readStream.GetInfo(size: (long)zf.UncompressedSize(i), omitFromScan: omitFromScan, keepReadOpen: true);
zipEntryRom.Filename = zf.Filename(i);
zipEntryRom.Parent = gamename;
string convertedDate = zf.LastModified(i).ToString("yyyy/MM/dd hh:mm:ss");

View File

@@ -321,13 +321,7 @@ namespace SabreTools.Library.Filtering
// Disk
public FilterItem<string> DatItem_MD5 { get; private set; } = new FilterItem<string>();
#if NET_FRAMEWORK
public FilterItem<string> DatItem_RIPEMD160 { get; private set; } = new FilterItem<string>();
#endif
public FilterItem<string> DatItem_SHA1 { get; private set; } = new FilterItem<string>();
public FilterItem<string> DatItem_SHA256 { get; private set; } = new FilterItem<string>();
public FilterItem<string> DatItem_SHA384 { get; private set; } = new FilterItem<string>();
public FilterItem<string> DatItem_SHA512 { get; private set; } = new FilterItem<string>();
public FilterItem<string> DatItem_Merge { get; private set; } = new FilterItem<string>();
public FilterItem<string> DatItem_Region { get; private set; } = new FilterItem<string>();
public FilterItem<string> DatItem_Index { get; private set; } = new FilterItem<string>();
@@ -335,6 +329,9 @@ namespace SabreTools.Library.Filtering
public FilterItem<bool?> DatItem_Optional { get; private set; } = new FilterItem<bool?>() { Neutral = null };
public FilterItem<ItemStatus> DatItem_Status { get; private set; } = new FilterItem<ItemStatus>() { Positive = ItemStatus.NULL, Negative = ItemStatus.NULL };
// Media
public FilterItem<string> DatItem_SHA256 { get; private set; } = new FilterItem<string>();
// Release
public FilterItem<string> DatItem_Language { get; private set; } = new FilterItem<string>();
public FilterItem<string> DatItem_Date { get; private set; } = new FilterItem<string>();
@@ -343,6 +340,11 @@ namespace SabreTools.Library.Filtering
public FilterItem<string> DatItem_Bios { get; private set; } = new FilterItem<string>();
public FilterItem<long> DatItem_Size { get; private set; } = new FilterItem<long>() { Positive = -1, Negative = -1, Neutral = -1 };
public FilterItem<string> DatItem_CRC { get; private set; } = new FilterItem<string>();
#if NET_FRAMEWORK
public FilterItem<string> DatItem_RIPEMD160 { get; private set; } = new FilterItem<string>();
#endif
public FilterItem<string> DatItem_SHA384 { get; private set; } = new FilterItem<string>();
public FilterItem<string> DatItem_SHA512 { get; private set; } = new FilterItem<string>();
public FilterItem<string> DatItem_Offset { get; private set; } = new FilterItem<string>();
public FilterItem<bool?> DatItem_Inverted { get; private set; } = new FilterItem<bool?>();
@@ -1832,15 +1834,6 @@ namespace SabreTools.Library.Filtering
DatItem_MD5.PositiveSet.Add(value);
break;
#if NET_FRAMEWORK
case Field.DatItem_RIPEMD160:
if (negate)
DatItem_RIPEMD160.NegativeSet.Add(value);
else
DatItem_RIPEMD160.PositiveSet.Add(value);
break;
#endif
case Field.DatItem_SHA1:
if (negate)
DatItem_SHA1.NegativeSet.Add(value);
@@ -1848,27 +1841,6 @@ namespace SabreTools.Library.Filtering
DatItem_SHA1.PositiveSet.Add(value);
break;
case Field.DatItem_SHA256:
if (negate)
DatItem_SHA256.NegativeSet.Add(value);
else
DatItem_SHA256.PositiveSet.Add(value);
break;
case Field.DatItem_SHA384:
if (negate)
DatItem_SHA384.NegativeSet.Add(value);
else
DatItem_SHA384.PositiveSet.Add(value);
break;
case Field.DatItem_SHA512:
if (negate)
DatItem_SHA512.NegativeSet.Add(value);
else
DatItem_SHA512.PositiveSet.Add(value);
break;
case Field.DatItem_Merge:
if (negate)
DatItem_Merge.NegativeSet.Add(value);
@@ -1911,6 +1883,14 @@ namespace SabreTools.Library.Filtering
DatItem_Status.Positive |= value.AsItemStatus();
break;
// Media
case Field.DatItem_SHA256:
if (negate)
DatItem_SHA256.NegativeSet.Add(value);
else
DatItem_SHA256.PositiveSet.Add(value);
break;
// Release
case Field.DatItem_Language:
if (negate)
@@ -1993,6 +1973,29 @@ namespace SabreTools.Library.Filtering
DatItem_CRC.PositiveSet.Add(value);
break;
#if NET_FRAMEWORK
case Field.DatItem_RIPEMD160:
if (negate)
DatItem_RIPEMD160.NegativeSet.Add(value);
else
DatItem_RIPEMD160.PositiveSet.Add(value);
break;
#endif
case Field.DatItem_SHA384:
if (negate)
DatItem_SHA384.NegativeSet.Add(value);
else
DatItem_SHA384.PositiveSet.Add(value);
break;
case Field.DatItem_SHA512:
if (negate)
DatItem_SHA512.NegativeSet.Add(value);
else
DatItem_SHA512.PositiveSet.Add(value);
break;
case Field.DatItem_Offset:
if (negate)
DatItem_Offset.NegativeSet.Add(value);

View File

@@ -245,6 +245,10 @@ namespace SabreTools.Library.IO
{
outFileType = FileType.SevenZipArchive;
}
else if (magic.StartsWith(Constants.AaruFormatSignature))
{
outFileType = FileType.AaruFormat;
}
else if (magic.StartsWith(Constants.CHDSignature))
{
outFileType = FileType.CHD;
@@ -307,7 +311,7 @@ namespace SabreTools.Library.IO
/// <param name="arr2">Second byte array to compare</param>
/// <param name="exact">True if the input arrays should match exactly, false otherwise (default)</param>
/// <returns>True if the first byte array starts with the second, false otherwise</returns>
private static bool StartsWith(this byte[] arr1, byte[] arr2, bool exact = false)
public static bool StartsWith(this byte[] arr1, byte[] arr2, bool exact = false)
{
// If we have any invalid inputs, we return false
if (arr1 == null || arr2 == null
@@ -335,9 +339,10 @@ namespace SabreTools.Library.IO
/// <param name="omitFromScan">Hash flag saying what hashes should not be calculated (defaults to none)</param>
/// <param name="date">True if the file Date should be included, false otherwise (default)</param>
/// <param name="header">Populated string representing the name of the skipper to use, a blank string to use the first available checker, null otherwise</param>
/// <param name="aaruFormatAsFiles">True if AaruFormats should be treated like regular files, false otherwise</param>
/// <param name="chdsAsFiles">True if CHDs should be treated like regular files, false otherwise</param>
/// <returns>Populated BaseFile object if success, empty one on error</returns>
public static BaseFile GetInfo(string input, Hash omitFromScan = 0x0, bool date = false, string header = null, bool chdsAsFiles = true)
public static BaseFile GetInfo(string input, Hash omitFromScan = 0x0, bool date = false, string header = null, bool aaruFormatAsFiles = true, bool chdsAsFiles = true)
{
// Add safeguard if file doesn't exist
if (!File.Exists(input))
@@ -358,7 +363,7 @@ namespace SabreTools.Library.IO
// Transform the stream and get the information from it
rule.TransformStream(inputStream, outputStream, keepReadOpen: false, keepWriteOpen: true);
baseFile = outputStream.GetInfo(omitFromScan: omitFromScan, keepReadOpen: false, chdsAsFiles: chdsAsFiles);
baseFile = outputStream.GetInfo(omitFromScan: omitFromScan, keepReadOpen: false, aaruFormatAsFiles: aaruFormatAsFiles, chdsAsFiles: chdsAsFiles);
// Dispose of the streams
outputStream.Dispose();
@@ -367,12 +372,12 @@ namespace SabreTools.Library.IO
// Otherwise, just get the info
else
{
baseFile = TryOpenRead(input).GetInfo(omitFromScan: omitFromScan, keepReadOpen: false, chdsAsFiles: chdsAsFiles);
baseFile = TryOpenRead(input).GetInfo(omitFromScan: omitFromScan, keepReadOpen: false, aaruFormatAsFiles: aaruFormatAsFiles, chdsAsFiles: chdsAsFiles);
}
}
else
{
baseFile = TryOpenRead(input).GetInfo(omitFromScan: omitFromScan, keepReadOpen: false, chdsAsFiles: chdsAsFiles);
baseFile = TryOpenRead(input).GetInfo(omitFromScan: omitFromScan, keepReadOpen: false, aaruFormatAsFiles: aaruFormatAsFiles, chdsAsFiles: chdsAsFiles);
}
// Add unique data from the file

View File

@@ -76,6 +76,14 @@ namespace SabreTools.Library.IO
// Check against the list of known archive extensions
switch (ext)
{
// Aaruformat
case "aaru":
case "aaruf":
case "aaruformat":
case "aif":
case "dicf":
// Archives
case "7z":
case "gz":
case "lzma":
@@ -88,6 +96,9 @@ namespace SabreTools.Library.IO
case "tlz":
case "zip":
case "zipx":
// CHD
case "chd":
return true;
default:
return false;

View File

@@ -45,11 +45,12 @@ namespace SabreTools.Library.IO
/// <param name="size">Size of the input stream</param>
/// <param name="omitFromScan">Hash flag saying what hashes should not be calculated (defaults to none)</param>
/// <param name="keepReadOpen">True if the underlying read stream should be kept open, false otherwise</param>
/// <param name="aaruFormatAsFiles">True if AaruFormats should be treated like regular files, false otherwise</param>
/// <param name="chdsAsFiles">True if CHDs should be treated like regular files, false otherwise</param>
/// <returns>Populated BaseFile object if success, empty one on error</returns>
public static BaseFile GetInfo(this Stream input, long size = -1, Hash omitFromScan = 0x0, bool keepReadOpen = false, bool chdsAsFiles = true)
public static BaseFile GetInfo(this Stream input, long size = -1, Hash omitFromScan = 0x0, bool keepReadOpen = false, bool aaruFormatAsFiles = true, bool chdsAsFiles = true)
{
return GetInfoAsync(input, size, omitFromScan, keepReadOpen, chdsAsFiles).ConfigureAwait(false).GetAwaiter().GetResult();
return GetInfoAsync(input, size, omitFromScan, keepReadOpen, aaruFormatAsFiles, chdsAsFiles).ConfigureAwait(false).GetAwaiter().GetResult();
}
/// <summary>
@@ -59,15 +60,32 @@ namespace SabreTools.Library.IO
/// <param name="size">Size of the input stream</param>
/// <param name="omitFromScan">Hash flag saying what hashes should not be calculated (defaults to none)</param>
/// <param name="keepReadOpen">True if the underlying read stream should be kept open, false otherwise</param>
/// <param name="aaruFormatAsFiles">True if AaruFormats should be treated like regular files, false otherwise</param>
/// <param name="chdsAsFiles">True if CHDs should be treated like regular files, false otherwise</param>
/// <returns>Populated BaseFile object if success, empty one on error</returns>
public static async Task<BaseFile> GetInfoAsync(Stream input, long size = -1, Hash omitFromScan = 0x0, bool keepReadOpen = false, bool chdsAsFiles = true)
public static async Task<BaseFile> GetInfoAsync(Stream input, long size = -1, Hash omitFromScan = 0x0, bool keepReadOpen = false, bool aaruFormatAsFiles = true, bool chdsAsFiles = true)
{
// If we want to automatically set the size
if (size == -1)
size = input.Length;
// We first check to see if it's a CHD if we have to
// We first check to see if it's an AaruFormat if we have to
if (!aaruFormatAsFiles)
{
var aaruFormat = AaruFormat.Create(input);
input.SeekIfPossible();
// If we found a valid AaruFormat
if (aaruFormat != null)
{
if (!keepReadOpen)
input.Dispose();
return aaruFormat;
}
}
// Then, we first check to see if it's a CHD if we have to
if (!chdsAsFiles)
{
var chd = CHDFile.Create(input);

View File

@@ -233,11 +233,21 @@ Options:
Normally, the DAT will be created with the date in the file name in
brackets. This flag removes that instead of the default.
-caf, --aaruformats-as-files Treat AaruFormats as regular files
Normally, AaruFormats would be processed using their internal hash to
compare against the input DATs. This flag forces all AaruFormats to be
treated like regular files.
-aaf, --archives-as-files Treat archives as files
Instead of trying to enumerate the files within archives, treat the
archives as files themselves. This is good for uncompressed sets that
include archives that should be read as-is.
-ic, --chds-as-files Treat CHDs as regular files
Normally, CHDs would be processed using their internal hash to
compare against the input DATs. This flag forces all CHDs to be
treated like regular files.
-ot=, --output-type= Output DATs to a specified format
Add outputting the created DAT to known format. Multiple instances of
this flag are allowed.
@@ -387,11 +397,6 @@ Options:
or specific copier headers by name (such as "fds.xml") to determine
if a file matches or not.
-ic, --chds-as-files Treat CHDs as regular files
Normally, CHDs would be processed using their internal hash to
compare against the input DATs. This flag forces all CHDs to be
treated like regular files.
-ini=, --extra-ini= Apply a MAME INI for given field(s)
Apply any valid MAME INI for any valid field in the DatFile. Inputs are
of the form 'Field:path\to\ini'. Multiple instances of this flag are
@@ -687,6 +692,11 @@ Options:
can only get the CRC and size from most archive formats, leading to
possible issues.
-caf, --aaruformats-as-files Treat AaruFormats as regular files
Normally, AaruFormats would be processed using their internal hash to
compare against the input DATs. This flag forces all AaruFormats to be
treated like regular files.
-ic, --chds-as-files Treat CHDs as regular files
Normally, CHDs would be processed using their internal hash to
compare against the input DATs. This flag forces all CHDs to be
@@ -1606,6 +1616,11 @@ Options:
or specific copier headers by name (such as "fds.xml") to determine
if a file matches or not.
-caf, --aaruformats-as-files Treat AaruFormats as regular files
Normally, AaruFormats would be processed using their internal hash to
compare against the input DATs. This flag forces all AaruFormats to be
treated like regular files.
-ic, --chds-as-files Treat CHDs as regular files
Normally, CHDs would be processed using their internal hash to
compare against the input DATs. This flag forces all CHDs to be

View File

@@ -118,7 +118,7 @@ namespace SabreTools.Library.Skippers
// Now add the information to the database if it's not already there
if (!nostore)
{
BaseFile baseFile = FileExtensions.GetInfo(newfile, chdsAsFiles: true);
BaseFile baseFile = FileExtensions.GetInfo(newfile, aaruFormatAsFiles: true, chdsAsFiles: true);
DatabaseTools.AddHeaderToDatabase(hstr, Utilities.ByteArrayToString(baseFile.SHA1), rule.SourceFile);
}
@@ -138,7 +138,7 @@ namespace SabreTools.Library.Skippers
Directory.CreateDirectory(outDir);
// First, get the SHA-1 hash of the file
BaseFile baseFile = FileExtensions.GetInfo(file, chdsAsFiles: true);
BaseFile baseFile = FileExtensions.GetInfo(file, aaruFormatAsFiles: true, chdsAsFiles: true);
// Retrieve a list of all related headers from the database
List<string> headers = DatabaseTools.RetrieveHeadersFromDatabase(Utilities.ByteArrayToString(baseFile.SHA1));

View File

@@ -1528,6 +1528,8 @@ namespace SabreTools.Library.Tools
return ItemType.Chip;
case "disk":
return ItemType.Disk;
case "media":
return ItemType.Media;
case "release":
return ItemType.Release;
case "rom":
@@ -1545,6 +1547,7 @@ namespace SabreTools.Library.Tools
"blank" => ItemType.Blank,
"chip" => ItemType.Chip,
"disk" => ItemType.Disk,
"media" => ItemType.Media,
"release" => ItemType.Release,
"rom" => ItemType.Rom,
"sample" => ItemType.Sample,
@@ -1914,6 +1917,8 @@ namespace SabreTools.Library.Tools
return "chip";
case ItemType.Disk:
return "disk";
case ItemType.Media:
return "media";
case ItemType.Release:
return "release";
case ItemType.Rom:
@@ -1931,6 +1936,7 @@ namespace SabreTools.Library.Tools
ItemType.Blank => "blank",
ItemType.Chip => "chip",
ItemType.Disk => "disk",
ItemType.Media => "media",
ItemType.Release => "release",
ItemType.Rom => "rom",
ItemType.Sample => "sample",