[ALL] Zip64 support! And no more standard zip output!

This commit is contained in:
Matt Nadareski
2016-10-08 23:28:09 -07:00
parent adb9949bef
commit 7791bab253
9 changed files with 205 additions and 268 deletions

View File

@@ -286,8 +286,6 @@ namespace SabreTools.Helper
helptext.Add(" -v, --verify Enable verification of output directory"); helptext.Add(" -v, --verify Enable verification of output directory");
helptext.Add(" -c, --convert Enable conversion of input files to TGZ"); helptext.Add(" -c, --convert Enable conversion of input files to TGZ");
helptext.Add(" Note: If a DAT is used, only files NOT included will rebuild"); helptext.Add(" Note: If a DAT is used, only files NOT included will rebuild");
helptext.Add(" -r, --romba Enable Romba depot dir output");
helptext.Add(" -tzip Enable TorrentZip output");
helptext.Add(" -tgz Enable TorrentGZ output"); helptext.Add(" -tgz Enable TorrentGZ output");
helptext.Add(" -r, --romba Enable Romba depot dir output"); helptext.Add(" -r, --romba Enable Romba depot dir output");
helptext.Add(" -do, --directory Output files as uncompressed"); helptext.Add(" -do, --directory Output files as uncompressed");

View File

@@ -438,7 +438,7 @@ namespace SabreTools.Helper
return ZipReturn.ZipLocalFileHeaderError; return ZipReturn.ZipLocalFileHeaderError;
} }
// If we don't have the zeroed flag set, then the size should match // If we don't have the zeroed flag set, then the size should match
if ((_generalPurposeBitFlag & GeneralPurposeBitFlag.ZeroedCRCAndSize) == 0 && readCompressedSize != _compressedSize) if (!_zip64 && (_generalPurposeBitFlag & GeneralPurposeBitFlag.ZeroedCRCAndSize) == 0 && readCompressedSize != _compressedSize)
{ {
return ZipReturn.ZipLocalFileHeaderError; return ZipReturn.ZipLocalFileHeaderError;
} }
@@ -455,7 +455,7 @@ namespace SabreTools.Helper
return ZipReturn.ZipLocalFileHeaderError; return ZipReturn.ZipLocalFileHeaderError;
} }
// If we don't have the zeroed flag set, then the size should match // If we don't have the zeroed flag set, then the size should match
if ((_generalPurposeBitFlag & GeneralPurposeBitFlag.ZeroedCRCAndSize) == 0 && readUncompressedSize != _uncompressedSize) if (!_zip64 && (_generalPurposeBitFlag & GeneralPurposeBitFlag.ZeroedCRCAndSize) == 0 && readUncompressedSize != _uncompressedSize)
{ {
return ZipReturn.ZipLocalFileHeaderError; return ZipReturn.ZipLocalFileHeaderError;
} }

View File

