[ALL] Overhaul to internal system

This massive change replaces the old "Rom" struct system with a new one that have different objects for each major item type. This required a lot of work and a lot of changes and has unfortunately been untested. But this is the first step in moving away from using structs. The next major step is converting Dat over to this as well.
This commit is contained in:
Matt Nadareski
2016-09-19 18:04:24 -07:00
parent f059b5389c
commit 902070c542
22 changed files with 1615 additions and 3017 deletions

View File

@@ -63,7 +63,7 @@ namespace SabreTools
Name = Path.GetFileName(inputs[0]) + " Dir2Dat", Name = Path.GetFileName(inputs[0]) + " Dir2Dat",
Description = Path.GetFileName(inputs[0]) + " Dir2Dat", Description = Path.GetFileName(inputs[0]) + " Dir2Dat",
OutputFormat = OutputFormat.Xml, OutputFormat = OutputFormat.Xml,
Files = new Dictionary<string, List<Rom>>(), Files = new Dictionary<string, List<DatItem>>(),
}; };
Logger logger = new Logger(false, ""); Logger logger = new Logger(false, "");

View File

@@ -191,116 +191,6 @@ namespace SabreTools.Helper
} }
} }
/// <summary>
/// Intermediate struct for holding and processing rom data
/// </summary>
public struct Rom : IComparable, IEquatable<Rom>
{
public Machine Machine;
public string Name;
public ItemType Type;
public Hash HashData;
public DupeType Dupe;
public bool Nodump;
public string Date;
public SourceMetadata Metadata;
// Non rom or disk
public string Region;
public string Language;
public bool? Default;
public string Description;
public int CompareTo(object obj)
{
int ret = 0;
try
{
Rom comp = (Rom)obj;
if (this.Machine.Name == comp.Machine.Name)
{
if (this.Name == comp.Name)
{
ret = (this.Equals(comp) ? 0 : 1);
}
ret = String.Compare(this.Name, comp.Name);
}
ret = String.Compare(this.Machine.Name, comp.Machine.Name);
}
catch
{
ret = 1;
}
return ret;
}
public bool Equals(Rom other)
{
bool dupefound = false;
// If either is a nodump, it's never a match
if (this.Nodump || other.Nodump)
{
return dupefound;
}
if (this.Type == ItemType.Rom && other.Type == ItemType.Rom)
{
dupefound = this.HashData.Equals(other.HashData, false);
}
else if (this.Type == ItemType.Disk && other.Type == ItemType.Disk)
{
dupefound = this.HashData.Equals(other.HashData, true);
}
return dupefound;
}
}
/// <summary>
/// Intermediate metadata kept with a RomData object representing source information
/// </summary>
public struct SourceMetadata
{
public int SystemID;
public string System;
public int SourceID;
public string Source;
}
/// <summary>
/// Intermediate struct for holding and processing Rom/Machine data
/// </summary>
public struct Machine : IEquatable<Machine>
{
public string Name;
public string Comment;
public string Description;
public string Year;
public string Manufacturer;
public string RomOf;
public string CloneOf;
public string SampleOf;
public string SourceFile;
public bool IsBios;
public string Board;
public string RebuildTo;
public bool TorrentZipped;
public bool Equals(Machine other)
{
if (this.Name == other.Name)
{
return true;
}
return false;
}
}
/// <summary> /// <summary>
/// Intermediate struct for holding DAT information /// Intermediate struct for holding DAT information
/// </summary> /// </summary>
@@ -326,7 +216,7 @@ namespace SabreTools.Helper
public ForcePacking ForcePacking; public ForcePacking ForcePacking;
public OutputFormat OutputFormat; public OutputFormat OutputFormat;
public bool MergeRoms; public bool MergeRoms;
public Dictionary<string, List<Rom>> Files; public Dictionary<string, List<DatItem>> Files;
// Data specific to the Miss DAT type // Data specific to the Miss DAT type
public bool UseGame; public bool UseGame;
@@ -416,7 +306,7 @@ namespace SabreTools.Helper
ForcePacking = this.ForcePacking, ForcePacking = this.ForcePacking,
OutputFormat = this.OutputFormat, OutputFormat = this.OutputFormat,
MergeRoms = this.MergeRoms, MergeRoms = this.MergeRoms,
Files = new Dictionary<string, List<Rom>>(), Files = new Dictionary<string, List<DatItem>>(),
UseGame = this.UseGame, UseGame = this.UseGame,
Prefix = this.Prefix, Prefix = this.Prefix,
Postfix = this.Postfix, Postfix = this.Postfix,

View File

