mirror of
https://github.com/claunia/SabreTools.git
synced 2025-12-16 19:14:27 +00:00
[ALL] Zip64 support! And no more standard zip output!
This commit is contained in:
@@ -286,8 +286,6 @@ namespace SabreTools.Helper
|
||||
helptext.Add(" -v, --verify Enable verification of output directory");
|
||||
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(" -r, --romba Enable Romba depot dir output");
|
||||
helptext.Add(" -tzip Enable TorrentZip output");
|
||||
helptext.Add(" -tgz Enable TorrentGZ output");
|
||||
helptext.Add(" -r, --romba Enable Romba depot dir output");
|
||||
helptext.Add(" -do, --directory Output files as uncompressed");
|
||||
|
||||
@@ -438,7 +438,7 @@ namespace SabreTools.Helper
|
||||
return ZipReturn.ZipLocalFileHeaderError;
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
@@ -455,7 +455,7 @@ namespace SabreTools.Helper
|
||||
return ZipReturn.ZipLocalFileHeaderError;
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace SabreTools.Helper
|
||||
private bool _toFolder;
|
||||
private bool _verify;
|
||||
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 _updateDat;
|
||||
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="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="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="archiveScanLevel">ArchiveScanLevel representing the archive handling levels</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>
|
||||
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)
|
||||
{
|
||||
_datdata = datdata;
|
||||
@@ -57,7 +57,7 @@ namespace SabreTools.Helper
|
||||
_toFolder = toFolder;
|
||||
_verify = verify;
|
||||
_delete = delete;
|
||||
_torrentX = torrentX;
|
||||
_tgz = tgz;
|
||||
_romba = romba;
|
||||
_archiveScanLevel = archiveScanLevel;
|
||||
_updateDat = updateDat;
|
||||
@@ -333,7 +333,7 @@ namespace SabreTools.Helper
|
||||
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
|
||||
{
|
||||
File.Copy(input, Path.Combine(gamedir, Path.GetFileName(found.Name)));
|
||||
@@ -342,17 +342,13 @@ namespace SabreTools.Helper
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_torrentX == true)
|
||||
{
|
||||
ArchiveTools.WriteTorrentZip(input, _outDir, found, _logger);
|
||||
}
|
||||
else if (_torrentX == false)
|
||||
if (_tgz)
|
||||
{
|
||||
ArchiveTools.WriteTorrentGZ(input, _outDir, _romba, _logger);
|
||||
}
|
||||
else
|
||||
{
|
||||
ArchiveTools.WriteToArchive(input, _outDir, found);
|
||||
ArchiveTools.WriteToArchive(input, _outDir, found, _logger);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -404,7 +400,7 @@ namespace SabreTools.Helper
|
||||
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
|
||||
{
|
||||
File.Copy(newinput, Path.Combine(gamedir, Path.GetFileName(found.Name)));
|
||||
@@ -413,17 +409,13 @@ namespace SabreTools.Helper
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_torrentX == true)
|
||||
{
|
||||
ArchiveTools.WriteTorrentZip(newinput, _outDir, found, _logger);
|
||||
}
|
||||
else if (_torrentX == false)
|
||||
if (_tgz)
|
||||
{
|
||||
ArchiveTools.WriteTorrentGZ(newinput, _outDir, _romba, _logger);
|
||||
}
|
||||
else
|
||||
{
|
||||
ArchiveTools.WriteToArchive(newinput, _outDir, found);
|
||||
ArchiveTools.WriteToArchive(newinput, _outDir, found, _logger);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -467,17 +459,13 @@ namespace SabreTools.Helper
|
||||
else
|
||||
{
|
||||
_logger.Verbose("Matched name: " + newfound.Name);
|
||||
if (_torrentX == true)
|
||||
{
|
||||
ArchiveTools.WriteTorrentZip(input, _outDir, newfound, _logger);
|
||||
}
|
||||
else if (_torrentX == false)
|
||||
if (_tgz)
|
||||
{
|
||||
ArchiveTools.WriteTorrentGZ(input, _outDir, _romba, _logger);
|
||||
}
|
||||
else
|
||||
{
|
||||
ArchiveTools.WriteToArchive(input, _outDir, newfound);
|
||||
ArchiveTools.WriteToArchive(input, _outDir, newfound, _logger);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -550,24 +538,20 @@ namespace SabreTools.Helper
|
||||
else
|
||||
{
|
||||
// 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);
|
||||
if (File.Exists(outfile))
|
||||
{
|
||||
if (_torrentX == true)
|
||||
{
|
||||
ArchiveTools.WriteTorrentZip(outfile, _outDir, found, _logger);
|
||||
}
|
||||
else if (_torrentX == false)
|
||||
if (_tgz)
|
||||
{
|
||||
ArchiveTools.WriteTorrentGZ(outfile, _outDir, _romba, _logger);
|
||||
}
|
||||
else
|
||||
{
|
||||
ArchiveTools.WriteToArchive(outfile, _outDir, found);
|
||||
ArchiveTools.WriteToArchive(outfile, _outDir, found, _logger);
|
||||
}
|
||||
|
||||
try
|
||||
@@ -995,7 +979,7 @@ namespace SabreTools.Helper
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Process inputs and convert to TGZ, optionally converting to Romba
|
||||
/// Process inputs and convert to TorrentZip or TorrentGZ, optionally converting to Romba
|
||||
/// </summary>
|
||||
/// <returns>True if processing was a success, false otherwise</returns>
|
||||
public bool Convert()
|
||||
@@ -1032,9 +1016,9 @@ namespace SabreTools.Helper
|
||||
if (shouldExternalProcess)
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
Rom rom = FileTools.GetFileInfo(input, _logger);
|
||||
if (rom.HasDuplicates(_datdata, _logger))
|
||||
{
|
||||
_logger.User("File '" + input + "' existed in the DAT, skipping...");
|
||||
@@ -1043,7 +1027,15 @@ namespace SabreTools.Helper
|
||||
}
|
||||
|
||||
_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
|
||||
@@ -1059,9 +1051,9 @@ namespace SabreTools.Helper
|
||||
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
|
||||
Rom rom = FileTools.GetFileInfo(file, _logger);
|
||||
if (_datdata != null && _datdata.Files.Count > 0)
|
||||
{
|
||||
Rom rom = FileTools.GetFileInfo(file, _logger);
|
||||
if (rom.HasDuplicates(_datdata, _logger))
|
||||
{
|
||||
_logger.User("File '" + file + "' existed in the DAT, skipping...");
|
||||
@@ -1069,8 +1061,16 @@ namespace SabreTools.Helper
|
||||
}
|
||||
}
|
||||
|
||||
_logger.User("Processing extracted file " + file);
|
||||
success &= ArchiveTools.WriteTorrentGZ(file, _outDir, _romba, _logger);
|
||||
_logger.User("Processing file " + input);
|
||||
|
||||
if (_tgz)
|
||||
{
|
||||
success &= ArchiveTools.WriteTorrentGZ(input, _outDir, _romba, _logger);
|
||||
}
|
||||
else
|
||||
{
|
||||
success &= ArchiveTools.WriteToArchive(input, _outDir, rom, _logger);
|
||||
}
|
||||
}
|
||||
|
||||
FileTools.CleanDirectory(_tempDir);
|
||||
|
||||
@@ -670,7 +670,10 @@ Options:
|
||||
|
||||
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
|
||||
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:
|
||||
SimpleSort.exe [options] [filename|dirname] ...
|
||||
@@ -712,24 +715,10 @@ Options:
|
||||
simple FixDAT. This can be misleading, currently, because it only checks for exact
|
||||
matches.
|
||||
|
||||
-c, --convert Enable conversion of input files to TGZ
|
||||
This allows conversion of a folder or set of folders to TorrentGZ format without
|
||||
requiring a DAT to rebuild from. It is only useful in a small amount of situations at
|
||||
the present, but it is mostly meant for Romba compatibility at the present. If a DAT
|
||||
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.
|
||||
-c, --convert Enable filtering by input DAT
|
||||
This overrides the default rebuilding by using the DAT as a filter of what not to
|
||||
output. If no DAT is supplied, the entire input folder will be rebuild file-by-file
|
||||
to the output folder.
|
||||
|
||||
-tgz Enable Torrent GZ output
|
||||
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
|
||||
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) -
|
||||
|
||||
-r=rootdir Set the directory name for path size
|
||||
|
||||
@@ -106,6 +106,7 @@
|
||||
<Compile Include="Objects\Dat\BiosSet.cs" />
|
||||
<Compile Include="Objects\Dat\DatFile.cs" />
|
||||
<Compile Include="Objects\Dat\DatItem.cs" />
|
||||
<Compile Include="Objects\Dat\DatItemKV.cs" />
|
||||
<Compile Include="Objects\Dat\Disk.cs" />
|
||||
<Compile Include="Objects\Dat\Release.cs" />
|
||||
<Compile Include="Objects\Dat\Sample.cs" />
|
||||
|
||||
@@ -5,7 +5,6 @@ using SharpCompress.Reader;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
@@ -26,12 +25,13 @@ namespace SabreTools.Helper
|
||||
/// <param name="destEntryName">Output entry name</param>
|
||||
/// <param name="logger">Logger object for file and console output</param>
|
||||
/// <returns>True if the copy was a success, false otherwise</returns>
|
||||
public static bool CopyFileBetweenArchives(string inputArchive, string outDir,
|
||||
string sourceEntryName, Rom destEntry, Logger logger)
|
||||
public static bool CopyFileBetweenArchives(string inputArchive, string outDir, string sourceEntryName, Rom destEntry, Logger logger)
|
||||
{
|
||||
string realName = "";
|
||||
Stream ms = ExtractSingleStreamFromArchive(inputArchive, sourceEntryName, out realName, logger);
|
||||
return WriteToArchive(ms, outDir, destEntry);
|
||||
string temp = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
|
||||
string realName = ExtractSingleItemFromArchive(inputArchive, sourceEntryName, temp, logger);
|
||||
bool success = WriteToArchive(realName, outDir, destEntry, logger);
|
||||
Directory.Delete(temp, true);
|
||||
return success;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -132,8 +132,46 @@ namespace SabreTools.Helper
|
||||
|
||||
encounteredErrors = false;
|
||||
}
|
||||
else if ((at == ArchiveType.Zip && (archiveScanLevel & ArchiveScanLevel.ZipInternal) != 0)
|
||||
|| (at == ArchiveType.Rar && (archiveScanLevel & ArchiveScanLevel.RarInternal) != 0))
|
||||
else if (at == ArchiveType.Zip && (archiveScanLevel & ArchiveScanLevel.ZipInternal) != 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);
|
||||
|
||||
@@ -179,26 +217,30 @@ namespace SabreTools.Helper
|
||||
/// <returns>Name of the extracted file, null on error</returns>
|
||||
public static string ExtractSingleItemFromArchive(string input, string entryName, string tempDir, Logger logger)
|
||||
{
|
||||
string outfile = null;
|
||||
|
||||
string realEntry = "";
|
||||
Stream ms = ExtractSingleStreamFromArchive(input, entryName, out realEntry, logger);
|
||||
|
||||
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);
|
||||
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
|
||||
ms.Dispose();
|
||||
fs.Dispose();
|
||||
|
||||
return outfile;
|
||||
return realEntry;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -228,7 +270,42 @@ namespace SabreTools.Helper
|
||||
IReader reader = null;
|
||||
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));
|
||||
while (reader.MoveToNextEntry())
|
||||
@@ -263,6 +340,7 @@ namespace SabreTools.Helper
|
||||
reader?.Dispose();
|
||||
}
|
||||
|
||||
st.Position = 0;
|
||||
return st;
|
||||
}
|
||||
|
||||
@@ -322,8 +400,34 @@ namespace SabreTools.Helper
|
||||
size = BitConverter.ToInt32(headersize.Reverse().ToArray(), 0);
|
||||
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));
|
||||
while (reader.MoveToNextEntry())
|
||||
@@ -634,169 +738,6 @@ namespace SabreTools.Helper
|
||||
|
||||
#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>
|
||||
/// Copy a file to an output torrentzip archive
|
||||
/// </summary>
|
||||
@@ -805,7 +746,7 @@ namespace SabreTools.Helper
|
||||
/// <param name="rom">RomData representing the new information</param>
|
||||
/// <param name="logger">Logger object for file and console output</param>
|
||||
/// <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
|
||||
List<string> inputFiles = new List<string>();
|
||||
@@ -813,7 +754,7 @@ namespace SabreTools.Helper
|
||||
List<Rom> roms = new List<Rom>();
|
||||
roms.Add(rom);
|
||||
|
||||
return WriteTorrentZip(inputFiles, outDir, roms, logger);
|
||||
return WriteToArchive(inputFiles, outDir, roms, logger);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -824,7 +765,7 @@ namespace SabreTools.Helper
|
||||
/// <param name="rom">List of Rom representing the new information</param>
|
||||
/// <param name="logger">Logger object for file and console output</param>
|
||||
/// <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;
|
||||
string tempFile = Path.GetTempFileName();
|
||||
@@ -894,6 +835,7 @@ namespace SabreTools.Helper
|
||||
while ((ilen = freadStream.Read(ibuffer, 0, _bufferSize)) > 0)
|
||||
{
|
||||
writeStream.Write(ibuffer, 0, ilen);
|
||||
writeStream.Flush();
|
||||
}
|
||||
freadStream.Dispose();
|
||||
zipFile.CloseWriteStream(Convert.ToUInt32(roms[index].CRC, 16));
|
||||
@@ -959,6 +901,7 @@ namespace SabreTools.Helper
|
||||
while ((ilen = freadStream.Read(ibuffer, 0, _bufferSize)) > 0)
|
||||
{
|
||||
writeStream.Write(ibuffer, 0, ilen);
|
||||
writeStream.Flush();
|
||||
}
|
||||
freadStream.Dispose();
|
||||
zipFile.CloseWriteStream(Convert.ToUInt32(roms[-index - 1].CRC, 16));
|
||||
@@ -980,6 +923,7 @@ namespace SabreTools.Helper
|
||||
while ((ilen = zreadStream.Read(ibuffer, 0, _bufferSize)) > 0)
|
||||
{
|
||||
writeStream.Write(ibuffer, 0, ilen);
|
||||
writeStream.Flush();
|
||||
}
|
||||
zipFile.CloseWriteStream(BitConverter.ToUInt32(oldZipFile.CRC32(index), 0));
|
||||
}
|
||||
|
||||
@@ -493,7 +493,7 @@ namespace SabreTools.Helper
|
||||
input.Seek(offset, SeekOrigin.Begin);
|
||||
}
|
||||
|
||||
byte[] buffer = new byte[1024];
|
||||
byte[] buffer = new byte[8 * 1024];
|
||||
int read;
|
||||
while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
|
||||
{
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace SabreTools
|
||||
#region Init Methods
|
||||
|
||||
/// <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>
|
||||
/// <param name="datfiles">Names of the DATs to compare against</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="zip">Integer representing the archive handling level for Zip</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)
|
||||
{
|
||||
// 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="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,
|
||||
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
|
||||
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,
|
||||
delete, torrentX, romba, asl, updateDat, logger);
|
||||
delete, tgz, romba, asl, updateDat, logger);
|
||||
ss.StartProcessing();
|
||||
}
|
||||
|
||||
|
||||
@@ -42,16 +42,15 @@ namespace SabreTools
|
||||
|
||||
// Set all default values
|
||||
bool help = false,
|
||||
convert = false,
|
||||
delete = false,
|
||||
convert = false,
|
||||
quickScan = false,
|
||||
romba = false,
|
||||
simpleSort = true,
|
||||
toFolder = false,
|
||||
tzip = false,
|
||||
tgz = false,
|
||||
updateDat = false,
|
||||
verify = false;
|
||||
bool? torrentX = null;
|
||||
int sevenzip = 0,
|
||||
gz = 2,
|
||||
rar = 2,
|
||||
@@ -93,11 +92,7 @@ namespace SabreTools
|
||||
break;
|
||||
case "-tgz":
|
||||
case "--tgz":
|
||||
torrentX = false;
|
||||
break;
|
||||
case "-tzip":
|
||||
case "--tzip":
|
||||
torrentX = true;
|
||||
tgz = true;
|
||||
break;
|
||||
case "-ud":
|
||||
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 (inputs.Count == 0 && ((simpleSort && !verify) || convert || tzip))
|
||||
if (inputs.Count == 0 && ((simpleSort && !verify) || convert))
|
||||
{
|
||||
logger.Error("This feature requires at least one input");
|
||||
Build.Help();
|
||||
@@ -194,10 +189,11 @@ namespace SabreTools
|
||||
return;
|
||||
}
|
||||
|
||||
// If we are converting the folder to TGZ
|
||||
// If we are converting the folder
|
||||
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
|
||||
@@ -206,7 +202,7 @@ namespace SabreTools
|
||||
if (datfiles.Count > 0)
|
||||
{
|
||||
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
|
||||
{
|
||||
@@ -228,21 +224,22 @@ namespace SabreTools
|
||||
}
|
||||
|
||||
/// <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>
|
||||
/// <param name="datfiles">Names of the DATs to compare against</param>
|
||||
/// <param name="inputs">List of all inputted files and folders</param>
|
||||
/// <param name="outDir">Output directory (empty for default directory)</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="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="sevenzip">Integer representing the archive handling level for 7z</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="zip">Integer representing the archive handling level for Zip</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,
|
||||
bool romba, int sevenzip, int gz, int rar, int zip, Logger logger)
|
||||
public static bool InitConvertFolder(List<string> datfiles, List<string> inputs, string outDir, string tempDir, bool delete,
|
||||
bool tgz, bool romba, int sevenzip, int gz, int rar, int zip, Logger logger)
|
||||
{
|
||||
// Get the archive scanning level
|
||||
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"));
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -295,7 +292,7 @@ namespace SabreTools
|
||||
/// <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="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="gz">Integer representing the archive handling level for GZip</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="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,
|
||||
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
|
||||
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"));
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user