using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using SabreTools.Helper; namespace SabreTools { public class HashSplit { // Internal variables List _inputs; Logger _logger; /// /// Create a HashSplit object /// /// The name of the file to be split /// Logger object for file and console output public HashSplit(List inputs, Logger logger) { _inputs = inputs; _logger = logger; } /// /// Start help or use supplied parameters /// /// String array representing command line parameters public static void Main(string[] args) { Console.Clear(); // Credits take precidence over all if ((new List(args)).Contains("--credits")) { Build.Credits(); return; } Logger logger = new Logger(true, "hashsplit.log"); logger.Start(); // First things first, take care of all of the arguments that this could have List inputs = new List(); foreach (string arg in args) { switch (arg) { case "-h": case "-?": case "--help": Build.Help(); logger.Close(); return; default: inputs.Add(arg); break; } } // If there's no inputs, show the help if (inputs.Count() == 0) { Build.Help(); logger.Close(); return; } // Output the title Build.Start("HashSplit"); // Verify the input file foreach (string input in inputs) { if (!File.Exists(input.Replace("\"", "")) && !Directory.Exists(input.Replace("\"", ""))) { logger.Error(input + " is not a valid file!"); Console.WriteLine(); Build.Help(); return; } } // If so, run the program HashSplit hs = new HashSplit(inputs, logger); hs.Split(); } /// /// Split the DAT into parts by best-available hash data /// /// True if the DATs were output, false otherwise public bool Split() { // First, clean the original filenames List newinputs = new List(); foreach (string input in _inputs) { newinputs.Add(Path.GetFullPath(input.Replace("\"", ""))); } _inputs = newinputs; // Now, process each file and folder in the input bool finalreturn = true; foreach (string input in _inputs) { if (File.Exists(input)) { finalreturn &= SplitHelper(input); } if (Directory.Exists(input)) { foreach (string file in Directory.EnumerateFiles(input, "*", SearchOption.AllDirectories)) { finalreturn &= SplitHelper(Path.GetFullPath(file)); } } } return finalreturn; } private bool SplitHelper(string filename) { // Get the file data to be split OutputFormat outputFormat = RomManipulation.GetOutputFormat(filename); DatData datdata = new DatData { Roms = new Dictionary>(), }; datdata = RomManipulation.Parse(filename, 0, 0, datdata, _logger, true); // Create each of the respective output DATs _logger.User("Creating and populating new DATs"); DatData sha1 = new DatData { Name = datdata.Name + " (SHA-1)", Description = datdata.Description + " (SHA-1)", Category = datdata.Category, Version = datdata.Version, Date = datdata.Date, Author = datdata.Author, Email = datdata.Email, Homepage = datdata.Homepage, Url = datdata.Url, Comment = datdata.Comment, Header = datdata.Header, Type = datdata.Type, ForceMerging = datdata.ForceMerging, ForceNodump = datdata.ForceNodump, ForcePacking = datdata.ForcePacking, OutputFormat = outputFormat, MergeRoms = datdata.MergeRoms, Roms = new Dictionary>(), }; DatData md5 = new DatData { Name = datdata.Name + " (MD5)", Description = datdata.Description + " (MD5)", Category = datdata.Category, Version = datdata.Version, Date = datdata.Date, Author = datdata.Author, Email = datdata.Email, Homepage = datdata.Homepage, Url = datdata.Url, Comment = datdata.Comment, Header = datdata.Header, Type = datdata.Type, ForceMerging = datdata.ForceMerging, ForceNodump = datdata.ForceNodump, ForcePacking = datdata.ForcePacking, OutputFormat = outputFormat, MergeRoms = datdata.MergeRoms, Roms = new Dictionary>(), }; DatData crc = new DatData { Name = datdata.Name + " (CRC and None)", Description = datdata.Description + " (CRC and None)", Category = datdata.Category, Version = datdata.Version, Date = datdata.Date, Author = datdata.Author, Email = datdata.Email, Homepage = datdata.Homepage, Url = datdata.Url, Comment = datdata.Comment, Header = datdata.Header, Type = datdata.Type, ForceMerging = datdata.ForceMerging, ForceNodump = datdata.ForceNodump, ForcePacking = datdata.ForcePacking, OutputFormat = outputFormat, MergeRoms = datdata.MergeRoms, Roms = new Dictionary>(), }; // Now populate each of the DAT objects in turn List keys = datdata.Roms.Keys.ToList(); foreach (string key in keys) { List roms = datdata.Roms[key]; foreach (RomData rom in roms) { // If the file has a SHA-1 if (rom.SHA1 != null && rom.SHA1 != "") { if (sha1.Roms.ContainsKey(key)) { sha1.Roms[key].Add(rom); } else { List temp = new List(); temp.Add(rom); sha1.Roms.Add(key, temp); } } // If the file has no SHA-1 but has an MD5 else if (rom.MD5 != null && rom.MD5 != "") { if (md5.Roms.ContainsKey(key)) { md5.Roms[key].Add(rom); } else { List temp = new List(); temp.Add(rom); md5.Roms.Add(key, temp); } } // All other cases else { if (crc.Roms.ContainsKey(key)) { crc.Roms[key].Add(rom); } else { List temp = new List(); temp.Add(rom); crc.Roms.Add(key, temp); } } } } bool success = true; // Now, output all of the files to the original location _logger.User("DAT information created, outputting new files"); string outdir = Path.GetDirectoryName(filename); success &= Output.WriteDatfile(sha1, outdir, _logger); success &= Output.WriteDatfile(md5, outdir, _logger); success &= Output.WriteDatfile(crc, outdir, _logger); return success; } } }