@@ -57,8 +57,8 @@ namespace SabreTools
{ {
_basePath = Path.GetFullPath(basePath); _basePath = Path.GetFullPath(basePath);
_datdata = datdata; _datdata = datdata;
_datdata.Files = new Dictionary<string, List<Rom>>(); _datdata.Files = new Dictionary<string, List<DatItem>>();
_datdata.Files.Add("null", new List<Rom>()); _datdata.Files.Add("null", new List<DatItem>());
_noMD5 = noMD5; _noMD5 = noMD5;
_noSHA1 = noSHA1; _noSHA1 = noSHA1;
_bare = bare; _bare = bare;
@@ -158,25 +158,7 @@ namespace SabreTools
} }
_logger.Log("Adding blank empty folder: " + gamename); _logger.Log("Adding blank empty folder: " + gamename);
_datdata.Files["null"].Add(new Rom(romname, gamename));
Rom blankrom = new Rom
{
Name = romname,
Machine = new Machine
{
Name = gamename,
Description = gamename,
},
HashData = new Hash
{
Size = -1,
CRC = "null",
MD5 = "null",
SHA1 = "null",
},
};
_datdata.Files["null"].Add(blankrom);
} }
}); });
} }
@@ -221,7 +203,7 @@ namespace SabreTools
{ {
if (!_datdata.Files.ContainsKey(key)) if (!_datdata.Files.ContainsKey(key))
{ {
_datdata.Files.Add(key, new List<Rom>()); _datdata.Files.Add(key, new List<DatItem>());
} }
_datdata.Files[key].Add(rom); _datdata.Files[key].Add(rom);
@@ -321,18 +303,33 @@ namespace SabreTools
/// Process a single file as a file (with found Rom data) /// Process a single file as a file (with found Rom data)
/// </summary> /// </summary>
/// <param name="item">File to be added</param> /// <param name="item">File to be added</param>
/// <param name="rom">Rom data to be used to write to file</param> /// <param name="item">Rom data to be used to write to file</param>
/// <param name="basepath">Path the represents the parent directory</param> /// <param name="basepath">Path the represents the parent directory</param>
/// <param name="parent">Parent game to be used</param> /// <param name="parent">Parent game to be used</param>
private void ProcessFileHelper(string item, Rom rom, string basepath, string parent) private void ProcessFileHelper(string item, DatItem datItem, string basepath, string parent)
{ {
// If the datItem isn't a Rom or Disk, return
if (datItem.Type != ItemType.Rom && datItem.Type != ItemType.Disk)
{
return;
}
string key = "";
if (datItem.Type == ItemType.Rom)
{
key = ((Rom)datItem).HashData.Size + "-" + ((Rom)datItem).HashData.CRC;
}
else
{
key = ((Disk)datItem).HashData.Size + "-" + ((Disk)datItem).HashData.MD5;
}
// Add the list if it doesn't exist already // Add the list if it doesn't exist already
string key = rom.HashData.Size + "-" + rom.HashData.CRC;
lock (_datdata.Files) lock (_datdata.Files)
{ {
if (!_datdata.Files.ContainsKey(key)) if (!_datdata.Files.ContainsKey(key))
{ {
_datdata.Files.Add(key, new List<Rom>()); _datdata.Files.Add(key, new List<DatItem>());
} }
} }
@@ -406,17 +403,14 @@ namespace SabreTools
} }
// Update rom information // Update rom information
rom.Machine = new Machine datItem.Name = romname;
{ datItem.MachineName = gamename;
Name = gamename, datItem.MachineDescription = gamename;
Description = gamename,
};
rom.Name = romname;
// Add the file information to the DAT // Add the file information to the DAT
lock (_datdata.Files) lock (_datdata.Files)
{ {
_datdata.Files[key].Add(rom); _datdata.Files[key].Add(datItem);
} }
_logger.User("File added: " + romname + Environment.NewLine); _logger.User("File added: " + romname + Environment.NewLine);

View File

@@ -0,0 +1,91 @@
namespace SabreTools.Helper
{
public class Archive : DatItem
{
#region Constructors
/// <summary>
/// Create a default, empty Archive object
/// </summary>
public Archive()
{
_name = "";
_itemType = ItemType.Archive;
}
/// <summary>
/// Create a new Archive object with the included information
/// </summary>
/// <param name="name">Name of the item, including extension</param>
public Archive(string name)
{
_name = name;
_itemType = ItemType.Archive;
}
/// <summary>
/// Create a new Archive object with the included information
/// </summary>
/// <param name="name">Name of the item, including extension</param>
/// <param name="machineName">Name for the machine/game</param>
/// <param name="comment">Comment for the machine/game</param>
/// <param name="machineDescription">Description for the machine/game</param>
/// <param name="year">Year for the machine/game</param>
/// <param name="manufacturer">Manufacturer name for the machine/game</param>
/// <param name="romOf">Set that this machine/game is a rom of</param>
/// <param name="cloneOf">Set that this machine/game is a clone of</param>
/// <param name="sampleOf">Set that this machine/game is a sample of</param>
/// <param name="sourceFile">Source file for the machine/game</param>
/// <param name="isBios">True if this game is a BIOS, false otherwise</param>
/// <param name="board">Name of the board for this machine/game</param>
/// <param name="rebuildTo">Name of the game to rebuild to</param>
/// <param name="systemId">System ID to be associated with</param>
/// <param name="systemName">System Name to be associated with</param>
/// <param name="sourceId">Source ID to be associated with</param>
/// <param name="sourceName">Source Name to be associated with</param>
public Archive(string name, string machineName, string comment, string machineDescription, string year,
string manufacturer, string romOf, string cloneOf, string sampleOf, string sourceFile, bool isBios, string board, string rebuildTo,
int systemId, string systemName, int sourceId, string sourceName)
{
_name = name;
_itemType = ItemType.Archive;
_machineName = machineName;
_comment = comment;
_machineDescription = machineDescription;
_year = year;
_manufacturer = manufacturer;
_romOf = romOf;
_cloneOf = cloneOf;
_sampleOf = sampleOf;
_sourceFile = sourceFile;
_isBios = isBios;
_board = board;
_rebuildTo = rebuildTo;
_systemId = systemId;
_systemName = systemName;
_sourceId = sourceId;
_sourceName = sourceName;
}
#endregion
#region Comparision Methods
public override bool Equals(DatItem other)
{
// If we don't have a rom, return false
if (_itemType == other.Type)
{
return false;
}
// Otherwise, treat it as a rom
Archive newOther = (Archive)other;
// If the archive information matches
return (_name == newOther.Name);
}
#endregion
}
}

View File

@@ -0,0 +1,121 @@
namespace SabreTools.Helper
{
public class BiosSet : DatItem
{
#region Private instance variables
private string _description;
private bool? _default;
#endregion
#region Publicly facing variables
public string Description
{
get { return _description; }
set { _description = value; }
}
public bool? Default
{
get { return _default; }
set { _default = value; }
}
#endregion
#region Constructors
/// <summary>
/// Create a default, empty Sample object
/// </summary>
public BiosSet()
{
_name = "";
_itemType = ItemType.BiosSet;
}
/// <summary>
/// Create a new Sample object with the included information
/// </summary>
/// <param name="name">Name of the item, including extension</param>
/// <param name="description">Description of the Bios set item</param>
/// <param name="default">True if this is the default BIOS, false if it is not, null for undefined</param>
public BiosSet(string name, string description, bool? @default)
{
_name = name;
_itemType = ItemType.BiosSet;
_description = description;
_default = @default;
}
/// <summary>
/// Create a new Sample object with the included information
/// </summary>
/// <param name="name">Name of the item, including extension</param>
/// <param name="description">Description of the Bios set item</param>
/// <param name="default">True if this is the default BIOS, false if it is not, null for undefined</param>
/// <param name="machineName">Name for the machine/game</param>
/// <param name="comment">Comment for the machine/game</param>
/// <param name="machineDescription">Description for the machine/game</param>
/// <param name="year">Year for the machine/game</param>
/// <param name="manufacturer">Manufacturer name for the machine/game</param>
/// <param name="romOf">Set that this machine/game is a rom of</param>
/// <param name="cloneOf">Set that this machine/game is a clone of</param>
/// <param name="sampleOf">Set that this machine/game is a sample of</param>
/// <param name="sourceFile">Source file for the machine/game</param>
/// <param name="isBios">True if this game is a BIOS, false otherwise</param>
/// <param name="board">Name of the board for this machine/game</param>
/// <param name="rebuildTo">Name of the game to rebuild to</param>
/// <param name="systemId">System ID to be associated with</param>
/// <param name="systemName">System Name to be associated with</param>
/// <param name="sourceId">Source ID to be associated with</param>
/// <param name="sourceName">Source Name to be associated with</param>
public BiosSet(string name, string description, bool? @default, string machineName, string comment, string machineDescription, string year,
string manufacturer, string romOf, string cloneOf, string sampleOf, string sourceFile, bool isBios, string board, string rebuildTo,
int systemId, string systemName, int sourceId, string sourceName)
{
_name = name;
_itemType = ItemType.BiosSet;
_description = description;
_default = @default;
_machineName = machineName;
_comment = comment;
_machineDescription = machineDescription;
_year = year;
_manufacturer = manufacturer;
_romOf = romOf;
_cloneOf = cloneOf;
_sampleOf = sampleOf;
_sourceFile = sourceFile;
_isBios = isBios;
_board = board;
_rebuildTo = rebuildTo;
_systemId = systemId;
_systemName = systemName;
_sourceId = sourceId;
_sourceName = sourceName;
}
#endregion
#region Comparision Methods
public override bool Equals(DatItem other)
{
// If we don't have a rom, return false
if (_itemType == other.Type)
{
return false;
}
// Otherwise, treat it as a rom
BiosSet newOther = (BiosSet)other;
// If the archive information matches
return (_name == newOther.Name && _description == newOther.Description && _default == newOther.Default);
}
#endregion
}
}

View File

@@ -0,0 +1,146 @@
namespace SabreTools.Helper
{
public class Disk : DatItem
{
#region Private instance variables
// Disk information
private Hash _hashData;
// private string _merge;
// private DiskStatus _romStatus;
private bool _nodump;
#endregion
#region Publicly facing variables
// Disk information
public Hash HashData
{
get { return _hashData; }
set { _hashData = value; }
}
public bool Nodump
{
get { return _nodump; }
set { _nodump = value; }
}
#endregion
#region Constructors
/// <summary>
/// Create a default, empty Disk object
/// </summary>
public Disk()
{
_name = "";
_itemType = ItemType.Disk;
_dupeType = DupeType.None;
_nodump = false;
}
/// <summary>
/// Create a new Disk object with the included information
/// </summary>
/// <param name="name">Name of the item, including extension</param>
/// <param name="md5">String representation of the MD5</param>
/// <param name="sha1">String representation of the SHA-1</param>
/// <param name="nodump">True if the file is a nodump, false otherwise</param>
public Disk(string name, string md5, string sha1, bool nodump)
{
_name = name;
_itemType = ItemType.Disk;
_hashData = new Hash
{
MD5 = md5.ToLowerInvariant(),
SHA1 = sha1.ToLowerInvariant(),
};
_nodump = nodump;
}
/// <summary>
/// Create a new Disk object with the included information
/// </summary>
/// <param name="name">Name of the item, including extension</param>
/// <param name="md5">String representation of the MD5</param>
/// <param name="sha1">String representation of the SHA-1</param>
/// <param name="nodump">True if the file is a nodump, false otherwise</param>
/// <param name="machineName">Name for the machine/game</param>
/// <param name="comment">Comment for the machine/game</param>
/// <param name="machineDescription">Description for the machine/game</param>
/// <param name="year">Year for the machine/game</param>
/// <param name="manufacturer">Manufacturer name for the machine/game</param>
/// <param name="romOf">Set that this machine/game is a rom of</param>
/// <param name="cloneOf">Set that this machine/game is a clone of</param>
/// <param name="sampleOf">Set that this machine/game is a sample of</param>
/// <param name="sourceFile">Source file for the machine/game</param>
/// <param name="isBios">True if this game is a BIOS, false otherwise</param>
/// <param name="board">Name of the board for this machine/game</param>
/// <param name="rebuildTo">Name of the game to rebuild to</param>
/// <param name="systemId">System ID to be associated with</param>
/// <param name="systemName">System Name to be associated with</param>
/// <param name="sourceId">Source ID to be associated with</param>
/// <param name="sourceName">Source Name to be associated with</param>
public Disk(string name, string md5, string sha1, bool nodump, string machineName, string comment,
string machineDescription, string year, string manufacturer, string romOf, string cloneOf, string sampleOf, string sourceFile,
bool isBios, string board, string rebuildTo, int systemId, string systemName, int sourceId, string sourceName)
{
_name = name;
_itemType = ItemType.Disk;
_hashData = new Hash
{
MD5 = md5.ToLowerInvariant(),
SHA1 = sha1.ToLowerInvariant(),
};
_nodump = nodump;
_machineName = machineName;
_comment = comment;
_machineDescription = machineDescription;
_year = year;
_manufacturer = manufacturer;
_romOf = romOf;
_cloneOf = cloneOf;
_sampleOf = sampleOf;
_sourceFile = sourceFile;
_isBios = isBios;
_board = board;
_rebuildTo = rebuildTo;
_systemId = systemId;
_systemName = systemName;
_sourceId = sourceId;
_sourceName = sourceName;
}
#endregion
#region Comparision Methods
public override bool Equals(DatItem other)
{
bool dupefound = false;
// If we don't have a rom, return false
if (_itemType == other.Type)
{
return dupefound;
}
// Otherwise, treat it as a rom
Disk newOther = (Disk)other;
// If either is a nodump, it's never a match
if (_nodump || newOther.Nodump)
{
return dupefound;
}
dupefound = _hashData.Equals(newOther.HashData, false);
return dupefound;
}
#endregion
}
}

View File

@@ -0,0 +1,149 @@
namespace SabreTools.Helper
{
public class Release : DatItem
{
#region Private instance variables
private string _region;
private string _language;
private string _date;
private bool? _default;
#endregion
#region Publicly facing variables
public string Region
{
get { return _region; }
set { _region = value; }
}
public string Language
{
get { return _language; }
set { _language = value; }
}
public string Date
{
get { return _date; }
set { _date = value; }
}
public bool? Default
{
get { return _default; }
set { _default = value; }
}
#endregion
#region Constructors
/// <summary>
/// Create a default, empty Release object
/// </summary>
public Release()
{
_name = "";
_itemType = ItemType.Release;
_region = "";
_language = "";
_date = "";
_default = null;
}
/// <summary>
/// Create a new Release object with the included information
/// </summary>
/// <param name="name">Name of the item, including extension</param>
/// <param name="region">Region of the item</param>
/// <param name="language">Language of the item</param>
/// <param name="date">String representation of the Date</param>
/// <param name="default">True if this is the default BIOS, false if it is not, null for undefined</param>
public Release(string name, string region, string language, string date, bool? @default)
{
_name = name;
_itemType = ItemType.Release;
_region = region;
_language = language;
_date = date;
_default = @default;
}
/// <summary>
/// Create a new Release object with the included information
/// </summary>
/// <param name="name">Name of the item, including extension</param>
/// <param name="region">Region of the item</param>
/// <param name="language">Language of the item</param>
/// <param name="date">String representation of the Date</param>
/// <param name="default">True if this is the default BIOS, false if it is not, null for undefined</param>
/// <param name="machineName">Name for the machine/game</param>
/// <param name="comment">Comment for the machine/game</param>
/// <param name="machineDescription">Description for the machine/game</param>
/// <param name="year">Year for the machine/game</param>
/// <param name="manufacturer">Manufacturer name for the machine/game</param>
/// <param name="romOf">Set that this machine/game is a rom of</param>
/// <param name="cloneOf">Set that this machine/game is a clone of</param>
/// <param name="sampleOf">Set that this machine/game is a sample of</param>
/// <param name="sourceFile">Source file for the machine/game</param>
/// <param name="isBios">True if this game is a BIOS, false otherwise</param>
/// <param name="board">Name of the board for this machine/game</param>
/// <param name="rebuildTo">Name of the game to rebuild to</param>
/// <param name="systemId">System ID to be associated with</param>
/// <param name="systemName">System Name to be associated with</param>
/// <param name="sourceId">Source ID to be associated with</param>
/// <param name="sourceName">Source Name to be associated with</param>
public Release(string name, string region, string language, string date, bool? @default, string machineName, string comment,
string machineDescription, string year, string manufacturer, string romOf, string cloneOf, string sampleOf, string sourceFile,
bool isBios, string board, string rebuildTo, int systemId, string systemName, int sourceId, string sourceName)
{
_name = name;
_itemType = ItemType.Release;
_region = region;
_language = language;
_date = date;
_default = @default;
_machineName = machineName;
_comment = comment;
_machineDescription = machineDescription;
_year = year;
_manufacturer = manufacturer;
_romOf = romOf;
_cloneOf = cloneOf;
_sampleOf = sampleOf;
_sourceFile = sourceFile;
_isBios = isBios;
_board = board;
_rebuildTo = rebuildTo;
_systemId = systemId;
_systemName = systemName;
_sourceId = sourceId;
_sourceName = sourceName;
}
#endregion
#region Comparision Methods
public override bool Equals(DatItem other)
{
// If we don't have a rom, return false
if (_itemType == other.Type)
{
return false;
}
// Otherwise, treat it as a rom
Release newOther = (Release)other;
// If the archive information matches
return (_name == newOther.Name
&& _region == newOther.Region
&& _language == newOther.Language
&& _date == newOther.Date
&& _default == newOther.Default);
}
#endregion
}
}

View File

@@ -0,0 +1,175 @@
namespace SabreTools.Helper
{
public class Rom : DatItem
{
#region Private instance variables
// Rom information
private Hash _hashData;
// private string _merge;
// private RomStatus _romStatus;
private bool _nodump;
private string _date;
#endregion
#region Publicly facing variables
// Rom information
public Hash HashData
{
get { return _hashData; }
set { _hashData = value; }
}
public bool Nodump
{
get { return _nodump; }
set { _nodump = value; }
}
public string Date
{
get { return _date; }
set { _date = value; }
}
#endregion
#region Constructors
/// <summary>
/// Create a default, empty Rom object
/// </summary>
public Rom()
{
_name = "";
_itemType = ItemType.Rom;
_dupeType = DupeType.None;
_nodump = false;
_date = "";
}
/// <summary>
/// Create a "blank" Rom object
/// </summary>
/// <param name="name"></param>
/// <param name="machineName"></param>
public Rom(string name, string machineName) :
this(name, -1, "null", "null", "null", false, null, machineName, null, machineName, null, null, null, null, null, null, false, null, null, -1, null, -1, null)
{
}
/// <summary>
/// Create a new Rom object with the included information
/// </summary>
/// <param name="name">Name of the item, including extension</param>
/// <param name="size">Long size of the item</param>
/// <param name="crc">String representation of the CRC</param>
/// <param name="md5">String representation of the MD5</param>
/// <param name="sha1">String representation of the SHA-1</param>
/// <param name="nodump">True if the file is a nodump, false otherwise</param>
/// <param name="date">String representation of the Date</param>
public Rom(string name, long size, string crc, string md5, string sha1, bool nodump, string date)
{
_name = name;
_itemType = ItemType.Rom;
_hashData = new Hash
{
Size = size,
CRC = crc.ToLowerInvariant(),
MD5 = md5.ToLowerInvariant(),
SHA1 = sha1.ToLowerInvariant(),
};
_nodump = nodump;
_date = date;
}
/// <summary>
/// Create a new Rom object with the included information
/// </summary>
/// <param name="name">Name of the item, including extension</param>
/// <param name="size">Long size of the item</param>
/// <param name="crc">String representation of the CRC</param>
/// <param name="md5">String representation of the MD5</param>
/// <param name="sha1">String representation of the SHA-1</param>
/// <param name="nodump">True if the file is a nodump, false otherwise</param>
/// <param name="date">String representation of the Date</param>
/// <param name="machineName">Name for the machine/game</param>
/// <param name="comment">Comment for the machine/game</param>
/// <param name="machineDescription">Description for the machine/game</param>
/// <param name="year">Year for the machine/game</param>
/// <param name="manufacturer">Manufacturer name for the machine/game</param>
/// <param name="romOf">Set that this machine/game is a rom of</param>
/// <param name="cloneOf">Set that this machine/game is a clone of</param>
/// <param name="sampleOf">Set that this machine/game is a sample of</param>
/// <param name="sourceFile">Source file for the machine/game</param>
/// <param name="isBios">True if this game is a BIOS, false otherwise</param>
/// <param name="board">Name of the board for this machine/game</param>
/// <param name="rebuildTo">Name of the game to rebuild to</param>
/// <param name="systemId">System ID to be associated with</param>
/// <param name="systemName">System Name to be associated with</param>
/// <param name="sourceId">Source ID to be associated with</param>
/// <param name="sourceName">Source Name to be associated with</param>
public Rom(string name, long size, string crc, string md5, string sha1, bool nodump, string date, string machineName,
string comment, string machineDescription, string year, string manufacturer, string romOf, string cloneOf, string sampleOf,
string sourceFile, bool isBios, string board, string rebuildTo, int systemId, string systemName, int sourceId, string sourceName)
{
_name = name;
_itemType = ItemType.Rom;
_hashData = new Hash
{
Size = size,
CRC = crc.ToLowerInvariant(),
MD5 = md5.ToLowerInvariant(),
SHA1 = sha1.ToLowerInvariant(),
};
_nodump = nodump;
_date = date;
_machineName = machineName;
_comment = comment;
_machineDescription = machineDescription;
_year = year;
_manufacturer = manufacturer;
_romOf = romOf;
_cloneOf = cloneOf;
_sampleOf = sampleOf;
_sourceFile = sourceFile;
_isBios = isBios;
_board = board;
_rebuildTo = rebuildTo;
_systemId = systemId;
_systemName = systemName;
_sourceId = sourceId;
_sourceName = sourceName;
}
#endregion
#region Comparision Methods
public override bool Equals(DatItem other)
{
bool dupefound = false;
// If we don't have a rom, return false
if (_itemType == other.Type)
{
return dupefound;
}
// Otherwise, treat it as a rom
Rom newOther = (Rom)other;
// If either is a nodump, it's never a match
if (_nodump || newOther.Nodump)
{
return dupefound;
}
dupefound = _hashData.Equals(newOther.HashData, false);
return dupefound;
}
#endregion
}
}

View File

@@ -0,0 +1,91 @@
namespace SabreTools.Helper
{
public class Sample : DatItem
{
#region Constructors
/// <summary>
/// Create a default, empty Sample object
/// </summary>
public Sample()
{
_name = "";
_itemType = ItemType.Sample;
}
/// <summary>
/// Create a new Sample object with the included information
/// </summary>
/// <param name="name">Name of the item, including extension</param>
public Sample(string name)
{
_name = name;
_itemType = ItemType.Sample;
}
/// <summary>
/// Create a new Sample object with the included information
/// </summary>
/// <param name="name">Name of the item, including extension</param>
/// <param name="machineName">Name for the machine/game</param>
/// <param name="comment">Comment for the machine/game</param>
/// <param name="machineDescription">Description for the machine/game</param>
/// <param name="year">Year for the machine/game</param>
/// <param name="manufacturer">Manufacturer name for the machine/game</param>
/// <param name="romOf">Set that this machine/game is a rom of</param>
/// <param name="cloneOf">Set that this machine/game is a clone of</param>
/// <param name="sampleOf">Set that this machine/game is a sample of</param>
/// <param name="sourceFile">Source file for the machine/game</param>
/// <param name="isBios">True if this game is a BIOS, false otherwise</param>
/// <param name="board">Name of the board for this machine/game</param>
/// <param name="rebuildTo">Name of the game to rebuild to</param>
/// <param name="systemId">System ID to be associated with</param>
/// <param name="systemName">System Name to be associated with</param>
/// <param name="sourceId">Source ID to be associated with</param>
/// <param name="sourceName">Source Name to be associated with</param>
public Sample(string name, string machineName, string comment, string machineDescription, string year,
string manufacturer, string romOf, string cloneOf, string sampleOf, string sourceFile, bool isBios, string board, string rebuildTo,
int systemId, string systemName, int sourceId, string sourceName)
{
_name = name;
_itemType = ItemType.Sample;
_machineName = machineName;
_comment = comment;
_machineDescription = machineDescription;
_year = year;
_manufacturer = manufacturer;
_romOf = romOf;
_cloneOf = cloneOf;
_sampleOf = sampleOf;
_sourceFile = sourceFile;
_isBios = isBios;
_board = board;
_rebuildTo = rebuildTo;
_systemId = systemId;
_systemName = systemName;
_sourceId = sourceId;
_sourceName = sourceName;
}
#endregion
#region Comparision Methods
public override bool Equals(DatItem other)
{
// If we don't have a rom, return false
if (_itemType == other.Type)
{
return false;
}
// Otherwise, treat it as a rom
Sample newOther = (Sample)other;
// If the archive information matches
return (_name == newOther.Name);
}
#endregion
}
}

View File

@@ -9,7 +9,7 @@ namespace SabreTools
/// <summary> /// <summary>
/// Generate a DAT from the data in the database /// Generate a DAT from the data in the database
/// </summary> /// </summary>
class Generate : IGenerate public class Generate : IGenerate
{ {
// Private instance variables // Private instance variables
private string _systems; private string _systems;
@@ -153,7 +153,7 @@ namespace SabreTools
} }
// Retrieve the list of processed roms // Retrieve the list of processed roms
Dictionary<string, List<Rom>> dict = ProcessRoms(); Dictionary<string, List<DatItem>> dict = ProcessRoms();
// If the output is null, nothing was found so return false // If the output is null, nothing was found so return false
if (dict.Count == 0) if (dict.Count == 0)
@@ -186,9 +186,9 @@ namespace SabreTools
/// Preprocess the rom data that is to be included in the outputted DAT /// Preprocess the rom data that is to be included in the outputted DAT
/// </summary> /// </summary>
/// <returns>A List of Rom objects containing all information about the files</returns> /// <returns>A List of Rom objects containing all information about the files</returns>
public Dictionary<string, List<Rom>> ProcessRoms() public Dictionary<string, List<DatItem>> ProcessRoms()
{ {
Dictionary<string, List<Rom>> roms = new Dictionary<string, List<Rom>>(); Dictionary<string, List<DatItem>> roms = new Dictionary<string, List<DatItem>>();
// Check if we have listed sources or systems // Check if we have listed sources or systems
bool sysmerged = (_systems == "" || _systems.Split(',').Length > 1); bool sysmerged = (_systems == "" || _systems.Split(',').Length > 1);
@@ -236,47 +236,42 @@ JOIN checksums
// Retrieve and process the roms for merging // Retrieve and process the roms for merging
while (sldr.Read()) while (sldr.Read())
{ {
Rom temp = new Rom DatItem temp;
string key = "";
switch (sldr.GetString(8).ToLowerInvariant())
{ {
Name = sldr.GetString(7), case "disk":
Type = (sldr.GetString(8) == "disk" ? ItemType.Disk : ItemType.Rom), temp = new Disk(sldr.GetString(7), sldr.GetString(11), sldr.GetString(12), false, sldr.GetString(13), sldr.GetString(6),
Machine = new Machine sldr.GetString(6), null, sldr.GetString(0), null, null, null, null, false, null, null, sldr.GetInt32(2),
{ sldr.GetString(1), sldr.GetInt32(5), sldr.GetString(3));
Name = sldr.GetString(6),
Manufacturer = sldr.GetString(0), key = ((Disk)temp).HashData.Size + "-" + ((Disk)temp).HashData.CRC;
}, break;
Metadata = new SourceMetadata case "rom":
{ default:
System = sldr.GetString(1), temp = new Rom(sldr.GetString(7), sldr.GetInt64(9), sldr.GetString(10), sldr.GetString(11), sldr.GetString(12), false,
SystemID = sldr.GetInt32(2), sldr.GetString(13), sldr.GetString(6), null, sldr.GetString(6), null, sldr.GetString(0), null, null, null, null, false,
Source = sldr.GetString(3), null, null, sldr.GetInt32(2), sldr.GetString(1), sldr.GetInt32(5), sldr.GetString(3));
SourceID = sldr.GetInt32(5),
}, key = ((Disk)temp).HashData.Size + "-" + ((Disk)temp).HashData.CRC;
HashData = new Hash break;
{ }
Size = sldr.GetInt64(9),
CRC = sldr.GetString(10),
MD5 = sldr.GetString(11),
SHA1 = sldr.GetString(12),
},
};
// Rename the game associated if it's still valid and we allow renames // Rename the game associated if it's still valid and we allow renames
if (merged && !_norename) if (merged && !_norename)
{ {
temp.Machine.Name = temp.Machine.Name + temp.MachineName = temp.MachineName +
(sysmerged ? " [" + temp.Machine.Manufacturer + " - " + temp.Metadata.System + "]" : "") + (sysmerged ? " [" + temp.Manufacturer + " - " + temp.System + "]" : "") +
(srcmerged ? " [" + temp.Metadata.Source + "]" : ""); (srcmerged ? " [" + temp.Source + "]" : "");
} }
string key = temp.HashData.Size + "-" + temp.HashData.CRC;
if (roms.ContainsKey(key)) if (roms.ContainsKey(key))
{ {
roms[key].Add(temp); roms[key].Add(temp);
} }
else else
{ {
List<Rom> templist = new List<Rom>(); List<DatItem> templist = new List<DatItem>();
templist.Add(temp); templist.Add(temp);
roms.Add(key, templist); roms.Add(key, templist);
} }
@@ -290,7 +285,7 @@ JOIN checksums
{ {
foreach (string key in roms.Keys) foreach (string key in roms.Keys)
{ {
roms[key] = RomTools.Merge(roms[key], _logger); roms[key] = DatItem.Merge(roms[key], _logger);
} }
} }
// END COMMENT // END COMMENT

View File

@@ -188,14 +188,14 @@ namespace SabreTools
List<string> keys = datdata.Files.Keys.ToList(); List<string> keys = datdata.Files.Keys.ToList();
foreach (string key in keys) foreach (string key in keys)
{ {
List<Rom> temp = new List<Rom>(); List<DatItem> temp = new List<DatItem>();
List<Rom> newroms = datdata.Files[key]; List<DatItem> newroms = datdata.Files[key];
for (int i = 0; i < newroms.Count; i++) for (int i = 0; i < newroms.Count; i++)
{ {
Rom rom = newroms[i]; Rom rom = (Rom)newroms[i];
// In the case that the RomData is incomplete, skip it // In the case that the RomData is incomplete, skip it
if (rom.Name == null || rom.Machine.Name == null) if (rom.Name == null || rom.MachineName == null)
{ {
continue; continue;
} }
@@ -209,27 +209,27 @@ namespace SabreTools
rom.Name = Regex.Replace(rom.Name, @"(.*) \.(.*)", "$1.$2"); rom.Name = Regex.Replace(rom.Name, @"(.*) \.(.*)", "$1.$2");
// Run the name through the filters to make sure that it's correct // Run the name through the filters to make sure that it's correct
rom.Machine.Name = Style.NormalizeChars(rom.Machine.Name); rom.MachineName = Style.NormalizeChars(rom.MachineName);
rom.Machine.Name = Style.RussianToLatin(rom.Machine.Name); rom.MachineName = Style.RussianToLatin(rom.MachineName);
rom.Machine.Name = Style.SearchPattern(rom.Machine.Name); rom.MachineName = Style.SearchPattern(rom.MachineName);
// WoD gets rid of anything past the first "(" or "[" as the name, we will do the same // WoD gets rid of anything past the first "(" or "[" as the name, we will do the same
string stripPattern = @"(([[(].*[\)\]] )?([^([]+))"; string stripPattern = @"(([[(].*[\)\]] )?([^([]+))";
Regex stripRegex = new Regex(stripPattern); Regex stripRegex = new Regex(stripPattern);
Match stripMatch = stripRegex.Match(rom.Machine.Name); Match stripMatch = stripRegex.Match(rom.MachineName);
rom.Machine.Name = stripMatch.Groups[1].Value; rom.MachineName = stripMatch.Groups[1].Value;
rom.Machine.Name = rom.Machine.Name.TrimEnd().TrimStart(); rom.MachineName = rom.MachineName.TrimEnd().TrimStart();
if (!_norename) if (!_norename)
{ {
rom.Machine.Name += " [" + sources[rom.Metadata.SourceID] + "]"; rom.MachineName += " [" + sources[rom.SourceID] + "]";
} }
// If a game has source "0" it's Default. Make this Int32.MaxValue for sorting purposes // If a game has source "0" it's Default. Make this Int32.MaxValue for sorting purposes
if (rom.Metadata.SourceID == 0) if (rom.SourceID == 0)
{ {
rom.Metadata.SourceID = Int32.MaxValue; rom.SourceID = Int32.MaxValue;
} }
temp.Add(rom); temp.Add(rom);

View File

@@ -370,27 +370,27 @@ namespace SabreTools
DatTools.Parse(_filepath, sysid, srcid, ref datdata, _logger); DatTools.Parse(_filepath, sysid, srcid, ref datdata, _logger);
// Sort inputted roms into games // Sort inputted roms into games
SortedDictionary<string, List<Rom>> sortable = new SortedDictionary<string, List<Rom>>(); SortedDictionary<string, List<DatItem>> sortable = new SortedDictionary<string, List<DatItem>>();
long count = 0; long count = 0;
foreach (List<Rom> roms in datdata.Files.Values) foreach (List<DatItem> roms in datdata.Files.Values)
{ {
List<Rom> newroms = roms; List<DatItem> newroms = roms;
if (datdata.MergeRoms) if (datdata.MergeRoms)
{ {
newroms = RomTools.Merge(newroms, _logger); newroms = DatItem.Merge(newroms, _logger);
} }
foreach (Rom rom in newroms) foreach (Rom rom in newroms)
{ {
count++; count++;
string key = rom.Metadata.SystemID.ToString().PadLeft(10, '0') + "-" + rom.Metadata.SourceID.ToString().PadLeft(10, '0') + "-" + rom.Machine.Name.ToLowerInvariant(); string key = rom.SystemID.ToString().PadLeft(10, '0') + "-" + rom.SourceID.ToString().PadLeft(10, '0') + "-" + rom.MachineName.ToLowerInvariant();
if (sortable.ContainsKey(key)) if (sortable.ContainsKey(key))
{ {
sortable[key].Add(rom); sortable[key].Add(rom);
} }
else else
{ {
List<Rom> temp = new List<Rom>(); List<DatItem> temp = new List<DatItem>();
temp.Add(rom); temp.Add(rom);
sortable.Add(key, temp); sortable.Add(key, temp);
} }
@@ -400,8 +400,8 @@ namespace SabreTools
// Loop over all roms, checking for adds // Loop over all roms, checking for adds
foreach (string key in sortable.Keys) foreach (string key in sortable.Keys)
{ {
List<Rom> roms = sortable[key]; List<DatItem> roms = sortable[key];
RomTools.Sort(ref roms, true); DatItem.Sort(ref roms, true);
long gameid = -1; long gameid = -1;
using (SqliteConnection dbc = new SqliteConnection(_connectionString)) using (SqliteConnection dbc = new SqliteConnection(_connectionString))
@@ -409,7 +409,7 @@ namespace SabreTools
dbc.Open(); dbc.Open();
// For each game, check for a new ID // For each game, check for a new ID
gameid = AddGame(sysid, roms[0].Machine.Name, srcid, dbc); gameid = AddGame(sysid, roms[0].MachineName, srcid, dbc);
foreach (Rom rom in roms) foreach (Rom rom in roms)
{ {
@@ -573,14 +573,14 @@ COMMIT;";
// WoD gets rid of anything past the first "(" or "[" as the name, we will do the same // WoD gets rid of anything past the first "(" or "[" as the name, we will do the same
string stripPattern = @"(([[(].*[\)\]] )?([^([]+))"; string stripPattern = @"(([[(].*[\)\]] )?([^([]+))";
Regex stripRegex = new Regex(stripPattern); Regex stripRegex = new Regex(stripPattern);
Match stripMatch = stripRegex.Match(rom.Machine.Name); Match stripMatch = stripRegex.Match(rom.MachineName);
rom.Machine.Name = stripMatch.Groups[1].Value; rom.MachineName = stripMatch.Groups[1].Value;
// Run the name through the filters to make sure that it's correct // Run the name through the filters to make sure that it's correct
rom.Machine.Name = Style.NormalizeChars(rom.Machine.Name); rom.MachineName = Style.NormalizeChars(rom.MachineName);
rom.Machine.Name = Style.RussianToLatin(rom.Machine.Name); rom.MachineName = Style.RussianToLatin(rom.MachineName);
rom.Machine.Name = Style.SearchPattern(rom.Machine.Name); rom.MachineName = Style.SearchPattern(rom.MachineName);
rom.Machine.Name = rom.Machine.Name.Trim(); rom.MachineName = rom.MachineName.Trim();
// Process the rom name // Process the rom name
@@ -629,11 +629,11 @@ COMMIT;";
query = @"BEGIN; query = @"BEGIN;
INSERT OR IGNORE INTO hashdata (hashid, key, value) VALUES " + INSERT OR IGNORE INTO hashdata (hashid, key, value) VALUES " +
"(" + hashid + ", 'name', '" + rom.Name.Replace("'", "''") + "'), " + "(" + hashid + ", 'name', '" + rom.Name.Replace("'", "''") + "'), " +
"(" + hashid + ", 'game', '" + rom.Machine.Name.Replace("'", "''") + "'), " + "(" + hashid + ", 'game', '" + rom.MachineName.Replace("'", "''") + "'), " +
"(" + hashid + ", 'type', '" + rom.Type + "'), " + "(" + hashid + ", 'type', '" + rom.Type + "'), " +
"(" + hashid + ", 'lastupdated', '" + date + @"'); "(" + hashid + ", 'lastupdated', '" + date + @"');
INSERT OR IGNORE INTO gamesystem (game, systemid) VALUES ('" + rom.Machine.Name.Replace("'", "''") + "', " + sysid + @"); INSERT OR IGNORE INTO gamesystem (game, systemid) VALUES ('" + rom.MachineName.Replace("'", "''") + "', " + sysid + @");
INSERT OR IGNORE INTO gamesource (game, sourceid) VALUES ('" + rom.Machine.Name.Replace("'", "''") + "', " + srcid + @"); INSERT OR IGNORE INTO gamesource (game, sourceid) VALUES ('" + rom.MachineName.Replace("'", "''") + "', " + srcid + @");
COMMIT;"; COMMIT;";
using (SqliteCommand slc = new SqliteCommand(query, dbc)) using (SqliteCommand slc = new SqliteCommand(query, dbc))

View File

@@ -76,7 +76,7 @@ namespace SabreTools.Helper
_cursorLeft = Console.CursorLeft; _cursorLeft = Console.CursorLeft;
_matched = new Dat _matched = new Dat
{ {
Files = new Dictionary<string, List<Rom>>(), Files = new Dictionary<string, List<DatItem>>(),
}; };
} }
@@ -145,7 +145,7 @@ namespace SabreTools.Helper
// Setup the fixdat // Setup the fixdat
_matched = (Dat)_datdata.CloneHeader(); _matched = (Dat)_datdata.CloneHeader();
_matched.Files = new Dictionary<string, List<Rom>>(); _matched.Files = new Dictionary<string, List<DatItem>>();
_matched.FileName = "fixDat_" + _matched.FileName; _matched.FileName = "fixDat_" + _matched.FileName;
_matched.Name = "fixDat_" + _matched.Name; _matched.Name = "fixDat_" + _matched.Name;
_matched.Description = "fixDat_" + _matched.Description; _matched.Description = "fixDat_" + _matched.Description;
@@ -153,12 +153,12 @@ namespace SabreTools.Helper
// Now that all files are parsed, get only files found in directory // Now that all files are parsed, get only files found in directory
bool found = false; bool found = false;
foreach (List<Rom> roms in _datdata.Files.Values) foreach (List<DatItem> roms in _datdata.Files.Values)
{ {
List<Rom> newroms = RomTools.Merge(roms, _logger); List<DatItem> newroms = DatItem.Merge(roms, _logger);
foreach (Rom rom in newroms) foreach (Rom rom in newroms)
{ {
if (rom.Metadata.SourceID == 99) if (rom.SourceID == 99)
{ {
found = true; found = true;
string key = rom.HashData.Size + "-" + rom.HashData.CRC; string key = rom.HashData.Size + "-" + rom.HashData.CRC;
@@ -168,7 +168,7 @@ namespace SabreTools.Helper
} }
else else
{ {
List<Rom> temp = new List<Rom>(); List<DatItem> temp = new List<DatItem>();
temp.Add(rom); temp.Add(rom);
_matched.Files.Add(key, temp); _matched.Files.Add(key, temp);
} }
@@ -343,7 +343,7 @@ namespace SabreTools.Helper
_logger.User("Getting source file information..."); _logger.User("Getting source file information...");
Dat matchdat = new Dat Dat matchdat = new Dat
{ {
Files = new Dictionary<string, List<Rom>>(), Files = new Dictionary<string, List<DatItem>>(),
}; };
foreach (string file in files) foreach (string file in files)
{ {
@@ -409,15 +409,15 @@ namespace SabreTools.Helper
#region Find all files to rebuild and bucket by game #region Find all files to rebuild and bucket by game
// Create a dictionary of from/to Rom mappings // Create a dictionary of from/to Rom mappings
Dictionary<Rom, Rom> toFromMap = new Dictionary<Rom, Rom>(); Dictionary<DatItem, DatItem> toFromMap = new Dictionary<DatItem, DatItem>();
// Now populate it // Now populate it
foreach (string key in matchdat.Files.Keys) foreach (string key in matchdat.Files.Keys)
{ {
foreach (Rom rom in matchdat.Files[key]) foreach (DatItem rom in matchdat.Files[key])
{ {
List<Rom> matched = RomTools.GetDuplicates(rom, _datdata, _logger, true); List<DatItem> matched = DatItem.GetDuplicates(rom, _datdata, _logger, true);
foreach (Rom match in matched) foreach (DatItem match in matched)
{ {
try try
{ {
@@ -429,7 +429,7 @@ namespace SabreTools.Helper
} }
// Then bucket the keys by game for better output // Then bucket the keys by game for better output
SortedDictionary<string, List<Rom>> keysByGame = DatTools.BucketByGame(toFromMap.Keys.ToList(), false, true, _logger); SortedDictionary<string, List<DatItem>> keysByGame = DatTools.BucketByGame(toFromMap.Keys.ToList(), false, true, _logger);
#endregion #endregion
@@ -467,7 +467,7 @@ namespace SabreTools.Helper
} }
// Otherwise, set the machine name as the full path to the file // Otherwise, set the machine name as the full path to the file
rom.Machine.Name = Path.GetDirectoryName(Path.GetFullPath(file)); rom.MachineName = Path.GetDirectoryName(Path.GetFullPath(file));
// Add the rom information to the Dat // Add the rom information to the Dat
string key = rom.HashData.Size + "-" + rom.HashData.CRC; string key = rom.HashData.Size + "-" + rom.HashData.CRC;
@@ -477,7 +477,7 @@ namespace SabreTools.Helper
} }
else else
{ {
List<Rom> temp = new List<Rom>(); List<DatItem> temp = new List<DatItem>();
temp.Add(rom); temp.Add(rom);
matchdat.Files.Add(key, temp); matchdat.Files.Add(key, temp);
} }
@@ -494,7 +494,7 @@ namespace SabreTools.Helper
Skippers.TransformStream(input, output, rule, _logger, false, true); Skippers.TransformStream(input, output, rule, _logger, false, true);
Rom romNH = FileTools.GetSingleStreamInfo(output); Rom romNH = FileTools.GetSingleStreamInfo(output);
romNH.Name = "HEAD::" + rom.Name; romNH.Name = "HEAD::" + rom.Name;
romNH.Machine.Name = rom.Machine.Name; romNH.MachineName = rom.MachineName;
// Add the rom information to the Dat // Add the rom information to the Dat
key = romNH.HashData.Size + "-" + romNH.HashData.CRC; key = romNH.HashData.Size + "-" + romNH.HashData.CRC;
@@ -504,7 +504,7 @@ namespace SabreTools.Helper
} }
else else
{ {
List<Rom> temp = new List<Rom>(); List<DatItem> temp = new List<DatItem>();
temp.Add(romNH); temp.Add(romNH);
matchdat.Files.Add(key, temp); matchdat.Files.Add(key, temp);
} }
@@ -548,7 +548,7 @@ namespace SabreTools.Helper
} }
// Try to find the matches to the file that was found // Try to find the matches to the file that was found
List<Rom> foundroms = RomTools.GetDuplicates(rom, _datdata, _logger); List<DatItem> foundroms = DatItem.GetDuplicates(rom, _datdata, _logger);
_logger.Log("File '" + input + "' had " + foundroms.Count + " matches in the DAT!"); _logger.Log("File '" + input + "' had " + foundroms.Count + " matches in the DAT!");
foreach (Rom found in foundroms) foreach (Rom found in foundroms)
{ {
@@ -562,7 +562,7 @@ namespace SabreTools.Helper
} }
else else
{ {
List<Rom> temp = new List<Rom>(); List<DatItem> temp = new List<DatItem>();
temp.Add(found); temp.Add(found);
_matched.Files.Add(key, temp); _matched.Files.Add(key, temp);
} }
@@ -570,7 +570,7 @@ namespace SabreTools.Helper
if (_toFolder) if (_toFolder)
{ {
// Copy file to output directory // Copy file to output directory
string gamedir = Path.Combine(_outDir, found.Machine.Name); string gamedir = Path.Combine(_outDir, found.MachineName);
if (!Directory.Exists(gamedir)) if (!Directory.Exists(gamedir))
{ {
Directory.CreateDirectory(gamedir); Directory.CreateDirectory(gamedir);
@@ -618,7 +618,7 @@ namespace SabreTools.Helper
} }
// Try to find the matches to the file that was found // Try to find the matches to the file that was found
List<Rom> founddroms = RomTools.GetDuplicates(drom, _datdata, _logger); List<DatItem> founddroms = DatItem.GetDuplicates(drom, _datdata, _logger);
_logger.Log("File '" + newinput + "' had " + founddroms.Count + " matches in the DAT!"); _logger.Log("File '" + newinput + "' had " + founddroms.Count + " matches in the DAT!");
foreach (Rom found in founddroms) foreach (Rom found in founddroms)
{ {
@@ -630,7 +630,7 @@ namespace SabreTools.Helper
} }
else else
{ {
List<Rom> temp = new List<Rom>(); List<DatItem> temp = new List<DatItem>();
temp.Add(found); temp.Add(found);
_matched.Files.Add(key, temp); _matched.Files.Add(key, temp);
} }
@@ -641,7 +641,7 @@ namespace SabreTools.Helper
if (_toFolder) if (_toFolder)
{ {
// Copy file to output directory // Copy file to output directory
string gamedir = Path.Combine(_outDir, found.Machine.Name); string gamedir = Path.Combine(_outDir, found.MachineName);
if (!Directory.Exists(gamedir)) if (!Directory.Exists(gamedir))
{ {
Directory.CreateDirectory(gamedir); Directory.CreateDirectory(gamedir);
@@ -683,7 +683,7 @@ namespace SabreTools.Helper
} }
else else
{ {
List<Rom> temp = new List<Rom>(); List<DatItem> temp = new List<DatItem>();
temp.Add(newfound); temp.Add(newfound);
_matched.Files.Add(key, temp); _matched.Files.Add(key, temp);
} }
@@ -691,7 +691,7 @@ namespace SabreTools.Helper
if (_toFolder) if (_toFolder)
{ {
// Copy file to output directory // Copy file to output directory
string gamedir = Path.Combine(_outDir, found.Machine.Name); string gamedir = Path.Combine(_outDir, found.MachineName);
if (!Directory.Exists(gamedir)) if (!Directory.Exists(gamedir))
{ {
Directory.CreateDirectory(gamedir); Directory.CreateDirectory(gamedir);
@@ -750,7 +750,7 @@ namespace SabreTools.Helper
foreach (Rom rom in internalRomData) foreach (Rom rom in internalRomData)
{ {
// Try to find the matches to the file that was found // Try to find the matches to the file that was found
List<Rom> foundroms = RomTools.GetDuplicates(rom, _datdata, _logger); List<DatItem> foundroms = DatItem.GetDuplicates(rom, _datdata, _logger);
_logger.Log("File '" + rom.Name + "' had " + foundroms.Count + " matches in the DAT!"); _logger.Log("File '" + rom.Name + "' had " + foundroms.Count + " matches in the DAT!");
foreach (Rom found in foundroms) foreach (Rom found in foundroms)
{ {
@@ -762,7 +762,7 @@ namespace SabreTools.Helper
} }
else else
{ {
List<Rom> temp = new List<Rom>(); List<DatItem> temp = new List<DatItem>();
temp.Add(found); temp.Add(found);
_matched.Files.Add(key, temp); _matched.Files.Add(key, temp);
} }
@@ -774,7 +774,7 @@ namespace SabreTools.Helper
string outfile = FileTools.ExtractSingleItemFromArchive(input, rom.Name, _tempDir, _logger); string outfile = FileTools.ExtractSingleItemFromArchive(input, rom.Name, _tempDir, _logger);
if (File.Exists(outfile)) if (File.Exists(outfile))
{ {
string gamedir = Path.Combine(_outDir, found.Machine.Name); string gamedir = Path.Combine(_outDir, found.MachineName);
if (!Directory.Exists(gamedir)) if (!Directory.Exists(gamedir))
{ {
Directory.CreateDirectory(gamedir); Directory.CreateDirectory(gamedir);
@@ -888,7 +888,7 @@ namespace SabreTools.Helper
} }
// Now process the inputs (assumed that it's archived sets as of right now // Now process the inputs (assumed that it's archived sets as of right now
Dictionary<string, List<Rom>> scanned = new Dictionary<string, List<Rom>>(); Dictionary<string, List<DatItem>> scanned = new Dictionary<string, List<DatItem>>();
foreach (string archive in Directory.EnumerateFiles(_outDir, "*", SearchOption.AllDirectories)) foreach (string archive in Directory.EnumerateFiles(_outDir, "*", SearchOption.AllDirectories))
{ {
// If we are in quickscan, get the list of roms that way // If we are in quickscan, get the list of roms that way
@@ -921,7 +921,7 @@ namespace SabreTools.Helper
} }
else else
{ {
List<Rom> templist = new List<Rom>(); List<DatItem> templist = new List<DatItem>();
templist.Add(rom); templist.Add(rom);
scanned.Add(key, templist); scanned.Add(key, templist);
} }
@@ -935,7 +935,7 @@ namespace SabreTools.Helper
} }
// Now that we have all of the from DAT and from folder roms, we try to match them, removing the perfect matches // Now that we have all of the from DAT and from folder roms, we try to match them, removing the perfect matches
Dictionary<string, List<Rom>> remove = new Dictionary<string, List<Rom>>(); Dictionary<string, List<DatItem>> remove = new Dictionary<string, List<DatItem>>();
foreach (string key in scanned.Keys) foreach (string key in scanned.Keys)
{ {
// If the key doesn't even exist in the DAT, then mark the entire key for removal // If the key doesn't even exist in the DAT, then mark the entire key for removal
@@ -953,8 +953,8 @@ namespace SabreTools.Helper
// Otherwise check each of the values individually // Otherwise check each of the values individually
else else
{ {
List<Rom> romsList = _datdata.Files[key]; List<DatItem> romsList = _datdata.Files[key];
List<Rom> scannedList = scanned[key]; List<DatItem> scannedList = scanned[key];
foreach (Rom rom in scannedList) foreach (Rom rom in scannedList)
{ {
if (!romsList.Contains(rom)) if (!romsList.Contains(rom))
@@ -965,7 +965,7 @@ namespace SabreTools.Helper
} }
else else
{ {
List<Rom> templist = new List<Rom>(); List<DatItem> templist = new List<DatItem>();
templist.Add(rom); templist.Add(rom);
remove.Add(key, templist); remove.Add(key, templist);
} }

View File

@@ -49,7 +49,7 @@ namespace SabreTools.Helper
List<String> games = new List<String>(); List<String> games = new List<String>();
Dat datdata = new Dat(); Dat datdata = new Dat();
DatTools.Parse(filename, 0, 0, ref datdata, _logger); DatTools.Parse(filename, 0, 0, ref datdata, _logger);
SortedDictionary<string, List<Rom>> newroms = DatTools.BucketByGame(datdata.Files, false, true, _logger, false); SortedDictionary<string, List<DatItem>> newroms = DatTools.BucketByGame(datdata.Files, false, true, _logger, false);
// Output single DAT stats (if asked) // Output single DAT stats (if asked)
if (_single) if (_single)
@@ -116,7 +116,7 @@ Please check the log folder if the stats scrolled offscreen");
datdata.NodumpCount = 0; datdata.NodumpCount = 0;
// Loop through and add // Loop through and add
foreach (List<Rom> roms in datdata.Files.Values) foreach (List<DatItem> roms in datdata.Files.Values)
{ {
foreach (Rom rom in roms) foreach (Rom rom in roms)
{ {
@@ -131,7 +131,7 @@ Please check the log folder if the stats scrolled offscreen");
} }
} }
SortedDictionary<string, List<Rom>> newroms = DatTools.BucketByGame(datdata.Files, false, true, logger, false); SortedDictionary<string, List<DatItem>> newroms = DatTools.BucketByGame(datdata.Files, false, true, logger, false);
if (datdata.TotalSize < 0) if (datdata.TotalSize < 0)
{ {
datdata.TotalSize = Int64.MaxValue + datdata.TotalSize; datdata.TotalSize = Int64.MaxValue + datdata.TotalSize;

View File

@@ -101,11 +101,18 @@
<Compile Include="External\Zlib\ZlibConstants.cs" /> <Compile Include="External\Zlib\ZlibConstants.cs" />
<Compile Include="External\Zlib\ZlibStream.cs" /> <Compile Include="External\Zlib\ZlibStream.cs" />
<Compile Include="Objects\DATFromDir.cs" /> <Compile Include="Objects\DATFromDir.cs" />
<Compile Include="Objects\DatObjects\Archive.cs" />
<Compile Include="Objects\DatObjects\BiosSet.cs" />
<Compile Include="Objects\DatObjects\DatItem.cs" />
<Compile Include="Objects\DatObjects\Disk.cs" />
<Compile Include="Objects\DatObjects\Release.cs" />
<Compile Include="Objects\DatObjects\Sample.cs" />
<Compile Include="Objects\Generate.cs" /> <Compile Include="Objects\Generate.cs" />
<Compile Include="Objects\GenerateTwo.cs" /> <Compile Include="Objects\GenerateTwo.cs" />
<Compile Include="Objects\Headerer.cs" /> <Compile Include="Objects\Headerer.cs" />
<Compile Include="Objects\Import.cs" /> <Compile Include="Objects\Import.cs" />
<Compile Include="Objects\ImportTwo.cs" /> <Compile Include="Objects\ImportTwo.cs" />
<Compile Include="Objects\DatObjects\Rom.cs" />
<Compile Include="Objects\SimpleSort.cs" /> <Compile Include="Objects\SimpleSort.cs" />
<Compile Include="Objects\ZipFileEntry.cs" /> <Compile Include="Objects\ZipFileEntry.cs" />
<Compile Include="Objects\ZipFile.cs" /> <Compile Include="Objects\ZipFile.cs" />
@@ -130,7 +137,6 @@
<DependentUpon>Resources.fr-FR.resx</DependentUpon> <DependentUpon>Resources.fr-FR.resx</DependentUpon>
</Compile> </Compile>
<Compile Include="Skippers\Skippers.cs" /> <Compile Include="Skippers\Skippers.cs" />
<Compile Include="Tools\DatToolsHash.cs" />
<Compile Include="Tools\FileTools.cs" /> <Compile Include="Tools\FileTools.cs" />
<Compile Include="Tools\DBTools.cs" /> <Compile Include="Tools\DBTools.cs" />
<Compile Include="Data\Enums.cs" /> <Compile Include="Data\Enums.cs" />
@@ -142,8 +148,6 @@
<Compile Include="Tools\DatTools.cs" /> <Compile Include="Tools\DatTools.cs" />
<Compile Include="Data\Structs.cs" /> <Compile Include="Data\Structs.cs" />
<Compile Include="Tools\FileToolsHash.cs" /> <Compile Include="Tools\FileToolsHash.cs" />
<Compile Include="Tools\RomTools.cs" />
<Compile Include="Tools\RomToolsHash.cs" />
<Compile Include="Objects\Stats.cs" /> <Compile Include="Objects\Stats.cs" />
<Compile Include="Tools\Style.cs" /> <Compile Include="Tools\Style.cs" />
<Compile Include="Data\Build.cs" /> <Compile Include="Data\Build.cs" />

View File

@@ -10,7 +10,7 @@ namespace SabreTools.Helper
public class Skippers public class Skippers
{ {
// Local paths // Local paths
public const string Path = "Skippers"; public const string LocalPath = "Skippers";
// Header skippers represented by a list of skipper objects // Header skippers represented by a list of skipper objects
private static List<Skipper> _list; private static List<Skipper> _list;
@@ -56,9 +56,9 @@ namespace SabreTools.Helper
_list = new List<Skipper>(); _list = new List<Skipper>();
} }
foreach (string skipperFile in Directory.EnumerateFiles(Path, "*", SearchOption.AllDirectories)) foreach (string skipperFile in Directory.EnumerateFiles(LocalPath, "*", SearchOption.AllDirectories))
{ {
_list.Add(PopulateSkippersHelper(System.IO.Path.GetFullPath(skipperFile))); _list.Add(PopulateSkippersHelper(Path.GetFullPath(skipperFile)));
} }
} }
@@ -527,9 +527,9 @@ namespace SabreTools.Helper
} }
// Create the output directory if it doesn't already // Create the output directory if it doesn't already
if (!Directory.Exists(System.IO.Path.GetDirectoryName(output))) if (!Directory.Exists(Path.GetDirectoryName(output)))
{ {
Directory.CreateDirectory(System.IO.Path.GetDirectoryName(output)); Directory.CreateDirectory(Path.GetDirectoryName(output));
} }
logger.User("Attempting to apply rule to '" + input + "'"); logger.User("Attempting to apply rule to '" + input + "'");
@@ -725,7 +725,7 @@ namespace SabreTools.Helper
XmlDocument doc = new XmlDocument(); XmlDocument doc = new XmlDocument();
try try
{ {
doc.LoadXml(File.ReadAllText(System.IO.Path.Combine(Path, skipper + ".xml"))); doc.LoadXml(File.ReadAllText(Path.Combine(LocalPath, skipper + ".xml")));
} }
catch (XmlException ex) catch (XmlException ex)
{ {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -63,7 +63,7 @@ namespace SabreTools.Helper
} }
// Get the output archive name from the first rebuild rom // Get the output archive name from the first rebuild rom
string archiveFileName = Path.Combine(outDir, roms[0].Machine.Name + ".zip"); string archiveFileName = Path.Combine(outDir, roms[0].MachineName + ".zip");
// First, open the archive // First, open the archive
ZipArchive outarchive = null; ZipArchive outarchive = null;
@@ -172,7 +172,7 @@ namespace SabreTools.Helper
} }
// Get the output archive name from the first rebuild rom // Get the output archive name from the first rebuild rom
string archiveFileName = Path.Combine(outDir, roms[0].Machine.Name + ".zip"); string archiveFileName = Path.Combine(outDir, roms[0].MachineName + ".zip");
// Set internal variables // Set internal variables
Stream writeStream = null; Stream writeStream = null;
@@ -760,18 +760,21 @@ namespace SabreTools.Helper
} }
crc.Update(buffer, 0, 0); crc.Update(buffer, 0, 0);
rom.HashData.CRC = crc.Value.ToString("X8").ToLowerInvariant(); Hash tempHash = new Hash();
tempHash.CRC = crc.Value.ToString("X8").ToLowerInvariant();
if (!noMD5) if (!noMD5)
{ {
md5.TransformFinalBlock(buffer, 0, 0); md5.TransformFinalBlock(buffer, 0, 0);
rom.HashData.MD5 = BitConverter.ToString(md5.Hash).Replace("-", "").ToLowerInvariant(); tempHash.MD5 = BitConverter.ToString(md5.Hash).Replace("-", "").ToLowerInvariant();
} }
if (!noSHA1) if (!noSHA1)
{ {
sha1.TransformFinalBlock(buffer, 0, 0); sha1.TransformFinalBlock(buffer, 0, 0);
rom.HashData.SHA1 = BitConverter.ToString(sha1.Hash).Replace("-", "").ToLowerInvariant(); tempHash.SHA1 = BitConverter.ToString(sha1.Hash).Replace("-", "").ToLowerInvariant();
} }
rom.HashData = tempHash;
} }
} }
catch (IOException) catch (IOException)
@@ -860,10 +863,7 @@ namespace SabreTools.Helper
{ {
Type = ItemType.Rom, Type = ItemType.Rom,
Name = reader.Entry.Key, Name = reader.Entry.Key,
Machine = new Machine MachineName = gamename,
{
Name = gamename,
},
HashData = new Hash HashData = new Hash
{ {
Size = (size == 0 ? reader.Entry.Size : size), Size = (size == 0 ? reader.Entry.Size : size),
@@ -948,10 +948,7 @@ namespace SabreTools.Helper
Rom rom = new Rom Rom rom = new Rom
{ {
Type = ItemType.Rom, Type = ItemType.Rom,
Machine = new Machine MachineName = Path.GetFileNameWithoutExtension(input).ToLowerInvariant(),
{
Name = Path.GetFileNameWithoutExtension(input).ToLowerInvariant(),
},
Name = Path.GetFileNameWithoutExtension(input).ToLowerInvariant(), Name = Path.GetFileNameWithoutExtension(input).ToLowerInvariant(),
HashData = new Hash HashData = new Hash
{ {

View File

@@ -1,505 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace SabreTools.Helper
{
public class RomTools
{
#region Rom-based sorting and merging
/// <summary>
/// Determine if a rom should be included based on filters
/// </summary>
/// <param name="romdata">User supplied Rom to check</param>
/// <param name="gamename">Name of the game to match (can use asterisk-partials)</param>
/// <param name="romname">Name of the rom to match (can use asterisk-partials)</param>
/// <param name="romtype">Type of the rom to match</param>
/// <param name="sgt">Find roms greater than or equal to this size</param>
/// <param name="slt">Find roms less than or equal to this size</param>
/// <param name="seq">Find roms equal to this size</param>
/// <param name="crc">CRC of the rom to match (can use asterisk-partials)</param>
/// <param name="md5">MD5 of the rom to match (can use asterisk-partials)</param>
/// <param name="sha1">SHA-1 of the rom to match (can use asterisk-partials)</param>
/// <param name="nodump">Select roms with nodump status as follows: null (match all), true (match Nodump only), false (exclude Nodump)</param>
/// <param name="logger">Logging object for console and file output</param>
/// <returns>Returns true if it should be included, false otherwise</returns>
public static bool Filter(Rom romdata, string gamename, string romname, string romtype, long sgt,
long slt, long seq, string crc, string md5, string sha1, bool? nodump, Logger logger)
{
// Filter on nodump status
if (nodump == true && !romdata.Nodump)
{
return false;
}
if (nodump == false && romdata.Nodump)
{
return false;
}
// Filter on game name
if (!String.IsNullOrEmpty(gamename))
{
if (gamename.StartsWith("*") && gamename.EndsWith("*"))
{
if (!romdata.Machine.Name.ToLowerInvariant().Contains(gamename.ToLowerInvariant().Replace("*", "")))
{
return false;
}
}
else if (gamename.StartsWith("*"))
{
if (!romdata.Machine.Name.EndsWith(gamename.Replace("*", ""), StringComparison.InvariantCultureIgnoreCase))
{
return false;
}
}
else if (gamename.EndsWith("*"))
{
if (!romdata.Machine.Name.StartsWith(gamename.Replace("*", ""), StringComparison.InvariantCultureIgnoreCase))
{
return false;
}
}
else
{
if (!String.Equals(romdata.Machine.Name, gamename, StringComparison.InvariantCultureIgnoreCase))
{
return false;
}
}
}
// Filter on rom name
if (!String.IsNullOrEmpty(romname))
{
if (romname.StartsWith("*") && romname.EndsWith("*"))
{
if (!romdata.Name.ToLowerInvariant().Contains(romname.ToLowerInvariant().Replace("*", "")))
{
return false;
}
}
else if (romname.StartsWith("*"))
{
if (!romdata.Name.EndsWith(romname.Replace("*", ""), StringComparison.InvariantCultureIgnoreCase))
{
return false;
}
}
else if (romname.EndsWith("*"))
{
if (!romdata.Name.StartsWith(romname.Replace("*", ""), StringComparison.InvariantCultureIgnoreCase))
{
return false;
}
}
else
{
if (!String.Equals(romdata.Name, romname, StringComparison.InvariantCultureIgnoreCase))
{
return false;
}
}
}
// Filter on rom type
if (String.IsNullOrEmpty(romtype) && romdata.Type != ItemType.Rom && romdata.Type != ItemType.Disk)
{
return false;
}
if (!String.IsNullOrEmpty(romtype) && !String.Equals(romdata.Type.ToString(), romtype, StringComparison.InvariantCultureIgnoreCase))
{
return false;
}
// Filter on rom size
if (seq != -1 && romdata.HashData.Size != seq)
{
return false;
}
else
{
if (sgt != -1 && romdata.HashData.Size < sgt)
{
return false;
}
if (slt != -1 && romdata.HashData.Size > slt)
{
return false;
}
}
// Filter on crc
if (!String.IsNullOrEmpty(crc))
{
if (crc.StartsWith("*") && crc.EndsWith("*"))
{
if (!romdata.HashData.CRC.ToLowerInvariant().Contains(crc.ToLowerInvariant().Replace("*", "")))
{
return false;
}
}
else if (crc.StartsWith("*"))
{
if (!romdata.HashData.CRC.EndsWith(crc.Replace("*", ""), StringComparison.InvariantCultureIgnoreCase))
{
return false;
}
}
else if (crc.EndsWith("*"))
{
if (!romdata.HashData.CRC.StartsWith(crc.Replace("*", ""), StringComparison.InvariantCultureIgnoreCase))
{
return false;
}
}
else
{
if (!String.Equals(romdata.HashData.CRC, crc, StringComparison.InvariantCultureIgnoreCase))
{
return false;
}
}
}
// Filter on md5
if (!String.IsNullOrEmpty(md5))
{
if (md5.StartsWith("*") && md5.EndsWith("*"))
{
if (!romdata.HashData.MD5.ToLowerInvariant().Contains(md5.ToLowerInvariant().Replace("*", "")))
{
return false;
}
}
else if (md5.StartsWith("*"))
{
if (!romdata.HashData.MD5.EndsWith(md5.Replace("*", ""), StringComparison.InvariantCultureIgnoreCase))
{
return false;
}
}
else if (md5.EndsWith("*"))
{
if (!romdata.HashData.MD5.StartsWith(md5.Replace("*", ""), StringComparison.InvariantCultureIgnoreCase))
{
return false;
}
}
else
{
if (!String.Equals(romdata.HashData.MD5, md5, StringComparison.InvariantCultureIgnoreCase))
{
return false;
}
}
}
// Filter on sha1
if (!String.IsNullOrEmpty(sha1))
{
if (sha1.StartsWith("*") && sha1.EndsWith("*"))
{
if (!romdata.HashData.SHA1.ToLowerInvariant().Contains(sha1.ToLowerInvariant().Replace("*", "")))
{
return false;
}
}
else if (sha1.StartsWith("*"))
{
if (!romdata.HashData.SHA1.EndsWith(sha1.Replace("*", ""), StringComparison.InvariantCultureIgnoreCase))
{
return false;
}
}
else if (sha1.EndsWith("*"))
{
if (!romdata.HashData.SHA1.StartsWith(sha1.Replace("*", ""), StringComparison.InvariantCultureIgnoreCase))
{
return false;
}
}
else
{
if (!String.Equals(romdata.HashData.SHA1, sha1, StringComparison.InvariantCultureIgnoreCase))
{
return false;
}
}
}
return true;
}
/// <summary>
/// Merge an arbitrary set of ROMs based on the supplied information
/// </summary>
/// <param name="inroms">List of RomData objects representing the roms to be merged</param>
/// <param name="logger">Logger object for console and/or file output</param>
/// <returns>A List of RomData objects representing the merged roms</returns>
public static List<Rom> Merge(List<Rom> inroms, Logger logger)
{
// Check for null or blank roms first
if (inroms == null || inroms.Count == 0)
{
return new List<Rom>();
}
// Create output list
List<Rom> outroms = new List<Rom>();
// Then deduplicate them by checking to see if data matches previous saved roms
foreach (Rom rom in inroms)
{
// If it's a nodump, add and skip
if (rom.Nodump)
{
outroms.Add(rom);
continue;
}
// If it's the first rom in the list, don't touch it
if (outroms.Count != 0)
{
// Check if the rom is a duplicate
DupeType dupetype = DupeType.None;
Rom savedrom = new Rom();
int pos = -1;
for (int i = 0; i < outroms.Count; i++)
{
Rom lastrom = outroms[i];
// Get the duplicate status
dupetype = GetDuplicateStatus(rom, lastrom, logger);
// If it's a duplicate, skip adding it to the output but add any missing information
if (dupetype != DupeType.None)
{
savedrom = lastrom;
pos = i;
savedrom.HashData.CRC = (String.IsNullOrEmpty(savedrom.HashData.CRC) && !String.IsNullOrEmpty(rom.HashData.CRC) ? rom.HashData.CRC : savedrom.HashData.CRC);
savedrom.HashData.MD5 = (String.IsNullOrEmpty(savedrom.HashData.MD5) && !String.IsNullOrEmpty(rom.HashData.MD5) ? rom.HashData.MD5 : savedrom.HashData.MD5);
savedrom.HashData.SHA1 = (String.IsNullOrEmpty(savedrom.HashData.SHA1) && !String.IsNullOrEmpty(rom.HashData.SHA1) ? rom.HashData.SHA1 : savedrom.HashData.SHA1);
savedrom.Dupe = dupetype;
// If the current system has a lower ID than the previous, set the system accordingly
if (rom.Metadata.SystemID < savedrom.Metadata.SystemID)
{
savedrom.Metadata.SystemID = rom.Metadata.SystemID;
savedrom.Metadata.System = rom.Metadata.System;
savedrom.Machine.Name = rom.Machine.Name;
savedrom.Name = rom.Name;
}
// If the current source has a lower ID than the previous, set the source accordingly
if (rom.Metadata.SourceID < savedrom.Metadata.SourceID)
{
savedrom.Metadata.SourceID = rom.Metadata.SourceID;
savedrom.Metadata.Source = rom.Metadata.Source;
savedrom.Machine.Name = rom.Machine.Name;
savedrom.Name = rom.Name;
}
break;
}
}
// If no duplicate is found, add it to the list
if (dupetype == DupeType.None)
{
outroms.Add(rom);
}
// Otherwise, if a new rom information is found, add that
else
{
outroms.RemoveAt(pos);
outroms.Insert(pos, savedrom);
}
}
else
{
outroms.Add(rom);
}
}
// Then return the result
return outroms;
}
/// <summary>
/// List all duplicates found in a DAT based on a rom
/// </summary>
/// <param name="lastrom">Rom to use as a base</param>
/// <param name="datdata">DAT to match against</param>
/// <param name="logger">Logger object for console and/or file output</param>
/// <param name="remove">True to remove matched roms from the input, false otherwise (default)</param>
/// <returns>List of matched RomData objects</returns>
public static List<Rom> GetDuplicates(Rom lastrom, Dat datdata, Logger logger, bool remove = false)
{
List<Rom> output = new List<Rom>();
// Check for an empty rom list first
if (datdata.Files == null || datdata.Files.Count == 0)
{
return output;
}
// Try to find duplicates
List<string> keys = datdata.Files.Keys.ToList();
foreach (string key in keys)
{
List<Rom> roms = datdata.Files[key];
List<Rom> left = new List<Rom>();
foreach (Rom rom in roms)
{
if (IsDuplicate(rom, lastrom, logger))
{
output.Add(rom);
}
else
{
left.Add(rom);
}
}
// If we're in removal mode, replace the list with the new one
if (remove)
{
datdata.Files[key] = left;
}
}
return output;
}
/// <summary>
/// Determine if a file is a duplicate using partial matching logic
/// </summary>
/// <param name="rom">Rom to check for duplicate status</param>
/// <param name="lastrom">Rom to use as a baseline</param>
/// <param name="logger">Logger object for console and/or file output</param>
/// <returns>True if the roms are duplicates, false otherwise</returns>
public static bool IsDuplicate(Rom rom, Rom lastrom, Logger logger)
{
bool dupefound = rom.Equals(lastrom);
// More wonderful SHA-1 logging that has to be done
if (rom.HashData.SHA1 == lastrom.HashData.SHA1 && rom.HashData.Size != lastrom.HashData.Size)
{
logger.User("SHA-1 mismatch - Hash: " + rom.HashData.SHA1);
}
return dupefound;
}
/// <summary>
/// Return the duplicate status of two roms
/// </summary>
/// <param name="rom">Current rom to check</param>
/// <param name="lastrom">Last rom to check against</param>
/// <param name="logger">Logger object for console and/or file output</param>
/// <returns>The DupeType corresponding to the relationship between the two</returns>
public static DupeType GetDuplicateStatus(Rom rom, Rom lastrom, Logger logger)
{
DupeType output = DupeType.None;
// If we don't have a duplicate at all, return none
if (!IsDuplicate(rom, lastrom, logger))
{
return output;
}
// If the duplicate is external already or should be, set it
if (lastrom.Dupe >= DupeType.ExternalHash || lastrom.Metadata.SystemID != rom.Metadata.SystemID || lastrom.Metadata.SourceID != rom.Metadata.SourceID)
{
if (lastrom.Machine.Name == rom.Machine.Name && lastrom.Name == rom.Name)
{
output = DupeType.ExternalAll;
}
else
{
output = DupeType.ExternalHash;
}
}
// Otherwise, it's considered an internal dupe
else
{
if (lastrom.Machine.Name == rom.Machine.Name && lastrom.Name == rom.Name)
{
output = DupeType.InternalAll;
}
else
{
output = DupeType.InternalHash;
}
}
return output;
}
/// <summary>
/// Sort a list of RomData objects by SystemID, SourceID, Game, and Name (in order)
/// </summary>
/// <param name="roms">List of RomData objects representing the roms to be sorted</param>
/// <param name="norename">True if files are not renamed, false otherwise</param>
/// <returns>True if it sorted correctly, false otherwise</returns>
public static bool Sort(ref List<Rom> roms, bool norename)
{
try
{
roms.Sort(delegate (Rom x, Rom y)
{
if (x.Metadata.SystemID == y.Metadata.SystemID)
{
if (x.Metadata.SourceID == y.Metadata.SourceID)
{
if (x.Machine.Name == y.Machine.Name)
{
if ((x.Type == ItemType.Rom || x.Type == ItemType.Disk) && (y.Type == ItemType.Rom || y.Type == ItemType.Disk))
{
if (Path.GetDirectoryName(x.Name) == Path.GetDirectoryName(y.Name))
{
return Style.CompareNumeric(Path.GetFileName(x.Name), Path.GetFileName(y.Name));
}
return Style.CompareNumeric(Path.GetDirectoryName(x.Name), Path.GetDirectoryName(y.Name));
}
else if ((x.Type == ItemType.Rom || x.Type == ItemType.Disk) && (y.Type != ItemType.Rom && y.Type != ItemType.Disk))
{
return -1;
}
else if ((x.Type != ItemType.Rom && x.Type != ItemType.Disk) && (y.Type == ItemType.Rom || y.Type == ItemType.Disk))
{
return 1;
}
else
{
if (Path.GetDirectoryName(x.Name) == Path.GetDirectoryName(y.Name))
{
return Style.CompareNumeric(Path.GetFileName(x.Name), Path.GetFileName(y.Name));
}
return Style.CompareNumeric(Path.GetDirectoryName(x.Name), Path.GetDirectoryName(y.Name));
}
}
return Style.CompareNumeric(x.Machine.Name, y.Machine.Name);
}
return (norename ? Style.CompareNumeric(x.Machine.Name, y.Machine.Name) : x.Metadata.SourceID - y.Metadata.SourceID);
}
return (norename ? Style.CompareNumeric(x.Machine.Name, y.Machine.Name) : x.Metadata.SystemID - y.Metadata.SystemID);
});
return true;
}
catch (Exception)
{
// Absorb the error
return false;
}
}
#endregion
}
}

View File

@@ -1,225 +0,0 @@
using System.Collections.Generic;
namespace SabreTools.Helper
{
public class RomToolsHash
{
#region HashData-based sorting and merging
/// <summary>
/// Merge an arbitrary set of ROMs based on the supplied information
/// </summary>
/// <param name="inhashes">List of HashData objects representing the roms to be merged</param>
/// <param name="logger">Logger object for console and/or file output</param>
/// <returns>A List of HashData objects representing the merged roms</returns>
public static List<HashData> Merge(List<HashData> inhashes, Logger logger)
{
// Create output list
List<HashData> outroms = new List<HashData>();
// Check for null or blank roms first
if (inhashes == null || inhashes.Count == 0)
{
return outroms;
}
// Then deduplicate them by checking to see if data matches previous saved roms
foreach (HashData hash in inhashes)
{
// If it's a nodump, add and skip
if (hash.Roms[0].Nodump)
{
outroms.Add(hash);
continue;
}
// If it's the first rom in the list, don't touch it
if (outroms.Count != 0)
{
// Check if the rom is a duplicate
DupeType dupetype = DupeType.None;
HashData savedHash = new HashData();
int pos = -1;
for (int i = 0; i < outroms.Count; i++)
{
HashData lastrom = outroms[i];
RomData savedRom = savedHash.Roms[0];
MachineData savedMachine = savedRom.Machine;
// Get the duplicate status
dupetype = GetDuplicateStatus(hash, lastrom, logger);
// If it's a duplicate, skip adding it to the output but add any missing information
if (dupetype != DupeType.None)
{
savedHash = lastrom;
pos = i;
savedHash.CRC = (savedHash.CRC == null && hash.CRC != null ? hash.CRC : savedHash.CRC);
savedHash.MD5 = (savedHash.MD5 == null && hash.MD5 != null ? hash.MD5 : savedHash.MD5);
savedHash.SHA1 = (savedHash.SHA1 == null && hash.SHA1 != null ? hash.SHA1 : savedHash.SHA1);
savedRom.DupeType = dupetype;
// If the current system has a lower ID than the previous, set the system accordingly
if (hash.Roms[0].Machine.SystemID < savedMachine.SystemID)
{
savedMachine.SystemID = hash.Roms[0].Machine.SystemID;
savedMachine.System = hash.Roms[0].Machine.System;
savedMachine.Name = hash.Roms[0].Machine.Name;
savedRom.Name = hash.Roms[0].Name;
}
// If the current source has a lower ID than the previous, set the source accordingly
if (hash.Roms[0].Machine.SourceID < savedMachine.SourceID)
{
savedMachine.SourceID = hash.Roms[0].Machine.SourceID;
savedMachine.Source = hash.Roms[0].Machine.Source;
savedMachine.Name = hash.Roms[0].Machine.Name;
savedRom.Name = hash.Roms[0].Name;
}
break;
}
}
// If no duplicate is found, add it to the list
if (dupetype == DupeType.None)
{
outroms.Add(hash);
}
// Otherwise, if a new rom information is found, add that
else
{
outroms.RemoveAt(pos);
outroms.Insert(pos, savedHash);
}
}
else
{
outroms.Add(hash);
}
}
// Then return the result
return outroms;
}
/*
/// <summary>
/// List all duplicates found in a DAT based on a rom
/// </summary>
/// <param name="lastrom">Hash to use as a base</param>
/// <param name="datdata">DAT to match against</param>
/// <param name="logger">Logger object for console and/or file output</param>
/// <param name="remove">True to remove matched roms from the input, false otherwise (default)</param>
/// <returns>List of matched HashData objects</returns>
public static List<HashData> GetDuplicates(HashData lastrom, DatData datdata, Logger logger, bool remove = false)
{
List<HashData> output = new List<HashData>();
// Check for an empty rom list first
if (datdata.Hashes == null || datdata.Hashes.Count == 0)
{
return output;
}
// Try to find duplicates
for (int i = 0; i < datdata.Hashes.Count; i++)
{
List<Rom> roms = datdata.Files[key];
List<Rom> left = new List<Rom>();
foreach (Rom rom in roms)
{
if (IsDuplicate(rom, lastrom, logger))
{
output.Add(rom);
}
else
{
left.Add(rom);
}
}
// If we're in removal mode, replace the list with the new one
if (remove)
{
datdata.Files[key] = left;
}
}
return output;
}
*/
/// <summary>
/// Determine if a file is a duplicate using partial matching logic
/// </summary>
/// <param name="hash">Hash to check for duplicate status</param>
/// <param name="lastHash">Hash to use as a baseline</param>
/// <param name="logger">Logger object for console and/or file output</param>
/// <returns>True if the hashes are duplicates, false otherwise</returns>
public static bool IsDuplicate(HashData hash, int hashIndex, HashData lastHash, int lastHashIndex, Logger logger)
{
bool dupefound = hash.Equals(lastHash);
// More wonderful SHA-1 logging that has to be done
if (hash.SHA1 == lastHash.SHA1 && hash.Size != lastHash.Size)
{
logger.User("SHA-1 mismatch - Hash: " + hash.SHA1);
}
return dupefound;
}
/// <summary>
/// Return the duplicate status of two hashes
/// </summary>
/// <param name="hash">Current hash to check</param>
/// <param name="lasthash">Last hash to check against</param>
/// <param name="logger">Logger object for console and/or file output</param>
/// <returns>The DupeType corresponding to the relationship between the two</returns>
public static DupeType GetDuplicateStatus(HashData hash, HashData lasthash, Logger logger)
{
DupeType output = DupeType.None;
/*
// If we don't have a duplicate at all, return none
if (!IsDuplicate(hash, lasthash, logger))
{
return output;
}
*/
// If the duplicate is external already or should be, set it
if (lasthash.Roms[0].DupeType >= DupeType.ExternalHash || lasthash.Roms[0].Machine.SystemID != hash.Roms[0].Machine.SystemID || lasthash.Roms[0].Machine.SourceID != hash.Roms[0].Machine.SourceID)
{
if (lasthash.Roms[0].Machine.Name == hash.Roms[0].Machine.Name && lasthash.Roms[0].Name == hash.Roms[0].Name)
{
output = DupeType.ExternalAll;
}
else
{
output = DupeType.ExternalHash;
}
}
// Otherwise, it's considered an internal dupe
else
{
if (lasthash.Roms[0].Machine.Name == hash.Roms[0].Machine.Name && lasthash.Roms[0].Name == hash.Roms[0].Name)
{
output = DupeType.InternalAll;
}
else
{
output = DupeType.InternalHash;
}
}
return output;
}
#endregion
}
}

View File

@@ -140,7 +140,7 @@ namespace SabreTools
OutputFormat = (outputFormat == 0 ? OutputFormat.Xml : outputFormat), OutputFormat = (outputFormat == 0 ? OutputFormat.Xml : outputFormat),
Romba = romba, Romba = romba,
Type = (superdat ? "SuperDAT" : ""), Type = (superdat ? "SuperDAT" : ""),
Files = new Dictionary<string, List<Rom>>(), Files = new Dictionary<string, List<DatItem>>(),
}; };
// For each input directory, create a DAT // For each input directory, create a DAT
@@ -150,7 +150,7 @@ namespace SabreTools
{ {
// Clone the base Dat for information // Clone the base Dat for information
Dat datdata = (Dat)basedat.Clone(); Dat datdata = (Dat)basedat.Clone();
datdata.Files = new Dictionary<string, List<Rom>>(); datdata.Files = new Dictionary<string, List<DatItem>>();
string basePath = Path.GetFullPath(path); string basePath = Path.GetFullPath(path);
DATFromDir dfd = new DATFromDir(basePath, datdata, noMD5, noSHA1, bare, archivesAsFiles, enableGzip, addBlanks, addDate, tempDir, maxDegreeOfParallelism, _logger); DATFromDir dfd = new DATFromDir(basePath, datdata, noMD5, noSHA1, bare, archivesAsFiles, enableGzip, addBlanks, addDate, tempDir, maxDegreeOfParallelism, _logger);