mirror of
https://github.com/claunia/SabreTools.git
synced 2025-12-16 19:14:27 +00:00
@@ -33,7 +33,7 @@ namespace SabreTools
|
||||
Dictionary<string, Tuple<long, bool>> depots = new Dictionary<string, Tuple<long, bool>>();
|
||||
|
||||
// Get the XML text reader for the configuration file, if possible
|
||||
XmlTextReader xtr = DatTools.GetXmlTextReader(_config, _logger);
|
||||
XmlTextReader xtr = DatFile.GetXmlTextReader(_config, _logger);
|
||||
|
||||
// Now parse the XML file for settings
|
||||
if (xtr != null)
|
||||
@@ -341,15 +341,15 @@ namespace SabreTools
|
||||
Rom dat = FileTools.GetSingleFileInfo(file);
|
||||
|
||||
// If the Dat isn't in the database and isn't already accounted for in the DatRoot, add it
|
||||
if (!databaseDats.Contains(dat.HashData.SHA1) && !toscan.ContainsKey(dat.HashData.SHA1))
|
||||
if (!databaseDats.Contains(dat.SHA1) && !toscan.ContainsKey(dat.SHA1))
|
||||
{
|
||||
toscan.Add(dat.HashData.SHA1, Path.GetFullPath(file));
|
||||
toscan.Add(dat.SHA1, Path.GetFullPath(file));
|
||||
}
|
||||
|
||||
// If the Dat is in the database already, remove it to find stragglers
|
||||
else if (databaseDats.Contains(dat.HashData.SHA1))
|
||||
else if (databaseDats.Contains(dat.SHA1))
|
||||
{
|
||||
databaseDats.Remove(dat.HashData.SHA1);
|
||||
databaseDats.Remove(dat.SHA1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -357,8 +357,8 @@ namespace SabreTools
|
||||
foreach (string key in toscan.Keys)
|
||||
{
|
||||
// Parse the Dat if possible
|
||||
Dat tempdat = new Dat();
|
||||
DatTools.Parse(toscan[key], 0, 0, ref tempdat, _logger);
|
||||
DatFile tempdat = new DatFile();
|
||||
DatFile.Parse(toscan[key], 0, 0, ref tempdat, _logger);
|
||||
|
||||
// If the Dat wasn't empty, add the information
|
||||
if (tempdat.Files.Count != 0)
|
||||
@@ -368,10 +368,10 @@ namespace SabreTools
|
||||
{
|
||||
foreach (Rom rom in tempdat.Files[romkey])
|
||||
{
|
||||
query = "SELECT id FROM data WHERE key=\"size\" AND value=\"" + rom.HashData.Size + "\" AND ("
|
||||
+ "(key=\"crc\" AND (value=\"" + rom.HashData.CRC + "\" OR value=\"null\"))"
|
||||
+ "AND (key=\"md5\" AND value=\"" + rom.HashData.MD5 + "\" OR value=\"null\"))"
|
||||
+ "AND (key=\"sha1\" AND value=\"" + rom.HashData.SHA1 + "\" OR value=\"null\")))";
|
||||
query = "SELECT id FROM data WHERE key=\"size\" AND value=\"" + rom.Size + "\" AND ("
|
||||
+ "(key=\"crc\" AND (value=\"" + rom.CRC + "\" OR value=\"null\"))"
|
||||
+ "AND (key=\"md5\" AND value=\"" + rom.MD5 + "\" OR value=\"null\"))"
|
||||
+ "AND (key=\"sha1\" AND value=\"" + rom.SHA1 + "\" OR value=\"null\")))";
|
||||
using (SqliteCommand slc = new SqliteCommand(query, dbc))
|
||||
{
|
||||
using (SqliteDataReader sldr = slc.ExecuteReader())
|
||||
@@ -392,7 +392,7 @@ namespace SabreTools
|
||||
// If it doesn't exist, add the hash and the dat hash for a new id
|
||||
else
|
||||
{
|
||||
string squery = "INSERT INTO data (key, value) VALUES (\"size\", \"" + rom.HashData.Size + "\")";
|
||||
string squery = "INSERT INTO data (key, value) VALUES (\"size\", \"" + rom.Size + "\")";
|
||||
using (SqliteCommand sslc = new SqliteCommand(squery, dbc))
|
||||
{
|
||||
sslc.ExecuteNonQuery();
|
||||
@@ -406,9 +406,9 @@ namespace SabreTools
|
||||
id = (long)sslc.ExecuteScalar();
|
||||
}
|
||||
|
||||
squery = "INSERT INTO data (id, key, value) VALUES (\"" + id + "\", \"crc\", \"" + rom.HashData.CRC + "\"),"
|
||||
+ " (\"" + id + "\", \"md5\", \"" + rom.HashData.MD5 + "\"),"
|
||||
+ " (\"" + id + "\", \"sha1\", \"" + rom.HashData.SHA1 + "\"),"
|
||||
squery = "INSERT INTO data (id, key, value) VALUES (\"" + id + "\", \"crc\", \"" + rom.CRC + "\"),"
|
||||
+ " (\"" + id + "\", \"md5\", \"" + rom.MD5 + "\"),"
|
||||
+ " (\"" + id + "\", \"sha1\", \"" + rom.SHA1 + "\"),"
|
||||
+ " (\"" + id + "\", \"dat\", \"" + key + "\"),"
|
||||
+ " (\"" + id + "\", \"exists\", \"false\")";
|
||||
using (SqliteCommand sslc = new SqliteCommand(squery, dbc))
|
||||
@@ -451,7 +451,7 @@ namespace SabreTools
|
||||
if (datRootDats.Contains(input.ToLowerInvariant()))
|
||||
{
|
||||
string fullpath = Path.GetFullPath(datRootDats[datRootDats.IndexOf(input.ToLowerInvariant())]);
|
||||
string sha1 = FileTools.GetSingleFileInfo(fullpath).HashData.SHA1;
|
||||
string sha1 = FileTools.GetSingleFileInfo(fullpath).SHA1;
|
||||
foundDats.Add(sha1, fullpath);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -57,13 +57,13 @@ namespace SabreTools
|
||||
private static void InitDir2Dat(List<string> inputs)
|
||||
{
|
||||
// Create a simple Dat output
|
||||
Dat datdata = new Dat()
|
||||
DatFile datdata = new DatFile()
|
||||
{
|
||||
FileName = Path.GetFileName(inputs[0]) + " Dir2Dat",
|
||||
Name = Path.GetFileName(inputs[0]) + " Dir2Dat",
|
||||
Description = Path.GetFileName(inputs[0]) + " Dir2Dat",
|
||||
OutputFormat = OutputFormat.Xml,
|
||||
Files = new Dictionary<string, List<Rom>>(),
|
||||
Files = new Dictionary<string, List<DatItem>>(),
|
||||
};
|
||||
|
||||
Logger logger = new Logger(false, "");
|
||||
@@ -73,7 +73,7 @@ namespace SabreTools
|
||||
DATFromDir dfd = new DATFromDir(input, datdata, false /* noMD5 */, false /* noSHA1 */, true /* bare */, false /* archivesAsFiles */,
|
||||
true /* enableGzip */, false /* addBlanks */, false /* addDate */, "__temp__" /* tempDir */, 4 /* maxDegreeOfParallelism */, _logger);
|
||||
dfd.Start();
|
||||
DatTools.WriteDatfile(dfd.DatData, "", logger);
|
||||
DatFile.WriteDatfile(dfd.DatData, "", logger);
|
||||
}
|
||||
logger.Close();
|
||||
}
|
||||
|
||||
@@ -3,436 +3,6 @@ using System.Collections.Generic;
|
||||
|
||||
namespace SabreTools.Helper
|
||||
{
|
||||
#region Hash-to-Dat structs [Currently Unused]
|
||||
|
||||
/* Thought experiment
|
||||
|
||||
So, here's a connundrum: Should the internal structure of how DATs work (down to the hash level) mirror
|
||||
how people see it (Dat to multiple games, game to multiple roms, rom to single hash) or
|
||||
should it more closely mirror real life (Hash to multiple roms, rom to multiple games, game to single DAT)
|
||||
|
||||
If I use the "how people see it":
|
||||
Things are pretty much how they are now with redundant data and the like
|
||||
It makes sense to write things out to file, though. And life is easier when output is easier.
|
||||
No code changes (big plus!)
|
||||
|
||||
If I use the "how it is":
|
||||
Less data is likely to be mirrored
|
||||
Refs to DAT files are possible so that there aren't duplicates
|
||||
A lot of code will have to change...
|
||||
*/
|
||||
|
||||
/// <summary>
|
||||
/// Intermediate struct for holding and processing Hash data (NEW SYSTEM)
|
||||
/// </summary>
|
||||
public struct HashData : IEquatable<HashData>
|
||||
{
|
||||
public long Size;
|
||||
public byte[] CRC;
|
||||
public byte[] MD5;
|
||||
public byte[] SHA1;
|
||||
public List<RomData> Roms;
|
||||
|
||||
public bool Equals(HashData other)
|
||||
{
|
||||
return this.Equals(other, false);
|
||||
}
|
||||
|
||||
public bool Equals(HashData other, bool IsDisk)
|
||||
{
|
||||
bool equals = false;
|
||||
|
||||
if (!IsDisk &&
|
||||
((this.MD5 == null || other.MD5 == null) || this.MD5 == other.MD5) &&
|
||||
((this.SHA1 == null || other.SHA1 == null) || this.SHA1 == other.SHA1))
|
||||
{
|
||||
equals = true;
|
||||
}
|
||||
else if (!IsDisk &&
|
||||
(this.Size == other.Size) &&
|
||||
((this.CRC == null || other.CRC != null) || this.CRC == other.CRC) &&
|
||||
((this.MD5 == null || other.MD5 == null) || this.MD5 == other.MD5) &&
|
||||
((this.SHA1 == null || other.SHA1 == null) || this.SHA1 == other.SHA1))
|
||||
{
|
||||
equals = true;
|
||||
}
|
||||
|
||||
return equals;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Intermediate struct for holding and processing Rom data (NEW SYSTEM)
|
||||
/// </summary>
|
||||
public struct RomData
|
||||
{
|
||||
public string Name;
|
||||
public ItemType Type;
|
||||
public bool Nodump;
|
||||
public string Date;
|
||||
public DupeType DupeType;
|
||||
public MachineData Machine;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Intermediate struct for holding and processing Game/Machine data (NEW SYSTEM)
|
||||
/// </summary>
|
||||
public struct MachineData
|
||||
{
|
||||
// Data specific to Machine/Game
|
||||
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;
|
||||
|
||||
// Data specific to the source of the Machine/Game
|
||||
public int SystemID;
|
||||
public string System;
|
||||
public int SourceID;
|
||||
public string Source;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Intermediate struct for holding and processing DAT data (NEW SYSTEM)
|
||||
/// </summary>
|
||||
public struct DatData
|
||||
{
|
||||
// Data common to most DAT types
|
||||
public string FileName;
|
||||
public string Name;
|
||||
public string Description;
|
||||
public string RootDir;
|
||||
public string Category;
|
||||
public string Version;
|
||||
public string Date;
|
||||
public string Author;
|
||||
public string Email;
|
||||
public string Homepage;
|
||||
public string Url;
|
||||
public string Comment;
|
||||
public string Header;
|
||||
public string Type; // Generally only used for SuperDAT
|
||||
public ForceMerging ForceMerging;
|
||||
public ForceNodump ForceNodump;
|
||||
public ForcePacking ForcePacking;
|
||||
public OutputFormat OutputFormat;
|
||||
public bool MergeRoms;
|
||||
public List<HashData> Hashes;
|
||||
|
||||
// Data specific to the Miss DAT type
|
||||
public bool UseGame;
|
||||
public string Prefix;
|
||||
public string Postfix;
|
||||
public bool Quotes;
|
||||
public string RepExt;
|
||||
public string AddExt;
|
||||
public bool GameName;
|
||||
public bool Romba;
|
||||
public bool? XSV; // true for tab-deliminated output, false for comma-deliminated output
|
||||
|
||||
// Statistical data related to the DAT
|
||||
public long RomCount;
|
||||
public long DiskCount;
|
||||
public long TotalSize;
|
||||
public long CRCCount;
|
||||
public long MD5Count;
|
||||
public long SHA1Count;
|
||||
public long NodumpCount;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Dat-to-Hash structs
|
||||
|
||||
/// <summary>
|
||||
/// Intermediate struct for holding and processing hash data
|
||||
/// </summary>
|
||||
public struct Hash : IEquatable<Hash>
|
||||
{
|
||||
public long Size;
|
||||
public string CRC;
|
||||
public string MD5;
|
||||
public string SHA1;
|
||||
|
||||
public bool Equals(Hash other)
|
||||
{
|
||||
return this.Equals(other, false);
|
||||
}
|
||||
|
||||
public bool Equals(Hash other, bool IsDisk)
|
||||
{
|
||||
bool equals = false;
|
||||
|
||||
if (IsDisk &&
|
||||
((String.IsNullOrEmpty(this.MD5) || String.IsNullOrEmpty(other.MD5)) || this.MD5 == other.MD5) &&
|
||||
((String.IsNullOrEmpty(this.SHA1) || String.IsNullOrEmpty(other.SHA1)) || this.SHA1 == other.SHA1))
|
||||
{
|
||||
equals = true;
|
||||
}
|
||||
else if (!IsDisk &&
|
||||
(this.Size == other.Size) &&
|
||||
((String.IsNullOrEmpty(this.CRC) || String.IsNullOrEmpty(other.CRC)) || this.CRC == other.CRC) &&
|
||||
((String.IsNullOrEmpty(this.MD5) || String.IsNullOrEmpty(other.MD5)) || this.MD5 == other.MD5) &&
|
||||
((String.IsNullOrEmpty(this.SHA1) || String.IsNullOrEmpty(other.SHA1)) || this.SHA1 == other.SHA1))
|
||||
{
|
||||
equals = true;
|
||||
}
|
||||
|
||||
return equals;
|
||||
}
|
||||
}
|
||||
|
||||
/// <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>
|
||||
/// Intermediate struct for holding DAT information
|
||||
/// </summary>
|
||||
public struct Dat : ICloneable
|
||||
{
|
||||
// Data common to most DAT types
|
||||
public string FileName;
|
||||
public string Name;
|
||||
public string Description;
|
||||
public string RootDir;
|
||||
public string Category;
|
||||
public string Version;
|
||||
public string Date;
|
||||
public string Author;
|
||||
public string Email;
|
||||
public string Homepage;
|
||||
public string Url;
|
||||
public string Comment;
|
||||
public string Header;
|
||||
public string Type; // Generally only used for SuperDAT
|
||||
public ForceMerging ForceMerging;
|
||||
public ForceNodump ForceNodump;
|
||||
public ForcePacking ForcePacking;
|
||||
public OutputFormat OutputFormat;
|
||||
public bool MergeRoms;
|
||||
public Dictionary<string, List<Rom>> Files;
|
||||
|
||||
// Data specific to the Miss DAT type
|
||||
public bool UseGame;
|
||||
public string Prefix;
|
||||
public string Postfix;
|
||||
public bool Quotes;
|
||||
public string RepExt;
|
||||
public string AddExt;
|
||||
public bool RemExt;
|
||||
public bool GameName;
|
||||
public bool Romba;
|
||||
public bool? XSV; // true for tab-deliminated output, false for comma-deliminated output
|
||||
|
||||
// Statistical data related to the DAT
|
||||
public long RomCount;
|
||||
public long DiskCount;
|
||||
public long TotalSize;
|
||||
public long CRCCount;
|
||||
public long MD5Count;
|
||||
public long SHA1Count;
|
||||
public long NodumpCount;
|
||||
|
||||
public object Clone()
|
||||
{
|
||||
return new Dat
|
||||
{
|
||||
FileName = this.FileName,
|
||||
Name = this.Name,
|
||||
Description = this.Description,
|
||||
RootDir = this.RootDir,
|
||||
Category = this.Category,
|
||||
Version = this.Version,
|
||||
Date = this.Date,
|
||||
Author = this.Author,
|
||||
Email = this.Email,
|
||||
Homepage = this.Homepage,
|
||||
Url = this.Url,
|
||||
Comment = this.Comment,
|
||||
Header = this.Header,
|
||||
Type = this.Type,
|
||||
ForceMerging = this.ForceMerging,
|
||||
ForceNodump = this.ForceNodump,
|
||||
ForcePacking = this.ForcePacking,
|
||||
OutputFormat = this.OutputFormat,
|
||||
MergeRoms = this.MergeRoms,
|
||||
Files = this.Files,
|
||||
UseGame = this.UseGame,
|
||||
Prefix = this.Prefix,
|
||||
Postfix = this.Postfix,
|
||||
Quotes = this.Quotes,
|
||||
RepExt = this.RepExt,
|
||||
AddExt = this.AddExt,
|
||||
RemExt = this.RemExt,
|
||||
GameName = this.GameName,
|
||||
Romba = this.Romba,
|
||||
XSV = this.XSV,
|
||||
RomCount = this.RomCount,
|
||||
DiskCount = this.DiskCount,
|
||||
TotalSize = this.TotalSize,
|
||||
CRCCount = this.CRCCount,
|
||||
MD5Count = this.MD5Count,
|
||||
SHA1Count = this.SHA1Count,
|
||||
NodumpCount = this.NodumpCount,
|
||||
};
|
||||
}
|
||||
|
||||
public object CloneHeader()
|
||||
{
|
||||
return new Dat
|
||||
{
|
||||
FileName = this.FileName,
|
||||
Name = this.Name,
|
||||
Description = this.Description,
|
||||
RootDir = this.RootDir,
|
||||
Category = this.Category,
|
||||
Version = this.Version,
|
||||
Date = this.Date,
|
||||
Author = this.Author,
|
||||
Email = this.Email,
|
||||
Homepage = this.Homepage,
|
||||
Url = this.Url,
|
||||
Comment = this.Comment,
|
||||
Header = this.Header,
|
||||
Type = this.Type,
|
||||
ForceMerging = this.ForceMerging,
|
||||
ForceNodump = this.ForceNodump,
|
||||
ForcePacking = this.ForcePacking,
|
||||
OutputFormat = this.OutputFormat,
|
||||
MergeRoms = this.MergeRoms,
|
||||
Files = new Dictionary<string, List<Rom>>(),
|
||||
UseGame = this.UseGame,
|
||||
Prefix = this.Prefix,
|
||||
Postfix = this.Postfix,
|
||||
Quotes = this.Quotes,
|
||||
RepExt = this.RepExt,
|
||||
AddExt = this.AddExt,
|
||||
RemExt = this.RemExt,
|
||||
GameName = this.GameName,
|
||||
Romba = this.Romba,
|
||||
XSV = this.XSV,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Skipper structs
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace SabreTools
|
||||
private string _tempDir;
|
||||
|
||||
// User specified inputs
|
||||
private Dat _datdata;
|
||||
private DatFile _datdata;
|
||||
private bool _noMD5;
|
||||
private bool _noSHA1;
|
||||
private bool _bare;
|
||||
@@ -32,7 +32,7 @@ namespace SabreTools
|
||||
private Logger _logger;
|
||||
|
||||
// Public variables
|
||||
public Dat DatData
|
||||
public DatFile DatData
|
||||
{
|
||||
get { return _datdata; }
|
||||
}
|
||||
@@ -52,13 +52,13 @@ namespace SabreTools
|
||||
/// <param name="tempDir">Name of the directory to create a temp folder in (blank is current directory)</param>
|
||||
/// <param name="maxDegreeOfParallelism">Integer representing the maximum amount of parallelization to be used</param>
|
||||
/// <param name="logger">Logger object for console and file output</param>
|
||||
public DATFromDir(string basePath, Dat datdata, bool noMD5, bool noSHA1, bool bare, bool archivesAsFiles,
|
||||
public DATFromDir(string basePath, DatFile datdata, bool noMD5, bool noSHA1, bool bare, bool archivesAsFiles,
|
||||
bool enableGzip, bool addBlanks, bool addDate, string tempDir, int maxDegreeOfParallelism, Logger logger)
|
||||
{
|
||||
_basePath = Path.GetFullPath(basePath);
|
||||
_datdata = datdata;
|
||||
_datdata.Files = new Dictionary<string, List<Rom>>();
|
||||
_datdata.Files.Add("null", new List<Rom>());
|
||||
_datdata.Files = new Dictionary<string, List<DatItem>>();
|
||||
_datdata.Files.Add("null", new List<DatItem>());
|
||||
_noMD5 = noMD5;
|
||||
_noSHA1 = noSHA1;
|
||||
_bare = bare;
|
||||
@@ -158,25 +158,7 @@ namespace SabreTools
|
||||
}
|
||||
|
||||
_logger.Log("Adding blank empty folder: " + 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);
|
||||
_datdata.Files["null"].Add(new Rom(romname, gamename));
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -215,13 +197,13 @@ namespace SabreTools
|
||||
if (rom.Name != null)
|
||||
{
|
||||
// Add the list if it doesn't exist already
|
||||
string key = rom.HashData.Size + "-" + rom.HashData.CRC;
|
||||
string key = rom.Size + "-" + rom.CRC;
|
||||
|
||||
lock (_datdata.Files)
|
||||
{
|
||||
if (!_datdata.Files.ContainsKey(key))
|
||||
{
|
||||
_datdata.Files.Add(key, new List<Rom>());
|
||||
_datdata.Files.Add(key, new List<DatItem>());
|
||||
}
|
||||
|
||||
_datdata.Files[key].Add(rom);
|
||||
@@ -321,18 +303,33 @@ namespace SabreTools
|
||||
/// Process a single file as a file (with found Rom data)
|
||||
/// </summary>
|
||||
/// <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="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).Size + "-" + ((Rom)datItem).CRC;
|
||||
}
|
||||
else
|
||||
{
|
||||
key = ((Disk)datItem).MD5;
|
||||
}
|
||||
|
||||
// Add the list if it doesn't exist already
|
||||
string key = rom.HashData.Size + "-" + rom.HashData.CRC;
|
||||
lock (_datdata.Files)
|
||||
{
|
||||
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
|
||||
rom.Machine = new Machine
|
||||
{
|
||||
Name = gamename,
|
||||
Description = gamename,
|
||||
};
|
||||
rom.Name = romname;
|
||||
datItem.Name = romname;
|
||||
datItem.MachineName = gamename;
|
||||
datItem.MachineDescription = gamename;
|
||||
|
||||
// Add the file information to the DAT
|
||||
lock (_datdata.Files)
|
||||
{
|
||||
_datdata.Files[key].Add(rom);
|
||||
_datdata.Files[key].Add(datItem);
|
||||
}
|
||||
|
||||
_logger.User("File added: " + romname + Environment.NewLine);
|
||||
|
||||
91
SabreTools.Helper/Objects/Dat/Archive.cs
Normal file
91
SabreTools.Helper/Objects/Dat/Archive.cs
Normal 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 an archive, return false
|
||||
if (_itemType != other.Type)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Otherwise, treat it as an archive
|
||||
Archive newOther = (Archive)other;
|
||||
|
||||
// If the archive information matches
|
||||
return (_name == newOther.Name);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
121
SabreTools.Helper/Objects/Dat/BiosSet.cs
Normal file
121
SabreTools.Helper/Objects/Dat/BiosSet.cs
Normal 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 biosset, return false
|
||||
if (_itemType != other.Type)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Otherwise, treat it as a biosset
|
||||
BiosSet newOther = (BiosSet)other;
|
||||
|
||||
// If the archive information matches
|
||||
return (_name == newOther.Name && _description == newOther.Description && _default == newOther.Default);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
784
SabreTools.Helper/Objects/Dat/DatItem.cs
Normal file
784
SabreTools.Helper/Objects/Dat/DatItem.cs
Normal file
@@ -0,0 +1,784 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace SabreTools.Helper
|
||||
{
|
||||
public abstract class DatItem : IEquatable<DatItem>, IComparable<DatItem>
|
||||
{
|
||||
#region Protected instance variables
|
||||
|
||||
// Standard item information
|
||||
protected string _name;
|
||||
protected ItemType _itemType;
|
||||
protected DupeType _dupeType;
|
||||
|
||||
// Machine information
|
||||
protected string _machineName;
|
||||
protected string _comment;
|
||||
protected string _machineDescription;
|
||||
protected string _year;
|
||||
protected string _manufacturer;
|
||||
protected string _romOf;
|
||||
protected string _cloneOf;
|
||||
protected string _sampleOf;
|
||||
protected string _sourceFile;
|
||||
protected bool _isBios;
|
||||
protected string _board;
|
||||
protected string _rebuildTo;
|
||||
|
||||
// Source metadata information
|
||||
protected int _systemId;
|
||||
protected string _systemName;
|
||||
protected int _sourceId;
|
||||
protected string _sourceName;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Publicly facing variables
|
||||
|
||||
// Standard item information
|
||||
public string Name
|
||||
{
|
||||
get { return _name; }
|
||||
set { _name = value; }
|
||||
}
|
||||
public ItemType Type
|
||||
{
|
||||
get { return _itemType; }
|
||||
set { _itemType = value; }
|
||||
}
|
||||
public DupeType Dupe
|
||||
{
|
||||
get { return _dupeType; }
|
||||
set { _dupeType = value; }
|
||||
}
|
||||
|
||||
// Machine information
|
||||
public string MachineName
|
||||
{
|
||||
get { return _machineName; }
|
||||
set { _machineName = value; }
|
||||
}
|
||||
public string Comment
|
||||
{
|
||||
get { return _comment; }
|
||||
set { _comment = value; }
|
||||
}
|
||||
public string MachineDescription
|
||||
{
|
||||
get { return _machineDescription; }
|
||||
set { _machineDescription = value; }
|
||||
}
|
||||
public string Year
|
||||
{
|
||||
get { return _year; }
|
||||
set { _year = value; }
|
||||
}
|
||||
public string Manufacturer
|
||||
{
|
||||
get { return _manufacturer; }
|
||||
set { _manufacturer = value; }
|
||||
}
|
||||
public string RomOf
|
||||
{
|
||||
get { return _romOf; }
|
||||
set { _romOf = value; }
|
||||
}
|
||||
public string CloneOf
|
||||
{
|
||||
get { return _cloneOf; }
|
||||
set { _cloneOf = value; }
|
||||
}
|
||||
public string SampleOf
|
||||
{
|
||||
get { return _sampleOf; }
|
||||
set { _sampleOf = value; }
|
||||
}
|
||||
public string SourceFile
|
||||
{
|
||||
get { return _sourceFile; }
|
||||
set { _sourceFile = value; }
|
||||
}
|
||||
public bool IsBios
|
||||
{
|
||||
get { return _isBios; }
|
||||
set { _isBios = value; }
|
||||
}
|
||||
public string Board
|
||||
{
|
||||
get { return _board; }
|
||||
set { _board = value; }
|
||||
}
|
||||
public string RebuildTo
|
||||
{
|
||||
get { return _rebuildTo; }
|
||||
set { _rebuildTo = value; }
|
||||
}
|
||||
|
||||
// Source metadata information
|
||||
public int SystemID
|
||||
{
|
||||
get { return _systemId; }
|
||||
set { _systemId = value; }
|
||||
}
|
||||
public string System
|
||||
{
|
||||
get { return _systemName; }
|
||||
set { _systemName = value; }
|
||||
}
|
||||
public int SourceID
|
||||
{
|
||||
get { return _sourceId; }
|
||||
set { _sourceId = value; }
|
||||
}
|
||||
public string Source
|
||||
{
|
||||
get { return _sourceName; }
|
||||
set { _sourceName = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Comparision Methods
|
||||
|
||||
public int CompareTo(DatItem other)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
try
|
||||
{
|
||||
if (_name == other.Name)
|
||||
{
|
||||
ret = (this.Equals(other) ? 0 : 1);
|
||||
}
|
||||
ret = String.Compare(_name, other.Name);
|
||||
}
|
||||
catch
|
||||
{
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public abstract bool Equals(DatItem other);
|
||||
|
||||
/// <summary>
|
||||
/// Determine if an item is a duplicate using partial matching logic
|
||||
/// </summary>
|
||||
/// <param name="lastItem">DatItem 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 bool IsDuplicate(DatItem lastItem, Logger logger)
|
||||
{
|
||||
bool dupefound = this.Equals(lastItem);
|
||||
|
||||
// More wonderful SHA-1 logging that has to be done
|
||||
if (_itemType == ItemType.Rom)
|
||||
{
|
||||
if (((Rom)this).SHA1 == ((Rom)lastItem).SHA1 && ((Rom)this).Size != ((Rom)lastItem).Size)
|
||||
{
|
||||
logger.User("SHA-1 mismatch - Hash: " + ((Rom)this).SHA1);
|
||||
}
|
||||
}
|
||||
|
||||
return dupefound;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the duplicate status of two items
|
||||
/// </summary>
|
||||
/// <param name="lastItem">DatItem 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 DupeType GetDuplicateStatus(DatItem lastItem, Logger logger)
|
||||
{
|
||||
DupeType output = DupeType.None;
|
||||
|
||||
// If we don't have a duplicate at all, return none
|
||||
if (!this.IsDuplicate(lastItem, logger))
|
||||
{
|
||||
return output;
|
||||
}
|
||||
|
||||
// If the duplicate is external already or should be, set it
|
||||
if (lastItem.Dupe >= DupeType.ExternalHash || lastItem.SystemID != this.SystemID || lastItem.SourceID != this.SourceID)
|
||||
{
|
||||
if (lastItem.MachineName == this.MachineName && lastItem.Name == this.Name)
|
||||
{
|
||||
output = DupeType.ExternalAll;
|
||||
}
|
||||
else
|
||||
{
|
||||
output = DupeType.ExternalHash;
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, it's considered an internal dupe
|
||||
else
|
||||
{
|
||||
if (lastItem.MachineName == this.MachineName && lastItem.Name == this.Name)
|
||||
{
|
||||
output = DupeType.InternalAll;
|
||||
}
|
||||
else
|
||||
{
|
||||
output = DupeType.InternalHash;
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Sorting and merging
|
||||
|
||||
/// <summary>
|
||||
/// Determine if a rom should be included based on filters
|
||||
/// </summary>
|
||||
/// <param name="itemdata">User supplied item 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(DatItem itemdata, string gamename, string romname, string romtype, long sgt,
|
||||
long slt, long seq, string crc, string md5, string sha1, bool? nodump, Logger logger)
|
||||
{
|
||||
// Take care of Rom and Disk specific differences
|
||||
if (itemdata.Type == ItemType.Rom)
|
||||
{
|
||||
Rom rom = (Rom)itemdata;
|
||||
|
||||
// Filter on nodump status
|
||||
if (nodump == true && !rom.Nodump)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (nodump == false && rom.Nodump)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Filter on rom size
|
||||
if (seq != -1 && rom.Size != seq)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sgt != -1 && rom.Size < sgt)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (slt != -1 && rom.Size > slt)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Filter on crc
|
||||
if (!String.IsNullOrEmpty(crc))
|
||||
{
|
||||
if (crc.StartsWith("*") && crc.EndsWith("*"))
|
||||
{
|
||||
if (!rom.CRC.ToLowerInvariant().Contains(crc.ToLowerInvariant().Replace("*", "")))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (crc.StartsWith("*"))
|
||||
{
|
||||
if (!rom.CRC.EndsWith(crc.Replace("*", ""), StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (crc.EndsWith("*"))
|
||||
{
|
||||
if (!rom.CRC.StartsWith(crc.Replace("*", ""), StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!String.Equals(rom.CRC, crc, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Filter on md5
|
||||
if (!String.IsNullOrEmpty(md5))
|
||||
{
|
||||
if (md5.StartsWith("*") && md5.EndsWith("*"))
|
||||
{
|
||||
if (!rom.MD5.ToLowerInvariant().Contains(md5.ToLowerInvariant().Replace("*", "")))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (md5.StartsWith("*"))
|
||||
{
|
||||
if (!rom.MD5.EndsWith(md5.Replace("*", ""), StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (md5.EndsWith("*"))
|
||||
{
|
||||
if (!rom.MD5.StartsWith(md5.Replace("*", ""), StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!String.Equals(rom.MD5, md5, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Filter on sha1
|
||||
if (!String.IsNullOrEmpty(sha1))
|
||||
{
|
||||
if (sha1.StartsWith("*") && sha1.EndsWith("*"))
|
||||
{
|
||||
if (!rom.SHA1.ToLowerInvariant().Contains(sha1.ToLowerInvariant().Replace("*", "")))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (sha1.StartsWith("*"))
|
||||
{
|
||||
if (!rom.SHA1.EndsWith(sha1.Replace("*", ""), StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (sha1.EndsWith("*"))
|
||||
{
|
||||
if (!rom.SHA1.StartsWith(sha1.Replace("*", ""), StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!String.Equals(rom.SHA1, sha1, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (itemdata.Type == ItemType.Disk)
|
||||
{
|
||||
Disk rom = (Disk)itemdata;
|
||||
|
||||
// Filter on nodump status
|
||||
if (nodump == true && !rom.Nodump)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (nodump == false && rom.Nodump)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Filter on md5
|
||||
if (!String.IsNullOrEmpty(md5))
|
||||
{
|
||||
if (md5.StartsWith("*") && md5.EndsWith("*"))
|
||||
{
|
||||
if (!rom.MD5.ToLowerInvariant().Contains(md5.ToLowerInvariant().Replace("*", "")))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (md5.StartsWith("*"))
|
||||
{
|
||||
if (!rom.MD5.EndsWith(md5.Replace("*", ""), StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (md5.EndsWith("*"))
|
||||
{
|
||||
if (!rom.MD5.StartsWith(md5.Replace("*", ""), StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!String.Equals(rom.MD5, md5, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Filter on sha1
|
||||
if (!String.IsNullOrEmpty(sha1))
|
||||
{
|
||||
if (sha1.StartsWith("*") && sha1.EndsWith("*"))
|
||||
{
|
||||
if (!rom.SHA1.ToLowerInvariant().Contains(sha1.ToLowerInvariant().Replace("*", "")))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (sha1.StartsWith("*"))
|
||||
{
|
||||
if (!rom.SHA1.EndsWith(sha1.Replace("*", ""), StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (sha1.EndsWith("*"))
|
||||
{
|
||||
if (!rom.SHA1.StartsWith(sha1.Replace("*", ""), StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!String.Equals(rom.SHA1, sha1, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Filter on game name
|
||||
if (!String.IsNullOrEmpty(gamename))
|
||||
{
|
||||
if (gamename.StartsWith("*") && gamename.EndsWith("*"))
|
||||
{
|
||||
if (!itemdata.MachineName.ToLowerInvariant().Contains(gamename.ToLowerInvariant().Replace("*", "")))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (gamename.StartsWith("*"))
|
||||
{
|
||||
if (!itemdata.MachineName.EndsWith(gamename.Replace("*", ""), StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (gamename.EndsWith("*"))
|
||||
{
|
||||
if (!itemdata.MachineName.StartsWith(gamename.Replace("*", ""), StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!String.Equals(itemdata.MachineName, gamename, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Filter on rom name
|
||||
if (!String.IsNullOrEmpty(romname))
|
||||
{
|
||||
if (romname.StartsWith("*") && romname.EndsWith("*"))
|
||||
{
|
||||
if (!itemdata.Name.ToLowerInvariant().Contains(romname.ToLowerInvariant().Replace("*", "")))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (romname.StartsWith("*"))
|
||||
{
|
||||
if (!itemdata.Name.EndsWith(romname.Replace("*", ""), StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (romname.EndsWith("*"))
|
||||
{
|
||||
if (!itemdata.Name.StartsWith(romname.Replace("*", ""), StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!String.Equals(itemdata.Name, romname, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Filter on rom type
|
||||
if (String.IsNullOrEmpty(romtype) && itemdata.Type != ItemType.Rom && itemdata.Type != ItemType.Disk)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!String.IsNullOrEmpty(romtype) && !String.Equals(itemdata.Type.ToString(), romtype, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Merge an arbitrary set of ROMs based on the supplied information
|
||||
/// </summary>
|
||||
/// <param name="infiles">List of File 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<DatItem> Merge(List<DatItem> infiles, Logger logger)
|
||||
{
|
||||
// Check for null or blank roms first
|
||||
if (infiles == null || infiles.Count == 0)
|
||||
{
|
||||
return new List<DatItem>();
|
||||
}
|
||||
|
||||
// Create output list
|
||||
List<DatItem> outfiles = new List<DatItem>();
|
||||
|
||||
// Then deduplicate them by checking to see if data matches previous saved roms
|
||||
foreach (DatItem file in infiles)
|
||||
{
|
||||
// If it's a nodump, add and skip
|
||||
if (file.Type == ItemType.Rom && ((Rom)file).Nodump)
|
||||
{
|
||||
outfiles.Add(file);
|
||||
continue;
|
||||
}
|
||||
else if (file.Type == ItemType.Disk && ((Disk)file).Nodump)
|
||||
{
|
||||
outfiles.Add(file);
|
||||
continue;
|
||||
}
|
||||
|
||||
// If it's the first rom in the list, don't touch it
|
||||
if (outfiles.Count != 0)
|
||||
{
|
||||
// Check if the rom is a duplicate
|
||||
DupeType dupetype = DupeType.None;
|
||||
DatItem saveditem = new Rom();
|
||||
int pos = -1;
|
||||
for (int i = 0; i < outfiles.Count; i++)
|
||||
{
|
||||
DatItem lastrom = outfiles[i];
|
||||
|
||||
// Get the duplicate status
|
||||
dupetype = file.GetDuplicateStatus(lastrom, logger);
|
||||
|
||||
// If it's a duplicate, skip adding it to the output but add any missing information
|
||||
if (dupetype != DupeType.None)
|
||||
{
|
||||
// If we don't have a rom or disk, then just skip adding
|
||||
if (file.Type != ItemType.Rom && file.Type != ItemType.Disk)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
saveditem = lastrom;
|
||||
pos = i;
|
||||
|
||||
// Roms have more infomration to save
|
||||
if (file.Type == ItemType.Rom)
|
||||
{
|
||||
((Rom)saveditem).Size = ((Rom)saveditem).Size;
|
||||
((Rom)saveditem).CRC = (String.IsNullOrEmpty(((Rom)saveditem).CRC) && !String.IsNullOrEmpty(((Rom)file).CRC)
|
||||
? ((Rom)file).CRC
|
||||
: ((Rom)saveditem).CRC);
|
||||
((Rom)saveditem).MD5 = (String.IsNullOrEmpty(((Rom)saveditem).MD5) && !String.IsNullOrEmpty(((Rom)file).MD5)
|
||||
? ((Rom)file).MD5
|
||||
: ((Rom)saveditem).MD5);
|
||||
((Rom)saveditem).SHA1 = (String.IsNullOrEmpty(((Rom)saveditem).SHA1) && !String.IsNullOrEmpty(((Rom)file).SHA1)
|
||||
? ((Rom)file).SHA1
|
||||
: ((Rom)saveditem).SHA1);
|
||||
}
|
||||
else
|
||||
{
|
||||
((Disk)saveditem).MD5 = (String.IsNullOrEmpty(((Disk)saveditem).MD5) && !String.IsNullOrEmpty(((Disk)file).MD5)
|
||||
? ((Disk)file).MD5
|
||||
: ((Disk)saveditem).MD5);
|
||||
((Disk)saveditem).SHA1 = (String.IsNullOrEmpty(((Disk)saveditem).SHA1) && !String.IsNullOrEmpty(((Disk)file).SHA1)
|
||||
? ((Disk)file).SHA1
|
||||
: ((Disk)saveditem).SHA1);
|
||||
}
|
||||
|
||||
saveditem.Dupe = dupetype;
|
||||
|
||||
// If the current system has a lower ID than the previous, set the system accordingly
|
||||
if (file.SystemID < saveditem.SystemID)
|
||||
{
|
||||
saveditem.SystemID = file.SystemID;
|
||||
saveditem.System = file.System;
|
||||
saveditem.MachineName = file.MachineName;
|
||||
saveditem.Name = file.Name;
|
||||
}
|
||||
|
||||
// If the current source has a lower ID than the previous, set the source accordingly
|
||||
if (file.SourceID < saveditem.SourceID)
|
||||
{
|
||||
saveditem.SourceID = file.SourceID;
|
||||
saveditem.Source = file.Source;
|
||||
saveditem.MachineName = file.MachineName;
|
||||
saveditem.Name = file.Name;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If no duplicate is found, add it to the list
|
||||
if (dupetype == DupeType.None)
|
||||
{
|
||||
outfiles.Add(file);
|
||||
}
|
||||
// Otherwise, if a new rom information is found, add that
|
||||
else
|
||||
{
|
||||
outfiles.RemoveAt(pos);
|
||||
outfiles.Insert(pos, saveditem);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
outfiles.Add(file);
|
||||
}
|
||||
}
|
||||
|
||||
// Then return the result
|
||||
return outfiles;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// List all duplicates found in a DAT based on a rom
|
||||
/// </summary>
|
||||
/// <param name="lastitem">Item 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 DatItem objects</returns>
|
||||
public static List<DatItem> GetDuplicates(DatItem lastitem, DatFile datdata, Logger logger, bool remove = false)
|
||||
{
|
||||
List<DatItem> output = new List<DatItem>();
|
||||
|
||||
// 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<DatItem> roms = datdata.Files[key];
|
||||
List<DatItem> left = new List<DatItem>();
|
||||
|
||||
foreach (DatItem rom in roms)
|
||||
{
|
||||
if (rom.IsDuplicate(lastitem, 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>
|
||||
/// Sort a list of File objects by SystemID, SourceID, Game, and Name (in order)
|
||||
/// </summary>
|
||||
/// <param name="roms">List of File 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<DatItem> roms, bool norename)
|
||||
{
|
||||
try
|
||||
{
|
||||
roms.Sort(delegate (DatItem x, DatItem y)
|
||||
{
|
||||
if (x.SystemID == y.SystemID)
|
||||
{
|
||||
if (x.SourceID == y.SourceID)
|
||||
{
|
||||
if (x.MachineName == y.MachineName)
|
||||
{
|
||||
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.MachineName, y.MachineName);
|
||||
}
|
||||
return (norename ? Style.CompareNumeric(x.MachineName, y.MachineName) : x.SourceID - y.SourceID);
|
||||
}
|
||||
return (norename ? Style.CompareNumeric(x.MachineName, y.MachineName) : x.SystemID - y.SystemID);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// Absorb the error
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
152
SabreTools.Helper/Objects/Dat/Disk.cs
Normal file
152
SabreTools.Helper/Objects/Dat/Disk.cs
Normal file
@@ -0,0 +1,152 @@
|
||||
using System;
|
||||
|
||||
namespace SabreTools.Helper
|
||||
{
|
||||
public class Disk : DatItem
|
||||
{
|
||||
#region Private instance variables
|
||||
|
||||
// Disk information
|
||||
protected string _md5;
|
||||
protected string _sha1;
|
||||
// private string _merge;
|
||||
// private DiskStatus _romStatus;
|
||||
protected bool _nodump;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Publicly facing variables
|
||||
|
||||
// Disk information
|
||||
public string MD5
|
||||
{
|
||||
get { return _md5; }
|
||||
set { _md5 = value; }
|
||||
}
|
||||
public string SHA1
|
||||
{
|
||||
get { return _sha1; }
|
||||
set { _sha1 = 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;
|
||||
_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;
|
||||
_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;
|
||||
}
|
||||
|
||||
if (((String.IsNullOrEmpty(_md5) || String.IsNullOrEmpty(newOther.MD5)) || this.MD5 == newOther.MD5) &&
|
||||
((String.IsNullOrEmpty(this.SHA1) || String.IsNullOrEmpty(newOther.SHA1)) || this.SHA1 == newOther.SHA1))
|
||||
{
|
||||
dupefound = true;
|
||||
}
|
||||
|
||||
return dupefound;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
149
SabreTools.Helper/Objects/Dat/Release.cs
Normal file
149
SabreTools.Helper/Objects/Dat/Release.cs
Normal 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 release return false
|
||||
if (_itemType != other.Type)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Otherwise, treat it as a reease
|
||||
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
|
||||
}
|
||||
}
|
||||
175
SabreTools.Helper/Objects/Dat/Rom.cs
Normal file
175
SabreTools.Helper/Objects/Dat/Rom.cs
Normal file
@@ -0,0 +1,175 @@
|
||||
using System;
|
||||
|
||||
namespace SabreTools.Helper
|
||||
{
|
||||
public class Rom : Disk
|
||||
{
|
||||
#region Private instance variables
|
||||
|
||||
// Rom information
|
||||
protected long _size;
|
||||
protected string _crc;
|
||||
private string _date;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Publicly facing variables
|
||||
|
||||
// Rom information
|
||||
public long Size
|
||||
{
|
||||
get { return _size; }
|
||||
set { _size = value; }
|
||||
}
|
||||
public string CRC
|
||||
{
|
||||
get { return _crc; }
|
||||
set { _crc = 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;
|
||||
_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;
|
||||
_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;
|
||||
}
|
||||
|
||||
if ((this.Size == newOther.Size) &&
|
||||
((String.IsNullOrEmpty(this.CRC) || String.IsNullOrEmpty(newOther.CRC)) || this.CRC == newOther.CRC) &&
|
||||
((String.IsNullOrEmpty(this.MD5) || String.IsNullOrEmpty(newOther.MD5)) || this.MD5 == newOther.MD5) &&
|
||||
((String.IsNullOrEmpty(this.SHA1) || String.IsNullOrEmpty(newOther.SHA1)) || this.SHA1 == newOther.SHA1))
|
||||
{
|
||||
dupefound = true;
|
||||
}
|
||||
|
||||
return dupefound;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
91
SabreTools.Helper/Objects/Dat/Sample.cs
Normal file
91
SabreTools.Helper/Objects/Dat/Sample.cs
Normal 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 sample, return false
|
||||
if (_itemType != other.Type)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Otherwise, treat it as a sample
|
||||
Sample newOther = (Sample)other;
|
||||
|
||||
// If the archive information matches
|
||||
return (_name == newOther.Name);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,472 +0,0 @@
|
||||
using Mono.Data.Sqlite;
|
||||
using SabreTools.Helper;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace SabreTools
|
||||
{
|
||||
/// <summary>
|
||||
/// Generate a DAT from the data in the database
|
||||
/// </summary>
|
||||
class Generate : IGenerate
|
||||
{
|
||||
// Private instance variables
|
||||
private string _systems;
|
||||
private string _sources;
|
||||
private string _outDir;
|
||||
private string _connectionString;
|
||||
private bool _norename;
|
||||
private bool _old;
|
||||
|
||||
// Private required variables
|
||||
private Logger _logger;
|
||||
|
||||
/// <summary>
|
||||
/// Initialize a Generate object with the given information
|
||||
/// </summary>
|
||||
/// <param name="systems">Comma-separated list of systems to be included in the DAT (blank means all)</param>
|
||||
/// <param name="sources">Comma-separated list of sources to be included in the DAT (blank means all)</param>
|
||||
/// <param name="outDir">The output folder where the generated DAT will be put; blank means the current directory</param>
|
||||
/// <param name="connectionString">Connection string for SQLite</param>
|
||||
/// <param name="logger">Logger object for file or console output</param>
|
||||
/// <param name="norename">True if files should not be renamed with system and/or source in merged mode (default false)</param>
|
||||
/// <param name="old">True if the output file should be in ClrMamePro format (default false)</param>
|
||||
public Generate(string systems, string sources, string outDir, string connectionString, Logger logger, bool norename = false, bool old = false)
|
||||
{
|
||||
_systems = systems;
|
||||
_sources = sources;
|
||||
_connectionString = connectionString;
|
||||
_norename = norename;
|
||||
_old = old;
|
||||
_logger = logger;
|
||||
|
||||
// Take care of special outfolder cases
|
||||
_outDir = (outDir == "" ? Environment.CurrentDirectory + Path.DirectorySeparatorChar :
|
||||
(!outDir.EndsWith(Path.DirectorySeparatorChar.ToString()) ? outDir + Path.DirectorySeparatorChar : outDir)
|
||||
);
|
||||
if (_outDir != "" && !Directory.Exists(_outDir))
|
||||
{
|
||||
Directory.CreateDirectory(_outDir);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generate a DAT file that is represented by the data in the Generate object.
|
||||
/// </summary>
|
||||
/// <returns>True if the file could be created, false otherwise</returns>
|
||||
public bool Export()
|
||||
{
|
||||
// Check to see if the source is an import-only. If so, tell the user and exit
|
||||
int id = 0;
|
||||
if (_sources != "" && Int32.TryParse(_sources, out id) && id <= 14)
|
||||
{
|
||||
_logger.Warning("This source (" + id + ") is import-only so a DAT cannot be created. We apologize for the inconvenience.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the system name, if applicable
|
||||
string systemname = "";
|
||||
if (_systems != "")
|
||||
{
|
||||
string query = "SELECT manufacturer, system FROM systems WHERE id in (" + _systems + ")";
|
||||
//string query = "SELECT manufacturer, name FROM system WHERE id in (" + _systems + ")";
|
||||
|
||||
using (SqliteConnection dbc = new SqliteConnection(_connectionString))
|
||||
{
|
||||
dbc.Open();
|
||||
using (SqliteCommand slc = new SqliteCommand(query, dbc))
|
||||
{
|
||||
using (SqliteDataReader sldr = slc.ExecuteReader())
|
||||
{
|
||||
// If there are no games for this combination, return nothing
|
||||
if (!sldr.HasRows)
|
||||
{
|
||||
_logger.Error("No system could be found with id in \"" + _systems + "\". Please check and try again.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Retrieve and build the system name from all retrieved
|
||||
int tempsize = 0;
|
||||
while (sldr.Read() && tempsize < 3)
|
||||
{
|
||||
systemname += (tempsize == 0 ?
|
||||
sldr.GetString(0) + " - " + sldr.GetString(1) :
|
||||
"; " + sldr.GetString(0) + " - " + sldr.GetString(1));
|
||||
tempsize++;
|
||||
}
|
||||
|
||||
// If there are more than 3 systems, just put "etc." on the end
|
||||
if (sldr.Read())
|
||||
{
|
||||
systemname += "; etc.";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
systemname = "ALL";
|
||||
}
|
||||
|
||||
string sourcename = "";
|
||||
if (_sources != "")
|
||||
{
|
||||
string query = "SELECT name FROM sources WHERE id in (" + _sources + ")";
|
||||
//string query = "SELECT name FROM source WHERE id in (" + _sources + ")";
|
||||
|
||||
using (SqliteConnection dbc = new SqliteConnection(_connectionString))
|
||||
{
|
||||
dbc.Open();
|
||||
using (SqliteCommand slc = new SqliteCommand(query, dbc))
|
||||
{
|
||||
using (SqliteDataReader sldr = slc.ExecuteReader())
|
||||
{
|
||||
// If there are no games for this combination, return nothing
|
||||
if (!sldr.HasRows)
|
||||
{
|
||||
_logger.Error("No source could be found with id in \"" + _sources + "\". Please check and try again.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Retrieve and build the source name from all retrieved
|
||||
int tempsize = 0;
|
||||
while (sldr.Read() && tempsize < 3)
|
||||
{
|
||||
sourcename += (tempsize == 0 ? sldr.GetString(0) : "; " + sldr.GetString(0));
|
||||
tempsize++;
|
||||
}
|
||||
|
||||
// If there are more than 3 systems, just put "etc." on the end
|
||||
if (sldr.Read())
|
||||
{
|
||||
sourcename += "; etc.";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sourcename = "Merged";
|
||||
}
|
||||
|
||||
// Retrieve the list of processed roms
|
||||
Dictionary<string, List<Rom>> dict = ProcessRoms();
|
||||
|
||||
// If the output is null, nothing was found so return false
|
||||
if (dict.Count == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create a name for the file based on the retrieved information
|
||||
string version = DateTime.Now.ToString("yyyyMMddHHmmss");
|
||||
string intname = systemname + " (" + sourcename + ")";
|
||||
string datname = systemname + " (" + sourcename + " " + version + ")";
|
||||
|
||||
Dat datdata = new Dat
|
||||
{
|
||||
Name = intname,
|
||||
Description = datname,
|
||||
Version = version,
|
||||
Date = version,
|
||||
Category = "The Wizard of DATz",
|
||||
Author = "The Wizard of DATz",
|
||||
ForcePacking = ForcePacking.None,
|
||||
OutputFormat = (_old ? OutputFormat.ClrMamePro : OutputFormat.Xml),
|
||||
Files = dict,
|
||||
};
|
||||
|
||||
return DatTools.WriteDatfile(datdata, _outDir, _logger);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Preprocess the rom data that is to be included in the outputted DAT
|
||||
/// </summary>
|
||||
/// <returns>A List of Rom objects containing all information about the files</returns>
|
||||
public Dictionary<string, List<Rom>> ProcessRoms()
|
||||
{
|
||||
Dictionary<string, List<Rom>> roms = new Dictionary<string, List<Rom>>();
|
||||
|
||||
// Check if we have listed sources or systems
|
||||
bool sysmerged = (_systems == "" || _systems.Split(',').Length > 1);
|
||||
bool srcmerged = (_sources == "" || _sources.Split(',').Length > 1);
|
||||
bool merged = sysmerged || srcmerged;
|
||||
|
||||
// BEGIN COMMENT
|
||||
string query = @"
|
||||
SELECT DISTINCT systems.manufacturer AS manufacturer, systems.system AS system, systems.id AS systemid,
|
||||
sources.name AS source, sources.url AS url, sources.id AS sourceid,
|
||||
games.name AS game, files.name AS name, files.type AS type,
|
||||
checksums.size AS size, checksums.crc AS crc, checksums.md5 AS md5, checksums.sha1 AS sha1,
|
||||
files.lastupdated AS lastupdated
|
||||
FROM systems
|
||||
JOIN games
|
||||
ON systems.id=games.system
|
||||
JOIN sources
|
||||
ON games.source=sources.id
|
||||
JOIN files
|
||||
ON games.id=files.setid
|
||||
JOIN checksums
|
||||
ON files.id=checksums.file" +
|
||||
(_systems != "" || _sources != "" ? "\nWHERE" : "") +
|
||||
(_sources != "" ? " sources.id in (" + _sources + ")" : "") +
|
||||
(_systems != "" && _sources != "" ? " AND" : "") +
|
||||
(_systems != "" ? " systems.id in (" + _systems + ")" : "") +
|
||||
"\nORDER BY " +
|
||||
(merged ? "checksums.size, checksums.crc, systems.id, sources.id, files.lastupdated DESC, checksums.md5, checksums.sha1"
|
||||
: "systems.id, sources.id, games.name, files.name");
|
||||
|
||||
using (SqliteConnection dbc = new SqliteConnection(_connectionString))
|
||||
{
|
||||
dbc.Open();
|
||||
using (SqliteCommand slc = new SqliteCommand(query, dbc))
|
||||
{
|
||||
using (SqliteDataReader sldr = slc.ExecuteReader())
|
||||
{
|
||||
// If there are no games for this combination, return nothing
|
||||
if (!sldr.HasRows)
|
||||
{
|
||||
_logger.Error("No games could be found with those inputs. Please check and try again.");
|
||||
return null;
|
||||
}
|
||||
|
||||
// Retrieve and process the roms for merging
|
||||
while (sldr.Read())
|
||||
{
|
||||
Rom temp = new Rom
|
||||
{
|
||||
Name = sldr.GetString(7),
|
||||
Type = (sldr.GetString(8) == "disk" ? ItemType.Disk : ItemType.Rom),
|
||||
Machine = new Machine
|
||||
{
|
||||
Name = sldr.GetString(6),
|
||||
Manufacturer = sldr.GetString(0),
|
||||
},
|
||||
Metadata = new SourceMetadata
|
||||
{
|
||||
System = sldr.GetString(1),
|
||||
SystemID = sldr.GetInt32(2),
|
||||
Source = sldr.GetString(3),
|
||||
SourceID = sldr.GetInt32(5),
|
||||
},
|
||||
HashData = new Hash
|
||||
{
|
||||
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
|
||||
if (merged && !_norename)
|
||||
{
|
||||
temp.Machine.Name = temp.Machine.Name +
|
||||
(sysmerged ? " [" + temp.Machine.Manufacturer + " - " + temp.Metadata.System + "]" : "") +
|
||||
(srcmerged ? " [" + temp.Metadata.Source + "]" : "");
|
||||
}
|
||||
|
||||
string key = temp.HashData.Size + "-" + temp.HashData.CRC;
|
||||
if (roms.ContainsKey(key))
|
||||
{
|
||||
roms[key].Add(temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
List<Rom> templist = new List<Rom>();
|
||||
templist.Add(temp);
|
||||
roms.Add(key, templist);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we're in a merged mode, merge and then resort by the correct parameters
|
||||
if (merged)
|
||||
{
|
||||
foreach (string key in roms.Keys)
|
||||
{
|
||||
roms[key] = RomTools.Merge(roms[key], _logger);
|
||||
}
|
||||
}
|
||||
// END COMMENT
|
||||
|
||||
/*
|
||||
// This block would replace the whole block above between BEGIN COMMENT and END COMMENT
|
||||
string query = @"
|
||||
SELECT hash.id AS id, hash.size AS size, hash.crc AS crc, hash.md5 AS md5, hash.sha1 AS sha1,
|
||||
a.key AS key, a.value AS value,
|
||||
source.id, source.name, source.url,
|
||||
system.id, system.manufacturer, system.name
|
||||
FROM hash
|
||||
JOIN hashdata a
|
||||
ON hash.id=a.hashid
|
||||
JOIN hashdata b
|
||||
ON a.hashid=b.hashid
|
||||
JOIN gamesystem
|
||||
ON b.value=gamesystem.game
|
||||
JOIN gamesource
|
||||
ON b.value=gamesource.game
|
||||
JOIN system
|
||||
ON gamesystem.systemid=system.id
|
||||
JOIN source
|
||||
ON gamesource.sourceid=source.id" +
|
||||
(_systems != "" || _sources != "" ? "\nWHERE" : "") +
|
||||
(_sources != "" ? " source.id in (" + _sources + ")" : "") +
|
||||
(_systems != "" && _sources != "" ? " AND" : "") +
|
||||
(_systems != "" ? " system.id in (" + _systems + ")" : "") +
|
||||
"\nORDER BY hash.id";
|
||||
|
||||
using (SqliteConnection dbc = new SqliteConnection(_connectionString))
|
||||
{
|
||||
dbc.Open();
|
||||
using (SqliteCommand slc = new SqliteCommand(query, dbc))
|
||||
{
|
||||
using (SqliteDataReader sldr = slc.ExecuteReader())
|
||||
{
|
||||
// If there are no games for this combination, return nothing
|
||||
if (!sldr.HasRows)
|
||||
{
|
||||
_logger.Error("No games could be found with those inputs. Please check and try again.");
|
||||
return null;
|
||||
}
|
||||
|
||||
// Retrieve and process the roms for merging
|
||||
int systemid = -1, sourceid = -1;
|
||||
long lastid = -1, size = -1;
|
||||
string name = "", game = "", type = "", manufacturer = "", system = "", source = "", url = "", crc = "", md5 = "", sha1 = "";
|
||||
while (sldr.Read())
|
||||
{
|
||||
// If the hash is different than the last
|
||||
if (lastid != -1 && sldr.GetInt64(0) != lastid)
|
||||
{
|
||||
Rom temp = new Rom
|
||||
{
|
||||
Manufacturer = manufacturer,
|
||||
System = system,
|
||||
SystemID = systemid,
|
||||
Source = source,
|
||||
URL = url,
|
||||
SourceID = sourceid,
|
||||
Game = game,
|
||||
Name = name,
|
||||
Type = type,
|
||||
Size = size,
|
||||
CRC = crc,
|
||||
MD5 = md5,
|
||||
SHA1 = sha1,
|
||||
};
|
||||
|
||||
// Rename the game associated if it's still valid and we allow renames
|
||||
if (merged && !_norename)
|
||||
{
|
||||
temp.Machine = temp.Machine +
|
||||
(sysmerged ? " [" + temp.Manufacturer + " - " + temp.System + "]" : "") +
|
||||
(srcmerged ? " [" + temp.Source + "]" : "");
|
||||
}
|
||||
|
||||
string key = temp.Size + "-" + temp.CRC;
|
||||
if (roms.ContainsKey(key))
|
||||
{
|
||||
roms[key].Add(temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
List<Rom> templist = new List<Rom>();
|
||||
templist.Add(temp);
|
||||
roms.Add(key, templist);
|
||||
}
|
||||
|
||||
// Reset the variables
|
||||
game = "";
|
||||
name = "";
|
||||
type = "";
|
||||
}
|
||||
|
||||
// Get all of the current ROM information
|
||||
manufacturer = sldr.GetString(11);
|
||||
system = sldr.GetString(12);
|
||||
systemid = sldr.GetInt32(10);
|
||||
source = sldr.GetString(8);
|
||||
url = sldr.GetString(9);
|
||||
sourceid = sldr.GetInt32(7);
|
||||
size = sldr.GetInt64(1);
|
||||
crc = sldr.GetString(2);
|
||||
md5 = sldr.GetString(3);
|
||||
sha1 = sldr.GetString(4);
|
||||
|
||||
switch (sldr.GetString(5))
|
||||
{
|
||||
case "game":
|
||||
game = sldr.GetString(6);
|
||||
break;
|
||||
case "name":
|
||||
name = sldr.GetString(6);
|
||||
break;
|
||||
case "type":
|
||||
type = sldr.GetString(6);
|
||||
break;
|
||||
}
|
||||
|
||||
lastid = sldr.GetInt64(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we're in a merged mode, merge
|
||||
if (merged)
|
||||
{
|
||||
foreach (string key in roms.Keys)
|
||||
{
|
||||
roms[key] = RomManipulation.Merge(roms[key]);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
// THIS CODE SHOULD BE PUT IN WriteToDatFromDict
|
||||
|
||||
// Now check rename within games
|
||||
string lastname = "", lastgame = "";
|
||||
for (int i = 0; i < roms.Count; i++)
|
||||
{
|
||||
Rom rom = roms[i];
|
||||
|
||||
// Now relable any roms that have the same name inside of the same game
|
||||
bool samename = false, samegame = false;
|
||||
if (rom.Name != "")
|
||||
{
|
||||
samename = (lastname == rom.Name);
|
||||
}
|
||||
if (rom.Machine != "")
|
||||
{
|
||||
samegame = (lastgame == rom.Machine);
|
||||
}
|
||||
|
||||
lastname = rom.Name;
|
||||
lastgame = rom.Machine;
|
||||
|
||||
// If the name and set are the same, rename it with whatever is different
|
||||
if (samename && samegame)
|
||||
{
|
||||
rom.Name = Regex.Replace(rom.Name, @"^(.*)(\..*)", "$1(" +
|
||||
(rom.CRC != "" ? rom.CRC :
|
||||
(rom.MD5 != "" ? rom.MD5 :
|
||||
(rom.SHA1 != "" ? rom.SHA1 : "Alt"))) +
|
||||
")$2");
|
||||
}
|
||||
|
||||
// Assign back just in case
|
||||
roms[i] = rom;
|
||||
}
|
||||
*/
|
||||
|
||||
return roms;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -144,7 +144,7 @@ namespace SabreTools
|
||||
}
|
||||
|
||||
// Create the output DatData object
|
||||
Dat datdata = new Dat
|
||||
DatFile datdata = new DatFile
|
||||
{
|
||||
FileName = description,
|
||||
Name = name,
|
||||
@@ -173,7 +173,7 @@ namespace SabreTools
|
||||
{
|
||||
Int32.TryParse(sourcemap[hash], out tempSrcId);
|
||||
}
|
||||
DatTools.Parse(file, 0, tempSrcId, ref datdata, _logger);
|
||||
DatFile.Parse(file, 0, tempSrcId, ref datdata, _logger);
|
||||
}
|
||||
|
||||
// If the dictionary is empty for any reason, tell the user and exit
|
||||
@@ -188,14 +188,14 @@ namespace SabreTools
|
||||
List<string> keys = datdata.Files.Keys.ToList();
|
||||
foreach (string key in keys)
|
||||
{
|
||||
List<Rom> temp = new List<Rom>();
|
||||
List<Rom> newroms = datdata.Files[key];
|
||||
List<DatItem> temp = new List<DatItem>();
|
||||
List<DatItem> newroms = datdata.Files[key];
|
||||
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
|
||||
if (rom.Name == null || rom.Machine.Name == null)
|
||||
if (rom.Name == null || rom.MachineName == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -209,27 +209,27 @@ namespace SabreTools
|
||||
rom.Name = Regex.Replace(rom.Name, @"(.*) \.(.*)", "$1.$2");
|
||||
|
||||
// Run the name through the filters to make sure that it's correct
|
||||
rom.Machine.Name = Style.NormalizeChars(rom.Machine.Name);
|
||||
rom.Machine.Name = Style.RussianToLatin(rom.Machine.Name);
|
||||
rom.Machine.Name = Style.SearchPattern(rom.Machine.Name);
|
||||
rom.MachineName = Style.NormalizeChars(rom.MachineName);
|
||||
rom.MachineName = Style.RussianToLatin(rom.MachineName);
|
||||
rom.MachineName = Style.SearchPattern(rom.MachineName);
|
||||
|
||||
// WoD gets rid of anything past the first "(" or "[" as the name, we will do the same
|
||||
string stripPattern = @"(([[(].*[\)\]] )?([^([]+))";
|
||||
Regex stripRegex = new Regex(stripPattern);
|
||||
Match stripMatch = stripRegex.Match(rom.Machine.Name);
|
||||
rom.Machine.Name = stripMatch.Groups[1].Value;
|
||||
Match stripMatch = stripRegex.Match(rom.MachineName);
|
||||
rom.MachineName = stripMatch.Groups[1].Value;
|
||||
|
||||
rom.Machine.Name = rom.Machine.Name.TrimEnd().TrimStart();
|
||||
rom.MachineName = rom.MachineName.TrimEnd().TrimStart();
|
||||
|
||||
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 (rom.Metadata.SourceID == 0)
|
||||
if (rom.SourceID == 0)
|
||||
{
|
||||
rom.Metadata.SourceID = Int32.MaxValue;
|
||||
rom.SourceID = Int32.MaxValue;
|
||||
}
|
||||
|
||||
temp.Add(rom);
|
||||
@@ -238,7 +238,7 @@ namespace SabreTools
|
||||
}
|
||||
|
||||
// Then write out the file
|
||||
DatTools.WriteDatfile(datdata, _outroot, _logger, _norename);
|
||||
DatFile.WriteDatfile(datdata, _outroot, _logger, _norename);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -132,7 +132,7 @@ namespace SabreTools
|
||||
|
||||
// Now add the information to the database if it's not already there
|
||||
Rom rom = FileTools.GetSingleFileInfo(newfile);
|
||||
AddHeaderToDatabase(hstr, rom.HashData.SHA1, type);
|
||||
AddHeaderToDatabase(hstr, rom.SHA1, type);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -191,7 +191,7 @@ namespace SabreTools
|
||||
// Then try to pull the corresponding headers from the database
|
||||
string header = "";
|
||||
|
||||
string query = @"SELECT header, type FROM data WHERE sha1='" + rom.HashData.SHA1 + "'";
|
||||
string query = @"SELECT header, type FROM data WHERE sha1='" + rom.SHA1 + "'";
|
||||
using (SqliteConnection dbc = new SqliteConnection(Constants.HeadererConnectionString))
|
||||
{
|
||||
dbc.Open();
|
||||
|
||||
@@ -1,652 +0,0 @@
|
||||
using Mono.Data.Sqlite;
|
||||
using SabreTools.Helper;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace SabreTools
|
||||
{
|
||||
/// <summary>
|
||||
/// Import data into the database from existing DATs
|
||||
/// </summary>
|
||||
public class Import : IImport
|
||||
{
|
||||
// Private instance variables
|
||||
private string _filepath;
|
||||
private string _connectionString;
|
||||
private Logger _logger;
|
||||
|
||||
/// <summary>
|
||||
/// Initialize an Import object with the given information
|
||||
/// </summary>
|
||||
/// <param name="filepath">Path to the file that is going to be imported</param>
|
||||
/// <param name="connectionString">Connection string for SQLite</param>
|
||||
/// <param name="logger">Logger object for file or console output</param>
|
||||
public Import(string filepath, string connectionString, Logger logger)
|
||||
{
|
||||
_filepath = filepath;
|
||||
_connectionString = connectionString;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Import the data from file into the database
|
||||
/// </summary>
|
||||
/// <returns>True if the data was imported, false otherwise</returns>
|
||||
public bool UpdateDatabase()
|
||||
{
|
||||
// If file doesn't exist, error and return
|
||||
if (!File.Exists(_filepath))
|
||||
{
|
||||
_logger.Error("File '" + _filepath + "' doesn't exist");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Determine which dattype we have
|
||||
string filename = Path.GetFileName(_filepath);
|
||||
GroupCollection fileinfo;
|
||||
DatType type = DatType.none;
|
||||
|
||||
if (Regex.IsMatch(filename, Constants.NonGoodPattern))
|
||||
{
|
||||
fileinfo = Regex.Match(filename, Constants.NonGoodPattern).Groups;
|
||||
type = DatType.NonGood;
|
||||
}
|
||||
else if (Regex.IsMatch(filename, Constants.NonGoodSpecialPattern))
|
||||
{
|
||||
fileinfo = Regex.Match(filename, Constants.NonGoodSpecialPattern).Groups;
|
||||
type = DatType.NonGood;
|
||||
}
|
||||
else if (Regex.IsMatch(filename, Constants.GoodPattern))
|
||||
{
|
||||
fileinfo = Regex.Match(filename, Constants.GoodPattern).Groups;
|
||||
type = DatType.Good;
|
||||
}
|
||||
else if (Regex.IsMatch(filename, Constants.GoodXmlPattern))
|
||||
{
|
||||
fileinfo = Regex.Match(filename, Constants.GoodXmlPattern).Groups;
|
||||
type = DatType.Good;
|
||||
}
|
||||
else if (Regex.IsMatch(filename, Constants.MaybeIntroPattern))
|
||||
{
|
||||
fileinfo = Regex.Match(filename, Constants.MaybeIntroPattern).Groups;
|
||||
type = DatType.MaybeIntro;
|
||||
}
|
||||
else if (Regex.IsMatch(filename, Constants.NoIntroPattern))
|
||||
{
|
||||
fileinfo = Regex.Match(filename, Constants.NoIntroPattern).Groups;
|
||||
type = DatType.NoIntro;
|
||||
}
|
||||
// For numbered DATs only
|
||||
else if (Regex.IsMatch(filename, Constants.NoIntroNumberedPattern))
|
||||
{
|
||||
fileinfo = Regex.Match(filename, Constants.NoIntroNumberedPattern).Groups;
|
||||
type = DatType.NoIntro;
|
||||
}
|
||||
// For N-Gage and Gizmondo only
|
||||
else if (Regex.IsMatch(filename, Constants.NoIntroSpecialPattern))
|
||||
{
|
||||
fileinfo = Regex.Match(filename, Constants.NoIntroSpecialPattern).Groups;
|
||||
type = DatType.NoIntro;
|
||||
}
|
||||
else if (Regex.IsMatch(filename, Constants.RedumpPattern))
|
||||
{
|
||||
fileinfo = Regex.Match(filename, Constants.RedumpPattern).Groups;
|
||||
type = DatType.Redump;
|
||||
}
|
||||
// For special BIOSes only
|
||||
else if (Regex.IsMatch(filename, Constants.RedumpBiosPattern))
|
||||
{
|
||||
fileinfo = Regex.Match(filename, Constants.RedumpBiosPattern).Groups;
|
||||
type = DatType.Redump;
|
||||
}
|
||||
else if (Regex.IsMatch(filename, Constants.TosecPattern))
|
||||
{
|
||||
fileinfo = Regex.Match(filename, Constants.TosecPattern).Groups;
|
||||
type = DatType.TOSEC;
|
||||
}
|
||||
else if (Regex.IsMatch(filename, Constants.TruripPattern))
|
||||
{
|
||||
fileinfo = Regex.Match(filename, Constants.TruripPattern).Groups;
|
||||
type = DatType.TruRip;
|
||||
}
|
||||
else if (Regex.IsMatch(filename, Constants.ZandroPattern))
|
||||
{
|
||||
filename = "Nintendo - Super Nintendo Entertainment System (Zandro " + File.GetLastWriteTime(_filepath).ToString("yyyyMMddHHmmss") + ").dat";
|
||||
fileinfo = Regex.Match(filename, Constants.DefaultPattern).Groups;
|
||||
type = DatType.Custom;
|
||||
}
|
||||
else if (Regex.IsMatch(filename, Constants.DefaultPattern))
|
||||
{
|
||||
fileinfo = Regex.Match(filename, Constants.DefaultPattern).Groups;
|
||||
type = DatType.Custom;
|
||||
}
|
||||
else if (Regex.IsMatch(filename, Constants.DefaultSpecialPattern))
|
||||
{
|
||||
fileinfo = Regex.Match(filename, Constants.DefaultSpecialPattern).Groups;
|
||||
type = DatType.Custom;
|
||||
}
|
||||
else if (Regex.IsMatch(filename, Constants.MamePattern))
|
||||
{
|
||||
fileinfo = Regex.Match(filename, Constants.MamePattern).Groups;
|
||||
type = DatType.MAME;
|
||||
}
|
||||
// If the type is still unmatched, the data can't be imported yet
|
||||
else
|
||||
{
|
||||
_logger.Warning("File " + filename + " cannot be imported at this time because it is not a known pattern.\nPlease try again with an unrenamed version.");
|
||||
return false;
|
||||
}
|
||||
|
||||
_logger.Log("Type detected: " + type.ToString());
|
||||
|
||||
// Check for and extract import information from the file name based on type
|
||||
string manufacturer = "";
|
||||
string system = "";
|
||||
string source = "";
|
||||
string datestring = "";
|
||||
string date = "";
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case DatType.Good:
|
||||
if (!Mappings.DatMaps["Good"].ContainsKey(fileinfo[1].Value))
|
||||
{
|
||||
_logger.Warning("The filename " + fileinfo[1].Value + " could not be mapped! Please check the mappings and try again");
|
||||
return false;
|
||||
}
|
||||
GroupCollection goodInfo = Regex.Match(Mappings.DatMaps["Good"][fileinfo[1].Value], Constants.RemappedPattern).Groups;
|
||||
|
||||
manufacturer = goodInfo[1].Value;
|
||||
system = goodInfo[2].Value;
|
||||
source = "Good";
|
||||
date = File.GetLastWriteTime(_filepath).ToString("yyyy-MM-dd HH:mm:ss");
|
||||
break;
|
||||
case DatType.MAME:
|
||||
if (!Mappings.DatMaps["MAME"].ContainsKey(fileinfo[1].Value))
|
||||
{
|
||||
_logger.Warning("The filename " + fileinfo[1].Value + " could not be mapped! Please check the mappings and try again");
|
||||
return false;
|
||||
}
|
||||
GroupCollection mameInfo = Regex.Match(Mappings.DatMaps["MAME"][fileinfo[1].Value], Constants.RemappedPattern).Groups;
|
||||
|
||||
manufacturer = mameInfo[1].Value;
|
||||
system = mameInfo[2].Value;
|
||||
source = "MAME";
|
||||
date = File.GetLastWriteTime(_filepath).ToString("yyyy-MM-dd HH:mm:ss");
|
||||
break;
|
||||
case DatType.MaybeIntro:
|
||||
if (!Mappings.DatMaps["MaybeIntro"].ContainsKey(fileinfo[1].Value))
|
||||
{
|
||||
_logger.Warning("The filename " + fileinfo[1].Value + " could not be mapped! Please check the mappings and try again");
|
||||
return false;
|
||||
}
|
||||
GroupCollection maybeIntroInfo = Regex.Match(Mappings.DatMaps["MaybeIntro"][fileinfo[1].Value], Constants.RemappedPattern).Groups;
|
||||
|
||||
manufacturer = maybeIntroInfo[1].Value;
|
||||
system = maybeIntroInfo[2].Value;
|
||||
source = "Maybe-Intro";
|
||||
datestring = fileinfo[2].Value;
|
||||
GroupCollection miDateInfo = Regex.Match(datestring, Constants.NoIntroSpecialDatePattern).Groups;
|
||||
date = miDateInfo[1].Value + "-" + miDateInfo[2].Value + "-" + miDateInfo[3].Value + " 00:00:00";
|
||||
break;
|
||||
case DatType.NoIntro:
|
||||
if (!Mappings.DatMaps["NoIntro"].ContainsKey(fileinfo[1].Value))
|
||||
{
|
||||
_logger.Warning("The filename " + fileinfo[1].Value + " could not be mapped! Please check the mappings and try again");
|
||||
return false;
|
||||
}
|
||||
GroupCollection nointroInfo = Regex.Match(Mappings.DatMaps["NoIntro"][fileinfo[1].Value], Constants.RemappedPattern).Groups;
|
||||
|
||||
manufacturer = nointroInfo[1].Value;
|
||||
system = nointroInfo[2].Value;
|
||||
source = "no-Intro";
|
||||
if (fileinfo.Count < 2)
|
||||
{
|
||||
date = File.GetLastWriteTime(_filepath).ToString("yyyy-MM-dd HH:mm:ss");
|
||||
}
|
||||
else if (Regex.IsMatch(fileinfo[2].Value, Constants.NoIntroDatePattern))
|
||||
{
|
||||
datestring = fileinfo[2].Value;
|
||||
GroupCollection niDateInfo = Regex.Match(datestring, Constants.NoIntroDatePattern).Groups;
|
||||
date = niDateInfo[1].Value + "-" + niDateInfo[2].Value + "-" + niDateInfo[3].Value + " " +
|
||||
niDateInfo[4].Value + ":" + niDateInfo[5].Value + ":" + niDateInfo[6].Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
datestring = fileinfo[2].Value;
|
||||
GroupCollection niDateInfo = Regex.Match(datestring, Constants.NoIntroSpecialDatePattern).Groups;
|
||||
date = niDateInfo[1].Value + "-" + niDateInfo[2].Value + "-" + niDateInfo[3].Value + " 00:00:00";
|
||||
}
|
||||
break;
|
||||
case DatType.NonGood:
|
||||
if (!Mappings.DatMaps["NonGood"].ContainsKey(fileinfo[1].Value))
|
||||
{
|
||||
_logger.Warning("The filename " + fileinfo[1].Value + " could not be mapped! Please check the mappings and try again");
|
||||
return false;
|
||||
}
|
||||
GroupCollection nonGoodInfo = Regex.Match(Mappings.DatMaps["NonGood"][fileinfo[1].Value], Constants.RemappedPattern).Groups;
|
||||
|
||||
manufacturer = nonGoodInfo[1].Value;
|
||||
system = nonGoodInfo[2].Value;
|
||||
source = "NonGood";
|
||||
date = File.GetLastWriteTime(_filepath).ToString("yyyy-MM-dd HH:mm:ss");
|
||||
break;
|
||||
case DatType.Redump:
|
||||
if (!Mappings.DatMaps["Redump"].ContainsKey(fileinfo[1].Value))
|
||||
{
|
||||
// Handle special case mappings found only in Redump
|
||||
fileinfo = Regex.Match(filename, Constants.RedumpBiosPattern).Groups;
|
||||
|
||||
if (!Mappings.DatMaps["Redump"].ContainsKey(fileinfo[1].Value))
|
||||
{
|
||||
_logger.Warning("The filename " + fileinfo[1].Value + " could not be mapped! Please check the mappings and try again");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
GroupCollection redumpInfo = Regex.Match(Mappings.DatMaps["Redump"][fileinfo[1].Value], Constants.RemappedPattern).Groups;
|
||||
|
||||
manufacturer = redumpInfo[1].Value;
|
||||
system = redumpInfo[2].Value;
|
||||
source = "Redump";
|
||||
datestring = fileinfo[2].Value;
|
||||
if (Regex.IsMatch(datestring, Constants.RedumpDatePattern))
|
||||
{
|
||||
GroupCollection rdDateInfo = Regex.Match(datestring, Constants.RedumpDatePattern).Groups;
|
||||
date = rdDateInfo[1].Value + "-" + rdDateInfo[2].Value + "-" + rdDateInfo[3].Value + " " +
|
||||
rdDateInfo[4].Value + ":" + rdDateInfo[5].Value + ":" + rdDateInfo[6].Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
GroupCollection rdDateInfo = Regex.Match(datestring, Constants.TosecDatePattern).Groups;
|
||||
date = rdDateInfo[1].Value + "-" + rdDateInfo[2].Value + "-" + rdDateInfo[3].Value + " 00:00:00";
|
||||
}
|
||||
|
||||
break;
|
||||
case DatType.TOSEC:
|
||||
if (!Mappings.DatMaps["TOSEC"].ContainsKey(fileinfo[1].Value))
|
||||
{
|
||||
// Handle special case mappings found only in TOSEC
|
||||
fileinfo = Regex.Match(filename, Constants.TosecSpecialPatternA).Groups;
|
||||
|
||||
if (!Mappings.DatMaps["TOSEC"].ContainsKey(fileinfo[1].Value))
|
||||
{
|
||||
fileinfo = Regex.Match(filename, Constants.TosecSpecialPatternB).Groups;
|
||||
|
||||
if (!Mappings.DatMaps["TOSEC"].ContainsKey(fileinfo[1].Value))
|
||||
{
|
||||
_logger.Warning("The filename " + fileinfo[1].Value + " could not be mapped! Please check the mappings and try again");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
GroupCollection tosecInfo = Regex.Match(Mappings.DatMaps["TOSEC"][fileinfo[1].Value], Constants.RemappedPattern).Groups;
|
||||
|
||||
manufacturer = tosecInfo[1].Value;
|
||||
system = tosecInfo[2].Value;
|
||||
source = "TOSEC";
|
||||
datestring = fileinfo[2].Value;
|
||||
GroupCollection toDateInfo = Regex.Match(datestring, Constants.TosecDatePattern).Groups;
|
||||
date = toDateInfo[1].Value + "-" + toDateInfo[2].Value + "-" + toDateInfo[3].Value + " 00:00:00";
|
||||
break;
|
||||
case DatType.TruRip:
|
||||
if (!Mappings.DatMaps["TruRip"].ContainsKey(fileinfo[1].Value))
|
||||
{
|
||||
_logger.Warning("The filename " + fileinfo[1].Value + " could not be mapped! Please check the mappings and try again");
|
||||
return false;
|
||||
}
|
||||
GroupCollection truripInfo = Regex.Match(Mappings.DatMaps["TruRip"][fileinfo[1].Value], Constants.RemappedPattern).Groups;
|
||||
|
||||
manufacturer = truripInfo[1].Value;
|
||||
system = truripInfo[2].Value;
|
||||
source = "trurip";
|
||||
date = File.GetLastWriteTime(_filepath).ToString("yyyy-MM-dd HH:mm:ss");
|
||||
break;
|
||||
case DatType.Custom:
|
||||
default:
|
||||
manufacturer = fileinfo[1].Value;
|
||||
system = fileinfo[2].Value;
|
||||
source = fileinfo[3].Value;
|
||||
datestring = fileinfo[4].Value;
|
||||
|
||||
GroupCollection cDateInfo = Regex.Match(datestring, Constants.DefaultDatePattern).Groups;
|
||||
date = cDateInfo[1].Value + "-" + cDateInfo[2].Value + "-" + cDateInfo[3].Value + " " +
|
||||
cDateInfo[4].Value + ":" + cDateInfo[5].Value + ":" + cDateInfo[6].Value;
|
||||
break;
|
||||
}
|
||||
|
||||
// Check to make sure that the manufacturer and system are valid according to the database
|
||||
int sysid = -1;
|
||||
string query = "SELECT id FROM systems WHERE manufacturer='" + manufacturer + "' AND system='" + system +"'";
|
||||
//string query = "SELECT id FROM system WHERE manufacturer='" + manufacturer + "' AND name='" + system + "'";
|
||||
using (SqliteConnection dbc = new SqliteConnection(_connectionString))
|
||||
{
|
||||
dbc.Open();
|
||||
using (SqliteCommand slc = new SqliteCommand(query, dbc))
|
||||
{
|
||||
using (SqliteDataReader sldr = slc.ExecuteReader())
|
||||
{
|
||||
// If nothing is found, tell the user and exit
|
||||
if (!sldr.HasRows)
|
||||
{
|
||||
_logger.Error("No suitable system for '" + filename + "' (" + manufacturer + " " + system + ") found! Please add the system and then try again.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set the system ID from the first found value
|
||||
sldr.Read();
|
||||
sysid = sldr.GetInt32(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check to make sure that the source is valid according to the database
|
||||
int srcid = -1;
|
||||
query = "SELECT id FROM sources WHERE name='" + source + "'";
|
||||
//query = "SELECT id FROM source WHERE name='" + source + "'";
|
||||
using (SqliteConnection dbc = new SqliteConnection(_connectionString))
|
||||
{
|
||||
dbc.Open();
|
||||
using (SqliteCommand slc = new SqliteCommand(query, dbc))
|
||||
{
|
||||
using (SqliteDataReader sldr = slc.ExecuteReader())
|
||||
{
|
||||
// If nothing is found, tell the user and exit
|
||||
if (!sldr.HasRows)
|
||||
{
|
||||
_logger.Error("No suitable source for '" + filename + "' found! Please add the source and then try again.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set the source ID from the first found value
|
||||
sldr.Read();
|
||||
srcid = sldr.GetInt32(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get all roms that are found in the DAT to see what needs to be added
|
||||
Dat datdata = new Dat();
|
||||
DatTools.Parse(_filepath, sysid, srcid, ref datdata, _logger);
|
||||
|
||||
// Sort inputted roms into games
|
||||
SortedDictionary<string, List<Rom>> sortable = new SortedDictionary<string, List<Rom>>();
|
||||
long count = 0;
|
||||
foreach (List<Rom> roms in datdata.Files.Values)
|
||||
{
|
||||
List<Rom> newroms = roms;
|
||||
if (datdata.MergeRoms)
|
||||
{
|
||||
newroms = RomTools.Merge(newroms, _logger);
|
||||
}
|
||||
|
||||
foreach (Rom rom in newroms)
|
||||
{
|
||||
count++;
|
||||
string key = rom.Metadata.SystemID.ToString().PadLeft(10, '0') + "-" + rom.Metadata.SourceID.ToString().PadLeft(10, '0') + "-" + rom.Machine.Name.ToLowerInvariant();
|
||||
if (sortable.ContainsKey(key))
|
||||
{
|
||||
sortable[key].Add(rom);
|
||||
}
|
||||
else
|
||||
{
|
||||
List<Rom> temp = new List<Rom>();
|
||||
temp.Add(rom);
|
||||
sortable.Add(key, temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Loop over all roms, checking for adds
|
||||
foreach (string key in sortable.Keys)
|
||||
{
|
||||
List<Rom> roms = sortable[key];
|
||||
RomTools.Sort(ref roms, true);
|
||||
|
||||
long gameid = -1;
|
||||
using (SqliteConnection dbc = new SqliteConnection(_connectionString))
|
||||
{
|
||||
dbc.Open();
|
||||
|
||||
// For each game, check for a new ID
|
||||
gameid = AddGame(sysid, roms[0].Machine.Name, srcid, dbc);
|
||||
|
||||
foreach (Rom rom in roms)
|
||||
{
|
||||
// BEGIN COMMENT
|
||||
// Try to add the rom with the game information
|
||||
AddRom(rom, gameid, date, dbc);
|
||||
// END COMMENT
|
||||
|
||||
/*
|
||||
// Try to add the romdata
|
||||
AddHash(rom, sysid, srcid, date, dbc);
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add a game to the database if it doesn't already exist
|
||||
/// </summary>
|
||||
/// <param name="sysid">System ID for the game to be added with</param>
|
||||
/// <param name="machinename">Name of the game to be added</param>
|
||||
/// <param name="srcid">Source ID for the game to be added with</param>
|
||||
/// <param name="dbc">SQLite database connection to use</param>
|
||||
/// <returns>Game ID of the inserted (or found) game, -1 on error</returns>
|
||||
private long AddGame(int sysid, string machinename, int srcid, SqliteConnection dbc)
|
||||
{
|
||||
// WoD gets rid of anything past the first "(" or "[" as the name, we will do the same
|
||||
string stripPattern = @"(([[(].*[\)\]] )?([^([]+))";
|
||||
Regex stripRegex = new Regex(stripPattern);
|
||||
Match stripMatch = stripRegex.Match(machinename);
|
||||
machinename = stripMatch.Groups[1].Value;
|
||||
|
||||
// Run the name through the filters to make sure that it's correct
|
||||
machinename = Style.NormalizeChars(machinename);
|
||||
machinename = Style.RussianToLatin(machinename);
|
||||
machinename = Style.SearchPattern(machinename);
|
||||
machinename = machinename.Trim();
|
||||
|
||||
long gameid = -1;
|
||||
string query = "SELECT id FROM games WHERE system=" + sysid +
|
||||
" AND name='" + machinename.Replace("'", "''") + "'" +
|
||||
" AND source=" + srcid;
|
||||
|
||||
using (SqliteCommand slc = new SqliteCommand(query, dbc))
|
||||
{
|
||||
using (SqliteDataReader sldr = slc.ExecuteReader())
|
||||
{
|
||||
// If nothing is found, add the game and get the insert ID
|
||||
if (!sldr.HasRows)
|
||||
{
|
||||
query = "INSERT INTO games (system, name, source)" +
|
||||
" VALUES (" + sysid + ", '" + machinename.Replace("'", "''") + "', " + srcid + ")";
|
||||
|
||||
using (SqliteCommand slc2 = new SqliteCommand(query, dbc))
|
||||
{
|
||||
slc2.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
query = "SELECT last_insertConstants.Rowid()";
|
||||
using (SqliteCommand slc2 = new SqliteCommand(query, dbc))
|
||||
{
|
||||
gameid = (long)slc2.ExecuteScalar();
|
||||
}
|
||||
}
|
||||
// Otherwise, retrieve the ID
|
||||
else
|
||||
{
|
||||
sldr.Read();
|
||||
gameid = sldr.GetInt64(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return gameid;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add a file to the database if it doesn't already exist
|
||||
/// </summary>
|
||||
/// <param name="rom">Rom object representing the rom</param>
|
||||
/// <param name="gameid">ID of the parent game to be mapped to</param>
|
||||
/// <param name="date">Last updated date</param>
|
||||
/// <param name="dbc">SQLite database connection to use</param>
|
||||
/// <returns>True if the file exists or could be added, false on error</returns>
|
||||
private bool AddRom(Rom rom, long gameid, string date, SqliteConnection dbc)
|
||||
{
|
||||
// WOD origninally stripped out any subdirs from the imported files, we do the same
|
||||
rom.Name = Path.GetFileName(rom.Name);
|
||||
|
||||
// Run the name through the filters to make sure that it's correct
|
||||
rom.Name = Style.NormalizeChars(rom.Name);
|
||||
rom.Name = Style.RussianToLatin(rom.Name);
|
||||
rom.Name = Regex.Replace(rom.Name, @"(.*) \.(.*)", "$1.$2");
|
||||
|
||||
if (rom.Type != ItemType.Rom && rom.Type != ItemType.Disk)
|
||||
{
|
||||
rom.Type = ItemType.Rom;
|
||||
}
|
||||
|
||||
// Check to see if this exact file is in the database already
|
||||
string query = @"
|
||||
SELECT files.id FROM files
|
||||
JOIN checksums
|
||||
ON files.id=checksums.file
|
||||
WHERE files.name='" + rom.Name.Replace("'", "''") + @"'
|
||||
AND files.type='" + rom.Type + @"'
|
||||
AND files.setid=" + gameid +
|
||||
" AND checksums.size=" + rom.HashData.Size +
|
||||
" AND checksums.crc='" + rom.HashData.CRC + "'" +
|
||||
" AND checksums.md5='" + rom.HashData.MD5 + "'" +
|
||||
" AND checksums.sha1='" + rom.HashData.SHA1 + "'";
|
||||
|
||||
using (SqliteCommand slc = new SqliteCommand(query, dbc))
|
||||
{
|
||||
using (SqliteDataReader sldr = slc.ExecuteReader())
|
||||
{
|
||||
// If the file doesn't exist, add it with its checksums
|
||||
if (!sldr.HasRows)
|
||||
{
|
||||
query = @"BEGIN;
|
||||
INSERT INTO files (setid, name, type, lastupdated)
|
||||
VALUES (" + gameid + ", '" + rom.Name.Replace("'", "''") + "', '" + rom.Type + "', '" + date + @"');
|
||||
INSERT INTO checksums (file, size, crc, md5, sha1)
|
||||
VALUES ((SELECT last_insertConstants.Rowid()), " + rom.HashData.Size + ", '" + rom.HashData.CRC + "'" + ", '" + rom.HashData.MD5 + "'" + ", '" + rom.HashData.SHA1 + @"');
|
||||
COMMIT;";
|
||||
using (SqliteCommand slc2 = new SqliteCommand(query, dbc))
|
||||
{
|
||||
int affected = slc2.ExecuteNonQuery();
|
||||
|
||||
// If the insert was unsuccessful, something bad happened
|
||||
if (affected < 1)
|
||||
{
|
||||
_logger.Error("There was an error adding " + rom.Name + " to the database!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add a hash to the database if it doesn't exist already
|
||||
/// </summary>
|
||||
/// <param name="rom">Rom object representing the rom</param>
|
||||
/// <param name="sysid">System ID for the game to be added with</param>
|
||||
/// <param name="srcid">Source ID for the game to be added with</param>
|
||||
/// <param name="date">Last updated date</param>
|
||||
/// <param name="dbc">SQLite database connection to use</param>
|
||||
/// <returns>True if the hash exists or could be added, false on error</returns>
|
||||
/// <remarks>This is currently unused. It is a test method for the new SabreTools DB schema</remarks>
|
||||
private bool AddHash(Rom rom, int sysid, int srcid, string date, SqliteConnection dbc)
|
||||
{
|
||||
// Process the game name
|
||||
|
||||
// WoD gets rid of anything past the first "(" or "[" as the name, we will do the same
|
||||
string stripPattern = @"(([[(].*[\)\]] )?([^([]+))";
|
||||
Regex stripRegex = new Regex(stripPattern);
|
||||
Match stripMatch = stripRegex.Match(rom.Machine.Name);
|
||||
rom.Machine.Name = stripMatch.Groups[1].Value;
|
||||
|
||||
// Run the name through the filters to make sure that it's correct
|
||||
rom.Machine.Name = Style.NormalizeChars(rom.Machine.Name);
|
||||
rom.Machine.Name = Style.RussianToLatin(rom.Machine.Name);
|
||||
rom.Machine.Name = Style.SearchPattern(rom.Machine.Name);
|
||||
rom.Machine.Name = rom.Machine.Name.Trim();
|
||||
|
||||
// Process the rom name
|
||||
|
||||
// WOD origninally stripped out any subdirs from the imported files, we do the same
|
||||
rom.Name = Path.GetFileName(rom.Name);
|
||||
|
||||
// Run the name through the filters to make sure that it's correct
|
||||
rom.Name = Style.NormalizeChars(rom.Name);
|
||||
rom.Name = Style.RussianToLatin(rom.Name);
|
||||
rom.Name = Regex.Replace(rom.Name, @"(.*) \.(.*)", "$1.$2");
|
||||
|
||||
// Retrieve or insert the hash
|
||||
long hashid = -1;
|
||||
string query = "SELECT id FROM hash WHERE size=" + rom.HashData.Size + " AND crc='" + rom.HashData.CRC + "' AND md5='" + rom.HashData.MD5 + "' AND sha1='" + rom.HashData.SHA1 + "'";
|
||||
using (SqliteCommand slc = new SqliteCommand(query, dbc))
|
||||
{
|
||||
using (SqliteDataReader sldr = slc.ExecuteReader())
|
||||
{
|
||||
// If nothing is found, add the hash and get the insert ID
|
||||
if (!sldr.HasRows)
|
||||
{
|
||||
query = "INSERT INTO hash (size, crc, md5, sha1)" +
|
||||
" VALUES (" + rom.HashData.Size + ", '" + rom.HashData.CRC + "', '" + rom.HashData.MD5 + "', '" + rom.HashData.SHA1 + "')";
|
||||
|
||||
using (SqliteCommand slc2 = new SqliteCommand(query, dbc))
|
||||
{
|
||||
slc2.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
query = "SELECT last_insertConstants.Rowid()";
|
||||
using (SqliteCommand slc2 = new SqliteCommand(query, dbc))
|
||||
{
|
||||
hashid = (long)slc2.ExecuteScalar();
|
||||
}
|
||||
}
|
||||
// Otherwise, retrieve the ID
|
||||
else
|
||||
{
|
||||
sldr.Read();
|
||||
hashid = sldr.GetInt64(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ignore or insert the file and game
|
||||
query = @"BEGIN;
|
||||
INSERT OR IGNORE INTO hashdata (hashid, key, value) VALUES " +
|
||||
"(" + hashid + ", 'name', '" + rom.Name.Replace("'", "''") + "'), " +
|
||||
"(" + hashid + ", 'game', '" + rom.Machine.Name.Replace("'", "''") + "'), " +
|
||||
"(" + hashid + ", 'type', '" + rom.Type + "'), " +
|
||||
"(" + hashid + ", 'lastupdated', '" + date + @"');
|
||||
INSERT OR IGNORE INTO gamesystem (game, systemid) VALUES ('" + rom.Machine.Name.Replace("'", "''") + "', " + sysid + @");
|
||||
INSERT OR IGNORE INTO gamesource (game, sourceid) VALUES ('" + rom.Machine.Name.Replace("'", "''") + "', " + srcid + @");
|
||||
COMMIT;";
|
||||
|
||||
using (SqliteCommand slc = new SqliteCommand(query, dbc))
|
||||
{
|
||||
int ret = slc.ExecuteNonQuery();
|
||||
if ((SQLiteErrorCode)ret == SQLiteErrorCode.Error)
|
||||
{
|
||||
_logger.Error("A SQLite error has occurred: " + ((SQLiteErrorCode)ret).ToString());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ namespace SabreTools.Helper
|
||||
public class SimpleSort
|
||||
{
|
||||
// Private instance variables
|
||||
private Dat _datdata;
|
||||
private DatFile _datdata;
|
||||
private List<string> _inputs;
|
||||
private string _outDir;
|
||||
private string _tempDir;
|
||||
@@ -30,7 +30,7 @@ namespace SabreTools.Helper
|
||||
// Other private variables
|
||||
private int _cursorTop;
|
||||
private int _cursorLeft;
|
||||
private Dat _matched;
|
||||
private DatFile _matched;
|
||||
|
||||
/// <summary>
|
||||
/// Create a new SimpleSort object
|
||||
@@ -51,7 +51,7 @@ namespace SabreTools.Helper
|
||||
/// <param name="zip">Integer representing the archive handling level for Zip</param>
|
||||
/// <param name="updateDat">True if the updated DAT should be output, false otherwise</param>
|
||||
/// <param name="logger">Logger object for file and console output</param>
|
||||
public SimpleSort(Dat datdata, List<string> inputs, string outDir, string tempDir,
|
||||
public SimpleSort(DatFile datdata, List<string> inputs, string outDir, string tempDir,
|
||||
bool quickScan, bool toFolder, bool verify, bool delete, bool? torrentX, bool romba, int sevenzip,
|
||||
int gz, int rar, int zip, bool updateDat, Logger logger)
|
||||
{
|
||||
@@ -74,9 +74,9 @@ namespace SabreTools.Helper
|
||||
|
||||
_cursorTop = Console.CursorTop;
|
||||
_cursorLeft = Console.CursorLeft;
|
||||
_matched = new Dat
|
||||
_matched = new DatFile
|
||||
{
|
||||
Files = new Dictionary<string, List<Rom>>(),
|
||||
Files = new Dictionary<string, List<DatItem>>(),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -144,8 +144,8 @@ namespace SabreTools.Helper
|
||||
}
|
||||
|
||||
// Setup the fixdat
|
||||
_matched = (Dat)_datdata.CloneHeader();
|
||||
_matched.Files = new Dictionary<string, List<Rom>>();
|
||||
_matched = (DatFile)_datdata.CloneHeader();
|
||||
_matched.Files = new Dictionary<string, List<DatItem>>();
|
||||
_matched.FileName = "fixDat_" + _matched.FileName;
|
||||
_matched.Name = "fixDat_" + _matched.Name;
|
||||
_matched.Description = "fixDat_" + _matched.Description;
|
||||
@@ -153,22 +153,22 @@ namespace SabreTools.Helper
|
||||
|
||||
// Now that all files are parsed, get only files found in directory
|
||||
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)
|
||||
{
|
||||
if (rom.Metadata.SourceID == 99)
|
||||
if (rom.SourceID == 99)
|
||||
{
|
||||
found = true;
|
||||
string key = rom.HashData.Size + "-" + rom.HashData.CRC;
|
||||
string key = rom.Size + "-" + rom.CRC;
|
||||
if (_matched.Files.ContainsKey(key))
|
||||
{
|
||||
_matched.Files[key].Add(rom);
|
||||
}
|
||||
else
|
||||
{
|
||||
List<Rom> temp = new List<Rom>();
|
||||
List<DatItem> temp = new List<DatItem>();
|
||||
temp.Add(rom);
|
||||
_matched.Files.Add(key, temp);
|
||||
}
|
||||
@@ -179,7 +179,7 @@ namespace SabreTools.Helper
|
||||
// Now output the fixdat to the main folder
|
||||
if (found)
|
||||
{
|
||||
DatTools.WriteDatfile(_matched, "", _logger, stats: true);
|
||||
DatFile.WriteDatfile(_matched, "", _logger, stats: true);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -273,7 +273,7 @@ namespace SabreTools.Helper
|
||||
_datdata.Name = "fixDat_" + _datdata.Name;
|
||||
_datdata.Description = "fixDat_" + _datdata.Description;
|
||||
_datdata.OutputFormat = OutputFormat.Xml;
|
||||
DatTools.WriteDatfile(_datdata, "", _logger);
|
||||
DatFile.WriteDatfile(_datdata, "", _logger);
|
||||
}
|
||||
|
||||
return success;
|
||||
@@ -341,9 +341,9 @@ namespace SabreTools.Helper
|
||||
|
||||
// Now loop through all of the files and check them, DFD style
|
||||
_logger.User("Getting source file information...");
|
||||
Dat matchdat = new Dat
|
||||
DatFile matchdat = new DatFile
|
||||
{
|
||||
Files = new Dictionary<string, List<Rom>>(),
|
||||
Files = new Dictionary<string, List<DatItem>>(),
|
||||
};
|
||||
foreach (string file in files)
|
||||
{
|
||||
@@ -409,15 +409,15 @@ namespace SabreTools.Helper
|
||||
#region Find all files to rebuild and bucket by game
|
||||
|
||||
// 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
|
||||
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);
|
||||
foreach (Rom match in matched)
|
||||
List<DatItem> matched = DatItem.GetDuplicates(rom, _datdata, _logger, true);
|
||||
foreach (DatItem match in matched)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -429,7 +429,7 @@ namespace SabreTools.Helper
|
||||
}
|
||||
|
||||
// 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 = DatFile.BucketByGame(toFromMap.Keys.ToList(), false, true, _logger);
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -456,7 +456,7 @@ namespace SabreTools.Helper
|
||||
/// <param name="file">Name of the file to attempt to add</param>
|
||||
/// <param name="matchdat">Reference to the Dat to add to</param>
|
||||
/// <returns>True if the file could be added, false otherwise</returns>
|
||||
public bool RebuildToOutputAlternateParseRomHelper(string file, ref Dat matchdat)
|
||||
public bool RebuildToOutputAlternateParseRomHelper(string file, ref DatFile matchdat)
|
||||
{
|
||||
Rom rom = FileTools.GetSingleFileInfo(file);
|
||||
|
||||
@@ -467,17 +467,17 @@ namespace SabreTools.Helper
|
||||
}
|
||||
|
||||
// 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
|
||||
string key = rom.HashData.Size + "-" + rom.HashData.CRC;
|
||||
string key = rom.Size + "-" + rom.CRC;
|
||||
if (matchdat.Files.ContainsKey(key))
|
||||
{
|
||||
matchdat.Files[key].Add(rom);
|
||||
}
|
||||
else
|
||||
{
|
||||
List<Rom> temp = new List<Rom>();
|
||||
List<DatItem> temp = new List<DatItem>();
|
||||
temp.Add(rom);
|
||||
matchdat.Files.Add(key, temp);
|
||||
}
|
||||
@@ -494,17 +494,17 @@ namespace SabreTools.Helper
|
||||
Skippers.TransformStream(input, output, rule, _logger, false, true);
|
||||
Rom romNH = FileTools.GetSingleStreamInfo(output);
|
||||
romNH.Name = "HEAD::" + rom.Name;
|
||||
romNH.Machine.Name = rom.Machine.Name;
|
||||
romNH.MachineName = rom.MachineName;
|
||||
|
||||
// Add the rom information to the Dat
|
||||
key = romNH.HashData.Size + "-" + romNH.HashData.CRC;
|
||||
key = romNH.Size + "-" + romNH.CRC;
|
||||
if (matchdat.Files.ContainsKey(key))
|
||||
{
|
||||
matchdat.Files[key].Add(romNH);
|
||||
}
|
||||
else
|
||||
{
|
||||
List<Rom> temp = new List<Rom>();
|
||||
List<DatItem> temp = new List<DatItem>();
|
||||
temp.Add(romNH);
|
||||
matchdat.Files.Add(key, temp);
|
||||
}
|
||||
@@ -548,21 +548,21 @@ namespace SabreTools.Helper
|
||||
}
|
||||
|
||||
// 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!");
|
||||
foreach (Rom found in foundroms)
|
||||
{
|
||||
_logger.Log("Matched name: " + found.Name);
|
||||
|
||||
// Add rom to the matched list
|
||||
string key = found.HashData.Size + "-" + found.HashData.CRC;
|
||||
string key = found.Size + "-" + found.CRC;
|
||||
if (_matched.Files.ContainsKey(key))
|
||||
{
|
||||
_matched.Files[key].Add(found);
|
||||
}
|
||||
else
|
||||
{
|
||||
List<Rom> temp = new List<Rom>();
|
||||
List<DatItem> temp = new List<DatItem>();
|
||||
temp.Add(found);
|
||||
_matched.Files.Add(key, temp);
|
||||
}
|
||||
@@ -570,13 +570,13 @@ namespace SabreTools.Helper
|
||||
if (_toFolder)
|
||||
{
|
||||
// Copy file to output directory
|
||||
string gamedir = Path.Combine(_outDir, found.Machine.Name);
|
||||
string gamedir = Path.Combine(_outDir, found.MachineName);
|
||||
if (!Directory.Exists(gamedir))
|
||||
{
|
||||
Directory.CreateDirectory(gamedir);
|
||||
}
|
||||
|
||||
_logger.Log("Rebuilding file '" + Path.GetFileName(rom.Name) + "' to '" + (_torrentX == false ? found.HashData.SHA1 : found.Name) + "'");
|
||||
_logger.Log("Rebuilding file '" + Path.GetFileName(rom.Name) + "' to '" + (_torrentX == false ? found.SHA1 : found.Name) + "'");
|
||||
try
|
||||
{
|
||||
File.Copy(input, Path.Combine(gamedir, Path.GetFileName(found.Name)));
|
||||
@@ -618,19 +618,19 @@ namespace SabreTools.Helper
|
||||
}
|
||||
|
||||
// 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!");
|
||||
foreach (Rom found in founddroms)
|
||||
{
|
||||
// Add rom to the matched list
|
||||
string key = found.HashData.Size + "-" + found.HashData.CRC;
|
||||
string key = found.Size + "-" + found.CRC;
|
||||
if (_matched.Files.ContainsKey(key))
|
||||
{
|
||||
_matched.Files[key].Add(found);
|
||||
}
|
||||
else
|
||||
{
|
||||
List<Rom> temp = new List<Rom>();
|
||||
List<DatItem> temp = new List<DatItem>();
|
||||
temp.Add(found);
|
||||
_matched.Files.Add(key, temp);
|
||||
}
|
||||
@@ -641,13 +641,13 @@ namespace SabreTools.Helper
|
||||
if (_toFolder)
|
||||
{
|
||||
// Copy file to output directory
|
||||
string gamedir = Path.Combine(_outDir, found.Machine.Name);
|
||||
string gamedir = Path.Combine(_outDir, found.MachineName);
|
||||
if (!Directory.Exists(gamedir))
|
||||
{
|
||||
Directory.CreateDirectory(gamedir);
|
||||
}
|
||||
|
||||
_logger.Log("Rebuilding file '" + Path.GetFileName(rom.Name) + "' to '" + (_torrentX == false ? found.HashData.SHA1 : found.Name) + "'");
|
||||
_logger.Log("Rebuilding file '" + Path.GetFileName(rom.Name) + "' to '" + (_torrentX == false ? found.SHA1 : found.Name) + "'");
|
||||
try
|
||||
{
|
||||
File.Copy(newinput, Path.Combine(gamedir, Path.GetFileName(found.Name)));
|
||||
@@ -672,18 +672,21 @@ namespace SabreTools.Helper
|
||||
|
||||
// Then output the headered rom (renamed)
|
||||
Rom newfound = found;
|
||||
newfound.Name = Path.GetFileNameWithoutExtension(newfound.Name) + " (" + rom.HashData.CRC + ")" + Path.GetExtension(newfound.Name);
|
||||
newfound.HashData = rom.HashData;
|
||||
newfound.Name = Path.GetFileNameWithoutExtension(newfound.Name) + " (" + rom.CRC + ")" + Path.GetExtension(newfound.Name);
|
||||
newfound.Size = rom.Size;
|
||||
newfound.CRC = rom.CRC;
|
||||
newfound.MD5 = rom.MD5;
|
||||
newfound.SHA1 = rom.SHA1;
|
||||
|
||||
// Add rom to the matched list
|
||||
key = newfound.HashData.Size + "-" + newfound.HashData.CRC;
|
||||
key = newfound.Size + "-" + newfound.CRC;
|
||||
if (_matched.Files.ContainsKey(key))
|
||||
{
|
||||
_matched.Files[key].Add(newfound);
|
||||
}
|
||||
else
|
||||
{
|
||||
List<Rom> temp = new List<Rom>();
|
||||
List<DatItem> temp = new List<DatItem>();
|
||||
temp.Add(newfound);
|
||||
_matched.Files.Add(key, temp);
|
||||
}
|
||||
@@ -691,7 +694,7 @@ namespace SabreTools.Helper
|
||||
if (_toFolder)
|
||||
{
|
||||
// Copy file to output directory
|
||||
string gamedir = Path.Combine(_outDir, found.Machine.Name);
|
||||
string gamedir = Path.Combine(_outDir, found.MachineName);
|
||||
if (!Directory.Exists(gamedir))
|
||||
{
|
||||
Directory.CreateDirectory(gamedir);
|
||||
@@ -750,19 +753,19 @@ namespace SabreTools.Helper
|
||||
foreach (Rom rom in internalRomData)
|
||||
{
|
||||
// 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!");
|
||||
foreach (Rom found in foundroms)
|
||||
{
|
||||
// Add rom to the matched list
|
||||
string key = found.HashData.Size + "-" + found.HashData.CRC;
|
||||
string key = found.Size + "-" + found.CRC;
|
||||
if (_matched.Files.ContainsKey(key))
|
||||
{
|
||||
_matched.Files[key].Add(found);
|
||||
}
|
||||
else
|
||||
{
|
||||
List<Rom> temp = new List<Rom>();
|
||||
List<DatItem> temp = new List<DatItem>();
|
||||
temp.Add(found);
|
||||
_matched.Files.Add(key, temp);
|
||||
}
|
||||
@@ -774,7 +777,7 @@ namespace SabreTools.Helper
|
||||
string outfile = FileTools.ExtractSingleItemFromArchive(input, rom.Name, _tempDir, _logger);
|
||||
if (File.Exists(outfile))
|
||||
{
|
||||
string gamedir = Path.Combine(_outDir, found.Machine.Name);
|
||||
string gamedir = Path.Combine(_outDir, found.MachineName);
|
||||
if (!Directory.Exists(gamedir))
|
||||
{
|
||||
Directory.CreateDirectory(gamedir);
|
||||
@@ -790,7 +793,7 @@ namespace SabreTools.Helper
|
||||
else
|
||||
{
|
||||
// Copy file between archives
|
||||
_logger.Log("Rebuilding file '" + Path.GetFileName(rom.Name) + "' to '" + (_torrentX == false ? found.HashData.SHA1 : found.Name) + "'");
|
||||
_logger.Log("Rebuilding file '" + Path.GetFileName(rom.Name) + "' to '" + (_torrentX == false ? found.SHA1 : found.Name) + "'");
|
||||
|
||||
if (Build.MonoEnvironment || _torrentX == false)
|
||||
{
|
||||
@@ -888,7 +891,7 @@ namespace SabreTools.Helper
|
||||
}
|
||||
|
||||
// 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))
|
||||
{
|
||||
// If we are in quickscan, get the list of roms that way
|
||||
@@ -914,14 +917,14 @@ namespace SabreTools.Helper
|
||||
// Then add each of the found files to the new dictionary
|
||||
foreach (Rom rom in roms)
|
||||
{
|
||||
string key = rom.HashData.Size + "-" + rom.HashData.CRC;
|
||||
string key = rom.Size + "-" + rom.CRC;
|
||||
if (scanned.ContainsKey(key))
|
||||
{
|
||||
scanned[key].Add(rom);
|
||||
}
|
||||
else
|
||||
{
|
||||
List<Rom> templist = new List<Rom>();
|
||||
List<DatItem> templist = new List<DatItem>();
|
||||
templist.Add(rom);
|
||||
scanned.Add(key, templist);
|
||||
}
|
||||
@@ -935,7 +938,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
|
||||
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)
|
||||
{
|
||||
// If the key doesn't even exist in the DAT, then mark the entire key for removal
|
||||
@@ -953,8 +956,8 @@ namespace SabreTools.Helper
|
||||
// Otherwise check each of the values individually
|
||||
else
|
||||
{
|
||||
List<Rom> romsList = _datdata.Files[key];
|
||||
List<Rom> scannedList = scanned[key];
|
||||
List<DatItem> romsList = _datdata.Files[key];
|
||||
List<DatItem> scannedList = scanned[key];
|
||||
foreach (Rom rom in scannedList)
|
||||
{
|
||||
if (!romsList.Contains(rom))
|
||||
@@ -965,7 +968,7 @@ namespace SabreTools.Helper
|
||||
}
|
||||
else
|
||||
{
|
||||
List<Rom> templist = new List<Rom>();
|
||||
List<DatItem> templist = new List<DatItem>();
|
||||
templist.Add(rom);
|
||||
remove.Add(key, templist);
|
||||
}
|
||||
|
||||
@@ -47,9 +47,9 @@ namespace SabreTools.Helper
|
||||
{
|
||||
_logger.Log("Beginning stat collection for '" + filename + "'");
|
||||
List<String> games = new List<String>();
|
||||
Dat datdata = new Dat();
|
||||
DatTools.Parse(filename, 0, 0, ref datdata, _logger);
|
||||
SortedDictionary<string, List<Rom>> newroms = DatTools.BucketByGame(datdata.Files, false, true, _logger, false);
|
||||
DatFile datdata = new DatFile();
|
||||
DatFile.Parse(filename, 0, 0, ref datdata, _logger);
|
||||
SortedDictionary<string, List<DatItem>> newroms = DatFile.BucketByGame(datdata.Files, false, true, _logger, false);
|
||||
|
||||
// Output single DAT stats (if asked)
|
||||
if (_single)
|
||||
@@ -76,7 +76,7 @@ namespace SabreTools.Helper
|
||||
|
||||
// Output total DAT stats
|
||||
if (!_single) { _logger.User(""); }
|
||||
Dat totaldata = new Dat
|
||||
DatFile totaldata = new DatFile
|
||||
{
|
||||
TotalSize = totalSize,
|
||||
RomCount = totalRom,
|
||||
@@ -102,7 +102,7 @@ Please check the log folder if the stats scrolled offscreen");
|
||||
/// <param name="logger">Logger object for file and console writing</param>
|
||||
/// <param name="recalculate">True if numbers should be recalculated for the DAT, false otherwise (default)</param>
|
||||
/// <param name="game">Number of games to use, -1 means recalculate games (default)</param>
|
||||
public static void OutputStats(Dat datdata, Logger logger, bool recalculate = false, long game = -1)
|
||||
public static void OutputStats(DatFile datdata, Logger logger, bool recalculate = false, long game = -1)
|
||||
{
|
||||
if (recalculate)
|
||||
{
|
||||
@@ -116,22 +116,22 @@ Please check the log folder if the stats scrolled offscreen");
|
||||
datdata.NodumpCount = 0;
|
||||
|
||||
// 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)
|
||||
{
|
||||
datdata.RomCount += (rom.Type == ItemType.Rom ? 1 : 0);
|
||||
datdata.DiskCount += (rom.Type == ItemType.Disk ? 1 : 0);
|
||||
datdata.TotalSize += (rom.Nodump ? 0 : rom.HashData.Size);
|
||||
datdata.CRCCount += (String.IsNullOrEmpty(rom.HashData.CRC) ? 0 : 1);
|
||||
datdata.MD5Count += (String.IsNullOrEmpty(rom.HashData.MD5) ? 0 : 1);
|
||||
datdata.SHA1Count += (String.IsNullOrEmpty(rom.HashData.SHA1) ? 0 : 1);
|
||||
datdata.TotalSize += (rom.Nodump ? 0 : rom.Size);
|
||||
datdata.CRCCount += (String.IsNullOrEmpty(rom.CRC) ? 0 : 1);
|
||||
datdata.MD5Count += (String.IsNullOrEmpty(rom.MD5) ? 0 : 1);
|
||||
datdata.SHA1Count += (String.IsNullOrEmpty(rom.SHA1) ? 0 : 1);
|
||||
datdata.NodumpCount += (rom.Nodump ? 1 : 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SortedDictionary<string, List<Rom>> newroms = DatTools.BucketByGame(datdata.Files, false, true, logger, false);
|
||||
SortedDictionary<string, List<DatItem>> newroms = DatFile.BucketByGame(datdata.Files, false, true, logger, false);
|
||||
if (datdata.TotalSize < 0)
|
||||
{
|
||||
datdata.TotalSize = Int64.MaxValue + datdata.TotalSize;
|
||||
|
||||
@@ -101,14 +101,20 @@
|
||||
<Compile Include="External\Zlib\ZlibConstants.cs" />
|
||||
<Compile Include="External\Zlib\ZlibStream.cs" />
|
||||
<Compile Include="Objects\DATFromDir.cs" />
|
||||
<Compile Include="Objects\Generate.cs" />
|
||||
<Compile Include="Objects\Dat\Archive.cs" />
|
||||
<Compile Include="Objects\Dat\BiosSet.cs" />
|
||||
<Compile Include="Objects\Dat\DatFile.cs" />
|
||||
<Compile Include="Objects\Dat\DatItem.cs" />
|
||||
<Compile Include="Objects\Dat\Disk.cs" />
|
||||
<Compile Include="Objects\Dat\Release.cs" />
|
||||
<Compile Include="Objects\Dat\Sample.cs" />
|
||||
<Compile Include="Objects\GenerateTwo.cs" />
|
||||
<Compile Include="Objects\Headerer.cs" />
|
||||
<Compile Include="Objects\Import.cs" />
|
||||
<Compile Include="Objects\ImportTwo.cs" />
|
||||
<Compile Include="Objects\Dat\Rom.cs" />
|
||||
<Compile Include="Objects\SimpleSort.cs" />
|
||||
<Compile Include="Objects\ZipFileEntry.cs" />
|
||||
<Compile Include="Objects\ZipFile.cs" />
|
||||
<Compile Include="Objects\Archive\ZipFileEntry.cs" />
|
||||
<Compile Include="Objects\Archive\ZipFile.cs" />
|
||||
<Compile Include="Resources\Resources.de-DE.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
@@ -130,7 +136,6 @@
|
||||
<DependentUpon>Resources.fr-FR.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Skippers\Skippers.cs" />
|
||||
<Compile Include="Tools\DatToolsHash.cs" />
|
||||
<Compile Include="Tools\FileTools.cs" />
|
||||
<Compile Include="Tools\DBTools.cs" />
|
||||
<Compile Include="Data\Enums.cs" />
|
||||
@@ -139,11 +144,7 @@
|
||||
<Compile Include="Objects\Logger.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Mappings\Mappings.cs" />
|
||||
<Compile Include="Tools\DatTools.cs" />
|
||||
<Compile Include="Data\Structs.cs" />
|
||||
<Compile Include="Tools\FileToolsHash.cs" />
|
||||
<Compile Include="Tools\RomTools.cs" />
|
||||
<Compile Include="Tools\RomToolsHash.cs" />
|
||||
<Compile Include="Objects\Stats.cs" />
|
||||
<Compile Include="Tools\Style.cs" />
|
||||
<Compile Include="Data\Build.cs" />
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace SabreTools.Helper
|
||||
public class Skippers
|
||||
{
|
||||
// Local paths
|
||||
public const string Path = "Skippers";
|
||||
public const string LocalPath = "Skippers";
|
||||
|
||||
// Header skippers represented by a list of skipper objects
|
||||
private static List<Skipper> _list;
|
||||
@@ -56,9 +56,9 @@ namespace SabreTools.Helper
|
||||
_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)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ namespace SabreTools.Helper
|
||||
|
||||
Logger logger = new Logger(false, "");
|
||||
logger.Start();
|
||||
XmlTextReader xtr = DatTools.GetXmlTextReader(filename, logger);
|
||||
XmlTextReader xtr = DatFile.GetXmlTextReader(filename, logger);
|
||||
|
||||
if (xtr == null)
|
||||
{
|
||||
@@ -527,9 +527,9 @@ namespace SabreTools.Helper
|
||||
}
|
||||
|
||||
// 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 + "'");
|
||||
@@ -725,7 +725,7 @@ namespace SabreTools.Helper
|
||||
XmlDocument doc = new XmlDocument();
|
||||
try
|
||||
{
|
||||
doc.LoadXml(File.ReadAllText(System.IO.Path.Combine(Path, skipper + ".xml")));
|
||||
doc.LoadXml(File.ReadAllText(Path.Combine(LocalPath, skipper + ".xml")));
|
||||
}
|
||||
catch (XmlException ex)
|
||||
{
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -63,7 +63,7 @@ namespace SabreTools.Helper
|
||||
}
|
||||
|
||||
// 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
|
||||
ZipArchive outarchive = null;
|
||||
@@ -172,7 +172,7 @@ namespace SabreTools.Helper
|
||||
}
|
||||
|
||||
// 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
|
||||
Stream writeStream = null;
|
||||
@@ -224,7 +224,7 @@ namespace SabreTools.Helper
|
||||
writeStream.Write(buffer, 0, len);
|
||||
}
|
||||
writeStream.Flush();
|
||||
zipFile.CloseWriteStream(Convert.ToUInt32(rom.HashData.CRC, 16));
|
||||
zipFile.CloseWriteStream(Convert.ToUInt32(rom.CRC, 16));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -291,7 +291,7 @@ namespace SabreTools.Helper
|
||||
}
|
||||
freadStream.Close();
|
||||
freadStream.Dispose();
|
||||
zipFile.CloseWriteStream(Convert.ToUInt32(roms[-index - 1].HashData.CRC, 16));
|
||||
zipFile.CloseWriteStream(Convert.ToUInt32(roms[-index - 1].CRC, 16));
|
||||
}
|
||||
|
||||
// Otherwise, copy the file from the old archive
|
||||
@@ -372,7 +372,7 @@ namespace SabreTools.Helper
|
||||
Rom rom = FileTools.GetSingleFileInfo(input);
|
||||
|
||||
// If it doesn't exist, create the output file and then write
|
||||
string outfile = Path.Combine(outDir, rom.HashData.SHA1 + ".gz");
|
||||
string outfile = Path.Combine(outDir, rom.SHA1 + ".gz");
|
||||
using (FileStream inputstream = new FileStream(input, FileMode.Open))
|
||||
using (GZipStream output = new GZipStream(File.Open(outfile, FileMode.Create, FileAccess.Write), CompressionMode.Compress))
|
||||
{
|
||||
@@ -386,9 +386,9 @@ namespace SabreTools.Helper
|
||||
{
|
||||
// Write standard header and TGZ info
|
||||
byte[] data = Constants.TorrentGZHeader
|
||||
.Concat(Style.StringToByteArray(rom.HashData.MD5)) // MD5
|
||||
.Concat(Style.StringToByteArray(rom.HashData.CRC)) // CRC
|
||||
.Concat(BitConverter.GetBytes(rom.HashData.Size).Reverse().ToArray()) // Long size (Mirrored)
|
||||
.Concat(Style.StringToByteArray(rom.MD5)) // MD5
|
||||
.Concat(Style.StringToByteArray(rom.CRC)) // CRC
|
||||
.Concat(BitConverter.GetBytes(rom.Size).Reverse().ToArray()) // Long size (Mirrored)
|
||||
.ToArray();
|
||||
sw.Write(data);
|
||||
|
||||
@@ -414,7 +414,7 @@ namespace SabreTools.Helper
|
||||
// If we're in romba mode, create the subfolder and move the file
|
||||
if (romba)
|
||||
{
|
||||
string subfolder = Path.Combine(rom.HashData.SHA1.Substring(0, 2), rom.HashData.SHA1.Substring(2, 2), rom.HashData.SHA1.Substring(4, 2), rom.HashData.SHA1.Substring(6, 2));
|
||||
string subfolder = Path.Combine(rom.SHA1.Substring(0, 2), rom.SHA1.Substring(2, 2), rom.SHA1.Substring(4, 2), rom.SHA1.Substring(6, 2));
|
||||
outDir = Path.Combine(outDir, subfolder);
|
||||
if (!Directory.Exists(outDir))
|
||||
{
|
||||
@@ -723,13 +723,10 @@ namespace SabreTools.Helper
|
||||
Rom rom = new Rom
|
||||
{
|
||||
Type = ItemType.Rom,
|
||||
HashData = new Hash
|
||||
{
|
||||
Size = input.Length - Math.Abs(offset),
|
||||
CRC = string.Empty,
|
||||
MD5 = string.Empty,
|
||||
SHA1 = string.Empty,
|
||||
},
|
||||
Size = input.Length - Math.Abs(offset),
|
||||
CRC = string.Empty,
|
||||
MD5 = string.Empty,
|
||||
SHA1 = string.Empty,
|
||||
};
|
||||
|
||||
try
|
||||
@@ -760,17 +757,17 @@ namespace SabreTools.Helper
|
||||
}
|
||||
|
||||
crc.Update(buffer, 0, 0);
|
||||
rom.HashData.CRC = crc.Value.ToString("X8").ToLowerInvariant();
|
||||
rom.CRC = crc.Value.ToString("X8").ToLowerInvariant();
|
||||
|
||||
if (!noMD5)
|
||||
{
|
||||
md5.TransformFinalBlock(buffer, 0, 0);
|
||||
rom.HashData.MD5 = BitConverter.ToString(md5.Hash).Replace("-", "").ToLowerInvariant();
|
||||
rom.MD5 = BitConverter.ToString(md5.Hash).Replace("-", "").ToLowerInvariant();
|
||||
}
|
||||
if (!noSHA1)
|
||||
{
|
||||
sha1.TransformFinalBlock(buffer, 0, 0);
|
||||
rom.HashData.SHA1 = BitConverter.ToString(sha1.Hash).Replace("-", "").ToLowerInvariant();
|
||||
rom.SHA1 = BitConverter.ToString(sha1.Hash).Replace("-", "").ToLowerInvariant();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -860,15 +857,9 @@ namespace SabreTools.Helper
|
||||
{
|
||||
Type = ItemType.Rom,
|
||||
Name = reader.Entry.Key,
|
||||
Machine = new Machine
|
||||
{
|
||||
Name = gamename,
|
||||
},
|
||||
HashData = new Hash
|
||||
{
|
||||
Size = (size == 0 ? reader.Entry.Size : size),
|
||||
CRC = (crc == "" ? reader.Entry.Crc.ToString("X").ToLowerInvariant() : crc),
|
||||
},
|
||||
MachineName = gamename,
|
||||
Size = (size == 0 ? reader.Entry.Size : size),
|
||||
CRC = (crc == "" ? reader.Entry.Crc.ToString("X").ToLowerInvariant() : crc),
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -948,18 +939,12 @@ namespace SabreTools.Helper
|
||||
Rom rom = new Rom
|
||||
{
|
||||
Type = ItemType.Rom,
|
||||
Machine = new Machine
|
||||
{
|
||||
Name = Path.GetFileNameWithoutExtension(input).ToLowerInvariant(),
|
||||
},
|
||||
MachineName = Path.GetFileNameWithoutExtension(input).ToLowerInvariant(),
|
||||
Name = Path.GetFileNameWithoutExtension(input).ToLowerInvariant(),
|
||||
HashData = new Hash
|
||||
{
|
||||
Size = extractedsize,
|
||||
CRC = gzcrc.ToLowerInvariant(),
|
||||
MD5 = gzmd5.ToLowerInvariant(),
|
||||
SHA1 = Path.GetFileNameWithoutExtension(input).ToLowerInvariant(),
|
||||
},
|
||||
Size = extractedsize,
|
||||
CRC = gzcrc.ToLowerInvariant(),
|
||||
MD5 = gzmd5.ToLowerInvariant(),
|
||||
SHA1 = Path.GetFileNameWithoutExtension(input).ToLowerInvariant(),
|
||||
};
|
||||
|
||||
return rom;
|
||||
|
||||
@@ -1,305 +0,0 @@
|
||||
using SharpCompress.Archive;
|
||||
using SharpCompress.Common;
|
||||
using SharpCompress.Reader;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace SabreTools.Helper
|
||||
{
|
||||
public class FileToolsHash
|
||||
{
|
||||
#region Archive Writing
|
||||
|
||||
// All things in this region are direct ports and do not take advantage of the multiple rom per hash that comes with the new system
|
||||
|
||||
/// <summary>
|
||||
/// Copy a file to an output archive
|
||||
/// </summary>
|
||||
/// <param name="input">Input filename to be moved</param>
|
||||
/// <param name="output">Output directory to build to</param>
|
||||
/// <param name="hash">RomData representing the new information</param>
|
||||
/// <remarks>This uses the new system that is not implemented anywhere yet</remarks>
|
||||
public static void WriteToArchive(string input, string output, RomData rom)
|
||||
{
|
||||
string archiveFileName = Path.Combine(output, rom.Machine + ".zip");
|
||||
|
||||
ZipArchive outarchive = null;
|
||||
try
|
||||
{
|
||||
if (!File.Exists(archiveFileName))
|
||||
{
|
||||
outarchive = System.IO.Compression.ZipFile.Open(archiveFileName, ZipArchiveMode.Create);
|
||||
}
|
||||
else
|
||||
{
|
||||
outarchive = System.IO.Compression.ZipFile.Open(archiveFileName, ZipArchiveMode.Update);
|
||||
}
|
||||
|
||||
if (File.Exists(input))
|
||||
{
|
||||
if (outarchive.Mode == ZipArchiveMode.Create || outarchive.GetEntry(rom.Name) == null)
|
||||
{
|
||||
outarchive.CreateEntryFromFile(input, rom.Name, CompressionLevel.Optimal);
|
||||
}
|
||||
}
|
||||
else if (Directory.Exists(input))
|
||||
{
|
||||
foreach (string file in Directory.EnumerateFiles(input, "*", SearchOption.AllDirectories))
|
||||
{
|
||||
if (outarchive.Mode == ZipArchiveMode.Create || outarchive.GetEntry(file) == null)
|
||||
{
|
||||
outarchive.CreateEntryFromFile(file, file, CompressionLevel.Optimal);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
outarchive?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copy a file to an output archive using SharpCompress
|
||||
/// </summary>
|
||||
/// <param name="input">Input filename to be moved</param>
|
||||
/// <param name="output">Output directory to build to</param>
|
||||
/// <param name="rom">RomData representing the new information</param>
|
||||
/// <remarks>This uses the new system that is not implemented anywhere yet</remarks>
|
||||
public static void WriteToManagedArchive(string input, string output, RomData rom)
|
||||
{
|
||||
string archiveFileName = Path.Combine(output, rom.Machine + ".zip");
|
||||
|
||||
// Delete an empty file first
|
||||
if (File.Exists(archiveFileName) && new FileInfo(archiveFileName).Length == 0)
|
||||
{
|
||||
File.Delete(archiveFileName);
|
||||
}
|
||||
|
||||
// Get if the file should be written out
|
||||
bool newfile = File.Exists(archiveFileName) && new FileInfo(archiveFileName).Length != 0;
|
||||
|
||||
using (SharpCompress.Archive.Zip.ZipArchive archive = (newfile
|
||||
? ArchiveFactory.Open(archiveFileName, Options.LookForHeader) as SharpCompress.Archive.Zip.ZipArchive
|
||||
: ArchiveFactory.Create(ArchiveType.Zip) as SharpCompress.Archive.Zip.ZipArchive))
|
||||
{
|
||||
try
|
||||
{
|
||||
if (File.Exists(input))
|
||||
{
|
||||
archive.AddEntry(rom.Name, input);
|
||||
}
|
||||
else if (Directory.Exists(input))
|
||||
{
|
||||
archive.AddAllFromDirectory(input, "*", SearchOption.AllDirectories);
|
||||
}
|
||||
|
||||
archive.SaveTo(archiveFileName + ".tmp", CompressionType.Deflate);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// Don't log archive write errors
|
||||
}
|
||||
}
|
||||
|
||||
if (File.Exists(archiveFileName + ".tmp"))
|
||||
{
|
||||
File.Delete(archiveFileName);
|
||||
File.Move(archiveFileName + ".tmp", archiveFileName);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region File Information
|
||||
|
||||
/// <summary>
|
||||
/// Generate a list of HashData objects from the header values in an archive
|
||||
/// </summary>
|
||||
/// <param name="input">Input file to get data from</param>
|
||||
/// <param name="logger">Logger object for file and console output</param>
|
||||
/// <returns>List of HashData objects representing the found data</returns>
|
||||
/// <remarks>This uses the new system that is not implemented anywhere yet</remarks>
|
||||
public static List<HashData> GetArchiveFileHashes(string input, Logger logger)
|
||||
{
|
||||
List<HashData> hashes = new List<HashData>();
|
||||
string gamename = Path.GetFileNameWithoutExtension(input);
|
||||
|
||||
// First get the archive type
|
||||
ArchiveType? at = FileTools.GetCurrentArchiveType(input, logger);
|
||||
|
||||
// If we got back null, then it's not an archive, so we we return
|
||||
if (at == null)
|
||||
{
|
||||
return hashes;
|
||||
}
|
||||
|
||||
// If we got back GZip, try to get TGZ info first
|
||||
else if (at == ArchiveType.GZip)
|
||||
{
|
||||
HashData possibleTgz = GetTorrentGZFileHash(input, logger);
|
||||
|
||||
// If it was, then add it to the outputs and continue
|
||||
if (possibleTgz.Size != -1)
|
||||
{
|
||||
hashes.Add(possibleTgz);
|
||||
return hashes;
|
||||
}
|
||||
}
|
||||
|
||||
IReader reader = null;
|
||||
try
|
||||
{
|
||||
logger.Log("Found archive of type: " + at);
|
||||
long size = 0;
|
||||
byte[] crc = null;
|
||||
|
||||
// If we have a gzip file, get the crc directly
|
||||
if (at == ArchiveType.GZip)
|
||||
{
|
||||
// Get the CRC and size from the file
|
||||
using (BinaryReader br = new BinaryReader(File.OpenRead(input)))
|
||||
{
|
||||
br.BaseStream.Seek(-8, SeekOrigin.End);
|
||||
crc = br.ReadBytes(4).Reverse().ToArray();
|
||||
byte[] headersize = br.ReadBytes(4);
|
||||
size = BitConverter.ToInt32(headersize.Reverse().ToArray(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
reader = ReaderFactory.Open(File.OpenRead(input));
|
||||
|
||||
if (at != ArchiveType.Tar)
|
||||
{
|
||||
while (reader.MoveToNextEntry())
|
||||
{
|
||||
if (reader.Entry != null && !reader.Entry.IsDirectory)
|
||||
{
|
||||
logger.Log("Entry found: '" + reader.Entry.Key + "': "
|
||||
+ (size == 0 ? reader.Entry.Size : size) + ", "
|
||||
+ (crc == null ? BitConverter.GetBytes(reader.Entry.Crc) : crc));
|
||||
|
||||
RomData temprom = new RomData
|
||||
{
|
||||
Type = ItemType.Rom,
|
||||
Name = reader.Entry.Key,
|
||||
Machine = new MachineData
|
||||
{
|
||||
Name = gamename,
|
||||
Description = gamename,
|
||||
},
|
||||
};
|
||||
HashData temphash = new HashData
|
||||
{
|
||||
Size = (size == 0 ? reader.Entry.Size : size),
|
||||
CRC = (crc == null ? BitConverter.GetBytes(reader.Entry.Crc) : crc),
|
||||
MD5 = null,
|
||||
SHA1 = null,
|
||||
Roms = new List<RomData>(),
|
||||
};
|
||||
temphash.Roms.Add(temprom);
|
||||
hashes.Add(temphash);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.Error(ex.ToString());
|
||||
}
|
||||
finally
|
||||
{
|
||||
reader?.Dispose();
|
||||
}
|
||||
|
||||
return hashes;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve file information for a single torrent GZ file
|
||||
/// </summary>
|
||||
/// <param name="input">Filename to get information from</param>
|
||||
/// <param name="logger">Logger object for file and console output</param>
|
||||
/// <returns>Populated HashData object if success, empty one on error</returns>
|
||||
/// <remarks>This uses the new system that is not implemented anywhere yet</remarks>
|
||||
public static HashData GetTorrentGZFileHash(string input, Logger logger)
|
||||
{
|
||||
string datum = Path.GetFileName(input).ToLowerInvariant();
|
||||
string sha1 = Path.GetFileNameWithoutExtension(input).ToLowerInvariant();
|
||||
long filesize = new FileInfo(input).Length;
|
||||
|
||||
// Check if the name is the right length
|
||||
if (!Regex.IsMatch(datum, @"^[0-9a-f]{40}\.gz"))
|
||||
{
|
||||
logger.Warning("Non SHA-1 filename found, skipping: '" + datum + "'");
|
||||
return new HashData();
|
||||
}
|
||||
|
||||
// Check if the file is at least the minimum length
|
||||
if (filesize < 40 /* bytes */)
|
||||
{
|
||||
logger.Warning("Possibly corrupt file '" + input + "' with size " + Style.GetBytesReadable(filesize));
|
||||
return new HashData();
|
||||
}
|
||||
|
||||
// Get the Romba-specific header data
|
||||
byte[] header; // Get preamble header for checking
|
||||
byte[] headermd5; // MD5
|
||||
byte[] headercrc; // CRC
|
||||
byte[] headersz; // Int64 size
|
||||
using (BinaryReader br = new BinaryReader(File.OpenRead(input)))
|
||||
{
|
||||
header = br.ReadBytes(12);
|
||||
headermd5 = br.ReadBytes(16);
|
||||
headercrc = br.ReadBytes(4);
|
||||
headersz = br.ReadBytes(8);
|
||||
}
|
||||
|
||||
// If the header is not correct, return a blank rom
|
||||
bool correct = true;
|
||||
for (int i = 0; i < header.Length; i++)
|
||||
{
|
||||
correct &= (header[i] == Constants.TorrentGZHeader[i]);
|
||||
}
|
||||
if (!correct)
|
||||
{
|
||||
return new HashData();
|
||||
}
|
||||
|
||||
// Now convert the size and get the right position
|
||||
long extractedsize = (long)BitConverter.ToUInt64(headersz.Reverse().ToArray(), 0);
|
||||
|
||||
RomData temprom = new RomData
|
||||
{
|
||||
Type = ItemType.Rom,
|
||||
Name = sha1,
|
||||
Machine = new MachineData
|
||||
{
|
||||
Name = sha1,
|
||||
Description = sha1,
|
||||
},
|
||||
};
|
||||
HashData temphash = new HashData
|
||||
{
|
||||
Size = extractedsize,
|
||||
CRC = headercrc,
|
||||
MD5 = headermd5,
|
||||
SHA1 = Style.StringToByteArray(sha1),
|
||||
Roms = new List<RomData>(),
|
||||
};
|
||||
temphash.Roms.Add(temprom);
|
||||
|
||||
return temphash;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -154,7 +154,7 @@ namespace SabreTools.Helper
|
||||
/// <param name="datdata">DAT information</param>
|
||||
/// <param name="overwrite">True if we ignore existing files (default), false otherwise</param>
|
||||
/// <returns>Dictionary of output formats mapped to file names</returns>
|
||||
public static Dictionary<OutputFormat, string> CreateOutfileNames(string outDir, Dat datdata, bool overwrite = true)
|
||||
public static Dictionary<OutputFormat, string> CreateOutfileNames(string outDir, DatFile datdata, bool overwrite = true)
|
||||
{
|
||||
// Create the output dictionary
|
||||
Dictionary<OutputFormat, string> outfileNames = new Dictionary<OutputFormat, string>();
|
||||
@@ -214,7 +214,7 @@ namespace SabreTools.Helper
|
||||
/// <param name="datdata">DAT information</param>
|
||||
/// <param name="overwrite">True if we ignore existing files, false otherwise</param>
|
||||
/// <returns>String containing the new filename</returns>
|
||||
private static string CreateOutfileNamesHelper(string outDir, string extension, Dat datdata, bool overwrite)
|
||||
private static string CreateOutfileNamesHelper(string outDir, string extension, DatFile datdata, bool overwrite)
|
||||
{
|
||||
string filename = (String.IsNullOrEmpty(datdata.FileName) ? datdata.Description : datdata.FileName);
|
||||
string outfile = outDir + filename + extension;
|
||||
|
||||
@@ -78,7 +78,7 @@ namespace SabreTools
|
||||
}
|
||||
}
|
||||
|
||||
SimpleSort ss = new SimpleSort(new Dat(), newinputs, outDir, tempDir, false, false, false, delete, false, romba, sevenzip, gz, rar, zip, false, logger);
|
||||
SimpleSort ss = new SimpleSort(new DatFile(), newinputs, outDir, tempDir, false, false, false, delete, false, romba, sevenzip, gz, rar, zip, false, logger);
|
||||
return ss.Convert();
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ namespace SabreTools
|
||||
int maxDegreeOfParallelism)
|
||||
{
|
||||
// Create a new DATFromDir object and process the inputs
|
||||
Dat basedat = new Dat
|
||||
DatFile basedat = new DatFile
|
||||
{
|
||||
FileName = filename,
|
||||
Name = name,
|
||||
@@ -140,7 +140,7 @@ namespace SabreTools
|
||||
OutputFormat = (outputFormat == 0 ? OutputFormat.Xml : outputFormat),
|
||||
Romba = romba,
|
||||
Type = (superdat ? "SuperDAT" : ""),
|
||||
Files = new Dictionary<string, List<Rom>>(),
|
||||
Files = new Dictionary<string, List<DatItem>>(),
|
||||
};
|
||||
|
||||
// For each input directory, create a DAT
|
||||
@@ -149,8 +149,8 @@ namespace SabreTools
|
||||
if (Directory.Exists(path))
|
||||
{
|
||||
// Clone the base Dat for information
|
||||
Dat datdata = (Dat)basedat.Clone();
|
||||
datdata.Files = new Dictionary<string, List<Rom>>();
|
||||
DatFile datdata = (DatFile)basedat.Clone();
|
||||
datdata.Files = new Dictionary<string, List<DatItem>>();
|
||||
|
||||
string basePath = Path.GetFullPath(path);
|
||||
DATFromDir dfd = new DATFromDir(basePath, datdata, noMD5, noSHA1, bare, archivesAsFiles, enableGzip, addBlanks, addDate, tempDir, maxDegreeOfParallelism, _logger);
|
||||
@@ -159,7 +159,7 @@ namespace SabreTools
|
||||
// If it was a success, write the DAT out
|
||||
if (success)
|
||||
{
|
||||
DatTools.WriteDatfile(dfd.DatData, "", _logger);
|
||||
DatFile.WriteDatfile(dfd.DatData, "", _logger);
|
||||
}
|
||||
|
||||
// Otherwise, show the help
|
||||
@@ -190,13 +190,13 @@ namespace SabreTools
|
||||
{
|
||||
if (File.Exists(input))
|
||||
{
|
||||
DatTools.SplitByExt(Path.GetFullPath(input), outDir, Path.GetDirectoryName(input), extaList, extbList, _logger);
|
||||
DatFile.SplitByExt(Path.GetFullPath(input), outDir, Path.GetDirectoryName(input), extaList, extbList, _logger);
|
||||
}
|
||||
else if (Directory.Exists(input))
|
||||
{
|
||||
foreach (string file in Directory.EnumerateFiles(input, "*", SearchOption.AllDirectories))
|
||||
{
|
||||
DatTools.SplitByExt(file, outDir, (input.EndsWith(Path.DirectorySeparatorChar.ToString()) ? input : input + Path.DirectorySeparatorChar), extaList, extbList, _logger);
|
||||
DatFile.SplitByExt(file, outDir, (input.EndsWith(Path.DirectorySeparatorChar.ToString()) ? input : input + Path.DirectorySeparatorChar), extaList, extbList, _logger);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -271,13 +271,13 @@ namespace SabreTools
|
||||
{
|
||||
if (File.Exists(input))
|
||||
{
|
||||
DatTools.SplitByHash(Path.GetFullPath(input), outDir, Path.GetDirectoryName(input), _logger);
|
||||
DatFile.SplitByHash(Path.GetFullPath(input), outDir, Path.GetDirectoryName(input), _logger);
|
||||
}
|
||||
else if (Directory.Exists(input))
|
||||
{
|
||||
foreach (string file in Directory.EnumerateFiles(input, "*", SearchOption.AllDirectories))
|
||||
{
|
||||
DatTools.SplitByHash(file, outDir, (input.EndsWith(Path.DirectorySeparatorChar.ToString()) ? input : input + Path.DirectorySeparatorChar), _logger);
|
||||
DatFile.SplitByHash(file, outDir, (input.EndsWith(Path.DirectorySeparatorChar.ToString()) ? input : input + Path.DirectorySeparatorChar), _logger);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -384,10 +384,10 @@ namespace SabreTools
|
||||
bool toFolder, bool verify, bool delete, bool? torrentX, bool romba, int sevenzip, int gz, int rar, int zip, bool updateDat, Logger logger)
|
||||
{
|
||||
// Add all of the input DATs into one huge internal DAT
|
||||
Dat datdata = new Dat();
|
||||
DatFile datdata = new DatFile();
|
||||
foreach (string datfile in datfiles)
|
||||
{
|
||||
DatTools.Parse(datfile, 99, 99, ref datdata, logger);
|
||||
DatFile.Parse(datfile, 99, 99, ref datdata, logger);
|
||||
}
|
||||
|
||||
SimpleSort ss = new SimpleSort(datdata, inputs, outDir, tempDir, quickScan, toFolder, verify,
|
||||
@@ -438,13 +438,13 @@ namespace SabreTools
|
||||
{
|
||||
if (File.Exists(input))
|
||||
{
|
||||
DatTools.SplitByType(Path.GetFullPath(input), outDir, Path.GetFullPath(Path.GetDirectoryName(input)), _logger);
|
||||
DatFile.SplitByType(Path.GetFullPath(input), outDir, Path.GetFullPath(Path.GetDirectoryName(input)), _logger);
|
||||
}
|
||||
else if (Directory.Exists(input))
|
||||
{
|
||||
foreach (string file in Directory.EnumerateFiles(input, "*", SearchOption.AllDirectories))
|
||||
{
|
||||
DatTools.SplitByType(file, outDir, Path.GetFullPath((input.EndsWith(Path.DirectorySeparatorChar.ToString()) ? input : input + Path.DirectorySeparatorChar)), _logger);
|
||||
DatFile.SplitByType(file, outDir, Path.GetFullPath((input.EndsWith(Path.DirectorySeparatorChar.ToString()) ? input : input + Path.DirectorySeparatorChar)), _logger);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -671,7 +671,7 @@ namespace SabreTools
|
||||
}
|
||||
|
||||
// Populate the DatData object
|
||||
Dat userInputDat = new Dat
|
||||
DatFile userInputDat = new DatFile
|
||||
{
|
||||
FileName = filename,
|
||||
Name = name,
|
||||
@@ -705,7 +705,7 @@ namespace SabreTools
|
||||
XSV = tsv,
|
||||
};
|
||||
|
||||
DatTools.Update(inputs, userInputDat, outputFormat, outDir, merge, diffMode, cascade, inplace, skip, bare, clean, softlist,
|
||||
DatFile.Update(inputs, userInputDat, outputFormat, outDir, merge, diffMode, cascade, inplace, skip, bare, clean, softlist,
|
||||
gamename, romname, romtype, sgt, slt, seq, crc, md5, sha1, nodump, trim, single, root, maxDegreeOfParallelism, _logger);
|
||||
}
|
||||
|
||||
|
||||
@@ -251,10 +251,10 @@ namespace SabreTools
|
||||
bool toFolder, bool verify, bool delete, bool? torrentX, bool romba, int sevenzip, int gz, int rar, int zip, bool updateDat, Logger logger)
|
||||
{
|
||||
// Add all of the input DATs into one huge internal DAT
|
||||
Dat datdata = new Dat();
|
||||
DatFile datdata = new DatFile();
|
||||
foreach (string datfile in datfiles)
|
||||
{
|
||||
DatTools.Parse(datfile, 99, 99, ref datdata, logger, keep: true, softlist: true);
|
||||
DatFile.Parse(datfile, 99, 99, ref datdata, logger, keep: true, softlist: true);
|
||||
}
|
||||
|
||||
SimpleSort ss = new SimpleSort(datdata, inputs, outDir, tempDir, quickScan, toFolder, verify,
|
||||
@@ -295,7 +295,7 @@ namespace SabreTools
|
||||
}
|
||||
}
|
||||
|
||||
SimpleSort ss = new SimpleSort(new Dat(), newinputs, outDir, tempDir, false, false, false,
|
||||
SimpleSort ss = new SimpleSort(new DatFile(), newinputs, outDir, tempDir, false, false, false,
|
||||
delete, false, romba, sevenzip, gz, rar, zip, false, logger);
|
||||
return ss.Convert();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user