diff --git a/RombaSharp/Partials/RombaSharp_Inits.cs b/RombaSharp/Partials/RombaSharp_Inits.cs index dbc47604..b4ceda69 100644 --- a/RombaSharp/Partials/RombaSharp_Inits.cs +++ b/RombaSharp/Partials/RombaSharp_Inits.cs @@ -66,7 +66,8 @@ namespace SabreTools Files = new Dictionary>(), }; - DATFromDir dfd = new DATFromDir(inputs, datdata, false, false, true, false, true, "__temp__", _logger); + DATFromDir dfd = new DATFromDir(inputs, datdata, false /* noMD5 */, false /* noSHA1 */, true /* bare */, + false /* archivesAsFiles */, true /* enableGzip */, false /* addblanks */, "__temp__" /* tempdir */, _logger); dfd.Start(); } diff --git a/SabreTools.Helper/Objects/DATFromDir.cs b/SabreTools.Helper/Objects/DATFromDir.cs index d1aa7484..bde179f6 100644 --- a/SabreTools.Helper/Objects/DATFromDir.cs +++ b/SabreTools.Helper/Objects/DATFromDir.cs @@ -47,10 +47,11 @@ namespace SabreTools /// True if the date should be omitted from the DAT, false otherwise /// True if archives should be treated as files, false otherwise /// True if GZIP archives should be treated as files, false otherwise + /// True if blank items should be created for empty folders, false otherwise /// Name of the directory to create a temp folder in (blank is current directory) /// True if the file should not be written out, false otherwise (default) /// Logger object for console and file output - public DATFromDir(List inputs, Dat datdata, bool noMD5, bool noSHA1, bool bare, bool archivesAsFiles, bool enableGzip, string tempDir, Logger logger, bool nowrite = false) + public DATFromDir(List inputs, Dat datdata, bool noMD5, bool noSHA1, bool bare, bool archivesAsFiles, bool enableGzip, bool addblanks, string tempDir, Logger logger, bool nowrite = false) { _inputs = inputs; _datdata = datdata; @@ -61,7 +62,7 @@ namespace SabreTools _enableGzip = enableGzip; _tempDir = tempDir; _logger = logger; - _addblanks = false; // This needs a proper flag later + _addblanks = addblanks; _nowrite = nowrite; } diff --git a/SabreTools.Helper/Objects/DATFromDirParallel.cs b/SabreTools.Helper/Objects/DATFromDirParallel.cs index 16096457..3ec1c4be 100644 --- a/SabreTools.Helper/Objects/DATFromDirParallel.cs +++ b/SabreTools.Helper/Objects/DATFromDirParallel.cs @@ -46,11 +46,12 @@ namespace SabreTools /// True if the date should be omitted from the DAT, false otherwise /// True if archives should be treated as files, false otherwise /// True if GZIP archives should be treated as files, false otherwise + /// True if blank items should be created for empty folders, false otherwise /// Name of the directory to create a temp folder in (blank is current directory) /// Integer representing the maximum amount of parallelization to be used /// Logger object for console and file output public DATFromDirParallel(string basePath, Dat datdata, bool noMD5, bool noSHA1, bool bare, - bool archivesAsFiles, bool enableGzip, string tempDir, int maxDegreeOfParallelism, Logger logger) + bool archivesAsFiles, bool enableGzip, bool addblanks, string tempDir, int maxDegreeOfParallelism, Logger logger) { _basePath = Path.GetFullPath(basePath); _datdata = datdata; @@ -61,7 +62,7 @@ namespace SabreTools _bare = bare; _archivesAsFiles = archivesAsFiles; _enableGzip = enableGzip; - _addblanks = false; // This needs a proper flag later + _addblanks = addblanks; _tempDir = tempDir; _maxDegreeOfParallelism = maxDegreeOfParallelism; _logger = logger; diff --git a/SabreTools.Helper/Objects/SimpleSort.cs b/SabreTools.Helper/Objects/SimpleSort.cs index 59389213..eddd247e 100644 --- a/SabreTools.Helper/Objects/SimpleSort.cs +++ b/SabreTools.Helper/Objects/SimpleSort.cs @@ -132,7 +132,8 @@ namespace SabreTools.Helper // Then, loop through and check each of the inputs _logger.User("Processing files:\n"); - DATFromDir dfd = new DATFromDir(files, _datdata, false, false, false, false, true, "", _logger, true); + DATFromDir dfd = new DATFromDir(files, _datdata, false /* noMD5 */, false /* noSHA1 */, false /* bare */, + false /* archivesAsFiles */, true /* enableGzip */, false /* addblanks */, "" /* tempdir */, _logger, true /* nowrite */); dfd.Start(); // Setup the fixdat @@ -331,7 +332,7 @@ namespace SabreTools.Helper } else { - FileTools.WriteToManagedArchive(input, _outdir, found); + FileTools.WriteToArchive(input, _outdir, found); } } } @@ -398,7 +399,7 @@ namespace SabreTools.Helper } else { - FileTools.WriteToManagedArchive(newinput, _outdir, found); + FileTools.WriteToArchive(newinput, _outdir, found); } } @@ -444,7 +445,7 @@ namespace SabreTools.Helper } else { - FileTools.WriteToManagedArchive(input, _outdir, newfound); + FileTools.WriteToArchive(input, _outdir, newfound); } } } @@ -530,7 +531,7 @@ namespace SabreTools.Helper } else { - FileTools.WriteToManagedArchive(outfile, _outdir, found); + FileTools.WriteToArchive(outfile, _outdir, found); } try @@ -542,8 +543,7 @@ namespace SabreTools.Helper } else { - string archiveFileName = Path.Combine(_outdir, found.Machine.Name + ".zip"); - FileTools.CopyFileBetweenArchives(input, archiveFileName, rom.Name, found.Name, _logger); + FileTools.CopyFileBetweenArchives(input, _outdir, rom.Name, found, _logger); } } } diff --git a/SabreTools.Helper/Tools/DatTools.cs b/SabreTools.Helper/Tools/DatTools.cs index b267a6e6..7a4044f6 100644 --- a/SabreTools.Helper/Tools/DatTools.cs +++ b/SabreTools.Helper/Tools/DatTools.cs @@ -468,7 +468,7 @@ namespace SabreTools.Helper switch (gc[1].Value) { case "name": - tempgamename = itemval; + tempgamename = (itemval.ToLowerInvariant().EndsWith(".zip") ? itemval.Remove(itemval.Length - 4) : itemval); break; case "description": gamedesc = itemval; diff --git a/SabreTools.Helper/Tools/FileTools.cs b/SabreTools.Helper/Tools/FileTools.cs index 89446a0f..ea422ec9 100644 --- a/SabreTools.Helper/Tools/FileTools.cs +++ b/SabreTools.Helper/Tools/FileTools.cs @@ -20,100 +20,65 @@ namespace SabreTools.Helper /// /// Copy a file to an output archive /// - /// Input filename to be moved - /// Output directory to build to + /// Input filename to be moved + /// Output directory to build to /// RomData representing the new information - public static void WriteToArchive(string input, string output, Rom rom) + /// True if the archive was written properly, false otherwise + public static bool WriteToArchive(string inputFile, string outputDirectory, Rom rom) { - string archiveFileName = Path.Combine(output, rom.Machine + ".zip"); + bool success = false; + + // If the input file doesn't exist, return + if (!File.Exists(inputFile)) + { + return success; + } + + string archiveFileName = Path.Combine(outputDirectory, rom.Machine.Name + ".zip"); ZipArchive outarchive = null; try { + // If the archive doesn't exist, create it if (!File.Exists(archiveFileName)) { outarchive = ZipFile.Open(archiveFileName, ZipArchiveMode.Create); - } - else - { - outarchive = ZipFile.Open(archiveFileName, ZipArchiveMode.Update); + outarchive.Dispose(); } - if (File.Exists(input)) + // Open the archive for writing + using (outarchive = ZipFile.Open(archiveFileName, ZipArchiveMode.Update)) { - if (outarchive.Mode == ZipArchiveMode.Create || outarchive.GetEntry(rom.Name) == null) + // If the archive doesn't already contain the entry, add it + if (outarchive.GetEntry(rom.Name) == null) { - outarchive.CreateEntryFromFile(input, rom.Name, CompressionLevel.Optimal); + outarchive.CreateEntryFromFile(inputFile, rom.Name, CompressionLevel.Optimal); } - } - else if (Directory.Exists(input)) - { - foreach (string file in Directory.EnumerateFiles(input, "*", SearchOption.AllDirectories)) + + // If there's a Date attached to the rom, change the entry to that Date + if (!String.IsNullOrEmpty(rom.Date)) { - if (outarchive.Mode == ZipArchiveMode.Create || outarchive.GetEntry(file) == null) + DateTimeOffset dto = DateTimeOffset.Now; + if (DateTimeOffset.TryParse(rom.Date, out dto)) { - outarchive.CreateEntryFromFile(file, file, CompressionLevel.Optimal); + outarchive.GetEntry(rom.Name).LastWriteTime = dto; } } } + + success = true; } catch (Exception ex) { Console.WriteLine(ex); + success = false; } finally { outarchive?.Dispose(); } - } - /// - /// Copy a file to an output archive using SharpCompress - /// - /// Input filename to be moved - /// Output directory to build to - /// RomData representing the new information - public static void WriteToManagedArchive(string input, string output, Rom rom) - { - string archiveFileName = Path.Combine(output, rom.Machine.Name + ".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); - } + return success; } /// @@ -423,82 +388,19 @@ namespace SabreTools.Helper #region Archive-to-Archive Handling /// - /// Attempt to copy a file between archives using SharpCompress + /// Attempt to copy a file between archives /// /// Source archive name - /// Destination archive name + /// Destination archive name /// Input entry name /// Output entry name /// Logger object for file and console output /// True if the copy was a success, false otherwise - public static bool CopyFileBetweenArchives(string inputArchive, string outputArchive, - string sourceEntryName, string destEntryName, Logger logger) + public static bool CopyFileBetweenArchives(string inputArchive, string outputDirectory, + string sourceEntryName, Rom destEntry, Logger logger) { - bool success = false; - - // First get the archive types - ArchiveType? iat = GetCurrentArchiveType(inputArchive, logger); - ArchiveType? oat = (File.Exists(outputArchive) ? GetCurrentArchiveType(outputArchive, logger) : ArchiveType.Zip); - - // If we got back null (or the output is not a Zipfile), then it's not an archive, so we we return - if (iat == null || (oat == null || oat != ArchiveType.Zip) || inputArchive == outputArchive) - { - return success; - } - - try - { - using (IReader reader = ReaderFactory.Open(File.OpenRead(inputArchive))) - { - if (iat == ArchiveType.Zip || iat == ArchiveType.SevenZip || iat == ArchiveType.Rar) - { - while (reader.MoveToNextEntry()) - { - logger.Log("Current entry name: '" + reader.Entry.Key + "'"); - if (reader.Entry != null && reader.Entry.Key.Contains(sourceEntryName)) - { - // Get if the file should be written out - bool newfile = File.Exists(outputArchive) && new FileInfo(outputArchive).Length != 0; - - using (SharpCompress.Archive.Zip.ZipArchive archive = (newfile - ? ArchiveFactory.Open(outputArchive, Options.LookForHeader) as SharpCompress.Archive.Zip.ZipArchive - : ArchiveFactory.Create(ArchiveType.Zip) as SharpCompress.Archive.Zip.ZipArchive)) - { - try - { - if (!archive.Entries.Contains(reader.Entry)) - { - Stream tempstream = new MemoryStream(); - reader.WriteEntryTo(tempstream); - archive.AddEntry(destEntryName, tempstream); - archive.SaveTo(outputArchive + ".tmp", CompressionType.Deflate); - } - } - catch (Exception) - { - // Don't log archive write errors - } - } - - if (File.Exists(outputArchive + ".tmp")) - { - File.Delete(outputArchive); - File.Move(outputArchive + ".tmp", outputArchive); - } - - success = true; - } - } - } - } - } - catch (Exception ex) - { - logger.Error(ex.ToString()); - success = false; - } - - return success; + string tempfile = ExtractSingleItemFromArchive(inputArchive, sourceEntryName, Path.GetTempPath(), logger); + return WriteToArchive(tempfile, outputDirectory, destEntry); } #endregion diff --git a/SabreTools/Partials/SabreTools_Inits.cs b/SabreTools/Partials/SabreTools_Inits.cs index 8b44ba3c..5ac4dd23 100644 --- a/SabreTools/Partials/SabreTools_Inits.cs +++ b/SabreTools/Partials/SabreTools_Inits.cs @@ -101,6 +101,7 @@ namespace SabreTools /// True if the date should be omitted from the DAT, false otherwise /// True if archives should be treated as files, false otherwise /// True if GZIP archives should be treated as files, false otherwise + /// True if blank items should be created for empty folders, false otherwise /// Name of the directory to create a temp folder in (blank is current directory /// Integer representing the maximum amount of parallelization to be used private static void InitDatFromDir(List inputs, @@ -119,6 +120,7 @@ namespace SabreTools bool bare, bool archivesAsFiles, bool enableGzip, + bool addblanks, string tempDir, int maxDegreeOfParallelism) { @@ -142,7 +144,7 @@ namespace SabreTools // If the user has only set a single thread, use the original version if (maxDegreeOfParallelism == 1) { - DATFromDir dfd = new DATFromDir(inputs, basedat, noMD5, noSHA1, bare, archivesAsFiles, enableGzip, tempDir, _logger); + DATFromDir dfd = new DATFromDir(inputs, basedat, noMD5, noSHA1, bare, archivesAsFiles, enableGzip, addblanks, tempDir, _logger); bool success = dfd.Start(); // If we failed, show the help @@ -166,7 +168,7 @@ namespace SabreTools datdata.Files = new Dictionary>(); string basePath = Path.GetFullPath(path); - DATFromDirParallel dfd = new DATFromDirParallel(basePath, datdata, noMD5, noSHA1, bare, archivesAsFiles, enableGzip, tempDir, maxDegreeOfParallelism, _logger); + DATFromDirParallel dfd = new DATFromDirParallel(basePath, datdata, noMD5, noSHA1, bare, archivesAsFiles, enableGzip, addblanks, tempDir, maxDegreeOfParallelism, _logger); bool success = dfd.Start(); // If it was a success, write the DAT out diff --git a/SabreTools/SabreTools.cs b/SabreTools/SabreTools.cs index 74adf1cb..7d2f86c6 100644 --- a/SabreTools/SabreTools.cs +++ b/SabreTools/SabreTools.cs @@ -77,6 +77,7 @@ namespace SabreTools // Set all default values bool help = false, add = false, + addblanks = false, archivesAsFiles = false, bare = false, clean = false, @@ -660,7 +661,7 @@ namespace SabreTools else if (datfromdir) { InitDatFromDir(inputs, filename, name, description, category, version, author, forceunpack, outputFormat, - romba, superdat, noMD5, noSHA1, bare, archivesAsFiles, enableGzip, tempdir, maxParallelism); + romba, superdat, noMD5, noSHA1, bare, archivesAsFiles, enableGzip, addblanks, tempdir, maxParallelism); } // Split a DAT by extension