diff --git a/SabreTools.Helper/Tools/DatTools.cs b/SabreTools.Helper/Tools/DatTools.cs
index 8417e268..88dc9b9d 100644
--- a/SabreTools.Helper/Tools/DatTools.cs
+++ b/SabreTools.Helper/Tools/DatTools.cs
@@ -1574,9 +1574,14 @@ namespace SabreTools.Helper
///
/// Convert, update, and filter a DAT file
///
- /// Name of the input file or folder
+ /// Names of the input files and/or folders
/// User specified inputs contained in a DatData object
/// Optional param for output directory
+ /// True if input files should be merged into a single file, false otherwise
+ /// True if the input files should be diffed with each other, false otherwise
+ /// True if the diffed files should be cascade diffed, false otherwise
+ /// True if the cascade-diffed files should overwrite their inputs, false otherwise
+ /// True if the date should not be appended to the default name, false otherwise [OBSOLETE]
/// True to clean the game names to WoD standard, false otherwise (default)
/// Name of the game to match (can use asterisk-partials)
/// Name of the rom to match (can use asterisk-partials)
@@ -1589,59 +1594,139 @@ namespace SabreTools.Helper
/// SHA-1 of the rom to match (can use asterisk-partials)
/// Select roms with nodump status as follows: null (match all), true (match Nodump only), false (exclude Nodump)
/// Logging object for console and file output
- public static void Update(string inputFileName, Dat datdata, string outputDirectory, bool clean, string gamename, string romname,
- string romtype, long sgt, long slt, long seq, string crc, string md5, string sha1, bool? nodump, Logger logger)
+ public static void Update(List inputFileNames, Dat datdata, string outputDirectory, bool merge, bool diff, bool cascade, bool inplace,
+ bool bare, bool clean, string gamename, string romname, string romtype, long sgt, long slt, long seq, string crc, string md5,
+ string sha1, bool? nodump, Logger logger)
{
- // Clean the input string
- if (inputFileName != "")
+ // If we're in merging or diffing mode, use the full list of inputs
+ if (merge || diff)
{
- inputFileName = Path.GetFullPath(inputFileName);
- }
+ // Create a dictionary of all ROMs from the input DATs
+ datdata.FileName = datdata.Description;
+ Dat userData;
+ List datHeaders = PopulateUserData(inputFileNames, inplace, clean, outputDirectory, datdata, out userData, logger);
- if (File.Exists(inputFileName))
- {
- logger.User("Processing \"" + Path.GetFileName(inputFileName) + "\"");
- datdata = Parse(inputFileName, 0, 0, datdata, logger, true, clean);
- datdata = Filter(datdata, gamename, romname, romtype, sgt, slt, seq, crc, md5, sha1, nodump, logger);
-
- // If the extension matches, append ".new" to the filename
- string extension = (datdata.OutputFormat == OutputFormat.Xml || datdata.OutputFormat == OutputFormat.SabreDat ? ".xml" : ".dat");
- if (outputDirectory == "" && Path.GetExtension(inputFileName) == extension)
+ // Modify the Dictionary if necessary and output the results
+ if (diff && !cascade)
{
- datdata.FileName += ".new";
+ DiffNoCascade(outputDirectory, userData, inputFileNames, logger);
}
-
- Output.WriteDatfile(datdata, (outputDirectory == "" ? Path.GetDirectoryName(inputFileName) : outputDirectory), logger);
- }
- else if (Directory.Exists(inputFileName))
- {
- inputFileName = Path.GetFullPath(inputFileName) + Path.DirectorySeparatorChar;
-
- foreach (string file in Directory.EnumerateFiles(inputFileName, "*", SearchOption.AllDirectories))
+ // If we're in cascade and diff, output only cascaded diffs
+ else if (diff && cascade)
{
- logger.User("Processing \"" + Path.GetFullPath(file).Remove(0, inputFileName.Length) + "\"");
- Dat innerDatdata = (Dat)datdata.Clone();
- innerDatdata.Roms = null;
- innerDatdata = Parse(file, 0, 0, innerDatdata, logger, true, clean);
- innerDatdata = Filter(innerDatdata, gamename, romname, romtype, sgt, slt, seq, crc, md5, sha1, nodump, logger);
-
- // If the extension matches, append ".new" to the filename
- string extension = (innerDatdata.OutputFormat == OutputFormat.Xml || innerDatdata.OutputFormat == OutputFormat.SabreDat ? ".xml" : ".dat");
- if (outputDirectory == "" && Path.GetExtension(file) == extension)
- {
- innerDatdata.FileName += ".new";
- }
-
- Output.WriteDatfile(innerDatdata, (outputDirectory == "" ? Path.GetDirectoryName(file) : outputDirectory + Path.GetDirectoryName(file).Remove(0, inputFileName.Length - 1)), logger);
+ DiffCascade(outputDirectory, inplace, userData, inputFileNames, datHeaders, logger);
+ }
+ // Output all entries with user-defined merge
+ else
+ {
+ MergeNoDiff(outputDirectory, userData, inputFileNames, datHeaders, logger);
}
}
+ // Otherwise, loop through all of the inputs individually
else
{
- logger.Error("I'm sorry but " + inputFileName + " doesn't exist!");
+ for (int i = 0; i < inputFileNames.Count; i++)
+ {
+ string inputFileName = inputFileNames[i];
+
+ // Clean the input string
+ if (inputFileName != "")
+ {
+ inputFileName = Path.GetFullPath(inputFileName);
+ }
+
+ if (File.Exists(inputFileName))
+ {
+ logger.User("Processing \"" + Path.GetFileName(inputFileName) + "\"");
+ datdata = Parse(inputFileName, 0, 0, datdata, logger, true, clean);
+ datdata = Filter(datdata, gamename, romname, romtype, sgt, slt, seq, crc, md5, sha1, nodump, logger);
+
+ // If the extension matches, append ".new" to the filename
+ string extension = (datdata.OutputFormat == OutputFormat.Xml || datdata.OutputFormat == OutputFormat.SabreDat ? ".xml" : ".dat");
+ if (outputDirectory == "" && Path.GetExtension(inputFileName) == extension)
+ {
+ datdata.FileName += ".new";
+ }
+
+ Output.WriteDatfile(datdata, (outputDirectory == "" ? Path.GetDirectoryName(inputFileName) : outputDirectory), logger);
+ }
+ else if (Directory.Exists(inputFileName))
+ {
+ inputFileName = Path.GetFullPath(inputFileName) + Path.DirectorySeparatorChar;
+
+ foreach (string file in Directory.EnumerateFiles(inputFileName, "*", SearchOption.AllDirectories))
+ {
+ logger.User("Processing \"" + Path.GetFullPath(file).Remove(0, inputFileName.Length) + "\"");
+ Dat innerDatdata = (Dat)datdata.Clone();
+ innerDatdata.Roms = null;
+ innerDatdata = Parse(file, 0, 0, innerDatdata, logger, true, clean);
+ innerDatdata = Filter(innerDatdata, gamename, romname, romtype, sgt, slt, seq, crc, md5, sha1, nodump, logger);
+
+ // If the extension matches, append ".new" to the filename
+ string extension = (innerDatdata.OutputFormat == OutputFormat.Xml || innerDatdata.OutputFormat == OutputFormat.SabreDat ? ".xml" : ".dat");
+ if (outputDirectory == "" && Path.GetExtension(file) == extension)
+ {
+ innerDatdata.FileName += ".new";
+ }
+
+ Output.WriteDatfile(innerDatdata, (outputDirectory == "" ? Path.GetDirectoryName(file) : outputDirectory + Path.GetDirectoryName(file).Remove(0, inputFileName.Length - 1)), logger);
+ }
+ }
+ else
+ {
+ logger.Error("I'm sorry but " + inputFileName + " doesn't exist!");
+ }
+ }
}
return;
}
+ ///
+ /// Populate the user DatData object from the input files
+ ///
+ /// Output user DatData object to output
+ /// List of DatData objects representing headers
+ private static List PopulateUserData(List inputs, bool inplace, bool clean, string outdir, Dat inputDat, out Dat userData, Logger logger)
+ {
+ List datHeaders = new List();
+
+ int i = 0;
+ userData = new Dat
+ {
+ Roms = new Dictionary>(),
+ MergeRoms = inputDat.MergeRoms,
+ };
+ foreach (string input in inputs)
+ {
+ logger.User("Adding DAT: " + input.Split('¬')[0]);
+ userData = DatTools.Parse(input.Split('¬')[0], i, 0, userData, logger, true, clean);
+ i++;
+
+ // If we are in inplace mode or redirecting output, save the DAT data
+ if (inplace || !String.IsNullOrEmpty(outdir))
+ {
+ datHeaders.Add((Dat)userData.CloneHeader());
+
+ // Reset the header values so the next can be captured
+ userData.FileName = "";
+ userData.Name = "";
+ userData.Description = "";
+ userData.Version = "";
+ userData.Date = "";
+ userData.Category = "";
+ userData.Author = "";
+ userData.ForcePacking = ForcePacking.None;
+ userData.OutputFormat = OutputFormat.None;
+ userData.Type = "";
+ }
+ }
+
+ // Set the output values
+ userData = (Dat)inputDat.CloneHeader();
+
+ return datHeaders;
+ }
+
///
/// Filter an input DAT file
///
@@ -1809,5 +1894,253 @@ namespace SabreTools.Helper
return datdata;
}
+
+ ///
+ /// Output non-cascading diffs
+ ///
+ /// Main DatData to draw information from
+ public static void DiffNoCascade(string outdir, Dat userData, List inputs, Logger logger)
+ {
+ DateTime start = DateTime.Now;
+ logger.User("Initializing all output DATs");
+
+ // Don't have External dupes
+ string post = " (No Duplicates)";
+ Dat outerDiffData = (Dat)userData.CloneHeader();
+ outerDiffData.FileName += post;
+ outerDiffData.Name += post;
+ outerDiffData.Description += post;
+
+ // Have External dupes
+ post = " (Duplicates)";
+ Dat dupeData = (Dat)userData.CloneHeader();
+ dupeData.FileName += post;
+ dupeData.Name += post;
+ dupeData.Description += post;
+
+ // Create a list of DatData objects representing individual output files
+ List outDats = new List();
+
+ // Loop through each of the inputs and get or create a new DatData object
+ for (int j = 0; j < inputs.Count; j++)
+ {
+ post = " (" + Path.GetFileNameWithoutExtension(inputs[j].Split('¬')[0]) + " Only)";
+ Dat diffData = (Dat)userData.CloneHeader();
+ diffData.FileName += post;
+ diffData.Name += post;
+ diffData.Description += post;
+ outDats.Add(diffData);
+ }
+ logger.User("Initializing complete in " + DateTime.Now.Subtract(start).ToString(@"hh\:mm\:ss\.fffff"));
+
+ // Now, loop through the dictionary and populate the correct DATs
+ start = DateTime.Now;
+ logger.User("Populating all output DATs");
+ List keys = userData.Roms.Keys.ToList();
+ foreach (string key in keys)
+ {
+ List roms = RomTools.Merge(userData.Roms[key], logger);
+
+ if (roms != null && roms.Count > 0)
+ {
+ foreach (Rom rom in roms)
+ {
+ // No duplicates
+ if (rom.Dupe < DupeType.ExternalHash)
+ {
+ // Individual DATs that are output
+ if (outDats[rom.Metadata.SystemID].Roms.ContainsKey(key))
+ {
+ outDats[rom.Metadata.SystemID].Roms[key].Add(rom);
+ }
+ else
+ {
+ List tl = new List();
+ tl.Add(rom);
+ outDats[rom.Metadata.SystemID].Roms.Add(key, tl);
+ }
+
+ // Merged no-duplicates DAT
+ Rom newrom = rom;
+ newrom.Game += " (" + Path.GetFileNameWithoutExtension(inputs[newrom.Metadata.SystemID].Split('¬')[0]) + ")";
+
+ if (outerDiffData.Roms.ContainsKey(key))
+ {
+ outerDiffData.Roms[key].Add(newrom);
+ }
+ else
+ {
+ List tl = new List();
+ tl.Add(rom);
+ outerDiffData.Roms.Add(key, tl);
+ }
+ }
+
+ // Duplicates only
+ if (rom.Dupe >= DupeType.ExternalHash)
+ {
+ Rom newrom = rom;
+ newrom.Game += " (" + Path.GetFileNameWithoutExtension(inputs[newrom.Metadata.SystemID].Split('¬')[0]) + ")";
+
+ if (dupeData.Roms.ContainsKey(key))
+ {
+ dupeData.Roms[key].Add(newrom);
+ }
+ else
+ {
+ List tl = new List();
+ tl.Add(rom);
+ dupeData.Roms.Add(key, tl);
+ }
+ }
+ }
+ }
+ }
+ logger.User("Populating complete in " + DateTime.Now.Subtract(start).ToString(@"hh\:mm\:ss\.fffff"));
+
+ // Finally, loop through and output each of the DATs
+ start = DateTime.Now;
+ logger.User("Outputting all created DATs");
+
+ // Output the difflist (a-b)+(b-a) diff
+ Output.WriteDatfile(outerDiffData, outdir, logger);
+
+ // Output the (ab) diff
+ Output.WriteDatfile(dupeData, outdir, logger);
+
+ // Output the individual (a-b) DATs
+ for (int j = 0; j < inputs.Count; j++)
+ {
+ // If we have an output directory set, replace the path
+ string path = outdir + (Path.GetDirectoryName(inputs[j].Split('¬')[0]).Remove(0, inputs[j].Split('¬')[1].Length));
+
+ // If we have more than 0 roms, output
+ if (outDats[j].Roms.Count > 0)
+ {
+ Output.WriteDatfile(outDats[j], path, logger);
+ }
+ }
+ logger.User("Outputting complete in " + DateTime.Now.Subtract(start).ToString(@"hh\:mm\:ss\.fffff"));
+ }
+
+ ///
+ /// Output cascading diffs
+ ///
+ /// Main DatData to draw information from
+ /// Dat headers used optionally
+ public static void DiffCascade(string outdir, bool inplace, Dat userData, List inputs, List datHeaders, Logger logger)
+ {
+ string post = "";
+
+ // Create a list of DatData objects representing output files
+ List outDats = new List();
+
+ // Loop through each of the inputs and get or create a new DatData object
+ DateTime start = DateTime.Now;
+ logger.User("Initializing all output DATs");
+ for (int j = 0; j < inputs.Count; j++)
+ {
+ post = " (" + Path.GetFileNameWithoutExtension(inputs[j].Split('¬')[0]) + " Only)";
+ Dat diffData;
+
+ // If we're in inplace mode, take the appropriate DatData object already stored
+ if (inplace || !String.IsNullOrEmpty(outdir))
+ {
+ diffData = datHeaders[j];
+ }
+ else
+ {
+ diffData = (Dat)userData.CloneHeader();
+ diffData.FileName += post;
+ diffData.Name += post;
+ diffData.Description += post;
+ }
+ outDats.Add(diffData);
+ }
+ logger.User("Initializing complete in " + DateTime.Now.Subtract(start).ToString(@"hh\:mm\:ss\.fffff"));
+
+ // Now, loop through the dictionary and populate the correct DATs
+ start = DateTime.Now;
+ logger.User("Populating all output DATs");
+ List keys = userData.Roms.Keys.ToList();
+ foreach (string key in keys)
+ {
+ List roms = RomTools.Merge(userData.Roms[key], logger);
+
+ if (roms != null && roms.Count > 0)
+ {
+ foreach (Rom rom in roms)
+ {
+ if (outDats[rom.Metadata.SystemID].Roms.ContainsKey(key))
+ {
+ outDats[rom.Metadata.SystemID].Roms[key].Add(rom);
+ }
+ else
+ {
+ List tl = new List();
+ tl.Add(rom);
+ outDats[rom.Metadata.SystemID].Roms.Add(key, tl);
+ }
+ }
+ }
+ }
+ logger.User("Populating complete in " + DateTime.Now.Subtract(start).ToString(@"hh\:mm\:ss\.fffff"));
+
+ // Finally, loop through and output each of the DATs
+ start = DateTime.Now;
+ logger.User("Outputting all created DATs");
+ for (int j = 0; j < inputs.Count; j++)
+ {
+ // If we have an output directory set, replace the path
+ string path = "";
+ if (inplace)
+ {
+ path = Path.GetDirectoryName(inputs[j].Split('¬')[0]);
+ }
+ else if (!String.IsNullOrEmpty(outdir))
+ {
+ path = outdir + (Path.GetDirectoryName(inputs[j].Split('¬')[0]).Remove(0, inputs[j].Split('¬')[1].Length));
+ }
+
+ // If we have more than 0 roms, output
+ if (outDats[j].Roms.Count > 0)
+ {
+ Output.WriteDatfile(outDats[j], path, logger);
+ }
+ }
+ logger.User("Outputting complete in " + DateTime.Now.Subtract(start).ToString(@"hh\:mm\:ss\.fffff"));
+ }
+
+ ///
+ /// Output user defined merge
+ ///
+ /// Main DatData to draw information from
+ /// Dat headers used optionally
+ public static void MergeNoDiff(string outdir, Dat userData, List inputs, List datHeaders, Logger logger)
+ {
+ // If we're in SuperDAT mode, prefix all games with their respective DATs
+ if (userData.Type == "SuperDAT")
+ {
+ List keys = userData.Roms.Keys.ToList();
+ foreach (string key in keys)
+ {
+ List newroms = new List();
+ foreach (Rom rom in userData.Roms[key])
+ {
+ Rom newrom = rom;
+ string filename = inputs[newrom.Metadata.SystemID].Split('¬')[0];
+ string rootpath = inputs[newrom.Metadata.SystemID].Split('¬')[1];
+
+ rootpath += (rootpath == "" ? "" : Path.DirectorySeparatorChar.ToString());
+ filename = filename.Remove(0, rootpath.Length);
+ newrom.Game = Path.Combine(Path.GetDirectoryName(filename), Path.GetFileNameWithoutExtension(filename), newrom.Game);
+ newroms.Add(newrom);
+ }
+ userData.Roms[key] = newroms;
+ }
+ }
+
+ Output.WriteDatfile(userData, outdir, logger);
+ }
}
}
diff --git a/SabreTools/MergeDiff.cs b/SabreTools/MergeDiff.cs
deleted file mode 100644
index 8c3b93be..00000000
--- a/SabreTools/MergeDiff.cs
+++ /dev/null
@@ -1,442 +0,0 @@
-using SabreTools.Helper;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-
-namespace SabreTools
-{
- public class MergeDiff
- {
- // Listing related variables
- private List _inputs;
-
- // User specified flags
- private bool _diff;
- private bool _dedup;
- private bool _bare;
- private bool _forceunpack;
- private bool _old;
- private bool _superdat;
- private bool _cascade;
- private bool _inplace;
- private bool _clean;
-
- // User specified strings
- private string _name;
- private string _desc;
- private string _cat;
- private string _version;
- private string _author;
- private string _outdir;
-
- // Other required variables
- private string _date = DateTime.Now.ToString("yyyy-MM-dd");
- private Logger _logger;
-
- ///
- /// Create a new MergeDAT object
- ///
- /// A List of Strings representing the DATs or DAT folders to be merged
- /// Internal name of the DAT
- /// Description and external name of the DAT
- /// Category for the DAT
- /// Version of the DAT
- /// Author of the DAT
- /// True if all diff variants should be outputted, false otherwise
- /// True if a DiffDat of all inputs is wanted, false otherwise
- /// True if the outputted file should remove duplicates, false otherwise
- /// True if the date should be omitted from the DAT, false otherwise
- /// True if the forcepacking="unzip" tag is to be added, false otherwise
- /// True if a old-style DAT should be output, false otherwise
- /// True if DATs should be parsed into SuperDAT format, false otherwise
- /// True if the outputted diffs should be cascaded, false otherwise
- /// True if cascaded diffs overwrite the source files, false otherwise
- /// New output directory for outputted DATs (blank means default)
- /// True to clean the game names to WoD standard, false otherwise (default)
- /// Logger object for console and file output
- public MergeDiff(List inputs, string name, string desc, string cat, string version, string author,
- bool diff, bool dedup, bool bare, bool forceunpack, bool old, bool superdat, bool cascade, bool inplace,
- string outdir, bool clean, Logger logger)
- {
- _inputs = inputs;
- _name = name;
- _desc = desc;
- _cat = cat;
- _version = version;
- _author = author;
- _diff = diff;
- _dedup = dedup;
- _bare = bare;
- _forceunpack = forceunpack;
- _old = old;
- _superdat = superdat;
- _cascade = cascade;
- _inplace = inplace;
- _outdir = outdir;
- _clean = clean;
- _logger = logger;
- }
-
- ///
- /// Combine DATs, optionally diffing and deduping them
- ///
- /// True if the DATs merged correctly, false otherwise
- public bool Process()
- {
- // Check if there are enough inputs
- if (_inputs.Count < 1)
- {
- _logger.Warning("At least 1 input is required!");
- return false;
- }
-
- // Get the values that will be used
- if (_name == "")
- {
- _name = (_diff ? "DiffDAT" : "MergeDAT") + (_superdat ? "-SuperDAT" : "") + (_dedup ? "-deduped" : "");
- }
- if (_desc == "")
- {
- _desc = (_diff ? "DiffDAT" : "MergeDAT") + (_superdat ? "-SuperDAT" : "") + (_dedup ? " - deduped" : "");
- if (!_bare)
- {
- _desc += " (" + _date + ")";
- }
- }
- if (_cat == "" && _diff)
- {
- _cat = "DiffDAT";
- }
- if (_author == "")
- {
- _author = "SabreTools";
- }
-
- // Create a dictionary of all ROMs from the input DATs
- Dat userData;
- List datHeaders = PopulateUserData(out userData);
-
- // Modify the Dictionary if necessary and output the results
- if (_diff && !_cascade)
- {
- DiffNoCascade(_outdir, userData, _inputs, _logger);
- }
- // If we're in cascade and diff, output only cascaded diffs
- else if (_diff && _cascade)
- {
- DiffCascade(_outdir, _inplace, userData, _inputs, datHeaders, _logger);
- }
- // Output all entries with user-defined merge
- else
- {
- MergeNoDiff(_outdir, userData, _inputs, datHeaders, _logger);
- }
-
- return true;
- }
-
- ///
- /// Populate the user DatData object from the input files
- ///
- /// Output user DatData object to output
- /// List of DatData objects representing headers
- private List PopulateUserData(out Dat userData)
- {
- List datHeaders = new List();
-
- int i = 0;
- userData = new Dat
- {
- Roms = new Dictionary>(),
- MergeRoms = _dedup,
- };
- foreach (string input in _inputs)
- {
- _logger.User("Adding DAT: " + input.Split('¬')[0]);
- userData = DatTools.Parse(input.Split('¬')[0], i, 0, userData, _logger, true, _clean);
- i++;
-
- // If we are in inplace mode or redirecting output, save the DAT data
- if (_inplace || !String.IsNullOrEmpty(_outdir))
- {
- datHeaders.Add((Dat)userData.CloneHeader());
-
- // Reset the header values so the next can be captured
- userData.FileName = "";
- userData.Name = "";
- userData.Description = "";
- userData.Version = "";
- userData.Date = "";
- userData.Category = "";
- userData.Author = "";
- userData.ForcePacking = ForcePacking.None;
- userData.OutputFormat = OutputFormat.None;
- userData.Type = "";
- }
- }
-
- // Set the output values
- userData.FileName = _desc;
- userData.Name = _name;
- userData.Description = _desc;
- userData.Version = _version;
- userData.Date = _date;
- userData.Category = _cat;
- userData.Author = _author;
- userData.ForcePacking = (_forceunpack ? ForcePacking.Unzip : ForcePacking.None);
- userData.OutputFormat = (_old ? OutputFormat.ClrMamePro : OutputFormat.Xml);
- userData.Type = (_superdat ? "SuperDAT" : "");
-
- return datHeaders;
- }
-
- ///
- /// Output non-cascading diffs
- ///
- /// Main DatData to draw information from
- public void DiffNoCascade(string outdir, Dat userData, List inputs, Logger logger)
- {
- DateTime start = DateTime.Now;
- logger.User("Initializing all output DATs");
-
- // Don't have External dupes
- string post = " (No Duplicates)";
- Dat outerDiffData = (Dat)userData.CloneHeader();
- outerDiffData.FileName += post;
- outerDiffData.Name += post;
- outerDiffData.Description += post;
-
- // Have External dupes
- post = " (Duplicates)";
- Dat dupeData = (Dat)userData.CloneHeader();
- dupeData.FileName += post;
- dupeData.Name += post;
- dupeData.Description += post;
-
- // Create a list of DatData objects representing individual output files
- List outDats = new List();
-
- // Loop through each of the inputs and get or create a new DatData object
- for (int j = 0; j < inputs.Count; j++)
- {
- post = " (" + Path.GetFileNameWithoutExtension(inputs[j].Split('¬')[0]) + " Only)";
- Dat diffData = (Dat)userData.CloneHeader();
- diffData.FileName += post;
- diffData.Name += post;
- diffData.Description += post;
- outDats.Add(diffData);
- }
- logger.User("Initializing complete in " + DateTime.Now.Subtract(start).ToString(@"hh\:mm\:ss\.fffff"));
-
- // Now, loop through the dictionary and populate the correct DATs
- start = DateTime.Now;
- logger.User("Populating all output DATs");
- List keys = userData.Roms.Keys.ToList();
- foreach (string key in keys)
- {
- List roms = RomTools.Merge(userData.Roms[key], logger);
-
- if (roms != null && roms.Count > 0)
- {
- foreach (Rom rom in roms)
- {
- // No duplicates
- if (rom.Dupe < DupeType.ExternalHash)
- {
- // Individual DATs that are output
- if (outDats[rom.Metadata.SystemID].Roms.ContainsKey(key))
- {
- outDats[rom.Metadata.SystemID].Roms[key].Add(rom);
- }
- else
- {
- List tl = new List();
- tl.Add(rom);
- outDats[rom.Metadata.SystemID].Roms.Add(key, tl);
- }
-
- // Merged no-duplicates DAT
- Rom newrom = rom;
- newrom.Game += " (" + Path.GetFileNameWithoutExtension(inputs[newrom.Metadata.SystemID].Split('¬')[0]) + ")";
-
- if (outerDiffData.Roms.ContainsKey(key))
- {
- outerDiffData.Roms[key].Add(newrom);
- }
- else
- {
- List tl = new List();
- tl.Add(rom);
- outerDiffData.Roms.Add(key, tl);
- }
- }
-
- // Duplicates only
- if (rom.Dupe >= DupeType.ExternalHash)
- {
- Rom newrom = rom;
- newrom.Game += " (" + Path.GetFileNameWithoutExtension(inputs[newrom.Metadata.SystemID].Split('¬')[0]) + ")";
-
- if (dupeData.Roms.ContainsKey(key))
- {
- dupeData.Roms[key].Add(newrom);
- }
- else
- {
- List tl = new List();
- tl.Add(rom);
- dupeData.Roms.Add(key, tl);
- }
- }
- }
- }
- }
- logger.User("Populating complete in " + DateTime.Now.Subtract(start).ToString(@"hh\:mm\:ss\.fffff"));
-
- // Finally, loop through and output each of the DATs
- start = DateTime.Now;
- logger.User("Outputting all created DATs");
-
- // Output the difflist (a-b)+(b-a) diff
- Output.WriteDatfile(outerDiffData, outdir, logger);
-
- // Output the (ab) diff
- Output.WriteDatfile(dupeData, outdir, logger);
-
- // Output the individual (a-b) DATs
- for (int j = 0; j < inputs.Count; j++)
- {
- // If we have an output directory set, replace the path
- string path = outdir + (Path.GetDirectoryName(inputs[j].Split('¬')[0]).Remove(0, inputs[j].Split('¬')[1].Length));
-
- // If we have more than 0 roms, output
- if (outDats[j].Roms.Count > 0)
- {
- Output.WriteDatfile(outDats[j], path, logger);
- }
- }
- logger.User("Outputting complete in " + DateTime.Now.Subtract(start).ToString(@"hh\:mm\:ss\.fffff"));
- }
-
- ///
- /// Output cascading diffs
- ///
- /// Main DatData to draw information from
- /// Dat headers used optionally
- private void DiffCascade(string outdir, bool inplace, Dat userData, List inputs, List datHeaders, Logger logger)
- {
- string post = "";
-
- // Create a list of DatData objects representing output files
- List outDats = new List();
-
- // Loop through each of the inputs and get or create a new DatData object
- DateTime start = DateTime.Now;
- logger.User("Initializing all output DATs");
- for (int j = 0; j < inputs.Count; j++)
- {
- post = " (" + Path.GetFileNameWithoutExtension(inputs[j].Split('¬')[0]) + " Only)";
- Dat diffData;
-
- // If we're in inplace mode, take the appropriate DatData object already stored
- if (inplace || !String.IsNullOrEmpty(outdir))
- {
- diffData = datHeaders[j];
- }
- else
- {
- diffData = (Dat)userData.CloneHeader();
- diffData.FileName += post;
- diffData.Name += post;
- diffData.Description += post;
- }
- outDats.Add(diffData);
- }
- logger.User("Initializing complete in " + DateTime.Now.Subtract(start).ToString(@"hh\:mm\:ss\.fffff"));
-
- // Now, loop through the dictionary and populate the correct DATs
- start = DateTime.Now;
- logger.User("Populating all output DATs");
- List keys = userData.Roms.Keys.ToList();
- foreach (string key in keys)
- {
- List roms = RomTools.Merge(userData.Roms[key], logger);
-
- if (roms != null && roms.Count > 0)
- {
- foreach (Rom rom in roms)
- {
- if (outDats[rom.Metadata.SystemID].Roms.ContainsKey(key))
- {
- outDats[rom.Metadata.SystemID].Roms[key].Add(rom);
- }
- else
- {
- List tl = new List();
- tl.Add(rom);
- outDats[rom.Metadata.SystemID].Roms.Add(key, tl);
- }
- }
- }
- }
- logger.User("Populating complete in " + DateTime.Now.Subtract(start).ToString(@"hh\:mm\:ss\.fffff"));
-
- // Finally, loop through and output each of the DATs
- start = DateTime.Now;
- logger.User("Outputting all created DATs");
- for (int j = 0; j < inputs.Count; j++)
- {
- // If we have an output directory set, replace the path
- string path = "";
- if (inplace)
- {
- path = Path.GetDirectoryName(inputs[j].Split('¬')[0]);
- }
- else if (!String.IsNullOrEmpty(outdir))
- {
- path = outdir + (Path.GetDirectoryName(inputs[j].Split('¬')[0]).Remove(0, inputs[j].Split('¬')[1].Length));
- }
-
- // If we have more than 0 roms, output
- if (outDats[j].Roms.Count > 0)
- {
- Output.WriteDatfile(outDats[j], path, logger);
- }
- }
- logger.User("Outputting complete in " + DateTime.Now.Subtract(start).ToString(@"hh\:mm\:ss\.fffff"));
- }
-
- ///
- /// Output user defined merge
- ///
- /// Main DatData to draw information from
- /// Dat headers used optionally
- private void MergeNoDiff(string outdir, Dat userData, List inputs, List datHeaders, Logger logger)
- {
- // If we're in SuperDAT mode, prefix all games with their respective DATs
- if (userData.Type == "SuperDAT")
- {
- List keys = userData.Roms.Keys.ToList();
- foreach (string key in keys)
- {
- List newroms = new List();
- foreach (Rom rom in userData.Roms[key])
- {
- Rom newrom = rom;
- string filename = inputs[newrom.Metadata.SystemID].Split('¬')[0];
- string rootpath = inputs[newrom.Metadata.SystemID].Split('¬')[1];
-
- rootpath += (rootpath == "" ? "" : Path.DirectorySeparatorChar.ToString());
- filename = filename.Remove(0, rootpath.Length);
- newrom.Game = Path.Combine(Path.GetDirectoryName(filename), Path.GetFileNameWithoutExtension(filename), newrom.Game);
- newroms.Add(newrom);
- }
- userData.Roms[key] = newroms;
- }
- }
-
- Output.WriteDatfile(userData, outdir, logger);
- }
- }
-}
diff --git a/SabreTools/Partials/SabreTools_Inits.cs b/SabreTools/Partials/SabreTools_Inits.cs
index 3805a232..53da1685 100644
--- a/SabreTools/Partials/SabreTools_Inits.cs
+++ b/SabreTools/Partials/SabreTools_Inits.cs
@@ -74,7 +74,7 @@ namespace SabreTools
///
/// Wrap converting and updating DAT file from any format to any format
///
- /// Input filename
+ /// List of input filenames
/// /* Normal DAT header info */
/// New filename
/// New name
@@ -107,6 +107,12 @@ namespace SabreTools
/// Add the dat name as a directory prefix
/// Output files in romba format
/// Output files in TSV format
+ /// /* Merging and Diffing info */
+ /// True if input files should be merged into a single file, false otherwise
+ /// True if the input files should be diffed with each other, false otherwise
+ /// True if the diffed files should be cascade diffed, false otherwise
+ /// True if the cascade-diffed files should overwrite their inputs, false otherwise
+ /// True if the date should not be appended to the default name, false otherwise [OBSOLETE]
/// /* Filtering info */
/// Name of the game to match (can use asterisk-partials)
/// Name of the rom to match (can use asterisk-partials)
@@ -122,7 +128,7 @@ namespace SabreTools
/// Optional param for output directory
/// True to clean the game names to WoD standard, false otherwise (default)
/// True to dedupe the roms in the DAT, false otherwise (default)
- private static void InitUpdate(string input,
+ private static void InitUpdate(List inputs,
/* Normal DAT header info */
string filename,
string name,
@@ -157,6 +163,13 @@ namespace SabreTools
bool romba,
bool tsv,
+ /* Merging and Diffing info */
+ bool merge,
+ bool diff,
+ bool cascade,
+ bool inplace,
+ bool bare,
+
/* Filtering info */
string gamename,
string romname,
@@ -227,6 +240,32 @@ namespace SabreTools
addext = (addext == "" || addext.StartsWith(".") ? addext : "." + addext);
repext = (repext == "" || repext.StartsWith(".") ? repext : "." + repext);
+ // If we're in merge or diff mode and the names aren't set, set defaults
+ if (merge || diff)
+ {
+ // Get the values that will be used
+ if (name == "")
+ {
+ name = (diff ? "DiffDAT" : "MergeDAT") + (superdat ? "-SuperDAT" : "") + (dedup ? "-deduped" : "");
+ }
+ if (description == "")
+ {
+ description = (diff ? "DiffDAT" : "MergeDAT") + (superdat ? "-SuperDAT" : "") + (dedup ? " - deduped" : "");
+ if (!bare)
+ {
+ description += " (" + date + ")";
+ }
+ }
+ if (category == "" && diff)
+ {
+ category = "DiffDAT";
+ }
+ if (author == "")
+ {
+ author = "SabreTools";
+ }
+ }
+
// Populate the DatData object
Dat userInputDat = new Dat
{
@@ -262,31 +301,37 @@ namespace SabreTools
if (outputCMP)
{
userInputDat.OutputFormat = OutputFormat.ClrMamePro;
- DatTools.Update(input, userInputDat, outdir, clean, gamename, romname, romtype, sgt, slt, seq, crc, md5, sha1, nodump, _logger);
+ DatTools.Update(inputs, userInputDat, outdir, merge, diff, cascade, inplace, bare, clean,
+ gamename, romname, romtype, sgt, slt, seq, crc, md5, sha1, nodump, _logger);
}
- if (outputMiss || romba)
+ if (outputMiss)
{
userInputDat.OutputFormat = OutputFormat.MissFile;
- DatTools.Update(input, userInputDat, outdir, clean, gamename, romname, romtype, sgt, slt, seq, crc, md5, sha1, nodump, _logger);
+ DatTools.Update(inputs, userInputDat, outdir, merge, diff, cascade, inplace, bare, clean,
+ gamename, romname, romtype, sgt, slt, seq, crc, md5, sha1, nodump, _logger);
}
if (outputRC)
{
userInputDat.OutputFormat = OutputFormat.RomCenter;
- DatTools.Update(input, userInputDat, outdir, clean, gamename, romname, romtype, sgt, slt, seq, crc, md5, sha1, nodump, _logger);
+ DatTools.Update(inputs, userInputDat, outdir, merge, diff, cascade, inplace, bare, clean,
+ gamename, romname, romtype, sgt, slt, seq, crc, md5, sha1, nodump, _logger);
}
if (outputSD)
{
userInputDat.OutputFormat = OutputFormat.SabreDat;
- DatTools.Update(input, userInputDat, outdir, clean, gamename, romname, romtype, sgt, slt, seq, crc, md5, sha1, nodump, _logger);
+ DatTools.Update(inputs, userInputDat, outdir, merge, diff, cascade, inplace, bare, clean,
+ gamename, romname, romtype, sgt, slt, seq, crc, md5, sha1, nodump, _logger);
}
if (outputXML)
{
userInputDat.OutputFormat = OutputFormat.Xml;
- DatTools.Update(input, userInputDat, outdir, clean, gamename, romname, romtype, sgt, slt, seq, crc, md5, sha1, nodump, _logger);
+ DatTools.Update(inputs, userInputDat, outdir, merge, diff, cascade, inplace, bare, clean,
+ gamename, romname, romtype, sgt, slt, seq, crc, md5, sha1, nodump, _logger);
}
- if (!outputCMP && !(outputMiss || romba) && !outputRC && !outputSD && !outputXML)
+ if (!outputCMP && !outputMiss && !outputRC && !outputSD && !outputXML)
{
- DatTools.Update(input, userInputDat, outdir, clean, gamename, romname, romtype, sgt, slt, seq, crc, md5, sha1, nodump, _logger);
+ DatTools.Update(inputs, userInputDat, outdir, merge, diff, cascade, inplace, bare, clean,
+ gamename, romname, romtype, sgt, slt, seq, crc, md5, sha1, nodump, _logger);
}
}
@@ -372,71 +417,6 @@ namespace SabreTools
}
}
- ///
- /// Wrap merging, diffing, and deduping 2 or mor DATs
- ///
- /// A List of Strings representing the DATs or DAT folders to be merged
- /// Internal name of the DAT
- /// Description and external name of the DAT
- /// Category for the DAT
- /// Version of the DAT
- /// Author of the DAT
- /// True if a DiffDat of all inputs is wanted, false otherwise
- /// True if the outputted file should remove duplicates, false otherwise
- /// True if the date should be omitted from the DAT, false otherwise
- /// True if the forcepacking="unzip" tag is to be added, false otherwise
- /// True if a old-style DAT should be output, false otherwise
- /// True if DATs should be merged in SuperDAT style, false otherwise
- /// True if the outputted diffs should be cascaded, false otherwise
- /// True if cascaded diffs overwrite the source files, false otherwise
- /// Output directory for the files (blank is default)
- /// True to clean the game names to WoD standard, false otherwise (default)
- private static void InitMergeDiff(List inputs, string name, string desc, string cat, string version, string author,
- bool diff, bool dedup, bool bare, bool forceunpack, bool old, bool superdat, bool cascade, bool inplace, string outdir = "", bool clean = false)
- {
- // Make sure there are no folders in inputs
- List newInputs = new List();
- foreach (string input in inputs)
- {
- if (Directory.Exists(input))
- {
- foreach (string file in Directory.EnumerateFiles(input, "*", SearchOption.AllDirectories))
- {
- try
- {
- newInputs.Add(Path.GetFullPath(file) + "¬" + Path.GetFullPath(input));
- }
- catch (PathTooLongException)
- {
- _logger.Warning("The path for " + file + " was too long");
- }
- catch (Exception ex)
- {
- _logger.Error(ex.ToString());
- }
- }
- }
- else if (File.Exists(input))
- {
- try
- {
- newInputs.Add(Path.GetFullPath(input) + "¬" + Path.GetDirectoryName(Path.GetFullPath(input)));
- }
- catch (PathTooLongException)
- {
- _logger.Warning("The path for " + input + " was too long");
- }
- catch (Exception ex)
- {
- _logger.Error(ex.ToString());
- }
- }
- }
-
- MergeDiff md = new MergeDiff(newInputs, name, desc, cat, version, author, diff, dedup, bare, forceunpack, old, superdat, cascade, inplace, outdir, clean, _logger);
- md.Process();
- }
-
///
/// Wrap splitting a DAT by 2 extensions
///
diff --git a/SabreTools/SabreTools.cs b/SabreTools/SabreTools.cs
index 6f9b90ee..079a5e60 100644
--- a/SabreTools/SabreTools.cs
+++ b/SabreTools/SabreTools.cs
@@ -638,16 +638,13 @@ namespace SabreTools
ListSystems();
}
- // Convert, update, and filter a DAT or folder of DATs
- else if (update || outputCMP || outputMiss || outputRC || outputSD || outputXML)
+ // Convert, update, merge, diff, and filter a DAT or folder of DATs
+ else if (update || outputCMP || outputMiss || outputRC || outputSD || outputXML || merge || diff)
{
- foreach (string input in inputs)
- {
- InitUpdate(input, filename, name, description, category, version, date, author, email, homepage, url, comment, header,
- superdat, forcemerge, forcend, forcepack, outputCMP, outputMiss, outputRC, outputSD, outputXML, usegame, prefix,
- postfix, quotes, repext, addext, datprefix, romba, tsv, gamename, romname, romtype, sgt, slt, seq, crc, md5,
- sha1, nodump, outdir, clean, dedup);
- }
+ InitUpdate(inputs, filename, name, description, category, version, date, author, email, homepage, url, comment, header,
+ superdat, forcemerge, forcend, forcepack, outputCMP, outputMiss, outputRC, outputSD, outputXML, usegame, prefix,
+ postfix, quotes, repext, addext, datprefix, romba, tsv, merge, diff, cascade, inplace, bare, gamename, romname,
+ romtype, sgt, slt, seq, crc, md5, sha1, nodump, outdir, clean, dedup);
}
// Add a source or system
@@ -699,12 +696,6 @@ namespace SabreTools
InitExtSplit(inputs, exta, extb, outdir);
}
- // Merge, diff, and dedupe at least 2 DATs
- else if (merge || diff)
- {
- InitMergeDiff(inputs, name, description, category, version, author, diff, dedup, bare, forceunpack, old, superdat, cascade, inplace, outdir, clean);
- }
-
// Split a DAT by available hashes
else if (hashsplit)
{
diff --git a/SabreTools/SabreTools.csproj b/SabreTools/SabreTools.csproj
index 2909e81d..f9208af4 100644
--- a/SabreTools/SabreTools.csproj
+++ b/SabreTools/SabreTools.csproj
@@ -106,7 +106,6 @@
-