diff --git a/.gitignore b/.gitignore index c78880ca..a90c9a98 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,9 @@ /Deheader/obj /Deheader/obj/Debug /Deheader/obj/Release +/DiffDat/obj +/DiffDat/obj/Debug +/DiffDat/obj/Release /SabreHelper/obj /SabreHelper/obj/Debug /SabreHelper/obj/Release diff --git a/DiffDat/App.config b/DiffDat/App.config new file mode 100644 index 00000000..88fa4027 --- /dev/null +++ b/DiffDat/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/DiffDat/DiffDat.cs b/DiffDat/DiffDat.cs new file mode 100644 index 00000000..9e57aa0f --- /dev/null +++ b/DiffDat/DiffDat.cs @@ -0,0 +1,90 @@ +using System; +using System.Collections.Generic; +using System.IO; + +using SabreTools.Helper; + +namespace SabreTools +{ + public class DiffDat + { + private static Logger logger; + + public static void Main(string[] args) + { + Console.Clear(); + + // Credits take precidence over all + if ((new List(args)).Contains("--credits")) + { + Build.Credits(); + return; + } + + if (args.Length == 0) + { + Build.Help(); + return; + } + + logger = new Logger(false, "diffdat.log"); + logger.Start(); + + // Output the title + Build.Start("DiffDat"); + + List inputs = new List(); + bool tofile = false, help = false; + foreach (string arg in args) + { + switch (arg) + { + case "-h": + case "-?": + case "--help": + help = true; + break; + case "-l": + case "--log": + tofile = true; + break; + default: + // Add actual files to the list of inputs + if (File.Exists(arg.Replace("\"", ""))) + { + inputs.Add(Path.GetFullPath(arg.Replace("\"", ""))); + } + else if (Directory.Exists(arg.Replace("\"", ""))) + { + foreach (string file in Directory.EnumerateFiles(arg, "*", SearchOption.AllDirectories)) + { + inputs.Add(Path.GetFullPath(file)); + } + } + break; + } + } + + // Set the possibly new value for logger + logger.ToFile = tofile; + + // Show help if explicitly asked for it or if not enough files are supplied + if (help || inputs.Count < 2) + { + Build.Help(); + logger.Close(); + return; + } + + // Otherwise, read in the two files, diff them, and write the result to the file type that the first one is + List A = new List(); + foreach (string input in inputs) + { + logger.Log("Merging in DAT: " + input); + List B = RomManipulation.Parse(input, 0, 0, logger); + A = RomManipulation.Diff(A, B); + } + Output.WriteToDat("diffdat", "diffdat", "", "", "DiffDat", "SabreTools", false, !RomManipulation.IsXmlDat(inputs[0]), "", A, logger); + } + } +} diff --git a/DiffDat/DiffDat.csproj b/DiffDat/DiffDat.csproj new file mode 100644 index 00000000..8adb5e6f --- /dev/null +++ b/DiffDat/DiffDat.csproj @@ -0,0 +1,66 @@ + + + + + Debug + AnyCPU + {785A4E9E-0DC1-4FAD-AA3A-57B5B122CD8E} + Exe + Properties + DiffDat + DiffDat + v4.5.2 + 512 + true + + + AnyCPU + true + full + false + ..\..\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + ..\..\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + {225a1afd-0890-44e8-b779-7502665c23a5} + SabreHelper + + + + + \ No newline at end of file diff --git a/DiffDat/Properties/AssemblyInfo.cs b/DiffDat/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..d86f7c5c --- /dev/null +++ b/DiffDat/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("DiffDat")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("DiffDat")] +[assembly: AssemblyCopyright("Copyright © 2016")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("785a4e9e-0dc1-4fad-aa3a-57b5b122cd8e")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/README.MD b/README.MD index 6787d779..abcc7f13 100644 --- a/README.MD +++ b/README.MD @@ -77,7 +77,7 @@ CURRENTLY UNCODED - A program to merge an arbitrary number of DATs into a single DiffDat

-CURRENTLY UNCODED - A program to create a DAT based on the differences between two input DATs. Optionally, if the output file exists, the information is appended. (This latter functionality may be wrapped into MergeDAT.) +A program to create a DAT based on the differences between two or more input DATs.

Licensing

diff --git a/SabreHelper/Build.cs b/SabreHelper/Build.cs index 77f8fd1a..e1084772 100644 --- a/SabreHelper/Build.cs +++ b/SabreHelper/Build.cs @@ -156,6 +156,15 @@ Options: -l, --log Enable log to file -sd, --superdat Enable SuperDAT creation"); break; + case "DiffDat": + Console.WriteLine(@"DiffDat - Get the difference between two or more DAT files +----------------------------------------- +Usage: DiffDat [options] [filename] [filename] ... + +Options: + -h, -?, --help Show this help dialog + -l, --log Enable log to file"); + break; default: Console.Write("This is the default help output"); break; diff --git a/SabreHelper/Output.cs b/SabreHelper/Output.cs index 73a513b1..d0dca637 100644 --- a/SabreHelper/Output.cs +++ b/SabreHelper/Output.cs @@ -171,5 +171,70 @@ namespace SabreTools.Helper return true; } + + ///

+ /// Convert a List of RomData objects to a List of tab-deliminated strings + /// + /// List of RomData objects representing the roms to be parsed + /// List of Strings representing the roms + public static List RomDataToString(List roms) + { + List outlist = new List(); + foreach (RomData rom in roms) + { + outlist.Add(rom.Manufacturer + "\t" + + rom.System + "\t" + + rom.SystemID + "\t" + + rom.Source + "\t" + + rom.URL + "\t" + + rom.SourceID + "\t" + + rom.Game + "\t" + + rom.Name + "\t" + + rom.Type + "\t" + + rom.Size + "\t" + + rom.CRC + "\t" + + rom.MD5 + "\t" + + rom.SHA1); + } + return outlist; + } + + /// + /// Convert a List of tab-deliminated strings objects to a List of RomData objects + /// + /// List of Strings representing the roms to be parsed + /// List of RomData objects representing the roms + public static List StringToRomData(List roms) + { + List outlist = new List(); + foreach (String rom in roms) + { + string[] temp = rom.Split('\t'); + try + { + outlist.Add(new RomData + { + Manufacturer = temp[0], + System = temp[1], + SystemID = Int32.Parse(temp[2]), + Source = temp[3], + URL = temp[4], + SourceID = Int32.Parse(temp[5]), + Game = temp[6], + Name = temp[7], + Type = temp[8], + Size = Int64.Parse(temp[9]), + CRC = temp[10], + MD5 = temp[11], + SHA1 = temp[12], + }); + } + catch (Exception ex) + { + Console.WriteLine(ex.ToString()); + } + } + return outlist; + } } } diff --git a/SabreHelper/RomManipulation.cs b/SabreHelper/RomManipulation.cs index 1afe6378..36475905 100644 --- a/SabreHelper/RomManipulation.cs +++ b/SabreHelper/RomManipulation.cs @@ -333,7 +333,10 @@ namespace SabreTools.Helper /// Adapted from http://stackoverflow.com/questions/5620266/the-opposite-of-intersect public static List Diff(List A, List B) { - return A.Except(B).Union(B.Except(A)).ToList(); + List AString = Output.RomDataToString(A); + List BString = Output.RomDataToString(B); + List CString = AString.Except(BString).Union(BString.Except(AString)).ToList(); + return Output.StringToRomData(CString); } } } diff --git a/SabreTools.sln b/SabreTools.sln index 581310a4..7e909153 100644 --- a/SabreTools.sln +++ b/SabreTools.sln @@ -17,6 +17,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SabreHelper", "SabreHelper\ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DATFromDir", "DATFromDir\DATFromDir.csproj", "{382B75D3-079E-49D5-A830-54DD6EB5A02D}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DiffDat", "DiffDat\DiffDat.csproj", "{785A4E9E-0DC1-4FAD-AA3A-57B5B122CD8E}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -52,6 +54,10 @@ Global {382B75D3-079E-49D5-A830-54DD6EB5A02D}.Debug|Any CPU.Build.0 = Debug|Any CPU {382B75D3-079E-49D5-A830-54DD6EB5A02D}.Release|Any CPU.ActiveCfg = Release|Any CPU {382B75D3-079E-49D5-A830-54DD6EB5A02D}.Release|Any CPU.Build.0 = Release|Any CPU + {785A4E9E-0DC1-4FAD-AA3A-57B5B122CD8E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {785A4E9E-0DC1-4FAD-AA3A-57B5B122CD8E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {785A4E9E-0DC1-4FAD-AA3A-57B5B122CD8E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {785A4E9E-0DC1-4FAD-AA3A-57B5B122CD8E}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE