mirror of
https://github.com/claunia/SabreTools.git
synced 2025-12-16 19:14:27 +00:00
[ArchiveTools] Add XZ output (not TXZ)
This commit is contained in:
@@ -561,6 +561,7 @@ namespace SabreTools.Helper.Dats
|
|||||||
case OutputFormat.TorrentRar:
|
case OutputFormat.TorrentRar:
|
||||||
break;
|
break;
|
||||||
case OutputFormat.TorrentXZ:
|
case OutputFormat.TorrentXZ:
|
||||||
|
rebuilt &= ArchiveTools.WriteTorrentXZ(file, outDir, item, date: date);
|
||||||
break;
|
break;
|
||||||
case OutputFormat.TorrentZip:
|
case OutputFormat.TorrentZip:
|
||||||
rebuilt &= ArchiveTools.WriteTorrentZip(file, outDir, item, date: date);
|
rebuilt &= ArchiveTools.WriteTorrentZip(file, outDir, item, date: date);
|
||||||
@@ -645,6 +646,7 @@ namespace SabreTools.Helper.Dats
|
|||||||
case OutputFormat.TorrentRar:
|
case OutputFormat.TorrentRar:
|
||||||
break;
|
break;
|
||||||
case OutputFormat.TorrentXZ:
|
case OutputFormat.TorrentXZ:
|
||||||
|
rebuilt &= ArchiveTools.WriteTorrentXZ(file, outDir, item, date: date);
|
||||||
break;
|
break;
|
||||||
case OutputFormat.TorrentZip:
|
case OutputFormat.TorrentZip:
|
||||||
rebuilt &= ArchiveTools.WriteTorrentZip(file, outDir, item, date: date);
|
rebuilt &= ArchiveTools.WriteTorrentZip(file, outDir, item, date: date);
|
||||||
@@ -749,6 +751,8 @@ namespace SabreTools.Helper.Dats
|
|||||||
case OutputFormat.TorrentRar:
|
case OutputFormat.TorrentRar:
|
||||||
break;
|
break;
|
||||||
case OutputFormat.TorrentXZ:
|
case OutputFormat.TorrentXZ:
|
||||||
|
rebuilt &= ArchiveTools.WriteTorrentXZ(file + ".new", outDir, item, date: date);
|
||||||
|
rebuilt &= ArchiveTools.WriteTorrentXZ(file, outDir, rom, date: date);
|
||||||
break;
|
break;
|
||||||
case OutputFormat.TorrentZip:
|
case OutputFormat.TorrentZip:
|
||||||
rebuilt &= ArchiveTools.WriteTorrentZip(file + ".new", outDir, item, date: date);
|
rebuilt &= ArchiveTools.WriteTorrentZip(file + ".new", outDir, item, date: date);
|
||||||
|
|||||||
@@ -435,10 +435,11 @@ Options:
|
|||||||
invalidate the output files as proper TorrentZip files because the date will not
|
invalidate the output files as proper TorrentZip files because the date will not
|
||||||
match the standard.
|
match the standard.
|
||||||
|
|
||||||
-t7z Enable Torrent 7zip output [NOT IMPLEMENTED]
|
-t7z Enable Torrent 7zip output
|
||||||
Instead of ouputting the files to folder, files will be rebuilt to Torrent7Zip (T7Z)
|
Instead of ouputting the files to folder, files will be rebuilt to Torrent7Zip (T7Z)
|
||||||
files. This format is based on the LZMA container format 7zip, but with custom header
|
files. This format is based on the LZMA container format 7zip, but with custom header
|
||||||
information. This is currently unused by any major application.
|
information. This is currently unused by any major application. Currently does not
|
||||||
|
produce proper Torrent-compatible outputs.
|
||||||
|
|
||||||
-tar Enable Tape ARchive output
|
-tar Enable Tape ARchive output
|
||||||
Instead of outputting the fiels to folder, files will be rebuilt to Tape ARchive (TAR)
|
Instead of outputting the fiels to folder, files will be rebuilt to Tape ARchive (TAR)
|
||||||
@@ -471,10 +472,11 @@ Options:
|
|||||||
files. This format is based on the RAR propietary format but with custom header
|
files. This format is based on the RAR propietary format but with custom header
|
||||||
information. This is currently unused by any major application;
|
information. This is currently unused by any major application;
|
||||||
|
|
||||||
-txz Enable Torrent XZ output [NOT IMPLEMENTED]
|
-txz Enable Torrent XZ output
|
||||||
Instead of outputting files to folder, files will be rebuilt to Torrent XZ (TXZ) files.
|
Instead of outputting files to folder, files will be rebuilt to Torrent XZ (TXZ) files.
|
||||||
This format is based on the LZMA container format XZ, but with custom header
|
This format is based on the LZMA container format XZ, but with custom header
|
||||||
information. This is currently unused by any major application;
|
information. This is currently unused by any major application. Currently does not
|
||||||
|
produce proper Torrent-compatible outputs.
|
||||||
|
|
||||||
-tzip Enable Torrent Zip output
|
-tzip Enable Torrent Zip output
|
||||||
Instead of ouputting files to folder, files will be rebuilt to TorrentZip (TZ) files.
|
Instead of ouputting files to folder, files will be rebuilt to TorrentZip (TZ) files.
|
||||||
@@ -561,10 +563,11 @@ Options:
|
|||||||
invalidate the output files as proper TorrentZip files because the date will not
|
invalidate the output files as proper TorrentZip files because the date will not
|
||||||
match the standard.
|
match the standard.
|
||||||
|
|
||||||
-t7z Enable Torrent 7zip output [NOT IMPLEMENTED]
|
-t7z Enable Torrent 7zip output
|
||||||
Instead of ouputting the files to folder, files will be rebuilt to Torrent7Zip (T7Z)
|
Instead of ouputting the files to folder, files will be rebuilt to Torrent7Zip (T7Z)
|
||||||
files. This format is based on the LZMA container format 7zip, but with custom header
|
files. This format is based on the LZMA container format 7zip, but with custom header
|
||||||
information. This is currently unused by any major application.
|
information. This is currently unused by any major application. Currently does not
|
||||||
|
produce proper Torrent-compatible outputs.
|
||||||
|
|
||||||
-tar Enable Tape ARchive output
|
-tar Enable Tape ARchive output
|
||||||
Instead of outputting the fiels to folder, files will be rebuilt to Tape ARchive (TAR)
|
Instead of outputting the fiels to folder, files will be rebuilt to Tape ARchive (TAR)
|
||||||
@@ -595,12 +598,13 @@ Options:
|
|||||||
-trar Enable Torrent RAR output [NOT IMPLEMENTED]
|
-trar Enable Torrent RAR output [NOT IMPLEMENTED]
|
||||||
Instead of outputting files to folder, files will be rebuilt to Torrent RAR (TRAR)
|
Instead of outputting files to folder, files will be rebuilt to Torrent RAR (TRAR)
|
||||||
files. This format is based on the RAR propietary format but with custom header
|
files. This format is based on the RAR propietary format but with custom header
|
||||||
information. This is currently unused by any major application;
|
information. This is currently unused by any major application.
|
||||||
|
|
||||||
-txz Enable Torrent XZ output [NOT IMPLEMENTED]
|
-txz Enable Torrent XZ output
|
||||||
Instead of outputting files to folder, files will be rebuilt to Torrent XZ (TXZ) files.
|
Instead of outputting files to folder, files will be rebuilt to Torrent XZ (TXZ) files.
|
||||||
This format is based on the LZMA container format XZ, but with custom header
|
This format is based on the LZMA container format XZ, but with custom header
|
||||||
information. This is currently unused by any major application;
|
information. This is currently unused by any major application. Currently does not
|
||||||
|
produce proper Torrent-compatible outputs.
|
||||||
|
|
||||||
-tzip Enable Torrent Zip output
|
-tzip Enable Torrent Zip output
|
||||||
Instead of ouputting files to folder, files will be rebuilt to TorrentZip (TZ) files.
|
Instead of ouputting files to folder, files will be rebuilt to TorrentZip (TZ) files.
|
||||||
|
|||||||
@@ -1310,7 +1310,7 @@ namespace SabreTools.Helper.Tools
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// (UNIMPLEMENTED) Write a set of input files to a torrent7z archive (assuming the same output archive name)
|
/// Write a set of input files to a torrent7z archive (assuming the same output archive name)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="inputFile">Input filenames to be moved</param>
|
/// <param name="inputFile">Input filenames to be moved</param>
|
||||||
/// <param name="outDir">Output directory to build to</param>
|
/// <param name="outDir">Output directory to build to</param>
|
||||||
@@ -1693,7 +1693,7 @@ namespace SabreTools.Helper.Tools
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// (UNIMPLEMENTED) Write a set of input files to a torrentxz archive (assuming the same output archive name)
|
/// Write a set of input files to a torrentxz archive (assuming the same output archive name)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="inputFile">Input filenames to be moved</param>
|
/// <param name="inputFile">Input filenames to be moved</param>
|
||||||
/// <param name="outDir">Output directory to build to</param>
|
/// <param name="outDir">Output directory to build to</param>
|
||||||
@@ -1702,7 +1702,208 @@ namespace SabreTools.Helper.Tools
|
|||||||
/// <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 WriteTorrentXZ(List<string> inputFiles, string outDir, List<Rom> roms, bool date = false)
|
public static bool WriteTorrentXZ(List<string> inputFiles, string outDir, List<Rom> roms, bool date = false)
|
||||||
{
|
{
|
||||||
return false;
|
bool success = false;
|
||||||
|
string tempFile = Path.Combine(outDir, "tmp" + Guid.NewGuid().ToString());
|
||||||
|
|
||||||
|
// If either list of roms is null or empty, return
|
||||||
|
if (inputFiles == null || roms == null || inputFiles.Count == 0 || roms.Count == 0)
|
||||||
|
{
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 output archive name from the first rebuild rom
|
||||||
|
string archiveFileName = Path.Combine(outDir, Style.RemovePathUnsafeCharacters(roms[0].Machine.Name) + (roms[0].Machine.Name.EndsWith(".7z") ? "" : ".7z"));
|
||||||
|
|
||||||
|
// Set internal variables
|
||||||
|
SevenZipBase.SetLibraryPath("7za.dll");
|
||||||
|
SevenZipExtractor oldZipFile;
|
||||||
|
SevenZipCompressor zipFile;
|
||||||
|
|
||||||
|
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 and put the single file
|
||||||
|
if (!File.Exists(archiveFileName))
|
||||||
|
{
|
||||||
|
zipFile = new SevenZipCompressor()
|
||||||
|
{
|
||||||
|
ArchiveFormat = OutArchiveFormat.XZ,
|
||||||
|
CompressionLevel = SevenZip.CompressionLevel.Normal,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Map all inputs to index
|
||||||
|
Dictionary<string, int> inputIndexMap = new Dictionary<string, int>();
|
||||||
|
for (int i = 0; i < inputFiles.Count; i++)
|
||||||
|
{
|
||||||
|
inputIndexMap.Add(roms[i].Name.Replace('\\', '/'), i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort the keys in TZIP order
|
||||||
|
List<string> keys = inputIndexMap.Keys.ToList();
|
||||||
|
keys.Sort(ZipFile.TorrentZipStringCompare);
|
||||||
|
|
||||||
|
// Create the temp directory
|
||||||
|
string tempPath = Path.Combine(Path.GetTempPath(), new Guid().ToString());
|
||||||
|
if (!Directory.Exists(tempPath))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(tempPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now add all of the files in order
|
||||||
|
foreach (string key in keys)
|
||||||
|
{
|
||||||
|
string newkey = Path.Combine(tempPath, key);
|
||||||
|
|
||||||
|
File.Move(inputFiles[inputIndexMap[key]], newkey);
|
||||||
|
zipFile.CompressFiles(tempFile, newkey);
|
||||||
|
File.Move(newkey, inputFiles[inputIndexMap[key]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
FileTools.CleanDirectory(tempPath);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Directory.Delete(tempPath);
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, sort the input files and write out in the correct order
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Open the old archive for reading
|
||||||
|
Stream oldZipFileStream = File.OpenRead(archiveFileName);
|
||||||
|
oldZipFile = new SevenZipExtractor(oldZipFileStream);
|
||||||
|
|
||||||
|
// Map all inputs to index
|
||||||
|
Dictionary<string, int> inputIndexMap = new Dictionary<string, int>();
|
||||||
|
for (int i = 0; i < inputFiles.Count; i++)
|
||||||
|
{
|
||||||
|
// If the old one contains the new file, then just skip out
|
||||||
|
if (oldZipFile.ArchiveFileNames.Contains(roms[i].Name.Replace('\\', '/')))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
inputIndexMap.Add(roms[i].Name.Replace('\\', '/'), -(i + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Then add all of the old entries to it too
|
||||||
|
for (int i = 0; i < oldZipFile.FilesCount; i++)
|
||||||
|
{
|
||||||
|
inputIndexMap.Add(oldZipFile.ArchiveFileNames[i], i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the number of entries is the same as the old archive, skip out
|
||||||
|
if (inputIndexMap.Keys.Count <= oldZipFile.FilesCount)
|
||||||
|
{
|
||||||
|
success = true;
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, process the old zipfile
|
||||||
|
zipFile = new SevenZipCompressor()
|
||||||
|
{
|
||||||
|
ArchiveFormat = OutArchiveFormat.XZ,
|
||||||
|
CompressionLevel = SevenZip.CompressionLevel.Normal,
|
||||||
|
};
|
||||||
|
Stream zipFileStream = File.OpenWrite(tempFile);
|
||||||
|
|
||||||
|
// Get the order for the entries with the new file
|
||||||
|
List<string> keys = inputIndexMap.Keys.ToList();
|
||||||
|
keys.Sort(ZipFile.TorrentZipStringCompare);
|
||||||
|
|
||||||
|
// Copy over all files to the new archive
|
||||||
|
foreach (string key in keys)
|
||||||
|
{
|
||||||
|
// Get the index mapped to the key
|
||||||
|
int index = inputIndexMap[key];
|
||||||
|
|
||||||
|
// If we have the input file, add it now
|
||||||
|
if (index < 0)
|
||||||
|
{
|
||||||
|
zipFile.CompressFiles(zipFileStream, inputFiles[-index - 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, copy the file from the old archive
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Stream oldZipFileEntryStream = File.Open(inputFiles[index], FileMode.Create, FileAccess.ReadWrite, FileShare.None);
|
||||||
|
oldZipFile.ExtractFile(index, oldZipFileEntryStream);
|
||||||
|
zipFile.CompressFiles(zipFileStream, inputFiles[index]);
|
||||||
|
|
||||||
|
oldZipFileEntryStream.Dispose();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
File.Delete(inputFiles[index]);
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
zipFileStream.Dispose();
|
||||||
|
oldZipFile.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine(ex);
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the old file exists, delete it and replace
|
||||||
|
if (File.Exists(archiveFileName))
|
||||||
|
{
|
||||||
|
File.Delete(archiveFileName);
|
||||||
|
}
|
||||||
|
File.Move(tempFile, archiveFileName);
|
||||||
|
|
||||||
|
// Now make the file TXZ
|
||||||
|
// TODO: Add ACTUAL TXZ compatible code (based on T7z)
|
||||||
|
|
||||||
|
BinaryWriter bw = new BinaryWriter(File.Open(archiveFileName, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite));
|
||||||
|
bw.Seek(0, SeekOrigin.Begin);
|
||||||
|
bw.Write(Constants.Torrent7ZipHeader);
|
||||||
|
bw.Seek(0, SeekOrigin.End);
|
||||||
|
|
||||||
|
oldZipFile = new SevenZipExtractor(File.Open(archiveFileName, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite));
|
||||||
|
|
||||||
|
// Get the correct signature to use (Default 0, Unicode 1, SingleFile 2, StripFileNames 4)
|
||||||
|
byte[] tempsig = Constants.Torrent7ZipSignature;
|
||||||
|
if (oldZipFile.FilesCount > 1)
|
||||||
|
{
|
||||||
|
tempsig[16] = 0x2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tempsig[16] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bw.Write(tempsig);
|
||||||
|
bw.Dispose();
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -611,7 +611,7 @@ namespace SabreTools.Helper.Tools
|
|||||||
}
|
}
|
||||||
if ((omitFromScan & Hash.xxHash) == 0)
|
if ((omitFromScan & Hash.xxHash) == 0)
|
||||||
{
|
{
|
||||||
rom.SHA512 = xxHash.Digest().ToString("X").ToLowerInvariant();
|
rom.SHA512 = xxHash.Digest().ToString("X").ToLowerInvariant(); // TODO: Not sure how long xxHash is supposed to be. Add the length here and in constants later
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dispose of the hashers
|
// Dispose of the hashers
|
||||||
|
|||||||
@@ -418,13 +418,11 @@ namespace SabreTools
|
|||||||
FeatureType.Flag,
|
FeatureType.Flag,
|
||||||
null));
|
null));
|
||||||
*/
|
*/
|
||||||
/*
|
|
||||||
sort.AddFeature("txz", new Feature(
|
sort.AddFeature("txz", new Feature(
|
||||||
new List<string>() { "-txz", "--txz" },
|
new List<string>() { "-txz", "--txz" },
|
||||||
"Enable TorrentXZ output",
|
"Enable TorrentXZ output",
|
||||||
FeatureType.Flag,
|
FeatureType.Flag,
|
||||||
null));
|
null));
|
||||||
*/
|
|
||||||
sort.AddFeature("tzip", new Feature(
|
sort.AddFeature("tzip", new Feature(
|
||||||
new List<string>() { "-tzip", "--tzip" },
|
new List<string>() { "-tzip", "--tzip" },
|
||||||
"Enable TorrentZip output",
|
"Enable TorrentZip output",
|
||||||
@@ -556,13 +554,11 @@ namespace SabreTools
|
|||||||
FeatureType.Flag,
|
FeatureType.Flag,
|
||||||
null));
|
null));
|
||||||
*/
|
*/
|
||||||
/*
|
|
||||||
sortDepot.AddFeature("txz", new Feature(
|
sortDepot.AddFeature("txz", new Feature(
|
||||||
new List<string>() { "-txz", "--txz" },
|
new List<string>() { "-txz", "--txz" },
|
||||||
"Enable TorrentXZ output",
|
"Enable TorrentXZ output",
|
||||||
FeatureType.Flag,
|
FeatureType.Flag,
|
||||||
null));
|
null));
|
||||||
*/
|
|
||||||
sortDepot.AddFeature("tzip", new Feature(
|
sortDepot.AddFeature("tzip", new Feature(
|
||||||
new List<string>() { "-tzip", "--tzip" },
|
new List<string>() { "-tzip", "--tzip" },
|
||||||
"Enable TorrentZip output",
|
"Enable TorrentZip output",
|
||||||
|
|||||||
Reference in New Issue
Block a user