diff --git a/SabreTools.Helper/Objects/DATFromDirParallel.cs b/SabreTools.Helper/Objects/DATFromDirParallel.cs index 7e93ea78..51bcd7f2 100644 --- a/SabreTools.Helper/Objects/DATFromDirParallel.cs +++ b/SabreTools.Helper/Objects/DATFromDirParallel.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; -using System.Threading; using System.Threading.Tasks; namespace SabreTools diff --git a/SabreTools.Helper/Tools/DatTools.cs b/SabreTools.Helper/Tools/DatTools.cs index 4e4ee267..04928be8 100644 --- a/SabreTools.Helper/Tools/DatTools.cs +++ b/SabreTools.Helper/Tools/DatTools.cs @@ -4,6 +4,7 @@ using System.IO; using System.Linq; using System.Text; using System.Text.RegularExpressions; +using System.Threading.Tasks; using System.Web; using System.Xml; @@ -2393,6 +2394,178 @@ namespace SabreTools.Helper #endregion + #region Converting and Updating (Parallel) + + /// + /// Convert, update, and filter a DAT file (Parallel) + /// + /// 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 + /// Non-zero flag for diffing mode, zero otherwise + /// True if the diffed files should be cascade diffed, false if diffed files should be reverse cascaded, null otherwise + /// True if the cascade-diffed files should overwrite their inputs, false otherwise + /// True if the first cascaded diff file should be skipped on output, 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) + /// True to allow SL DATs to have game names used instead of descriptions, false otherwise (default) + /// Name of the game to match (can use asterisk-partials) + /// Name of the rom to match (can use asterisk-partials) + /// Type of the rom to match + /// Find roms greater than or equal to this size + /// Find roms less than or equal to this size + /// Find roms equal to this size + /// CRC of the rom to match (can use asterisk-partials) + /// MD5 of the rom to match (can use asterisk-partials) + /// 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) + /// True if we are supposed to trim names to NTFS length, false otherwise + /// True if all games should be replaced by '!', false otherwise + /// String representing root directory to compare against for length calculation + /// Logging object for console and file output + public static void UpdateParallel(List inputFileNames, Dat datdata, string outputDirectory, bool merge, DiffMode diff, bool? cascade, bool inplace, + bool skip, bool bare, bool clean, bool softlist, string gamename, string romname, string romtype, long sgt, long slt, long seq, string crc, + string md5, string sha1, bool? nodump, bool trim, bool single, string root, Logger logger) + { + // If we're in merging or diffing mode, use the full list of inputs + if (merge || diff != 0) + { + // Make sure there are no folders in inputs + List newInputFileNames = new List(); + foreach (string input in inputFileNames) + { + if (Directory.Exists(input)) + { + foreach (string file in Directory.EnumerateFiles(input, "*", SearchOption.AllDirectories)) + { + try + { + newInputFileNames.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 + { + newInputFileNames.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()); + } + } + } + + // If we're in inverse cascade, reverse the list + if (cascade == false) + { + newInputFileNames.Reverse(); + } + + // Create a dictionary of all ROMs from the input DATs + Dat userData; + List datHeaders = PopulateUserData(newInputFileNames, inplace, clean, softlist, + outputDirectory, datdata, out userData, gamename, romname, romtype, sgt, slt, seq, + crc, md5, sha1, nodump, trim, single, root, logger); + + // Modify the Dictionary if necessary and output the results + if (diff != 0 && cascade == null) + { + DiffNoCascade(diff, outputDirectory, userData, newInputFileNames, logger); + } + // If we're in cascade and diff, output only cascaded diffs + else if (diff != 0 && cascade != null) + { + DiffCascade(outputDirectory, inplace, userData, newInputFileNames, datHeaders, skip, logger); + } + // Output all entries with user-defined merge + else + { + MergeNoDiff(outputDirectory, userData, newInputFileNames, datHeaders, logger); + } + } + // Otherwise, loop through all of the inputs individually + else + { + Parallel.ForEach(inputFileNames, inputFileName => + { + // 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, gamename, romname, + romtype, sgt, slt, seq, crc, md5, sha1, nodump, trim, single, + root, logger, true, clean, softlist, keepext: (datdata.XSV != null)); + + // 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"; + } + + // If we have roms, output them + if (datdata.Files.Count != 0) + { + DatTools.WriteDatfile(datdata, (outputDirectory == "" ? Path.GetDirectoryName(inputFileName) : outputDirectory), logger); + } + } + else if (Directory.Exists(inputFileName)) + { + inputFileName = Path.GetFullPath(inputFileName) + Path.DirectorySeparatorChar; + + Parallel.ForEach(Directory.EnumerateFiles(inputFileName, "*", SearchOption.AllDirectories), file => + { + logger.User("Processing \"" + Path.GetFullPath(file).Remove(0, inputFileName.Length) + "\""); + Dat innerDatdata = (Dat)datdata.Clone(); + innerDatdata.Files = null; + innerDatdata = Parse(file, 0, 0, innerDatdata, gamename, romname, romtype, sgt, + slt, seq, crc, md5, sha1, nodump, trim, single, root, logger, true, clean, keepext: (datdata.XSV != null)); + + // 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"; + } + + // If we have roms, output them + if (innerDatdata.Files != null && innerDatdata.Files.Count != 0) + { + DatTools.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; + } + + #endregion + #region DAT Writing ///