@@ -17,7 +17,7 @@ namespace SabreTools.Helper
private bool _toFolder; private bool _toFolder;
private bool _verify; private bool _verify;
private bool _delete; private bool _delete;
private bool? _torrentX; // True is for TorrentZip, False is for TorrentGZ, Null is for standard zip private bool _tgz;
private bool _romba; private bool _romba;
private bool _updateDat; private bool _updateDat;
private ArchiveScanLevel _archiveScanLevel; private ArchiveScanLevel _archiveScanLevel;
@@ -40,13 +40,13 @@ namespace SabreTools.Helper
/// <param name="toFolder">True if files should be output to folder, false otherwise</param> /// <param name="toFolder">True if files should be output to folder, false otherwise</param>
/// <param name="verify">True if output directory should be checked instead of rebuilt to, false otherwise</param> /// <param name="verify">True if output directory should be checked instead of rebuilt to, false otherwise</param>
/// <param name="delete">True if input files should be deleted, false otherwise</param> /// <param name="delete">True if input files should be deleted, false otherwise</param>
/// <param name="torrentX">True is for TorrentZip, False is for TorrentGZ, Null is for standard zip</param> /// <param name="tgz">True if output files should be written to TorrentGZ instead of TorrentZip</param>
/// <param name="romba">True if files should be output in Romba depot folders, false otherwise</param> /// <param name="romba">True if files should be output in Romba depot folders, false otherwise</param>
/// <param name="archiveScanLevel">ArchiveScanLevel representing the archive handling levels</param> /// <param name="archiveScanLevel">ArchiveScanLevel representing the archive handling levels</param>
/// <param name="updateDat">True if the updated DAT should be output, false otherwise</param> /// <param name="updateDat">True if the updated DAT should be output, false otherwise</param>
/// <param name="logger">Logger object for file and console output</param> /// <param name="logger">Logger object for file and console output</param>
public SimpleSort(DatFile datdata, List<string> inputs, string outDir, string tempDir, public SimpleSort(DatFile datdata, List<string> inputs, string outDir, string tempDir,
bool quickScan, bool toFolder, bool verify, bool delete, bool? torrentX, bool romba, bool quickScan, bool toFolder, bool verify, bool delete, bool tgz, bool romba,
ArchiveScanLevel archiveScanLevel, bool updateDat, Logger logger) ArchiveScanLevel archiveScanLevel, bool updateDat, Logger logger)
{ {
_datdata = datdata; _datdata = datdata;
@@ -57,7 +57,7 @@ namespace SabreTools.Helper
_toFolder = toFolder; _toFolder = toFolder;
_verify = verify; _verify = verify;
_delete = delete; _delete = delete;
_torrentX = torrentX; _tgz = tgz;
_romba = romba; _romba = romba;
_archiveScanLevel = archiveScanLevel; _archiveScanLevel = archiveScanLevel;
_updateDat = updateDat; _updateDat = updateDat;
@@ -333,7 +333,7 @@ namespace SabreTools.Helper
Directory.CreateDirectory(gamedir); Directory.CreateDirectory(gamedir);
} }
_logger.Verbose("Rebuilding file '" + Path.GetFileName(rom.Name) + "' to '" + (_torrentX == false ? found.SHA1 : found.Name) + "'"); _logger.Verbose("Rebuilding file '" + Path.GetFileName(rom.Name) + "' to '" + (_tgz ? found.SHA1 : found.Name) + "'");
try try
{ {
File.Copy(input, Path.Combine(gamedir, Path.GetFileName(found.Name))); File.Copy(input, Path.Combine(gamedir, Path.GetFileName(found.Name)));
@@ -342,17 +342,13 @@ namespace SabreTools.Helper
} }
else else
{ {
if (_torrentX == true) if (_tgz)
{
ArchiveTools.WriteTorrentZip(input, _outDir, found, _logger);
}
else if (_torrentX == false)
{ {
ArchiveTools.WriteTorrentGZ(input, _outDir, _romba, _logger); ArchiveTools.WriteTorrentGZ(input, _outDir, _romba, _logger);
} }
else else
{ {
ArchiveTools.WriteToArchive(input, _outDir, found); ArchiveTools.WriteToArchive(input, _outDir, found, _logger);
} }
} }
} }
@@ -404,7 +400,7 @@ namespace SabreTools.Helper
Directory.CreateDirectory(gamedir); Directory.CreateDirectory(gamedir);
} }
_logger.Verbose("Rebuilding file '" + Path.GetFileName(rom.Name) + "' to '" + (_torrentX == false ? found.SHA1 : found.Name) + "'"); _logger.Verbose("Rebuilding file '" + Path.GetFileName(rom.Name) + "' to '" + (_tgz ? found.SHA1 : found.Name) + "'");
try try
{ {
File.Copy(newinput, Path.Combine(gamedir, Path.GetFileName(found.Name))); File.Copy(newinput, Path.Combine(gamedir, Path.GetFileName(found.Name)));
@@ -413,17 +409,13 @@ namespace SabreTools.Helper
} }
else else
{ {
if (_torrentX == true) if (_tgz)
{
ArchiveTools.WriteTorrentZip(newinput, _outDir, found, _logger);
}
else if (_torrentX == false)
{ {
ArchiveTools.WriteTorrentGZ(newinput, _outDir, _romba, _logger); ArchiveTools.WriteTorrentGZ(newinput, _outDir, _romba, _logger);
} }
else else
{ {
ArchiveTools.WriteToArchive(newinput, _outDir, found); ArchiveTools.WriteToArchive(newinput, _outDir, found, _logger);
} }
} }
@@ -467,17 +459,13 @@ namespace SabreTools.Helper
else else
{ {
_logger.Verbose("Matched name: " + newfound.Name); _logger.Verbose("Matched name: " + newfound.Name);
if (_torrentX == true) if (_tgz)
{
ArchiveTools.WriteTorrentZip(input, _outDir, newfound, _logger);
}
else if (_torrentX == false)
{ {
ArchiveTools.WriteTorrentGZ(input, _outDir, _romba, _logger); ArchiveTools.WriteTorrentGZ(input, _outDir, _romba, _logger);
} }
else else
{ {
ArchiveTools.WriteToArchive(input, _outDir, newfound); ArchiveTools.WriteToArchive(input, _outDir, newfound, _logger);
} }
} }
} }
@@ -550,24 +538,20 @@ namespace SabreTools.Helper
else else
{ {
// Copy file between archives // Copy file between archives
_logger.Verbose("Rebuilding file '" + Path.GetFileName(rom.Name) + "' to '" + (_torrentX == false ? found.SHA1 : found.Name) + "'"); _logger.Verbose("Rebuilding file '" + Path.GetFileName(rom.Name) + "' to '" + (_tgz ? found.SHA1 : found.Name) + "'");
if (Build.MonoEnvironment || _torrentX == false) if (Build.MonoEnvironment || _tgz)
{ {
string outfile = ArchiveTools.ExtractSingleItemFromArchive(input, rom.Name, _tempDir, _logger); string outfile = ArchiveTools.ExtractSingleItemFromArchive(input, rom.Name, _tempDir, _logger);
if (File.Exists(outfile)) if (File.Exists(outfile))
{ {
if (_torrentX == true) if (_tgz)
{
ArchiveTools.WriteTorrentZip(outfile, _outDir, found, _logger);
}
else if (_torrentX == false)
{ {
ArchiveTools.WriteTorrentGZ(outfile, _outDir, _romba, _logger); ArchiveTools.WriteTorrentGZ(outfile, _outDir, _romba, _logger);
} }
else else
{ {
ArchiveTools.WriteToArchive(outfile, _outDir, found); ArchiveTools.WriteToArchive(outfile, _outDir, found, _logger);
} }
try try
@@ -995,7 +979,7 @@ namespace SabreTools.Helper
} }
/// <summary> /// <summary>
/// Process inputs and convert to TGZ, optionally converting to Romba /// Process inputs and convert to TorrentZip or TorrentGZ, optionally converting to Romba
/// </summary> /// </summary>
/// <returns>True if processing was a success, false otherwise</returns> /// <returns>True if processing was a success, false otherwise</returns>
public bool Convert() public bool Convert()
@@ -1032,9 +1016,9 @@ namespace SabreTools.Helper
if (shouldExternalProcess) if (shouldExternalProcess)
{ {
// If a DAT is defined, we want to make sure that this file is not in there // If a DAT is defined, we want to make sure that this file is not in there
Rom rom = FileTools.GetFileInfo(input, _logger);
if (_datdata != null && _datdata.Files.Count > 0) if (_datdata != null && _datdata.Files.Count > 0)
{ {
Rom rom = FileTools.GetFileInfo(input, _logger);
if (rom.HasDuplicates(_datdata, _logger)) if (rom.HasDuplicates(_datdata, _logger))
{ {
_logger.User("File '" + input + "' existed in the DAT, skipping..."); _logger.User("File '" + input + "' existed in the DAT, skipping...");
@@ -1043,7 +1027,15 @@ namespace SabreTools.Helper
} }
_logger.User("Processing file " + input); _logger.User("Processing file " + input);
success &= ArchiveTools.WriteTorrentGZ(input, _outDir, _romba, _logger);
if (_tgz)
{
success &= ArchiveTools.WriteTorrentGZ(input, _outDir, _romba, _logger);
}
else
{
success &= ArchiveTools.WriteToArchive(input, _outDir, rom, _logger);
}
} }
// Process the file as an archive, if necessary // Process the file as an archive, if necessary
@@ -1059,9 +1051,9 @@ namespace SabreTools.Helper
foreach (string file in Directory.EnumerateFiles(_tempDir, "*", SearchOption.AllDirectories)) foreach (string file in Directory.EnumerateFiles(_tempDir, "*", SearchOption.AllDirectories))
{ {
// If a DAT is defined, we want to make sure that this file is not in there // If a DAT is defined, we want to make sure that this file is not in there
Rom rom = FileTools.GetFileInfo(file, _logger);
if (_datdata != null && _datdata.Files.Count > 0) if (_datdata != null && _datdata.Files.Count > 0)
{ {
Rom rom = FileTools.GetFileInfo(file, _logger);
if (rom.HasDuplicates(_datdata, _logger)) if (rom.HasDuplicates(_datdata, _logger))
{ {
_logger.User("File '" + file + "' existed in the DAT, skipping..."); _logger.User("File '" + file + "' existed in the DAT, skipping...");
@@ -1069,8 +1061,16 @@ namespace SabreTools.Helper
} }
} }
_logger.User("Processing extracted file " + file); _logger.User("Processing file " + input);
success &= ArchiveTools.WriteTorrentGZ(file, _outDir, _romba, _logger);
if (_tgz)
{
success &= ArchiveTools.WriteTorrentGZ(input, _outDir, _romba, _logger);
}
else
{
success &= ArchiveTools.WriteToArchive(input, _outDir, rom, _logger);
}
} }
FileTools.CleanDirectory(_tempDir); FileTools.CleanDirectory(_tempDir);

View File

@@ -670,7 +670,10 @@ Options:
SimpleSort is a WIP program that is meant as a command-line tool to quickly rebuild and SimpleSort is a WIP program that is meant as a command-line tool to quickly rebuild and
verify files based on a supplied DAT file. The eventual aim for this program is to have verify files based on a supplied DAT file. The eventual aim for this program is to have
a full rom management tool without a GUI, though this may not happen for a while. a full rom management tool without a GUI, though this may not happen for a while. By default
all files will be rebuilt to TorrentZip (TZ) files. This format is based on the ZIP archive
format, but with custom header information. This is primarily used by external tool RomVault
(http://www.romvault.com/) and is already widely used.
Usage: Usage:
SimpleSort.exe [options] [filename|dirname] ... SimpleSort.exe [options] [filename|dirname] ...
@@ -712,24 +715,10 @@ Options:
simple FixDAT. This can be misleading, currently, because it only checks for exact simple FixDAT. This can be misleading, currently, because it only checks for exact
matches. matches.
-c, --convert Enable conversion of input files to TGZ -c, --convert Enable filtering by input DAT
This allows conversion of a folder or set of folders to TorrentGZ format without This overrides the default rebuilding by using the DAT as a filter of what not to
requiring a DAT to rebuild from. It is only useful in a small amount of situations at output. If no DAT is supplied, the entire input folder will be rebuild file-by-file
the present, but it is mostly meant for Romba compatibility at the present. If a DAT to the output folder.
is supplied, then files NOT matching the DAT will be written out only.
-r, --romba Enable Romba depot directory output
As an extension of the parent flag, this outputs the TGZ files into directories
based on the structure used by Romba. This uses nested folders using the first
4 bytes of the SHA-1, 1 byte for each layer of the directory name. It also
includes two auxilary files, .romba_size and .romba_size.backup, that have the
compressed size of the folder inside for use with Romba.
-tzip Enable TorrentZip output
Instead of outputting the files to standard ZIP archives, files will be rebuilt to
TorrentZip (TZ) files. This format is based on the ZIP archive format, but with
custom header information. This is primarily used by external tool RomVault
(http://www.romvault.com/) and is already widely used.
-tgz Enable Torrent GZ output -tgz Enable Torrent GZ output
Instead of outputting the files to ZIP archives, files will be rebuilt to TorrentGZ Instead of outputting the files to ZIP archives, files will be rebuilt to TorrentGZ
@@ -1176,6 +1165,14 @@ Below are originally from SabreTools / DATabase -
file manager that allows for it, this will force the outputted files to be in file manager that allows for it, this will force the outputted files to be in
subdirectories instead of archives. subdirectories instead of archives.
Below are originally from SimpleSort (Standalone) -
-tzip Enable TorrentZip output
Instead of outputting the files to ZIP archives, files will be rebuilt to TorrentZip
(TZip) files. This format is based on the ZIP archive format, but with custom header
information. This is primarily used by external tool RomVault (http://www.romvault.com/)
and is already widely used.
Below are originally from SingleGame (Standalone) - Below are originally from SingleGame (Standalone) -
-r=rootdir Set the directory name for path size -r=rootdir Set the directory name for path size

View File

@@ -106,6 +106,7 @@
<Compile Include="Objects\Dat\BiosSet.cs" /> <Compile Include="Objects\Dat\BiosSet.cs" />
<Compile Include="Objects\Dat\DatFile.cs" /> <Compile Include="Objects\Dat\DatFile.cs" />
<Compile Include="Objects\Dat\DatItem.cs" /> <Compile Include="Objects\Dat\DatItem.cs" />
<Compile Include="Objects\Dat\DatItemKV.cs" />
<Compile Include="Objects\Dat\Disk.cs" /> <Compile Include="Objects\Dat\Disk.cs" />
<Compile Include="Objects\Dat\Release.cs" /> <Compile Include="Objects\Dat\Release.cs" />
<Compile Include="Objects\Dat\Sample.cs" /> <Compile Include="Objects\Dat\Sample.cs" />

View File

@@ -5,7 +5,6 @@ using SharpCompress.Reader;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.IO.Compression;
using System.Linq; using System.Linq;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
@@ -26,12 +25,13 @@ namespace SabreTools.Helper
/// <param name="destEntryName">Output entry name</param> /// <param name="destEntryName">Output entry name</param>
/// <param name="logger">Logger object for file and console output</param> /// <param name="logger">Logger object for file and console output</param>
/// <returns>True if the copy was a success, false otherwise</returns> /// <returns>True if the copy was a success, false otherwise</returns>
public static bool CopyFileBetweenArchives(string inputArchive, string outDir, public static bool CopyFileBetweenArchives(string inputArchive, string outDir, string sourceEntryName, Rom destEntry, Logger logger)
string sourceEntryName, Rom destEntry, Logger logger)
{ {
string realName = ""; string temp = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
Stream ms = ExtractSingleStreamFromArchive(inputArchive, sourceEntryName, out realName, logger); string realName = ExtractSingleItemFromArchive(inputArchive, sourceEntryName, temp, logger);
return WriteToArchive(ms, outDir, destEntry); bool success = WriteToArchive(realName, outDir, destEntry, logger);
Directory.Delete(temp, true);
return success;
} }
/// <summary> /// <summary>
@@ -132,8 +132,46 @@ namespace SabreTools.Helper
encounteredErrors = false; encounteredErrors = false;
} }
else if ((at == ArchiveType.Zip && (archiveScanLevel & ArchiveScanLevel.ZipInternal) != 0) else if (at == ArchiveType.Zip && (archiveScanLevel & ArchiveScanLevel.ZipInternal) != 0)
|| (at == ArchiveType.Rar && (archiveScanLevel & ArchiveScanLevel.RarInternal) != 0)) {
logger.Verbose("Found archive of type: " + at);
// Create the temp directory
Directory.CreateDirectory(tempDir);
// Extract all files to the temp directory
ZipFile zf = new ZipFile();
ZipReturn zr = zf.Open(input, new FileInfo(input).LastWriteTime.Ticks, true);
if (zr != ZipReturn.ZipGood)
{
throw new Exception(ZipFile.ZipErrorMessageText(zr));
}
for (int i = 0; i < zf.EntriesCount && zr == ZipReturn.ZipGood; i++)
{
// Set defaults before writing out
Stream readStream;
ulong streamsize = 0;
CompressionMethod cm = CompressionMethod.Stored;
zr = zf.OpenReadStream(i, false, out readStream, out streamsize, out cm);
FileStream writeStream = File.OpenWrite(Path.Combine(tempDir, zf.Entries[i].FileName));
byte[] ibuffer = new byte[_bufferSize];
int ilen;
while ((ilen = readStream.Read(ibuffer, 0, _bufferSize)) > 0)
{
writeStream.Write(ibuffer, 0, ilen);
writeStream.Flush();
}
encounteredErrors = false;
zr = zf.CloseReadStream();
writeStream.Dispose();
}
}
else if (at == ArchiveType.Rar && (archiveScanLevel & ArchiveScanLevel.RarInternal) != 0)
{ {
logger.Verbose("Found archive of type: " + at); logger.Verbose("Found archive of type: " + at);
@@ -179,26 +217,30 @@ namespace SabreTools.Helper
/// <returns>Name of the extracted file, null on error</returns> /// <returns>Name of the extracted file, null on error</returns>
public static string ExtractSingleItemFromArchive(string input, string entryName, string tempDir, Logger logger) public static string ExtractSingleItemFromArchive(string input, string entryName, string tempDir, Logger logger)
{ {
string outfile = null;
string realEntry = ""; string realEntry = "";
Stream ms = ExtractSingleStreamFromArchive(input, entryName, out realEntry, logger); Stream ms = ExtractSingleStreamFromArchive(input, entryName, out realEntry, logger);
realEntry = Path.GetFullPath(Path.Combine(tempDir, realEntry)); realEntry = Path.GetFullPath(Path.Combine(tempDir, realEntry));
if (!Directory.Exists(Path.GetDirectoryName(outfile))) if (!Directory.Exists(Path.GetDirectoryName(realEntry)))
{ {
Directory.CreateDirectory(Path.GetDirectoryName(outfile)); Directory.CreateDirectory(Path.GetDirectoryName(realEntry));
} }
FileStream fs = File.Open(realEntry, FileMode.Create, FileAccess.Write); FileStream fs = File.Open(realEntry, FileMode.Create, FileAccess.Write);
ms.CopyTo(fs);
fs.Flush(); byte[] ibuffer = new byte[_bufferSize];
int ilen;
while ((ilen = ms.Read(ibuffer, 0, _bufferSize)) > 0)
{
fs.Write(ibuffer, 0, ilen);
fs.Flush();
}
// Dispose of the streams // Dispose of the streams
ms.Dispose(); ms.Dispose();
fs.Dispose(); fs.Dispose();
return outfile; return realEntry;
} }
/// <summary> /// <summary>
@@ -228,7 +270,42 @@ namespace SabreTools.Helper
IReader reader = null; IReader reader = null;
try try
{ {
if (at == ArchiveType.Zip || at == ArchiveType.SevenZip || at == ArchiveType.Rar) if (at == ArchiveType.Zip)
{
ZipFile zf = new ZipFile();
ZipReturn zr = zf.Open(input, new FileInfo(input).LastWriteTime.Ticks, true);
if (zr != ZipReturn.ZipGood)
{
throw new Exception(ZipFile.ZipErrorMessageText(zr));
}
for (int i = 0; i < zf.EntriesCount && zr == ZipReturn.ZipGood; i++)
{
logger.Verbose("Current entry name: '" + zf.Entries[i].FileName + "'");
if (zf.Entries[i].FileName.Contains(entryName))
{
realEntry = zf.Entries[i].FileName;
// Set defaults before writing out
Stream readStream;
ulong streamsize = 0;
CompressionMethod cm = CompressionMethod.Stored;
zr = zf.OpenReadStream(i, false, out readStream, out streamsize, out cm);
byte[] ibuffer = new byte[_bufferSize];
int ilen;
while ((ilen = readStream.Read(ibuffer, 0, _bufferSize)) > 0)
{
st.Write(ibuffer, 0, ilen);
st.Flush();
}
zr = zf.CloseReadStream();
}
}
}
else if (at == ArchiveType.SevenZip || at == ArchiveType.Rar)
{ {
reader = ReaderFactory.Open(File.OpenRead(input)); reader = ReaderFactory.Open(File.OpenRead(input));
while (reader.MoveToNextEntry()) while (reader.MoveToNextEntry())
@@ -263,6 +340,7 @@ namespace SabreTools.Helper
reader?.Dispose(); reader?.Dispose();
} }
st.Position = 0;
return st; return st;
} }
@@ -322,8 +400,34 @@ namespace SabreTools.Helper
size = BitConverter.ToInt32(headersize.Reverse().ToArray(), 0); size = BitConverter.ToInt32(headersize.Reverse().ToArray(), 0);
br.Dispose(); br.Dispose();
} }
else if (at == ArchiveType.Zip)
{
ZipFile zf = new ZipFile();
ZipReturn zr = zf.Open(input, new FileInfo(input).LastWriteTime.Ticks, true);
if (zr != ZipReturn.ZipGood)
{
throw new Exception(ZipFile.ZipErrorMessageText(zr));
}
if (at != ArchiveType.Tar) for (int i = 0; i < zf.EntriesCount && zr == ZipReturn.ZipGood; i++)
{
string newname = zf.Entries[i].FileName;
long newsize = (size == 0 ? (long)zf.Entries[i].UncompressedSize : size);
string newcrc = BitConverter.ToString(zf.Entries[i].CRC.Reverse().ToArray(), 0, zf.Entries[i].CRC.Length).Replace("-", string.Empty).ToLowerInvariant();
logger.Verbose("Entry found: '" + newname + "': " + newsize + ", " + newcrc);
roms.Add(new Rom
{
Type = ItemType.Rom,
Name = newname,
MachineName = gamename,
Size = newsize,
CRC = newcrc,
});
}
}
else if (at != ArchiveType.Tar)
{ {
reader = ReaderFactory.Open(File.OpenRead(input)); reader = ReaderFactory.Open(File.OpenRead(input));
while (reader.MoveToNextEntry()) while (reader.MoveToNextEntry())
@@ -634,169 +738,6 @@ namespace SabreTools.Helper
#region Writing #region Writing
/// <summary>
/// Copy a file to an output archive
/// </summary>
/// <param name="inputFile">Input filename to be moved</param>
/// <param name="outDir">Output directory to build to</param>
/// <param name="rom">RomData representing the new information</param>
/// <returns>True if the archive was written properly, false otherwise</returns>
public static bool WriteToArchive(string inputFile, string outDir, Rom rom)
{
// Get the stream from the input file
Stream fs = File.OpenRead(inputFile);
bool success = WriteToArchive(fs, outDir, rom);
fs.Dispose();
return success;
}
/// <summary>
/// Copy a stream to an output archive
/// </summary>
/// <param name="inputStream">Input stream to be written</param>
/// <param name="outDir">Output directory to build to</param>
/// <param name="rom">RomData representing the new information</param>
/// <returns>True if the archive was written properly, false otherwise</returns>
public static bool WriteToArchive(Stream inputStream, string outDir, Rom rom)
{
// Wrap the individual inputs into lists
List<Stream> inputFiles = new List<Stream>();
inputFiles.Add(inputStream);
List<Rom> roms = new List<Rom>();
roms.Add(rom);
return WriteToArchive(inputFiles, outDir, roms);
}
/// <summary>
/// Copy a set of files to an output archive (assuming the same output archive name)
/// </summary>
/// <param name="inputFiles">Input filenames to be moved</param>
/// <param name="outDir">Output directory to build to</param>
/// <param name="roms">List of Rom representing the new information</param>
/// <returns>True if the archive was written properly, false otherwise</returns>
public static bool WriteToArchive(List<string> inputFiles, string outDir, List<Rom> roms)
{
bool success = false;
// If the number of inputs is less than the number of available roms, return
if (inputFiles.Count < roms.Count)
{
return success;
}
// If one of the files doesn't exist, return
foreach (string file in inputFiles)
{
if (!File.Exists(file))
{
return success;
}
}
// Get the streams from the input files
List<Stream> inputStreams = new List<Stream>();
foreach (string inputFile in inputFiles)
{
inputStreams.Add(File.OpenRead(inputFile));
}
success = WriteToArchive(inputStreams, outDir, roms);
// Now close all of the streams
foreach (Stream inputStream in inputStreams)
{
inputStream.Dispose();
}
return success;
}
/// <summary>
/// Copy a set of streams to an output archive (assuming the same output archive name)
/// </summary>
/// <param name="inputStreams">Input streams to be moved</param>
/// <param name="outDir">Output directory to build to</param>
/// <param name="roms">List of Rom representing the new information</param>
/// <returns>True if the archive was written properly, false otherwise</returns>
public static bool WriteToArchive(List<Stream> inputStreams, string outDir, List<Rom> roms)
{
bool success = false;
// If the number of inputs is less than the number of available roms, return
if (inputStreams.Count < roms.Count)
{
return success;
}
// Get the output archive name from the first rebuild rom
string archiveFileName = Path.Combine(outDir, roms[0].MachineName + ".zip");
// First, open the archive
ZipArchive outarchive = null;
try
{
// If the full output path doesn't exist, create it
if (!Directory.Exists(Path.GetDirectoryName(archiveFileName)))
{
Directory.CreateDirectory(Path.GetDirectoryName(archiveFileName));
}
// If the archive doesn't exist, create it
if (!File.Exists(archiveFileName))
{
outarchive = System.IO.Compression.ZipFile.Open(archiveFileName, ZipArchiveMode.Create);
outarchive.Dispose();
}
// Open the archive for writing
outarchive = System.IO.Compression.ZipFile.Open(archiveFileName, ZipArchiveMode.Update);
// Now loop through and add all files
for (int i = 0; i < inputStreams.Count; i++)
{
Rom rom = roms[i];
// If the archive doesn't already contain the entry, add it
if (outarchive.GetEntry(rom.Name) == null)
{
ZipArchiveEntry ae = outarchive.CreateEntry(rom.Name);
Stream outputStream = ae.Open();
inputStreams[i].CopyTo(outputStream);
outputStream.Flush();
outputStream.Dispose();
}
// If there's a Date attached to the rom, change the entry to that Date
if (!string.IsNullOrEmpty(rom.Date))
{
DateTimeOffset dto = DateTimeOffset.Now;
if (DateTimeOffset.TryParse(rom.Date, out dto))
{
outarchive.GetEntry(rom.Name).LastWriteTime = dto;
}
}
}
// Dispose of the streams
outarchive.Dispose();
success = true;
}
catch (Exception ex)
{
Console.WriteLine(ex);
success = false;
}
finally
{
outarchive?.Dispose();
}
return success;
}
/// <summary> /// <summary>
/// Copy a file to an output torrentzip archive /// Copy a file to an output torrentzip archive
/// </summary> /// </summary>
@@ -805,7 +746,7 @@ namespace SabreTools.Helper
/// <param name="rom">RomData representing the new information</param> /// <param name="rom">RomData representing the new information</param>
/// <param name="logger">Logger object for file and console output</param> /// <param name="logger">Logger object for file and console output</param>
/// <returns>True if the archive was written properly, false otherwise</returns> /// <returns>True if the archive was written properly, false otherwise</returns>
public static bool WriteTorrentZip(string inputFile, string outDir, Rom rom, Logger logger) public static bool WriteToArchive(string inputFile, string outDir, Rom rom, Logger logger)
{ {
// Wrap the individual inputs into lists // Wrap the individual inputs into lists
List<string> inputFiles = new List<string>(); List<string> inputFiles = new List<string>();
@@ -813,7 +754,7 @@ namespace SabreTools.Helper
List<Rom> roms = new List<Rom>(); List<Rom> roms = new List<Rom>();
roms.Add(rom); roms.Add(rom);
return WriteTorrentZip(inputFiles, outDir, roms, logger); return WriteToArchive(inputFiles, outDir, roms, logger);
} }
/// <summary> /// <summary>
@@ -824,7 +765,7 @@ namespace SabreTools.Helper
/// <param name="rom">List of Rom representing the new information</param> /// <param name="rom">List of Rom representing the new information</param>
/// <param name="logger">Logger object for file and console output</param> /// <param name="logger">Logger object for file and console output</param>
/// <returns>True if the archive was written properly, false otherwise</returns> /// <returns>True if the archive was written properly, false otherwise</returns>
public static bool WriteTorrentZip(List<string> inputFiles, string outDir, List<Rom> roms, Logger logger) public static bool WriteToArchive(List<string> inputFiles, string outDir, List<Rom> roms, Logger logger)
{ {
bool success = false; bool success = false;
string tempFile = Path.GetTempFileName(); string tempFile = Path.GetTempFileName();
@@ -894,6 +835,7 @@ namespace SabreTools.Helper
while ((ilen = freadStream.Read(ibuffer, 0, _bufferSize)) > 0) while ((ilen = freadStream.Read(ibuffer, 0, _bufferSize)) > 0)
{ {
writeStream.Write(ibuffer, 0, ilen); writeStream.Write(ibuffer, 0, ilen);
writeStream.Flush();
} }
freadStream.Dispose(); freadStream.Dispose();
zipFile.CloseWriteStream(Convert.ToUInt32(roms[index].CRC, 16)); zipFile.CloseWriteStream(Convert.ToUInt32(roms[index].CRC, 16));
@@ -959,6 +901,7 @@ namespace SabreTools.Helper
while ((ilen = freadStream.Read(ibuffer, 0, _bufferSize)) > 0) while ((ilen = freadStream.Read(ibuffer, 0, _bufferSize)) > 0)
{ {
writeStream.Write(ibuffer, 0, ilen); writeStream.Write(ibuffer, 0, ilen);
writeStream.Flush();
} }
freadStream.Dispose(); freadStream.Dispose();
zipFile.CloseWriteStream(Convert.ToUInt32(roms[-index - 1].CRC, 16)); zipFile.CloseWriteStream(Convert.ToUInt32(roms[-index - 1].CRC, 16));
@@ -980,6 +923,7 @@ namespace SabreTools.Helper
while ((ilen = zreadStream.Read(ibuffer, 0, _bufferSize)) > 0) while ((ilen = zreadStream.Read(ibuffer, 0, _bufferSize)) > 0)
{ {
writeStream.Write(ibuffer, 0, ilen); writeStream.Write(ibuffer, 0, ilen);
writeStream.Flush();
} }
zipFile.CloseWriteStream(BitConverter.ToUInt32(oldZipFile.CRC32(index), 0)); zipFile.CloseWriteStream(BitConverter.ToUInt32(oldZipFile.CRC32(index), 0));
} }

View File

@@ -493,7 +493,7 @@ namespace SabreTools.Helper
input.Seek(offset, SeekOrigin.Begin); input.Seek(offset, SeekOrigin.Begin);
} }
byte[] buffer = new byte[1024]; byte[] buffer = new byte[8 * 1024];
int read; int read;
while ((read = input.Read(buffer, 0, buffer.Length)) > 0) while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
{ {

View File

@@ -11,7 +11,7 @@ namespace SabreTools
#region Init Methods #region Init Methods
/// <summary> /// <summary>
/// Wrap converting a folder to TGZ, optionally filtering by an input DAT(s) /// Wrap converting a folder to TorrentZip or TorrentGZ, optionally filtering by an input DAT(s)
/// </summary> /// </summary>
/// <param name="datfiles">Names of the DATs to compare against</param> /// <param name="datfiles">Names of the DATs to compare against</param>
/// <param name="inputs">List of all inputted files and folders</param> /// <param name="inputs">List of all inputted files and folders</param>
@@ -24,7 +24,7 @@ namespace SabreTools
/// <param name="rar">Integer representing the archive handling level for RAR</param> /// <param name="rar">Integer representing the archive handling level for RAR</param>
/// <param name="zip">Integer representing the archive handling level for Zip</param> /// <param name="zip">Integer representing the archive handling level for Zip</param>
/// <param name="logger">Logger object for file and console output</param> /// <param name="logger">Logger object for file and console output</param>
public static bool InitConvertFolderTGZ(List<string> datfiles, List<string> inputs, string outDir, string tempDir, bool delete, public static bool InitConvertFolder(List<string> datfiles, List<string> inputs, string outDir, string tempDir, bool delete,
bool romba, int sevenzip, int gz, int rar, int zip, Logger logger) bool romba, int sevenzip, int gz, int rar, int zip, Logger logger)
{ {
// Add all of the input DATs into one huge internal DAT // Add all of the input DATs into one huge internal DAT
@@ -297,7 +297,7 @@ namespace SabreTools
/// <param name="updateDat">True if the updated DAT should be output, false otherwise</param> /// <param name="updateDat">True if the updated DAT should be output, false otherwise</param>
/// <param name="logger">Logger object for file and console output</param> /// <param name="logger">Logger object for file and console output</param>
private static void InitSortVerify(List<string> datfiles, List<string> inputs, string outDir, string tempDir, bool quickScan, private static void InitSortVerify(List<string> datfiles, List<string> inputs, string outDir, string tempDir, bool quickScan,
bool toFolder, bool verify, bool delete, bool? torrentX, bool romba, int sevenzip, int gz, int rar, int zip, bool updateDat, Logger logger) bool toFolder, bool verify, bool delete, bool tgz, bool romba, int sevenzip, int gz, int rar, int zip, bool updateDat, Logger logger)
{ {
// Get the archive scanning level // Get the archive scanning level
ArchiveScanLevel asl = ArchiveTools.GetArchiveScanLevelFromNumbers(sevenzip, gz, rar, zip); ArchiveScanLevel asl = ArchiveTools.GetArchiveScanLevelFromNumbers(sevenzip, gz, rar, zip);
@@ -310,7 +310,7 @@ namespace SabreTools
} }
SimpleSort ss = new SimpleSort(datdata, inputs, outDir, tempDir, quickScan, toFolder, verify, SimpleSort ss = new SimpleSort(datdata, inputs, outDir, tempDir, quickScan, toFolder, verify,
delete, torrentX, romba, asl, updateDat, logger); delete, tgz, romba, asl, updateDat, logger);
ss.StartProcessing(); ss.StartProcessing();
} }

View File

@@ -42,16 +42,15 @@ namespace SabreTools
// Set all default values // Set all default values
bool help = false, bool help = false,
convert = false,
delete = false, delete = false,
convert = false,
quickScan = false, quickScan = false,
romba = false, romba = false,
simpleSort = true, simpleSort = true,
toFolder = false, toFolder = false,
tzip = false, tgz = false,
updateDat = false, updateDat = false,
verify = false; verify = false;
bool? torrentX = null;
int sevenzip = 0, int sevenzip = 0,
gz = 2, gz = 2,
rar = 2, rar = 2,
@@ -93,11 +92,7 @@ namespace SabreTools
break; break;
case "-tgz": case "-tgz":
case "--tgz": case "--tgz":
torrentX = false; tgz = true;
break;
case "-tzip":
case "--tzip":
torrentX = true;
break; break;
case "-ud": case "-ud":
case "--updated-dat": case "--updated-dat":
@@ -186,7 +181,7 @@ namespace SabreTools
} }
// If a switch that requires a filename is set and no file is, show the help screen // If a switch that requires a filename is set and no file is, show the help screen
if (inputs.Count == 0 && ((simpleSort && !verify) || convert || tzip)) if (inputs.Count == 0 && ((simpleSort && !verify) || convert))
{ {
logger.Error("This feature requires at least one input"); logger.Error("This feature requires at least one input");
Build.Help(); Build.Help();
@@ -194,10 +189,11 @@ namespace SabreTools
return; return;
} }
// If we are converting the folder to TGZ // If we are converting the folder
else if (convert) else if (convert)
{ {
InitConvertFolderTGZ(datfiles, inputs, outDir, tempDir, delete, romba, sevenzip, gz, rar, zip, logger); InitConvertFolder(datfiles, inputs, outDir, tempDir, delete, tgz, romba, sevenzip,
gz, rar, zip, logger);
} }
// If we are doing a simple sort // If we are doing a simple sort
@@ -206,7 +202,7 @@ namespace SabreTools
if (datfiles.Count > 0) if (datfiles.Count > 0)
{ {
InitSortVerify(datfiles, inputs, outDir, tempDir, quickScan, toFolder, InitSortVerify(datfiles, inputs, outDir, tempDir, quickScan, toFolder,
verify, delete, torrentX, romba, sevenzip, gz, rar, zip, updateDat, logger); verify, delete, tgz, romba, sevenzip, gz, rar, zip, updateDat, logger);
} }
else else
{ {
@@ -228,21 +224,22 @@ namespace SabreTools
} }
/// <summary> /// <summary>
/// Wrap converting a folder to TGZ, optionally filtering by an input DAT(s) /// Wrap converting a folder to TorrentZip or TorrentGZ, optionally filtering by an input DAT(s)
/// </summary> /// </summary>
/// <param name="datfiles">Names of the DATs to compare against</param> /// <param name="datfiles">Names of the DATs to compare against</param>
/// <param name="inputs">List of all inputted files and folders</param> /// <param name="inputs">List of all inputted files and folders</param>
/// <param name="outDir">Output directory (empty for default directory)</param> /// <param name="outDir">Output directory (empty for default directory)</param>
/// <param name="tempDir">Temporary directory for archive extraction</param> /// <param name="tempDir">Temporary directory for archive extraction</param>
/// <param name="delete">True if input files should be deleted, false otherwise</param> /// <param name="delete">True if input files should be deleted, false otherwise</param>
/// <param name="tgz">True to output files in TorrentGZ format, false for TorrentZip</param>
/// <param name="romba">True if files should be output in Romba depot folders, false otherwise</param> /// <param name="romba">True if files should be output in Romba depot folders, false otherwise</param>
/// <param name="sevenzip">Integer representing the archive handling level for 7z</param> /// <param name="sevenzip">Integer representing the archive handling level for 7z</param>
/// <param name="gz">Integer representing the archive handling level for GZip</param> /// <param name="gz">Integer representing the archive handling level for GZip</param>
/// <param name="rar">Integer representing the archive handling level for RAR</param> /// <param name="rar">Integer representing the archive handling level for RAR</param>
/// <param name="zip">Integer representing the archive handling level for Zip</param> /// <param name="zip">Integer representing the archive handling level for Zip</param>
/// <param name="logger">Logger object for file and console output</param> /// <param name="logger">Logger object for file and console output</param>
public static bool InitConvertFolderTGZ(List<string> datfiles, List<string> inputs, string outDir, string tempDir, bool delete, public static bool InitConvertFolder(List<string> datfiles, List<string> inputs, string outDir, string tempDir, bool delete,
bool romba, int sevenzip, int gz, int rar, int zip, Logger logger) bool tgz, bool romba, int sevenzip, int gz, int rar, int zip, Logger logger)
{ {
// Get the archive scanning level // Get the archive scanning level
ArchiveScanLevel asl = ArchiveTools.GetArchiveScanLevelFromNumbers(sevenzip, gz, rar, zip); ArchiveScanLevel asl = ArchiveTools.GetArchiveScanLevelFromNumbers(sevenzip, gz, rar, zip);
@@ -279,7 +276,7 @@ namespace SabreTools
logger.User("Organizing complete in " + DateTime.Now.Subtract(start).ToString(@"hh\:mm\:ss\.fffff")); logger.User("Organizing complete in " + DateTime.Now.Subtract(start).ToString(@"hh\:mm\:ss\.fffff"));
SimpleSort ss = new SimpleSort(datdata, newinputs, outDir, tempDir, false, false, false, SimpleSort ss = new SimpleSort(datdata, newinputs, outDir, tempDir, false, false, false,
delete, false, romba, asl, false, logger); delete, tgz, romba, asl, false, logger);
return ss.Convert(); return ss.Convert();
} }
@@ -295,7 +292,7 @@ namespace SabreTools
/// <param name="toFolder">True if files should be output to folder, false otherwise</param> /// <param name="toFolder">True if files should be output to folder, false otherwise</param>
/// <param name="verify">True if output directory should be checked instead of rebuilt to, false otherwise</param> /// <param name="verify">True if output directory should be checked instead of rebuilt to, false otherwise</param>
/// <param name="delete">True if input files should be deleted, false otherwise</param> /// <param name="delete">True if input files should be deleted, false otherwise</param>
/// <param name="torrentX">True is for TorrentZip, False is for TorrentGZ, Null is for standard zip</param> /// <param name="tgz">True to output files in TorrentGZ format, false for TorrentZip</param>
/// <param name="romba">True if files should be output in Romba depot folders, false otherwise</param> /// <param name="romba">True if files should be output in Romba depot folders, false otherwise</param>
/// <param name="gz">Integer representing the archive handling level for GZip</param> /// <param name="gz">Integer representing the archive handling level for GZip</param>
/// <param name="rar">Integer representing the archive handling level for RAR</param> /// <param name="rar">Integer representing the archive handling level for RAR</param>
@@ -303,7 +300,7 @@ namespace SabreTools
/// <param name="updateDat">True if the updated DAT should be output, false otherwise</param> /// <param name="updateDat">True if the updated DAT should be output, false otherwise</param>
/// <param name="logger">Logger object for file and console output</param> /// <param name="logger">Logger object for file and console output</param>
private static void InitSortVerify(List<string> datfiles, List<string> inputs, string outDir, string tempDir, bool quickScan, private static void InitSortVerify(List<string> datfiles, List<string> inputs, string outDir, string tempDir, bool quickScan,
bool toFolder, bool verify, bool delete, bool? torrentX, bool romba, int sevenzip, int gz, int rar, int zip, bool updateDat, Logger logger) bool toFolder, bool verify, bool delete, bool tgz, bool romba, int sevenzip, int gz, int rar, int zip, bool updateDat, Logger logger)
{ {
// Get the archive scanning level // Get the archive scanning level
ArchiveScanLevel asl = ArchiveTools.GetArchiveScanLevelFromNumbers(sevenzip, gz, rar, zip); ArchiveScanLevel asl = ArchiveTools.GetArchiveScanLevelFromNumbers(sevenzip, gz, rar, zip);
@@ -320,7 +317,7 @@ namespace SabreTools
logger.User("Populating complete in " + DateTime.Now.Subtract(start).ToString(@"hh\:mm\:ss\.fffff")); logger.User("Populating complete in " + DateTime.Now.Subtract(start).ToString(@"hh\:mm\:ss\.fffff"));
SimpleSort ss = new SimpleSort(datdata, inputs, outDir, tempDir, quickScan, toFolder, verify, SimpleSort ss = new SimpleSort(datdata, inputs, outDir, tempDir, quickScan, toFolder, verify,
delete, torrentX, romba, asl, updateDat, logger); delete, tgz, romba, asl, updateDat, logger);
ss.StartProcessing(); ss.StartProcessing();
} }
} }