mirror of
https://github.com/wabbajack-tools/wabbajack.git
synced 2024-08-30 18:42:17 +00:00
Removed cruft of old extractor
This commit is contained in:
parent
3bdab577e1
commit
9de30ea8b7
@ -83,8 +83,7 @@ namespace Compression.BSA.Test
|
||||
var folder = _bsaFolder.Combine(game.ToString(), modid.ToString());
|
||||
await folder.DeleteDirectory();
|
||||
folder.CreateDirectory();
|
||||
await using var files = await FileExtractor.ExtractAll(Queue, filename);
|
||||
await files.MoveAllTo(folder);
|
||||
await FileExtractor2.ExtractAll(filename, folder);
|
||||
|
||||
foreach (var bsa in folder.EnumerateFiles().Where(f => Consts.SupportedBSAs.Contains(f.Extension)))
|
||||
{
|
||||
|
@ -51,8 +51,6 @@ namespace Wabbajack.Lib
|
||||
|
||||
}
|
||||
|
||||
|
||||
private ExtractedFiles? ExtractedModListFiles { get; set; } = null;
|
||||
public async Task ExtractModlist()
|
||||
{
|
||||
ExtractedModlistFolder = await TempFolder.Create();
|
||||
@ -143,20 +141,27 @@ namespace Wabbajack.Lib
|
||||
await using var s = await sf.GetStream();
|
||||
foreach (var directive in grouped[vf])
|
||||
{
|
||||
var file = directive.Directive;
|
||||
s.Position = 0;
|
||||
|
||||
switch (directive.Directive)
|
||||
switch (file)
|
||||
{
|
||||
case PatchedFromArchive pfa:
|
||||
{
|
||||
var patchData = await LoadBytesFromPath(pfa.PatchID);
|
||||
await using var os = await directive.Directive.To.RelativeTo(OutputFolder).Create();
|
||||
var toFile = file.To.RelativeTo(OutputFolder);
|
||||
await using var os = await toFile.Create();
|
||||
Utils.ApplyPatch(s, () => new MemoryStream(patchData), os);
|
||||
|
||||
if (await VirusScanner.ShouldScan(toFile) &&
|
||||
await ClientAPI.GetVirusScanResult(toFile) == VirusScanner.Result.Malware)
|
||||
{
|
||||
await toFile.DeleteAsync();
|
||||
Utils.ErrorThrow(new Exception($"Virus scan of patched executable reported possible malware: {toFile.ToString()} ({(long)await toFile.FileHashCachedAsync()})"));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
|
||||
case FromArchive _:
|
||||
await directive.Directive.To.RelativeTo(OutputFolder).WriteAllAsync(s, false);
|
||||
break;
|
||||
@ -165,102 +170,7 @@ namespace Wabbajack.Lib
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private async Task InstallArchive(WorkQueue queue, Archive archive, AbsolutePath absolutePath, IGrouping<Hash, FromArchive> grouping)
|
||||
{
|
||||
Status($"Extracting {archive.Name}");
|
||||
|
||||
List<FromArchive> vFiles = grouping.Select(g =>
|
||||
{
|
||||
var file = VFS.Index.FileForArchiveHashPath(g.ArchiveHashPath);
|
||||
g.FromFile = file;
|
||||
return g;
|
||||
}).ToList();
|
||||
|
||||
var onFinish = await VFS.Stage(vFiles.Select(f => f.FromFile).Distinct());
|
||||
|
||||
|
||||
Status($"Copying files for {archive.Name}");
|
||||
|
||||
async ValueTask CopyFile(AbsolutePath from, AbsolutePath to)
|
||||
{
|
||||
if (to.Exists)
|
||||
{
|
||||
if (to.IsReadOnly)
|
||||
to.IsReadOnly = false;
|
||||
await to.DeleteAsync();
|
||||
}
|
||||
|
||||
if (from.Exists)
|
||||
{
|
||||
if (from.IsReadOnly)
|
||||
from.IsReadOnly = false;
|
||||
}
|
||||
|
||||
await @from.CopyToAsync(to);
|
||||
// If we don't do this, the file will use the last-modified date of the file when it was compressed
|
||||
// into an archive, which isn't really what we want in the case of files installed archives
|
||||
to.LastModified = DateTime.Now;
|
||||
}
|
||||
|
||||
foreach (var (idx, group) in vFiles.GroupBy(f => f.FromFile).Select((grp, i) => (i, grp)))
|
||||
{
|
||||
Utils.Status("Installing files", Percent.FactoryPutInRange(idx, vFiles.Count));
|
||||
if (group.Key == null)
|
||||
{
|
||||
throw new ArgumentNullException("FromFile was null");
|
||||
}
|
||||
var firstDest = OutputFolder.Combine(group.First().To);
|
||||
|
||||
if (group.Key.IsNative)
|
||||
{
|
||||
await group.Key.AbsoluteName.HardLinkIfOversize(firstDest);
|
||||
}
|
||||
else
|
||||
{
|
||||
await group.Key.StagedFile.MoveTo(firstDest);
|
||||
}
|
||||
|
||||
foreach (var copy in group.Skip(1))
|
||||
{
|
||||
await CopyFile(firstDest, OutputFolder.Combine(copy.To));
|
||||
}
|
||||
|
||||
foreach (var toPatch in group.OfType<PatchedFromArchive>())
|
||||
{
|
||||
await using var patchStream = new MemoryStream();
|
||||
Status($"Patching {toPatch.To.FileName}");
|
||||
// Read in the patch data
|
||||
|
||||
Status($"Verifying unpatched file {toPatch.To.FileName}");
|
||||
var toFile = OutputFolder.Combine(toPatch.To);
|
||||
|
||||
byte[] patchData = await LoadBytesFromPath(toPatch.PatchID);
|
||||
|
||||
var oldData = new MemoryStream(await toFile.ReadAllBytesAsync());
|
||||
|
||||
// Remove the file we're about to patch
|
||||
await toFile.DeleteAsync();
|
||||
|
||||
// Patch it
|
||||
await using (var outStream = await toFile.Create())
|
||||
{
|
||||
Utils.ApplyPatch(oldData, () => new MemoryStream(patchData), outStream);
|
||||
}
|
||||
|
||||
if (await VirusScanner.ShouldScan(toFile) &&
|
||||
await ClientAPI.GetVirusScanResult(toFile) == VirusScanner.Result.Malware)
|
||||
{
|
||||
await toFile.DeleteAsync();
|
||||
Utils.ErrorThrow(new Exception($"Virus scan of patched executable reported possible malware: {toFile.ToString()} ({(long)await toFile.FileHashCachedAsync()})"));
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var file in group)
|
||||
{
|
||||
if (file is PatchedFromArchive)
|
||||
{
|
||||
await file.To.RelativeTo(OutputFolder).FileHashAsync();
|
||||
@ -276,12 +186,7 @@ namespace Wabbajack.Lib
|
||||
await file.To.RelativeTo(OutputFolder).Compact(FileCompaction.Algorithm.XPRESS16K);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Status("Unstaging files");
|
||||
await onFinish();
|
||||
});
|
||||
}
|
||||
|
||||
public async Task DownloadArchives()
|
||||
|
@ -230,43 +230,6 @@ namespace Wabbajack.VirtualFileSystem
|
||||
await filesByParent[top].PMap(queue, async file => await HandleFile(file, new NativeFileStreamFactory(file.AbsoluteName)));
|
||||
}
|
||||
|
||||
public async Task<Func<Task>> Stage(IEnumerable<VirtualFile> files)
|
||||
{
|
||||
await _cleanupTask;
|
||||
|
||||
var grouped = files.SelectMany(f => f.FilesInFullPath)
|
||||
.Distinct()
|
||||
.Where(f => f.Parent != null)
|
||||
.GroupBy(f => f.Parent)
|
||||
.OrderBy(f => f.Key?.NestingFactor ?? 0)
|
||||
.ToList();
|
||||
|
||||
var paths = new List<IAsyncDisposable>();
|
||||
|
||||
foreach (var group in grouped)
|
||||
{
|
||||
var only = group.Select(f => f.RelativeName);
|
||||
var extracted = await group.Key.StagedFile.ExtractAll(Queue, only, true);
|
||||
paths.Add(extracted);
|
||||
foreach (var file in group)
|
||||
file.StagedFile = extracted[file.RelativeName];
|
||||
}
|
||||
|
||||
return async () =>
|
||||
{
|
||||
foreach (var p in paths)
|
||||
{
|
||||
await p.DisposeAsync();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<AsyncDisposableList<VirtualFile>> StageWith(IEnumerable<VirtualFile> files)
|
||||
{
|
||||
return new AsyncDisposableList<VirtualFile>(await Stage(files), files);
|
||||
}
|
||||
|
||||
|
||||
#region KnownFiles
|
||||
|
||||
private List<HashRelativePath> _knownFiles = new List<HashRelativePath>();
|
||||
|
@ -1,51 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Compression.BSA;
|
||||
using Wabbajack.Common;
|
||||
|
||||
namespace Wabbajack.VirtualFileSystem
|
||||
{
|
||||
public class ExtractedBSAFile : IExtractedFile
|
||||
{
|
||||
private readonly IFile _file;
|
||||
public ExtractedBSAFile(IFile file)
|
||||
{
|
||||
_file = file;
|
||||
}
|
||||
|
||||
public RelativePath Path => _file.Path;
|
||||
|
||||
public async Task<Hash> HashAsync()
|
||||
{
|
||||
await using var stream = await OpenRead();
|
||||
return await stream.xxHashAsync();
|
||||
}
|
||||
public DateTime LastModifiedUtc => DateTime.UtcNow;
|
||||
public long Size => _file.Size;
|
||||
public async ValueTask<Stream> OpenRead()
|
||||
{
|
||||
var ms = new MemoryStream();
|
||||
await _file.CopyDataTo(ms);
|
||||
ms.Position = 0;
|
||||
return ms;
|
||||
}
|
||||
|
||||
public async Task<bool> CanExtract()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public Task<ExtractedFiles> ExtractAll(WorkQueue queue, IEnumerable<RelativePath> OnlyFiles, bool throwOnError)
|
||||
{
|
||||
throw new Exception("BSAs can't contain archives");
|
||||
}
|
||||
|
||||
public async Task MoveTo(AbsolutePath path)
|
||||
{
|
||||
await using var fs = await path.Create();
|
||||
await _file.CopyDataTo(fs);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Wabbajack.Common;
|
||||
|
||||
namespace Wabbajack.VirtualFileSystem
|
||||
{
|
||||
public class ExtractedDiskFile : IExtractedFile
|
||||
{
|
||||
protected AbsolutePath _path;
|
||||
|
||||
public ExtractedDiskFile(AbsolutePath path)
|
||||
{
|
||||
if (path == default)
|
||||
throw new InvalidDataException("Path cannot be empty");
|
||||
_path = path;
|
||||
}
|
||||
|
||||
public virtual async Task<Hash> HashAsync()
|
||||
{
|
||||
return await _path.FileHashAsync();
|
||||
}
|
||||
public DateTime LastModifiedUtc => _path.LastModifiedUtc;
|
||||
public long Size => _path.Size;
|
||||
public async ValueTask<Stream> OpenRead()
|
||||
{
|
||||
return await _path.OpenRead();
|
||||
}
|
||||
|
||||
public async Task<bool> CanExtract()
|
||||
{
|
||||
return await FileExtractor.CanExtract(_path);
|
||||
}
|
||||
|
||||
public Task<ExtractedFiles> ExtractAll(WorkQueue queue, IEnumerable<RelativePath> onlyFiles, bool throwOnError)
|
||||
{
|
||||
return FileExtractor.ExtractAll(queue, _path, onlyFiles, throwOnError);
|
||||
}
|
||||
|
||||
public async Task MoveTo(AbsolutePath path)
|
||||
{
|
||||
if (FileExtractor.MightBeArchive(_path.Extension))
|
||||
{
|
||||
path.Parent.CreateDirectory();
|
||||
await _path.CopyToAsync(path);
|
||||
return;
|
||||
}
|
||||
await _path.MoveToAsync(path, true);
|
||||
_path = path;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Wabbajack.Common;
|
||||
|
||||
namespace Wabbajack.VirtualFileSystem
|
||||
{
|
||||
public class ExtractedFiles : IAsyncDisposable, IEnumerable<KeyValuePair<RelativePath, IExtractedFile>>
|
||||
{
|
||||
private Dictionary<RelativePath, IExtractedFile> _files;
|
||||
private IAsyncDisposable _disposable;
|
||||
private AbsolutePath _tempFolder;
|
||||
|
||||
public ExtractedFiles(Dictionary<RelativePath, IExtractedFile> files, IAsyncDisposable disposeOther = null)
|
||||
{
|
||||
_files = files;
|
||||
_disposable = disposeOther;
|
||||
}
|
||||
|
||||
public ExtractedFiles(TempFolder tempPath)
|
||||
{
|
||||
_files = tempPath.Dir.EnumerateFiles().ToDictionary(f => f.RelativeTo(tempPath.Dir),
|
||||
f => (IExtractedFile)new ExtractedDiskFile(f));
|
||||
_disposable = tempPath;
|
||||
}
|
||||
|
||||
public async ValueTask DisposeAsync()
|
||||
{
|
||||
if (_disposable != null)
|
||||
{
|
||||
await _disposable.DisposeAsync();
|
||||
_disposable = null;
|
||||
}
|
||||
}
|
||||
|
||||
public bool ContainsKey(RelativePath key)
|
||||
{
|
||||
return _files.ContainsKey(key);
|
||||
}
|
||||
|
||||
public int Count => _files.Count;
|
||||
|
||||
public IExtractedFile this[RelativePath key] => _files[key];
|
||||
public IEnumerator<KeyValuePair<RelativePath, IExtractedFile>> GetEnumerator()
|
||||
{
|
||||
return _files.GetEnumerator();
|
||||
}
|
||||
|
||||
public async Task MoveAllTo(AbsolutePath folder)
|
||||
{
|
||||
foreach (var (key, value) in this)
|
||||
{
|
||||
await value.MoveTo(key.RelativeTo(folder));
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,284 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reactive.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Alphaleonis.Win32.Filesystem;
|
||||
using Compression.BSA;
|
||||
using OMODFramework;
|
||||
using Wabbajack.Common.StatusFeed;
|
||||
using Wabbajack.Common.StatusFeed.Errors;
|
||||
using Wabbajack.Common;
|
||||
using Wabbajack.Common.FileSignatures;
|
||||
using Wabbajack.VirtualFileSystem.SevenZipExtractor;
|
||||
using Utils = Wabbajack.Common.Utils;
|
||||
|
||||
|
||||
namespace Wabbajack.VirtualFileSystem
|
||||
{
|
||||
public class FileExtractor
|
||||
{
|
||||
public static readonly SignatureChecker ArchiveSigs = new SignatureChecker(Definitions.FileType.TES3,
|
||||
Definitions.FileType.BSA,
|
||||
Definitions.FileType.BA2,
|
||||
Definitions.FileType.ZIP,
|
||||
Definitions.FileType.EXE,
|
||||
Definitions.FileType.RAR,
|
||||
Definitions.FileType._7Z);
|
||||
|
||||
public static async Task<ExtractedFiles> ExtractAll(WorkQueue queue, AbsolutePath source, IEnumerable<RelativePath> OnlyFiles = null, bool throwOnError = true)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
OnlyFiles ??= new RelativePath[0];
|
||||
|
||||
try
|
||||
{
|
||||
var sig = await ArchiveSigs.MatchesAsync(source);
|
||||
|
||||
if (source.Extension == Consts.OMOD)
|
||||
return await ExtractAllWithOMOD(source);
|
||||
|
||||
switch (sig)
|
||||
{
|
||||
case Definitions.FileType.BSA:
|
||||
case Definitions.FileType.TES3:
|
||||
case Definitions.FileType.BA2:
|
||||
return await ExtractAllWithBSA(queue, source);
|
||||
case Definitions.FileType.EXE:
|
||||
return await ExtractAllExe(source);
|
||||
case Definitions.FileType._7Z:
|
||||
case Definitions.FileType.ZIP:
|
||||
case Definitions.FileType.RAR:
|
||||
return await ExtractAllWith7Zip(source, OnlyFiles);
|
||||
}
|
||||
throw new Exception("Invalid archive format");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (!throwOnError)
|
||||
return new ExtractedFiles(await TempFolder.Create());
|
||||
|
||||
Utils.Log(ex.ToString());
|
||||
Utils.ErrorThrow(ex, $"Error while extracting {source}");
|
||||
throw new Exception();
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task<ExtractedFiles> ExtractAllExe(AbsolutePath source)
|
||||
{
|
||||
var isArchive = await TestWith7z(source);
|
||||
|
||||
if (isArchive)
|
||||
{
|
||||
return await ExtractAllWith7Zip(source, (IEnumerable<RelativePath>) null);
|
||||
}
|
||||
|
||||
var dest = await TempFolder.Create();
|
||||
Utils.Log($"Extracting {(string)source.FileName}");
|
||||
|
||||
var process = new ProcessHelper
|
||||
{
|
||||
Path = @"Extractors\innounp.exe".RelativeTo(AbsolutePath.EntryPoint),
|
||||
Arguments = new object[] {"-x", "-y", "-b", $"-d\"{dest.Dir}\"", source}
|
||||
};
|
||||
|
||||
|
||||
var result = process.Output.Where(d => d.Type == ProcessHelper.StreamType.Output)
|
||||
.ForEachAsync(p =>
|
||||
{
|
||||
var (_, line) = p;
|
||||
if (line == null)
|
||||
return;
|
||||
|
||||
if (line.Length <= 4 || line[3] != '%')
|
||||
return;
|
||||
|
||||
int.TryParse(line.Substring(0, 3), out var percentInt);
|
||||
Utils.Status($"Extracting {source.FileName} - {line.Trim()}", Percent.FactoryPutInRange(percentInt / 100d));
|
||||
});
|
||||
await process.Start();
|
||||
return new ExtractedFiles(dest);
|
||||
}
|
||||
|
||||
private class OMODProgress : ICodeProgress
|
||||
{
|
||||
private long _total;
|
||||
|
||||
public void SetProgress(long inSize, long outSize)
|
||||
{
|
||||
Utils.Status("Extracting OMOD", Percent.FactoryPutInRange(inSize, _total));
|
||||
}
|
||||
|
||||
public void Init(long totalSize, bool compressing)
|
||||
{
|
||||
_total = totalSize;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task<ExtractedFiles> ExtractAllWithOMOD(AbsolutePath source)
|
||||
{
|
||||
var dest = await TempFolder.Create();
|
||||
Utils.Log($"Extracting {(string)source.FileName}");
|
||||
|
||||
Framework.Settings.TempPath = (string)dest.Dir;
|
||||
Framework.Settings.CodeProgress = new OMODProgress();
|
||||
|
||||
var omod = new OMOD((string)source);
|
||||
omod.GetDataFiles();
|
||||
omod.GetPlugins();
|
||||
|
||||
return new ExtractedFiles(dest);
|
||||
}
|
||||
|
||||
|
||||
private static async Task<ExtractedFiles> ExtractAllWithBSA(WorkQueue queue, AbsolutePath source)
|
||||
{
|
||||
try
|
||||
{
|
||||
var arch = await BSADispatch.OpenRead(source);
|
||||
var files = arch.Files.ToDictionary(f => f.Path, f => (IExtractedFile)new ExtractedBSAFile(f));
|
||||
return new ExtractedFiles(files);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Utils.ErrorThrow(ex, $"While Extracting {source}");
|
||||
throw new Exception();
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task<ExtractedFiles> ExtractAllWith7Zip(AbsolutePath source, IEnumerable<RelativePath> onlyFiles)
|
||||
{
|
||||
var dest = await TempFolder.Create();
|
||||
Utils.Log(new GenericInfo($"Extracting {(string)source.FileName}", $"The contents of {(string)source.FileName} are being extracted to {(string)source.FileName} using 7zip.exe"));
|
||||
|
||||
var files = onlyFiles.ToHashSet();
|
||||
|
||||
using var archive = await ArchiveFile.Open(source);
|
||||
if (files.Count > 0)
|
||||
{
|
||||
await archive.Extract(path =>
|
||||
{
|
||||
Utils.Log($"Extract file {path} {files.Contains(path)} {dest.Dir.Combine(path)}");
|
||||
return files.Contains(path) ? dest.Dir.Combine(path) : default;
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
await archive.Extract(path => dest.Dir.Combine(path));
|
||||
}
|
||||
|
||||
return new ExtractedFiles(dest);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the given extension type can be extracted
|
||||
/// </summary>
|
||||
/// <param name="v"></param>
|
||||
/// <returns></returns>
|
||||
public static async Task<bool> CanExtract(AbsolutePath v)
|
||||
{
|
||||
var found = await ArchiveSigs.MatchesAsync(v);
|
||||
switch (found)
|
||||
{
|
||||
case null:
|
||||
return false;
|
||||
case Definitions.FileType.EXE:
|
||||
{
|
||||
var process = new ProcessHelper
|
||||
{
|
||||
Path = @"Extractors\innounp.exe".RelativeTo(AbsolutePath.EntryPoint),
|
||||
Arguments = new object[] {"-t", v},
|
||||
};
|
||||
|
||||
return await process.Start() == 0;
|
||||
}
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task<bool> TestWith7z(AbsolutePath file)
|
||||
{
|
||||
var process = new ProcessHelper()
|
||||
{
|
||||
Path = @"Extractors\7z.exe".RelativeTo(AbsolutePath.EntryPoint),
|
||||
Arguments = new object[] {"t", file},
|
||||
};
|
||||
|
||||
return await process.Start() == 0;
|
||||
}
|
||||
|
||||
private static Extension _exeExtension = new Extension(".exe");
|
||||
|
||||
public static bool MightBeArchive(Extension ext)
|
||||
{
|
||||
return ext == _exeExtension || Consts.SupportedArchives.Contains(ext) || Consts.SupportedBSAs.Contains(ext);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extract the specific files to the specific locations
|
||||
/// </summary>
|
||||
/// <param name="queue"></param>
|
||||
/// <param name="archive"></param>
|
||||
/// <param name="indexed"></param>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
public static async Task ExtractTo(WorkQueue queue, AbsolutePath source, Dictionary<RelativePath,AbsolutePath> indexed)
|
||||
{
|
||||
try
|
||||
{
|
||||
var sig = await ArchiveSigs.MatchesAsync(source);
|
||||
|
||||
/*if (source.Extension == Consts.OMOD)
|
||||
return await ExtractAllWithOMOD(source);*/
|
||||
|
||||
switch (sig)
|
||||
{
|
||||
case Definitions.FileType.BSA:
|
||||
case Definitions.FileType.TES3:
|
||||
case Definitions.FileType.BA2:
|
||||
await ExtractAllWithBSA(queue, source, indexed);
|
||||
return;
|
||||
case Definitions.FileType.EXE:
|
||||
await ExtractAllExe(source, indexed);
|
||||
return;
|
||||
case Definitions.FileType._7Z:
|
||||
case Definitions.FileType.ZIP:
|
||||
case Definitions.FileType.RAR:
|
||||
await ExtractAllWith7Zip(source, indexed);
|
||||
return;
|
||||
}
|
||||
throw new Exception("Invalid archive format");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Utils.Log(ex.ToString());
|
||||
Utils.ErrorThrow(ex, $"Error while extracting {source}");
|
||||
throw new Exception();
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task ExtractAllWith7Zip(AbsolutePath source, Dictionary<RelativePath,AbsolutePath> onlyFiles)
|
||||
{
|
||||
using var archive = await ArchiveFile.Open(source);
|
||||
await archive.Extract(f => onlyFiles.TryGetValue(f, out var dest) ? dest : default);
|
||||
}
|
||||
|
||||
private static async Task ExtractAllExe(AbsolutePath source, Dictionary<RelativePath,AbsolutePath> indexed)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private static async Task ExtractAllWithBSA(WorkQueue queue, AbsolutePath source, Dictionary<RelativePath,AbsolutePath> indexed)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Wabbajack.Common;
|
||||
|
||||
namespace Wabbajack.VirtualFileSystem
|
||||
{
|
||||
public interface IExtractedFile
|
||||
{
|
||||
public Task<Hash> HashAsync();
|
||||
public DateTime LastModifiedUtc { get; }
|
||||
public long Size { get; }
|
||||
|
||||
public ValueTask<Stream> OpenRead();
|
||||
|
||||
public Task<bool> CanExtract();
|
||||
|
||||
public Task<ExtractedFiles> ExtractAll(WorkQueue queue, IEnumerable<RelativePath> Only = null, bool throwOnError = false);
|
||||
|
||||
public Task MoveTo(AbsolutePath path);
|
||||
|
||||
}
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Wabbajack.Common;
|
||||
|
||||
namespace Wabbajack.VirtualFileSystem
|
||||
{
|
||||
public class RootDiskFile : ExtractedDiskFile
|
||||
{
|
||||
public RootDiskFile(AbsolutePath path) : base(path)
|
||||
{
|
||||
}
|
||||
|
||||
public override async Task<Hash> HashAsync()
|
||||
{
|
||||
return await _path.FileHashCachedAsync();
|
||||
}
|
||||
}
|
||||
}
|
@ -18,30 +18,7 @@ namespace Wabbajack.VirtualFileSystem.SevenZipExtractor
|
||||
|
||||
private static readonly AbsolutePath LibraryFilePath = @"Extractors\7z.dll".RelativeTo(AbsolutePath.EntryPoint);
|
||||
private static SignatureChecker _checker = new SignatureChecker(Formats.FileTypeGuidMapping.Keys.ToArray());
|
||||
|
||||
public static async Task<ArchiveFile> Open(AbsolutePath archiveFilePath)
|
||||
{
|
||||
var self = new ArchiveFile();
|
||||
|
||||
self.InitializeAndValidateLibrary();
|
||||
|
||||
if (!archiveFilePath.IsFile)
|
||||
{
|
||||
throw new SevenZipException("Archive file not found");
|
||||
}
|
||||
|
||||
var format = await _checker.MatchesAsync(archiveFilePath);
|
||||
|
||||
if (format == null)
|
||||
{
|
||||
throw new SevenZipException($"Unknown format for {archiveFilePath}");
|
||||
}
|
||||
|
||||
self._archive = self._sevenZipHandle.CreateInArchive(Formats.FileTypeGuidMapping[format.Value]);
|
||||
self._archiveStream = new InStreamWrapper(await archiveFilePath.OpenRead());
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
public static async Task<ArchiveFile> Open(Stream archiveStream, Definitions.FileType format)
|
||||
{
|
||||
var self = new ArchiveFile();
|
||||
@ -51,64 +28,6 @@ namespace Wabbajack.VirtualFileSystem.SevenZipExtractor
|
||||
return self;
|
||||
}
|
||||
|
||||
public async Task Extract(AbsolutePath outputFolder, bool overwrite = false)
|
||||
{
|
||||
await this.Extract(entry =>
|
||||
{
|
||||
var fileName = outputFolder.Combine(entry.FileName);
|
||||
|
||||
if (!fileName.Exists || overwrite)
|
||||
{
|
||||
return fileName;
|
||||
}
|
||||
|
||||
return default;
|
||||
});
|
||||
}
|
||||
|
||||
public async Task Extract(Func<RelativePath, AbsolutePath> getOutputPath)
|
||||
{
|
||||
IList<Stream> fileStreams = new List<Stream>();
|
||||
|
||||
try
|
||||
{
|
||||
foreach (Entry entry in Entries)
|
||||
{
|
||||
|
||||
AbsolutePath outputPath = entry.IsFolder ? default : getOutputPath((RelativePath)entry.FileName);
|
||||
|
||||
if (outputPath == default) // getOutputPath = null means SKIP
|
||||
{
|
||||
fileStreams.Add(null);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (entry.IsFolder)
|
||||
{
|
||||
outputPath.CreateDirectory();
|
||||
fileStreams.Add(null);
|
||||
continue;
|
||||
}
|
||||
|
||||
var directoryName = outputPath.Parent;
|
||||
directoryName.CreateDirectory();
|
||||
|
||||
fileStreams.Add(await outputPath.Create());
|
||||
}
|
||||
|
||||
this._archive.Extract(null, 0xFFFFFFFF, 0, new ArchiveStreamsCallback(fileStreams));
|
||||
}
|
||||
finally
|
||||
{
|
||||
foreach (Stream stream in fileStreams)
|
||||
{
|
||||
if (stream == null) continue;
|
||||
var tsk = stream?.DisposeAsync();
|
||||
await tsk.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IList<Entry> Entries
|
||||
{
|
||||
get
|
||||
@ -123,7 +42,7 @@ namespace Wabbajack.VirtualFileSystem.SevenZipExtractor
|
||||
|
||||
if (open != 0)
|
||||
{
|
||||
throw new SevenZipException("Unable to open archive");
|
||||
throw new Exception("Unable to open archive");
|
||||
}
|
||||
|
||||
uint itemsCount = this._archive.GetNumberOfItems();
|
||||
@ -221,7 +140,7 @@ namespace Wabbajack.VirtualFileSystem.SevenZipExtractor
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new SevenZipException("Unable to initialize SevenZipHandle", e);
|
||||
throw new Exception("Unable to initialize SevenZipHandle", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,57 +0,0 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Wabbajack.VirtualFileSystem.SevenZipExtractor
|
||||
{
|
||||
internal class ArchiveFileCallback : IArchiveExtractCallback
|
||||
{
|
||||
private readonly string fileName;
|
||||
private readonly uint fileNumber;
|
||||
private OutStreamWrapper fileStream; // to be removed
|
||||
|
||||
public ArchiveFileCallback(uint fileNumber, string fileName)
|
||||
{
|
||||
this.fileNumber = fileNumber;
|
||||
this.fileName = fileName;
|
||||
}
|
||||
|
||||
public void SetTotal(ulong total)
|
||||
{
|
||||
}
|
||||
|
||||
public void SetCompleted(ref ulong completeValue)
|
||||
{
|
||||
}
|
||||
|
||||
public int GetStream(uint index, out ISequentialOutStream outStream, AskMode askExtractMode)
|
||||
{
|
||||
if ((index != this.fileNumber) || (askExtractMode != AskMode.kExtract))
|
||||
{
|
||||
outStream = null;
|
||||
return 0;
|
||||
}
|
||||
|
||||
string fileDir = Path.GetDirectoryName(this.fileName);
|
||||
|
||||
if (!string.IsNullOrEmpty(fileDir))
|
||||
{
|
||||
Directory.CreateDirectory(fileDir);
|
||||
}
|
||||
|
||||
this.fileStream = new OutStreamWrapper(File.Create(this.fileName));
|
||||
|
||||
outStream = this.fileStream;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void PrepareOperation(AskMode askExtractMode)
|
||||
{
|
||||
}
|
||||
|
||||
public void SetOperationResult(OperationResult resultEOperationResult)
|
||||
{
|
||||
this.fileStream.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
using System.IO;
|
||||
|
||||
namespace Wabbajack.VirtualFileSystem.SevenZipExtractor
|
||||
{
|
||||
internal class ArchiveStreamCallback : IArchiveExtractCallback
|
||||
{
|
||||
private readonly uint fileNumber;
|
||||
private readonly Stream stream;
|
||||
|
||||
public ArchiveStreamCallback(uint fileNumber, Stream stream)
|
||||
{
|
||||
this.fileNumber = fileNumber;
|
||||
this.stream = stream;
|
||||
}
|
||||
|
||||
public void SetTotal(ulong total)
|
||||
{
|
||||
}
|
||||
|
||||
public void SetCompleted(ref ulong completeValue)
|
||||
{
|
||||
}
|
||||
|
||||
public int GetStream(uint index, out ISequentialOutStream outStream, AskMode askExtractMode)
|
||||
{
|
||||
if ((index != this.fileNumber) || (askExtractMode != AskMode.kExtract))
|
||||
{
|
||||
outStream = null;
|
||||
return 0;
|
||||
}
|
||||
|
||||
outStream = new OutStreamWrapper(this.stream);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void PrepareOperation(AskMode askExtractMode)
|
||||
{
|
||||
}
|
||||
|
||||
public void SetOperationResult(OperationResult resultEOperationResult)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace Wabbajack.VirtualFileSystem.SevenZipExtractor
|
||||
{
|
||||
internal class ArchiveStreamsCallback : IArchiveExtractCallback
|
||||
{
|
||||
private readonly IList<Stream> streams;
|
||||
|
||||
public ArchiveStreamsCallback(IList<Stream> streams)
|
||||
{
|
||||
this.streams = streams;
|
||||
}
|
||||
|
||||
public void SetTotal(ulong total)
|
||||
{
|
||||
}
|
||||
|
||||
public void SetCompleted(ref ulong completeValue)
|
||||
{
|
||||
}
|
||||
|
||||
public int GetStream(uint index, out ISequentialOutStream outStream, AskMode askExtractMode)
|
||||
{
|
||||
if (askExtractMode != AskMode.kExtract)
|
||||
{
|
||||
outStream = null;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (this.streams == null)
|
||||
{
|
||||
outStream = null;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Stream stream = this.streams[(int) index];
|
||||
|
||||
if (stream == null)
|
||||
{
|
||||
outStream = null;
|
||||
return 0;
|
||||
}
|
||||
|
||||
outStream = new OutStreamWrapper(stream);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void PrepareOperation(AskMode askExtractMode)
|
||||
{
|
||||
}
|
||||
|
||||
public void SetOperationResult(OperationResult resultEOperationResult)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@ -85,35 +85,5 @@ namespace Wabbajack.VirtualFileSystem.SevenZipExtractor
|
||||
/// True if there are parts of this file in next split archive parts
|
||||
/// </summary>
|
||||
public bool IsSplitAfter { get; set; }
|
||||
|
||||
public void Extract(string fileName, bool preserveTimestamp = true)
|
||||
{
|
||||
if (this.IsFolder)
|
||||
{
|
||||
Directory.CreateDirectory(fileName);
|
||||
return;
|
||||
}
|
||||
|
||||
string directoryName = Path.GetDirectoryName(fileName);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(directoryName))
|
||||
{
|
||||
Directory.CreateDirectory(directoryName);
|
||||
}
|
||||
|
||||
using (FileStream fileStream = File.Create(fileName))
|
||||
{
|
||||
this.Extract(fileStream);
|
||||
}
|
||||
|
||||
if (preserveTimestamp)
|
||||
{
|
||||
File.SetLastWriteTime(fileName, this.LastWriteTime);
|
||||
}
|
||||
}
|
||||
public void Extract(Stream stream)
|
||||
{
|
||||
this.archive.Extract(new[] { this.index }, 1, 0, new ArchiveStreamCallback(this.index, stream));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,87 +6,7 @@ namespace Wabbajack.VirtualFileSystem.SevenZipExtractor
|
||||
{
|
||||
public class Formats
|
||||
{
|
||||
internal static readonly Dictionary<string, SevenZipFormat> ExtensionFormatMapping = new Dictionary<string, SevenZipFormat>
|
||||
{
|
||||
{"7z", SevenZipFormat.SevenZip},
|
||||
{"gz", SevenZipFormat.GZip},
|
||||
{"tar", SevenZipFormat.Tar},
|
||||
{"rar", SevenZipFormat.Rar},
|
||||
{"zip", SevenZipFormat.Zip},
|
||||
{"lzma", SevenZipFormat.Lzma},
|
||||
{"lzh", SevenZipFormat.Lzh},
|
||||
{"arj", SevenZipFormat.Arj},
|
||||
{"bz2", SevenZipFormat.BZip2},
|
||||
{"cab", SevenZipFormat.Cab},
|
||||
{"chm", SevenZipFormat.Chm},
|
||||
{"deb", SevenZipFormat.Deb},
|
||||
{"iso", SevenZipFormat.Iso},
|
||||
{"rpm", SevenZipFormat.Rpm},
|
||||
{"wim", SevenZipFormat.Wim},
|
||||
{"udf", SevenZipFormat.Udf},
|
||||
{"mub", SevenZipFormat.Mub},
|
||||
{"xar", SevenZipFormat.Xar},
|
||||
{"hfs", SevenZipFormat.Hfs},
|
||||
{"dmg", SevenZipFormat.Dmg},
|
||||
{"z", SevenZipFormat.Lzw},
|
||||
{"xz", SevenZipFormat.XZ},
|
||||
{"flv", SevenZipFormat.Flv},
|
||||
{"swf", SevenZipFormat.Swf},
|
||||
{"exe", SevenZipFormat.PE},
|
||||
{"dll", SevenZipFormat.PE},
|
||||
{"vhd", SevenZipFormat.Vhd}
|
||||
};
|
||||
|
||||
internal static Dictionary<SevenZipFormat, Guid> FormatGuidMapping = new Dictionary<SevenZipFormat, Guid>
|
||||
{
|
||||
{SevenZipFormat.SevenZip, new Guid("23170f69-40c1-278a-1000-000110070000")},
|
||||
{SevenZipFormat.Arj, new Guid("23170f69-40c1-278a-1000-000110040000")},
|
||||
{SevenZipFormat.BZip2, new Guid("23170f69-40c1-278a-1000-000110020000")},
|
||||
{SevenZipFormat.Cab, new Guid("23170f69-40c1-278a-1000-000110080000")},
|
||||
{SevenZipFormat.Chm, new Guid("23170f69-40c1-278a-1000-000110e90000")},
|
||||
{SevenZipFormat.Compound, new Guid("23170f69-40c1-278a-1000-000110e50000")},
|
||||
{SevenZipFormat.Cpio, new Guid("23170f69-40c1-278a-1000-000110ed0000")},
|
||||
{SevenZipFormat.Deb, new Guid("23170f69-40c1-278a-1000-000110ec0000")},
|
||||
{SevenZipFormat.GZip, new Guid("23170f69-40c1-278a-1000-000110ef0000")},
|
||||
{SevenZipFormat.Iso, new Guid("23170f69-40c1-278a-1000-000110e70000")},
|
||||
{SevenZipFormat.Lzh, new Guid("23170f69-40c1-278a-1000-000110060000")},
|
||||
{SevenZipFormat.Lzma, new Guid("23170f69-40c1-278a-1000-0001100a0000")},
|
||||
{SevenZipFormat.Nsis, new Guid("23170f69-40c1-278a-1000-000110090000")},
|
||||
{SevenZipFormat.Rar, new Guid("23170f69-40c1-278a-1000-000110030000")},
|
||||
{SevenZipFormat.Rar5, new Guid("23170f69-40c1-278a-1000-000110CC0000")},
|
||||
{SevenZipFormat.Rpm, new Guid("23170f69-40c1-278a-1000-000110eb0000")},
|
||||
{SevenZipFormat.Split, new Guid("23170f69-40c1-278a-1000-000110ea0000")},
|
||||
{SevenZipFormat.Tar, new Guid("23170f69-40c1-278a-1000-000110ee0000")},
|
||||
{SevenZipFormat.Wim, new Guid("23170f69-40c1-278a-1000-000110e60000")},
|
||||
{SevenZipFormat.Lzw, new Guid("23170f69-40c1-278a-1000-000110050000")},
|
||||
{SevenZipFormat.Zip, new Guid("23170f69-40c1-278a-1000-000110010000")},
|
||||
{SevenZipFormat.Udf, new Guid("23170f69-40c1-278a-1000-000110E00000")},
|
||||
{SevenZipFormat.Xar, new Guid("23170f69-40c1-278a-1000-000110E10000")},
|
||||
{SevenZipFormat.Mub, new Guid("23170f69-40c1-278a-1000-000110E20000")},
|
||||
{SevenZipFormat.Hfs, new Guid("23170f69-40c1-278a-1000-000110E30000")},
|
||||
{SevenZipFormat.Dmg, new Guid("23170f69-40c1-278a-1000-000110E40000")},
|
||||
{SevenZipFormat.XZ, new Guid("23170f69-40c1-278a-1000-0001100C0000")},
|
||||
{SevenZipFormat.Mslz, new Guid("23170f69-40c1-278a-1000-000110D50000")},
|
||||
{SevenZipFormat.PE, new Guid("23170f69-40c1-278a-1000-000110DD0000")},
|
||||
{SevenZipFormat.Elf, new Guid("23170f69-40c1-278a-1000-000110DE0000")},
|
||||
{SevenZipFormat.Swf, new Guid("23170f69-40c1-278a-1000-000110D70000")},
|
||||
{SevenZipFormat.Vhd, new Guid("23170f69-40c1-278a-1000-000110DC0000")},
|
||||
{SevenZipFormat.Flv, new Guid("23170f69-40c1-278a-1000-000110D60000")},
|
||||
{SevenZipFormat.SquashFS, new Guid("23170f69-40c1-278a-1000-000110D20000")},
|
||||
{SevenZipFormat.Lzma86, new Guid("23170f69-40c1-278a-1000-0001100B0000")},
|
||||
{SevenZipFormat.Ppmd, new Guid("23170f69-40c1-278a-1000-0001100D0000")},
|
||||
{SevenZipFormat.TE, new Guid("23170f69-40c1-278a-1000-000110CF0000")},
|
||||
{SevenZipFormat.UEFIc, new Guid("23170f69-40c1-278a-1000-000110D00000")},
|
||||
{SevenZipFormat.UEFIs, new Guid("23170f69-40c1-278a-1000-000110D10000")},
|
||||
{SevenZipFormat.CramFS, new Guid("23170f69-40c1-278a-1000-000110D30000")},
|
||||
{SevenZipFormat.APM, new Guid("23170f69-40c1-278a-1000-000110D40000")},
|
||||
{SevenZipFormat.Swfc, new Guid("23170f69-40c1-278a-1000-000110D80000")},
|
||||
{SevenZipFormat.Ntfs, new Guid("23170f69-40c1-278a-1000-000110D90000")},
|
||||
{SevenZipFormat.Fat, new Guid("23170f69-40c1-278a-1000-000110DA0000")},
|
||||
{SevenZipFormat.Mbr, new Guid("23170f69-40c1-278a-1000-000110DB0000")},
|
||||
{SevenZipFormat.MachO, new Guid("23170f69-40c1-278a-1000-000110DF0000")}
|
||||
};
|
||||
|
||||
|
||||
internal static Dictionary<Definitions.FileType, Guid> FileTypeGuidMapping = new Dictionary<Definitions.FileType, Guid>
|
||||
{
|
||||
{Definitions.FileType._7Z, new Guid("23170f69-40c1-278a-1000-000110070000")},
|
||||
@ -96,27 +16,5 @@ namespace Wabbajack.VirtualFileSystem.SevenZipExtractor
|
||||
{Definitions.FileType.ZIP, new Guid("23170f69-40c1-278a-1000-000110010000")},
|
||||
};
|
||||
|
||||
internal static Dictionary<SevenZipFormat, byte[]> FileSignatures = new Dictionary<SevenZipFormat, byte[]>
|
||||
{
|
||||
{SevenZipFormat.Rar5, new byte[] {0x52, 0x61, 0x72, 0x21, 0x1A, 0x07, 0x01, 0x00}},
|
||||
{SevenZipFormat.Rar, new byte[] { 0x52, 0x61, 0x72, 0x21, 0x1A, 0x07, 0x00 }},
|
||||
{SevenZipFormat.Vhd, new byte[] { 0x63, 0x6F, 0x6E, 0x65, 0x63, 0x74, 0x69, 0x78 }},
|
||||
{SevenZipFormat.Deb, new byte[] { 0x21, 0x3C, 0x61, 0x72, 0x63, 0x68, 0x3E }},
|
||||
{SevenZipFormat.Dmg, new byte[] { 0x78, 0x01, 0x73, 0x0D, 0x62, 0x62, 0x60 }},
|
||||
{SevenZipFormat.SevenZip, new byte[] { 0x37, 0x7A, 0xBC, 0xAF, 0x27, 0x1C }},
|
||||
{SevenZipFormat.Tar, new byte[] { 0x75, 0x73, 0x74, 0x61, 0x72 }},
|
||||
{SevenZipFormat.Iso, new byte[] { 0x43, 0x44, 0x30, 0x30, 0x31 }},
|
||||
{SevenZipFormat.Cab, new byte[] { 0x4D, 0x53, 0x43, 0x46 }},
|
||||
{SevenZipFormat.Rpm, new byte[] { 0xed, 0xab, 0xee, 0xdb }},
|
||||
{SevenZipFormat.Xar, new byte[] { 0x78, 0x61, 0x72, 0x21 }},
|
||||
{SevenZipFormat.Chm, new byte[] { 0x49, 0x54, 0x53, 0x46 }},
|
||||
{SevenZipFormat.BZip2, new byte[] { 0x42, 0x5A, 0x68 }},
|
||||
{SevenZipFormat.Flv, new byte[] { 0x46, 0x4C, 0x56 }},
|
||||
{SevenZipFormat.Swf, new byte[] { 0x46, 0x57, 0x53 }},
|
||||
{SevenZipFormat.GZip, new byte[] { 0x1f, 0x0b }},
|
||||
{SevenZipFormat.Zip, new byte[] { 0x50, 0x4b }},
|
||||
{SevenZipFormat.Arj, new byte[] { 0x60, 0xEA }},
|
||||
{SevenZipFormat.Lzh, new byte[] { 0x2D, 0x6C, 0x68 }}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -1,24 +0,0 @@
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace Wabbajack.VirtualFileSystem.SevenZipExtractor
|
||||
{
|
||||
public class SevenZipException : Exception
|
||||
{
|
||||
public SevenZipException()
|
||||
{
|
||||
}
|
||||
|
||||
public SevenZipException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public SevenZipException(string message, Exception innerException) : base(message, innerException)
|
||||
{
|
||||
}
|
||||
|
||||
protected SevenZipException(SerializationInfo info, StreamingContext context) : base(info, context)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@ -1,285 +0,0 @@
|
||||
namespace Wabbajack.VirtualFileSystem.SevenZipExtractor
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public enum SevenZipFormat
|
||||
{
|
||||
// Default invalid format value
|
||||
Undefined = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Open 7-zip archive format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/7-zip">Wikipedia information</a></remarks>
|
||||
SevenZip,
|
||||
|
||||
/// <summary>
|
||||
/// Proprietary Arj archive format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/ARJ">Wikipedia information</a></remarks>
|
||||
Arj,
|
||||
|
||||
/// <summary>
|
||||
/// Open Bzip2 archive format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/Bzip2">Wikipedia information</a></remarks>
|
||||
BZip2,
|
||||
|
||||
/// <summary>
|
||||
/// Microsoft cabinet archive format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/Cabinet_(file_format)">Wikipedia information</a></remarks>
|
||||
Cab,
|
||||
|
||||
/// <summary>
|
||||
/// Microsoft Compiled HTML Help file format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/Microsoft_Compiled_HTML_Help">Wikipedia information</a></remarks>
|
||||
Chm,
|
||||
|
||||
/// <summary>
|
||||
/// Microsoft Compound file format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/Compound_File_Binary_Format">Wikipedia information</a></remarks>
|
||||
Compound,
|
||||
|
||||
/// <summary>
|
||||
/// Open Cpio archive format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/Cpio">Wikipedia information</a></remarks>
|
||||
Cpio,
|
||||
|
||||
/// <summary>
|
||||
/// Open Debian software package format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/Deb_(file_format)">Wikipedia information</a></remarks>
|
||||
Deb,
|
||||
|
||||
/// <summary>
|
||||
/// Open Gzip archive format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/Gzip">Wikipedia information</a></remarks>
|
||||
GZip,
|
||||
|
||||
/// <summary>
|
||||
/// Open ISO disk image format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/ISO_image">Wikipedia information</a></remarks>
|
||||
Iso,
|
||||
|
||||
/// <summary>
|
||||
/// Open Lzh archive format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/Lzh">Wikipedia information</a></remarks>
|
||||
Lzh,
|
||||
|
||||
/// <summary>
|
||||
/// Open core 7-zip Lzma raw archive format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/Lzma">Wikipedia information</a></remarks>
|
||||
Lzma,
|
||||
|
||||
/// <summary>
|
||||
/// Nullsoft installation package format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/NSIS">Wikipedia information</a></remarks>
|
||||
Nsis,
|
||||
|
||||
/// <summary>
|
||||
/// RarLab Rar archive format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="https://en.wikipedia.org/wiki/RAR_(file_format)">Wikipedia information</a></remarks>
|
||||
Rar,
|
||||
|
||||
/// <summary>
|
||||
/// RarLab Rar archive format, version 5.
|
||||
/// </summary>
|
||||
/// <remarks><a href="https://en.wikipedia.org/wiki/RAR_(file_format)">Wikipedia information</a></remarks>
|
||||
Rar5,
|
||||
|
||||
/// <summary>
|
||||
/// Open Rpm software package format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/RPM_Package_Manager">Wikipedia information</a></remarks>
|
||||
Rpm,
|
||||
|
||||
/// <summary>
|
||||
/// Open split file format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="?">Wikipedia information</a></remarks>
|
||||
Split,
|
||||
|
||||
/// <summary>
|
||||
/// Open Tar archive format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/Tar_(file_format)">Wikipedia information</a></remarks>
|
||||
Tar,
|
||||
|
||||
/// <summary>
|
||||
/// Microsoft Windows Imaging disk image format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/Windows_Imaging_Format">Wikipedia information</a></remarks>
|
||||
Wim,
|
||||
|
||||
/// <summary>
|
||||
/// Open LZW archive format; implemented in "compress" program; also known as "Z" archive format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/Compress">Wikipedia information</a></remarks>
|
||||
Lzw,
|
||||
|
||||
/// <summary>
|
||||
/// Open Zip archive format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/ZIP_(file_format)">Wikipedia information</a></remarks>
|
||||
Zip,
|
||||
|
||||
/// <summary>
|
||||
/// Open Udf disk image format.
|
||||
/// </summary>
|
||||
Udf,
|
||||
|
||||
/// <summary>
|
||||
/// Xar open source archive format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/Xar_(archiver)">Wikipedia information</a></remarks>
|
||||
Xar,
|
||||
|
||||
/// <summary>
|
||||
/// Mub
|
||||
/// </summary>
|
||||
Mub,
|
||||
|
||||
/// <summary>
|
||||
/// Macintosh Disk Image on CD.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/HFS_Plus">Wikipedia information</a></remarks>
|
||||
Hfs,
|
||||
|
||||
/// <summary>
|
||||
/// Apple Mac OS X Disk Copy Disk Image format.
|
||||
/// </summary>
|
||||
Dmg,
|
||||
|
||||
/// <summary>
|
||||
/// Open Xz archive format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/Xz">Wikipedia information</a></remarks>
|
||||
XZ,
|
||||
|
||||
/// <summary>
|
||||
/// MSLZ archive format.
|
||||
/// </summary>
|
||||
Mslz,
|
||||
|
||||
/// <summary>
|
||||
/// Flash video format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/Flv">Wikipedia information</a></remarks>
|
||||
Flv,
|
||||
|
||||
/// <summary>
|
||||
/// Shockwave Flash format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/Swf">Wikipedia information</a></remarks>
|
||||
Swf,
|
||||
|
||||
/// <summary>
|
||||
/// Windows PE executable format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/Portable_Executable">Wikipedia information</a></remarks>
|
||||
PE,
|
||||
|
||||
/// <summary>
|
||||
/// Linux executable Elf format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/Executable_and_Linkable_Format">Wikipedia information</a></remarks>
|
||||
Elf,
|
||||
|
||||
/// <summary>
|
||||
/// Windows Installer Database.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/Windows_Installer">Wikipedia information</a></remarks>
|
||||
Msi,
|
||||
|
||||
/// <summary>
|
||||
/// Microsoft virtual hard disk file format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="http://en.wikipedia.org/wiki/VHD_%28file_format%29">Wikipedia information</a></remarks>
|
||||
Vhd,
|
||||
|
||||
/// <summary>
|
||||
/// SquashFS file system format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="https://en.wikipedia.org/wiki/SquashFS">Wikipedia information</a></remarks>
|
||||
SquashFS,
|
||||
|
||||
/// <summary>
|
||||
/// Lzma86 file format.
|
||||
/// </summary>
|
||||
Lzma86,
|
||||
|
||||
/// <summary>
|
||||
/// Prediction by Partial Matching by Dmitry algorithm.
|
||||
/// </summary>
|
||||
/// <remarks><a href="https://en.wikipedia.org/wiki/Prediction_by_partial_matching">Wikipedia information</a></remarks>
|
||||
Ppmd,
|
||||
|
||||
/// <summary>
|
||||
/// TE format.
|
||||
/// </summary>
|
||||
TE,
|
||||
|
||||
/// <summary>
|
||||
/// UEFIc format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="https://en.wikipedia.org/wiki/Unified_Extensible_Firmware_Interface">Wikipedia information</a></remarks>
|
||||
UEFIc,
|
||||
|
||||
/// <summary>
|
||||
/// UEFIs format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="https://en.wikipedia.org/wiki/Unified_Extensible_Firmware_Interface">Wikipedia information</a></remarks>
|
||||
UEFIs,
|
||||
|
||||
/// <summary>
|
||||
/// Compressed ROM file system format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="https://en.wikipedia.org/wiki/Cramfs">Wikipedia information</a></remarks>
|
||||
CramFS,
|
||||
|
||||
/// <summary>
|
||||
/// APM format.
|
||||
/// </summary>
|
||||
APM,
|
||||
|
||||
/// <summary>
|
||||
/// Swfc format.
|
||||
/// </summary>
|
||||
Swfc,
|
||||
|
||||
/// <summary>
|
||||
/// NTFS file system format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="https://en.wikipedia.org/wiki/NTFS">Wikipedia information</a></remarks>
|
||||
Ntfs,
|
||||
|
||||
/// <summary>
|
||||
/// FAT file system format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="https://en.wikipedia.org/wiki/File_Allocation_Table">Wikipedia information</a></remarks>
|
||||
Fat,
|
||||
|
||||
/// <summary>
|
||||
/// MBR format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="https://en.wikipedia.org/wiki/Master_boot_record">Wikipedia information</a></remarks>
|
||||
Mbr,
|
||||
|
||||
/// <summary>
|
||||
/// Mach-O file format.
|
||||
/// </summary>
|
||||
/// <remarks><a href="https://en.wikipedia.org/wiki/Mach-O">Wikipedia information</a></remarks>
|
||||
MachO
|
||||
}
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Wabbajack.Common;
|
||||
|
||||
namespace Wabbajack.VirtualFileSystem.SevenZipExtractor
|
||||
{
|
||||
internal class TypedExtractor<T> : IArchiveExtractCallback
|
||||
{
|
||||
private Dictionary<RelativePath, T> _mappings;
|
||||
private Action<RelativePath, T, Func<Stream>> _callback;
|
||||
private Dictionary<uint, RelativePath> _indexToFile;
|
||||
|
||||
public TypedExtractor(Dictionary<RelativePath, T> mappings, Action<RelativePath, T, Func<Stream>> callback)
|
||||
{
|
||||
_mappings = mappings;
|
||||
_callback = callback;
|
||||
}
|
||||
|
||||
public void Extract(ArchiveFile file)
|
||||
{
|
||||
_indexToFile = new Dictionary<uint, RelativePath>();
|
||||
|
||||
uint idx = 0;
|
||||
foreach (var entry in file.Entries)
|
||||
{
|
||||
var rel = (RelativePath)entry.FileName;
|
||||
if (_mappings.ContainsKey(rel)) ;
|
||||
{
|
||||
_indexToFile.Add(idx, rel);
|
||||
}
|
||||
idx += 1;
|
||||
}
|
||||
|
||||
file._archive.Extract(null, 0xFFFFFFFF, 0, this);
|
||||
}
|
||||
|
||||
public void SetTotal(ulong total)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public void SetCompleted(ref ulong completeValue)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public int GetStream(uint index, out ISequentialOutStream outStream, AskMode askExtractMode)
|
||||
{
|
||||
outStream = null;
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public void PrepareOperation(AskMode askExtractMode)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public void SetOperationResult(OperationResult resultEOperationResult)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
@ -49,23 +49,6 @@ namespace Wabbajack.VirtualFileSystem
|
||||
|
||||
public Context Context { get; set; }
|
||||
|
||||
private IExtractedFile _stagedFile = null;
|
||||
public IExtractedFile StagedFile
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsNative) return new ExtractedDiskFile(AbsoluteName);
|
||||
if (_stagedFile == null)
|
||||
throw new InvalidDataException("File is unstaged");
|
||||
return _stagedFile;
|
||||
}
|
||||
set
|
||||
{
|
||||
_stagedFile = value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the nesting factor for this file. Native files will have a nesting of 1, the factor
|
||||
/// goes up for each nesting of a file in an archive.
|
||||
@ -382,11 +365,6 @@ namespace Wabbajack.VirtualFileSystem
|
||||
var path = new HashRelativePath(FilesInFullPath.First().Hash, paths);
|
||||
return path;
|
||||
}
|
||||
|
||||
public async ValueTask<Stream> OpenRead()
|
||||
{
|
||||
return await StagedFile.OpenRead();
|
||||
}
|
||||
}
|
||||
|
||||
public class ExtendedHashes
|
||||
|
Loading…
Reference in New Issue
Block a user